Why must a variable be initialized ?

Started by
49 comments, last by Aardvajk 12 years, 10 months ago

The point isn't that int has an inherent invariant that's being preserved by initialization; the point is that your code's interpretation of that int has invariants. Are you using the int to represent a counter? Initialize to 0. Are you using the int to represent a multiplicative accumulator? Initialize to 1. Are you using the int to represent the answer to life, the universe, and everything? Initialize to 42.


I agree with you.

For those who doesn't agree; It's just about choosing logical numbers when you initilize. For example, if I have a timer that counts down from 60 seconds, wouldn't the most logical initialization number be 60 then?

When we are talking about initialization, I just have to put in a small question. When programming in C# XNA, how would you initialize your variables?
1. When you declare them
2. In the constructor
3. In the Initialize method

All three ways works. So far I've always initilized in the constructor as some classes recives parameters. Which one is the "more" correct?
Advertisement

When we are talking about initialization, I just have to put in a small question. When programming in C# XNA, how would you initialize your variables?
1. When you declare them
2. In the constructor
3. In the Initialize method

All three ways works. So far I've always initilized in the constructor as some classes recives parameters. Which one is the "more" correct?


well C# is kind of different. C# default initializes every member variable to 0 or null if they are a value type or reference type respectively. Personally I would do it in the constructor for 99% of the cases. If you are going to fill it with a meaningful value in the initialize function vs constructor (if they have to be different), I would still give it some default value in the constructor.

One time I might not is if I am perhaps storing some sort of cache or something whose point of existing is that something shouldn't be stored in it all the time. This sentence sounded horrible in my head and I'm not quite sure how to say it better, so I am just going to stop. C# is managed and usually throws useful errors, so I find myself slightly less willing to learn the ins and outs perfectly.
Class members in C# are default initialized, so it's recommended that you don't do additional initialization on top of them unless you're going to be setting them to a different value than the default. Locals, on the other hand, require that you initialize them before first use, and the compiler will give you an error if you don't.
Mike Popoloski | Journal | SlimDX
We are arguing apples and oranges here. If there is a logical initial value for a variable, then nobody is arguing that it shouldn't be initialised. The debate as I understood it was whether you should initialise a local POD if you are going to then overwrite that value with another one prior to first-read.

I actually agree with iMalc's comment on the last page - I've been struggling to think of an example of an instance where you actually need to declare a variable prior to knowing what it needs to contain, apart from the idiomatic std::cin example. In that example, given that you would be checking the fail state of the stream rather than the contents of the variable for an error, I still maintain that there is little point giving an int a "default" value prior to the read. If you are incorrectly assuming the variable contains a valid value, the error is not checking the stream for a fail, not not default initialising the variable.

But of course it is irrelevant with a modern compiler, so I'll still probably sleep okay tonight. :)
Resource acquisition is initialization. This is a deep mantra of C++ and should be taken to heart.

If you don't need a resource yet (POD variable, in this case) don't define it. If you do need it, initialize it. Period.


Nobody's saying you should initialize and then overwrite and then read; I'm saying you should initialize with preference to assigning over top of an uninitialized value. This has serious implications for non-POD types so doing it for all types is a good habit. I disagree fundamentally with the std::cin example for reasons I already provided, as well as the fact that a "real" system should be wrapping error checking for potential stream failures into a template function or something, as someone else already indicated as well.

In short, in properly written code, the initialize-write-read situation should never occur in the first place. You either have initialize-read, or you don't define the variable/object at all.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


Resource acquisition is initialization. This is a deep mantra of C++ and should be taken to heart.

If you don't need a resource yet (POD variable, in this case) don't define it. If you do need it, initialize it. Period.


Nobody's saying you should initialize and then overwrite and then read; I'm saying you should initialize with preference to assigning over top of an uninitialized value. This has serious implications for non-POD types so doing it for all types is a good habit. I disagree fundamentally with the std::cin example for reasons I already provided, as well as the fact that a "real" system should be wrapping error checking for potential stream failures into a template function or something, as someone else already indicated as well.

In short, in properly written code, the initialize-write-read situation should never occur in the first place. You either have initialize-read, or you don't define the variable/object at all.


I totally agree with this right here. This is the one thing that every programmer should take to heart. When I code I create the variable when I need it I don't declare/initialize it before that moment. This is actually one of the biggest advantages C++ has over C. In C prior to C99 I believe correct me if I am wrong but you MUST declare all your variables at the top of a function before code. With C++ and C99 you can declare your variables anywhere.

A majority of the time when I declare my variables it is when I need it and it is receiving a variable from somewhere that it should have. You see this in for loops when you use for(int i = 0; i <= 20; i++) or even more often the variable receives something from a function int i = add(3, 5); If you sit down and look at proper C++ usually this is how it is done period. If you don't need a variable at that exact moment why waste memory leaving it lay around till later.
Well I can think of a few examples. For example, what if the initialization code is conditional, but you need access to the variable in the enclosing scope?

int f;

switch (x)
{
case 0: f = someval; break;
case 1: f = someotherval; break;
default: f = somethirdval; break;
}

//value of f used here
I trust exceptions about as far as I can throw them.

Well I can think of a few examples. For example, what if the initialization code is conditional, but you need access to the variable in the enclosing scope?

int f;

switch (x)
{
case 0: f = someval; break;
case 1: f = someotherval; break;
default: f = somethirdval; break;
}

//value of f used here



This is the kind of code where the new lambda support in C++0x can come into play:


int f = [&x]() -> int
{
switch (x)
{
case 0: return someval;
case 1: return someotherval;
default: return somethirdval;
}
}();


You get the best of both worlds. You can even declare f const if you want.

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]

Well I'm using GCC 4.4.1, which unfortunately doesn't support lambdas.
I trust exceptions about as far as I can throw them.
What if the switch statement calculates multiple values?
I guess you could create a special struct and make a function that returns it, but that is starting to get unnecessarily complicated.

Also, what if you're stuck with an older compiler that doens't have full C++0x support?
I trust exceptions about as far as I can throw them.

This topic is closed to new replies.

Advertisement