Question

I understand that local variables are not initialised automatically in C++, so before using them, you should always assign a value to them. However, at least in simple cases, the compiler should warn you in case you forget it. I'm more or less relying on and referring to this article.

Given this program, I'd assume to get a warning when sending x to std::cout...

#include <iostream>

int main(int argc, const char * argv[])
{

  int x;
  std::cout << x;

  return 0;
}

...but no warning pops up. If, however, I run the static analyzer, I do get the expected warning: Function call argument is an uninitialized value.

I compile & run using Xcode 5.1 with the Apple LLVM 5.1 compiler. I use the standard build settings from Xcode's command line project template (C++), the language dialects are set to GNU99 (for C) and GNU++11 (C++).

The Uninitialized Variables option is set to Yes (Aggressive) (-Wconditional-uninitialized). Switching to just Yes (-Wuninitialized) raises the warning: Variable 'x' is uninitialized when used here. Question Part 1: Why does the warning not show with the default setting (-Wconditional-uninitialized)? The documentation in Xcode suggests that the aggressive option finds more issues:

You can toggle between the normal uninitialized value checking or the more aggressive (conservative) checking which finds more issues but the checking is much stricter.

Strangely enough, when I run the program, the value is always set to 0, so for some reason, it seems to be initialised. Question Part 2: Why is that?

Was it helpful?

Solution

  1. Why not the warning?

Using clang with -Wall on my system correctly warns about the error. Apparently, the default settings do not include -Wall (may be to avoid generating warnings with correct code that was written before some of the warnings were introduced).

In general, you're however going to be in trouble if you rely on the compiler to help you with sloppy programming. Typing in code without thinking carefully and hoping the compiler will tell you all mistakes is bad in any language but a true total disaster with C++. The main philosophy of C++ is simply that the programmer doesn't make any error, so just don't make them ;-)

Think carefully and also always work with -Wall if you can.

  1. Why is initialized?

Apparently, you've not understood what is the meaning of "undefined behavior". It doesn't mean the program crashes, it doesn't mean it will do anything funny. It means it can do anything and normally the programs do whatever will create the most problems for you in the future.

Often this most dangerous behavior is to make it look as if everything is fine (e.g. that your variable is indeed initialized). The bad values will only show once you put that code in production or only when you show your program running in front of a vast audience. At that point, the value will be different and the video of your public crash will go viral on youtube, your wife will change the door locks and even your parents will not answer your phone calls.

Just initialize your variables; it's better :-)

OTHER TIPS

It's necessary but enough to turn on -Wall to make our code safe.

e.g. The following code, under MacOS's g++(it's clang) will print out 0, but it is definitely a UB:

#include <stdio.h>
#include <iostream>

using namespace std;

class Blob {
public:
    int age;
    void hello() { printf("hello\n"); }
};

int main() {
    Blob a;
    //a.hello();
    cout << a.age << endl;

    return 0;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top