24

I know that sometimes if you don't initialize an int, you will get a random number if you print the integer.

But initializing everything to zero seems kind of silly.

I ask because I'm commenting up my C project and I'm pretty straight on the indenting and it compiles fully (90/90 thank you Stackoverflow) but I want to get 10/10 on the style points.

So, the question: when is it appropriate to initialize, and when should you just declare a variable:

int a = 0;

vs.

int a;
Arthur Collé
  • 2,541
  • 5
  • 27
  • 39

10 Answers10

39

There are several circumstances where you should not initialize a variable:

  1. When it has static storage duration (static keyword or global var) and you want the initial value to be zero. Most compilers will actually store zeros in the binary if you explicitly initialize, which is usually just a waste of space (possibly a huge waste for large arrays).
  2. When you will be immediately passing the address of the variable to another function that fills its value. Here, initializing is just a waste of time and may be confusing to readers of the code who wonder why you're storing something in a variable that's about to be overwritten.
  3. When a meaningful value for the variable can't be determined until subsequent code has completed execution. In this case, it's actively harmful to initialize the variable with a dummy value such as zero/NULL, as this prevents the compiler from warning you if you have some code paths where a meaningful value is never assigned. Compilers are good at warning you about accessing uninitialized variables, but can't warn you about "still contains dummy value" variables.

Aside from these issues, I'd say it's generally good practice to initialize your non-static variables when possible.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • +1 I agree with your answer, and find myself totally surprised at most of the other answers. (What do they teach them in schools these days?) But I've a minor quibble wrt your "huge waste": in the old days initializing the `.bss` was only about three lines of assembly code (and the question is tagged `C`). – Joseph Quinsey Nov 03 '11 at 04:06
  • 1
    The "huge waste" is when the all-zero object gets stored in data rather than bss. Most (all?) compilers do this when you *explicitly* initialize, which is why I advised always using implicit zero initialization when possible. – R.. GitHub STOP HELPING ICE Nov 03 '11 at 12:33
  • 1
    I was thinking back to crt0's for ROM-based systems in the mid-80s. But now the OS apparently uses zero-fill-on-demand; see [this](http://stackoverflow.com/questions/3532334/how-about-bss-section-not-zero-initialized/3532593#3532593). A quick test `echo 'char foo[0x88888]; int main(void) {return 0;}' | gcc -x c - && readelf -a a.out | grep bss` gives `... .bss NOBITS ... 0888a8 ...`. – Joseph Quinsey Nov 03 '11 at 21:19
  • +1 for thoughtful well-reasoned reply. This gives good insights about the reasons for variables not being initialized. However, I'm from the opposite camp.I was always told, that all variables must be initialized to avoid occasional use of random value (and as consequence, non-reproducible bugs).And I wanted to give counter-example for the third case: unfortunately lately I work a lot with code, authors of which did not care about warnings. So I have hundreds of those. As a result I cannot rely on compiler warnings.In this case I prefer to have deterministic behavior rather then another warnig – Dmitrii Semikin Jun 02 '15 at 21:25
  • And one more counter-example for the second case: imagine, the function, which have "out" argument, i.e. it takes `Type** pObject` and resets the pointer to new object. IMHO in such a case it would be natural to require `*pObject == NULL`, which would make our intention to use argument as pure "out" more explicit. Theoretically it may help to find memory leaks (when the function is called on pointer, which point to existing object). But as a bottom line I have to admit, that probably, this discussion is just kind of "holy war" and the answer mostly depends on preferences of the programmer. – Dmitrii Semikin Jun 02 '15 at 21:37
  • 1
    I believe code cleanness and readability are often underestimated. Saving one word write at the expenses of higher error-proneness in code maintenance (what if someone will later use that variable? Will he/she have compiler warnings enabled? What if the function which is supposed to update the value does not touch it, e.g. because of an error?) looks a little crazy to me. I hope this kind of optimization is only performed in performance critical sections such as software decoders and nowhere else. (BTW, many compilers will even skip that write if another one is in the codepath) – Narcolessico Jan 16 '20 at 13:03
  • Sure, have you read mine? I don't state that yours is false ;) and I've read the closing phrase, but I still think the argument is purely theoretical. For example, point 2 can't be in a performance-critical section, where you would rarely have actual function calls, so "wasting time" with a single write is in 99,99% cases an overkill with respect to readability. – Narcolessico Jan 17 '20 at 19:04
  • @Narcolessico: The performance aspect of #2 isn't relevant to a single `int`, but would be when it's `char buf[4096];`. The matter that it's confusing is more important. If I saw someone store to an object they're about to pass to a function, I'd assume the function was going to read the stored value from it rather than just write over top of it, and I'd spend time digging into why that's the case for a function whose name doesn't make sense to do that...then discover that it was just a bogus gratuitous initialization. – R.. GitHub STOP HELPING ICE Jan 17 '20 at 21:01
  • Fair enough, my comment holds in the specific examples reported in the answer where a single primitive value is initialized. – Narcolessico Jan 18 '20 at 23:07
  • @Narcolessico: Yes. But I'd still be confused to see something like `int foo = 0; get_val(&foo, bar, x);` -- does `get_val` somehow depend on the pointed-to value being in a particular state before the call? – R.. GitHub STOP HELPING ICE Jan 18 '20 at 23:09
  • (sorry I can't mention your nick properly...) You should not answer to a semantic question from the variable initialization anyway. It might be a bug: what if you don't initialize, but the function reads its value? And what if some lines of code or new calls are added later in between? A bug would be introduced. Side consideration, that's why this kind of reference passing is considered not particularly readable for primitive types, unless the existing code/architecture does really impose this legacy style. – Narcolessico Jan 20 '20 at 06:31
31

A rule that hasn't been mentioned yet is this: when the variable is declared inside a function it is not initialised, and when it is declared in static or global scope it's set to 0:

int a; // is set to 0

void foo() {
  int b;  // set to whatever happens to be in memory there
}

However - for readability I would usually initialise everything at declaration time.

If you're interested in learning this sort of thing in detail, I'd recommend this presentation and this book

Timothy Jones
  • 21,495
  • 6
  • 60
  • 90
5

I can think of a couple of reason off the top of my head:

  1. When you're going to be initializing it later on in your code.

    int x;
    
    if(condition)
    {
        func();
        x = 2;
    }
    else
    {
       x = 3;
    }
    anotherFunc(x); // x will have been set a value no matter what
    
  2. When you need some memory to store a value set by a function or another piece of code:

    int x;  // Would be pointless to give x a value here
    scanf("%d", &x);
    
  • 2
    That code will generate a warning in g++ because x is used without being initialized. – anio Nov 02 '11 at 02:05
5

Static and global variables will be initialized to zero for you so you may skip initialization. Automatic variables (e.g. non-static variables defined in function body) may contain garbage and should probably always be initialized.

If there is a non-zero specific value you need at initialization then you should always initialize explicitly.

Adam Zalcman
  • 26,643
  • 4
  • 71
  • 92
5

If the variable is in the scope of of a function and not a member of a class I always initialize it because otherwise you will get warnings. Even if this variable will be used later I prefer to assign it on declaration.

As for member variables, you should initialize them in the constructor of your class.

For pointers, always initialize them to some default, particularly NULL, even if they are to be used later, they are dangerous when uninitialized.

Also it is recommended to build your code with the highest level of warnings that your compiler supports, it helps to identify bad practices and potential errors.

anio
  • 8,903
  • 7
  • 35
  • 53
  • Thanks, I'm programming on Terminal on a gcc/Linux shell (sorry if these are wrong words, I just type code and hope for the best) and we are told to compile with gcc -Wall -Werror -ansi -pedantic-errors xxx.c main.c so it tells you that the dumbest little things are errors, so thanks for the tip! – Arthur Collé Nov 02 '11 at 02:35
4

It's always good practice to initialize your variables, but sometimes it's not strictly necessary. Consider the following:

int a;
for (a = 0; a < 10; a++) { } // a is initialized later

or

void myfunc(int& num) {
  num = 10;
}

int a;
myfunc(&a); // myfunc sets, but does not read, the value in a

or

char a;
cin >> a; // perhaps the most common example in code of where
          // initialization isn't strictly necessary

These are just a couple of examples where it isn't strictly necessary to initialize a variable, since it's set later (but not accessed between declaration and initialization).

In general though, it doesn't hurt to always initialize your variables at declaration (and indeed, this is probably best practice).

Jared Ng
  • 4,891
  • 2
  • 19
  • 18
2

In general, there's no need to initialize a variable, with 2 notable exceptions:

  1. You're declaring a pointer (and not assigning it immediately) - you should always set these to NULL as good style and defensive programming.
  2. If, when you declare the variable, you already know what value is going to be assigned to it. Further assignments use up more CPU cycles.

Beyond that, it's about getting the variables into the right state that you want them in for the operation you're going to perform. If you're not going to be reading them before an operation changes their value (and the operation doesn't care what state it is in), there's no need to initialize them.

Personally, I always like to initialize them anyway; if you forgot to assign it a value, and it's passed into a function by mistake (like a remaining buffer length) 0 is usually cleanly handled - 32532556 wouldn't be.

septical
  • 430
  • 2
  • 8
  • 1
    So you advise him it's only necessary under two conditions but then say you always do it and give an example why he should? – Lou Nov 02 '11 at 02:28
  • thanks septical, I liked "Beyond that, it's about getting the variables into the right state that you want them in for the operation you're going to perform." very insightful – Arthur Collé Nov 02 '11 at 02:39
  • I never said it's only necessary, just that in 90% of the situations nobody would notice the difference. In the example, the application would still be broken - only without initialization, you're likely to crash rather than provide incorrect results. Good style dictates that you should initialize them (nothing mandates that you should), and so that's why I provided my opinion. – septical Nov 02 '11 at 02:44
2

There is absolutely no reason why variables shouldn't be initialised, the compiler is clever enough to ignore the first assignment if a variable is being assigned twice. It is easy for code to grow in size where things you took for granted (such as assigning a variable before being used) are no longer true. Consider:

int MyVariable;
void Simplistic(int aArg){
    MyVariable=aArg;
}

//Months later:

int MyVariable;
void Simplistic(int aArg){
    MyVariable+=aArg; // Unsafe, since MyVariable was never initialized.
}

One is fine, the other lands you in a heap of trouble. Occasionally you'll have issues where your application will run in debug mode, but release mode will throw an exception, one reason for this is using an uninitialised variable.

anio
  • 8,903
  • 7
  • 35
  • 53
R4D4
  • 1,382
  • 2
  • 13
  • 34
  • The first version of simplistic is safe. The second version is not since it adds to the existing value of MyVariable. MyVariable was never initialized so we add aArg to some unknown value. – anio Nov 02 '11 at 03:53
  • 3
    `MyVariable` had static storage duration so it's impossible to be uninitialized. If it's not explicitly initialized, its initial value is zero. – R.. GitHub STOP HELPING ICE Nov 02 '11 at 06:47
1

As long as I have not read from a variable before writing to it, I have not had to bother with initializing it.

Reading before writing can cause serious and hard to catch bugs. I think this class of bugs is notorious enough to gain a mention in the popular SICP lecture videos.

vpit3833
  • 7,817
  • 2
  • 25
  • 25
  • It means using the variable in print statements, using it as part of an expression whose result depends on the value of the variable, etc. And, writing to a variable means, assigning a value to it. – vpit3833 Nov 02 '11 at 02:56
0

Initializing a variable, even if it is not strictly required, is ALWAYS a good practice. The few extra characters (like "= 0") typed during development may save hours of debugging time later, particularly when it is forgotten that some variables remained uninitialized.

In passing, I feel it is good to declare a variable close to its use.

The following is bad:

int a;    // line 30
...
a = 0;    // line 40

The following is good:

int a = 0;  // line 40

Also, if the variable is to be overwritten right after initialization, like

int a = 0;
a = foo();

it is better to write it as

int a = foo();
Arun
  • 19,750
  • 10
  • 51
  • 60