1

Consider the following program

struct X
{
    int d;
    X(){} // forget to initialize d
};

int main()
{
    X x;
    volatile int y=x.d; // read uninitialized d
    (void)y; // (kill useless warning)
}

Clearly it has undefined behavior, which I'd like in general to be able to catch using some debugging tool. I've tried cppcheck (using their online demo) and g++ -fsanitize=address as well as g++ -fsanitize=undefined, and valgrind. But these tools don't report me that x.d is uninitialized when read.

What tools can I use to catch these sorts of undefined behavior (preferably running on Linux)?

Ruslan
  • 18,162
  • 8
  • 67
  • 136
  • 1
    If you use GCC you can use the `-Weffc++` option, it should cause a warning for not initializing member variables with the constructor. – Some programmer dude Dec 27 '15 at 08:38
  • 1
    @JoachimPileborg but what if the class is defined in a library header, and there're tons of such classes? It will distract with lots of useless warnings and won't actually be helpful for cases where I've forgotten to set the member after having constructed the class before using that member. Example: `Eigen::Matrix` template. – Ruslan Dec 27 '15 at 08:40
  • If the code is open source, Coverity will let you run their static analysis checker for free. If it is closed source, they will let you run their static analysis tool - but they want paying. (It is very good though) – Martin Bonner supports Monica Dec 27 '15 at 08:45
  • Asking for tool or library recommendation is **off topic**. Voted to close. – Cheers and hth. - Alf Jan 03 '16 at 21:13
  • You can't eat your cake and have it, either you want warning for constructor not initializing variables or not. It's impossible to only warn when uninitialized variables are used (this would require solving the halting problem). – M.M Jan 03 '16 at 22:11
  • @M.M well you can always put this into runtime, as e.g. address sanitizer does. – Ruslan Jan 04 '16 at 07:35
  • I believe you should use [MemorySanitizer](http://clang.llvm.org/docs/MemorySanitizer.html), not address sanitizer for such checks. Unfortunately, right now it's only in clang – Jurasic Feb 04 '16 at 09:48

3 Answers3

2

Scanning the provided example

$ more test.cpp 
struct X
{
  int d;
  X(){} // forget to initialize d
};

int main()
{
  X x;
  volatile int y=x.d; // read uninitialized d
  (void)y; // (kill useless warning)
}

with the latest version of cppcheck (version 1.72 dev) gives:

$ cppcheck --enable=all test.cpp 
 Checking test.cpp...
 [test.cpp:4]: (warning) Member variable 'X::d' is not initialized in the constructor.
orbitcowboy
  • 1,438
  • 13
  • 25
0

I read a lot about the tool PVS-Studio. It should catch such warnings. Unfortunately it is not free, but at least you can try a demo to check if it works good enough for you.

Alex
  • 9,891
  • 11
  • 53
  • 87
0

You were close with -fsanitize=address. Memory sanitizer should do what you want (-fsanitize=memory).

the swine
  • 10,713
  • 7
  • 58
  • 100
  • g++ 7.3 doesn't support this option, and trying with clang++ 6.0 doesn't find the error in the OP. – Ruslan Jan 28 '19 at 21:44
  • @Ruslan I think the sanitizer might be silencing it (in error) since there is a constructor. Can you try with an ordinary variable and see if the error is detected then? It should be. – the swine Feb 04 '19 at 17:42
  • `int d; volatile int Y=d;` also doesn't give any errors from sanitizer. – Ruslan Feb 04 '19 at 18:17
  • Strange, should work, fairly sure it works on clang, I get hit by these errors from time to time. – the swine Feb 04 '19 at 23:18