If you've used Memcheck (from Valgrind) you'll probably be familiar with this message...
Conditional jump or move depends on uninitialized value(s)
I've read about this and it simply occurs when you use an uninitialized value.
MyClass s;
s.DoStuff();
This will work because s
is automatically initialized... So if this is the case, and it works, why does Memcheck tell me that it's uninitialized? Should the message be ignored?
Perhaps I misunderstood where the error was directing me. From the Valgrind manual, the actual erroneous snippet is...
int main()
{
int x;
printf ("x = %d\n", x);
}
However, in my code, I can't see anything like that. I have noticed however that the function at the top of the stack trace Memcheck shows me is a virtual function; could this be something to do with it?
==14446== Conditional jump or move depends on uninitialised value(s)
==14446== at 0x414164: vimrid::glut::GlutApplication::FinishRender() (GlutApplication.cpp:120)
==14446== by 0x422434: vimrid::demos::filterdemos::FilterDemo3::Render() (FilterDemo3.cpp:260)
==14446== by 0x412D3D: vimrid::VimridApplication::UpdateAndRender() (VimridApplication.cpp:93)
==14446== by 0x4144BA: vimrid::glut::GlutApplication::glutHandleDisplay() (GlutApplication.cpp:201)
==14446== by 0x41486A: vimrid::glut::GlutApplication::glutCallbackDisplay() (GlutApplication.cpp:277)
==14446== by 0x54D9FAA: (within /usr/lib64/libglut.so.3.8.0)
==14446== by 0x54DDA4A: fgEnumWindows (in /usr/lib64/libglut.so.3.8.0)
==14446== by 0x54DA4A3: glutMainLoopEvent (in /usr/lib64/libglut.so.3.8.0)
==14446== by 0x54DAEB5: glutMainLoop (in /usr/lib64/libglut.so.3.8.0)
==14446== by 0x413FF8: vimrid::glut::GlutApplication::Run() (GlutApplication.cpp:112)
==14446== by 0x41249D: vimrid::Launcher::runDemo(vimrid::VimridSettings&) (Launcher.cpp:150)
==14446== by 0x412767: vimrid::Launcher::Launch(int, char**) (Launcher.cpp:62)
I took a look at GlutApplication.cpp:120, and it looks like the uninitialized variable was being passed in to a function on that line. Simple!
I most commonly see this error in code like the following
MyClass s1;
...
if ( someCondition ) {
goto Foo:
}
MyClass s2;
Foo:
cout << s2.GetName();
This code is fundamentally incorrect. The reason why is that even though s2
has a constructor, it's not executed if someCondition
is true. The goto
statement will jump over the initialization, and at the last line of the program, s2
will be uninitialized and essentially point to garbage.
You may also want to check out this page, which gives hints on how to decipher this particular valgrind error
https://computing.llnl.gov/code/memcheck/#deciphering4
Addendum
Another common cause for this is when you pass over some integer constants to a variadic function, which are put on the stack as int
s, but when the caller gets it as long
s, you've got a problem on 64-bit machines.
I was almost about to give up and just consider valgrind being stupid, then I've realised that simply casting it to long
fixes it.
So my upshot is: take this messages seriously.