tags 251815 - moreinfo found 251815 1:3.7.0-6 thanks On Fri, May 11, 2012 at 04:01:37PM +0200, Alessandro Ghedini wrote: > > ==17712== Conditional jump or move depends on uninitialised value(s) > > > > I was getting such a message. But when I looked at it closely it > > appears that the value isn't actually unintialized. What happened was > > two values - one known to be 0 and another uninitialized - were > > multiplied together to give this value that valgrind thinks is > > unitialized. Of course zero times an unitialized (in this case, > > integer) value is always 0. So this warning is spurious on Valgrind's > > part.
I'm very dubious as to whether "fixing" this would be an improvement. At the C level, it's undefined behaviour. While you might think you'll get 0 out, the optimisers can take advantage of knowing it's undefined and give a different answer. That warning from valgrind really is something you should be fixing in your code. The reason why valgrind generally only reports when undefined values actually affect control flow or get passed to a syscall is because of hand-written assembler and optimised compiler output which do things like copy undefined values around. That isn't the case here - this is C code doing things which are undefined in C. I've not managed to get this particular case to give a result other than zero (it seems that currently "multiplication by zero" gets optimised before taking advantage of the undefined value), but this example shows the sort of optimisations that I'm talking about: $ cat x.c int f(int y) { int x; return y < 0 ? 42 : x + y; } $ gcc -O2 -S -o- x.c .file "x.c" .text .p2align 4,,15 .globl f .type f, @function f: .LFB0: .cfi_startproc movl $42, %eax ret .cfi_endproc .LFE0: .size f, .-f .ident "GCC: (Debian 4.7.2-4) 4.7.2" .section .note.GNU-stack,"",@progbits So the compiler has taken advantage of the result of computing x+y being undefined behaviour and optimised the function to effectively just: int f(int y) { return 42; } And that's totally valid - if y is negative, then 42 is the right answer. If y isn't negative, the program is permitted to do anything, and that includes returning 42 from f. > Does this still happen with the sid version of valgrind? If so, it would be > much more helpful if you could provide a snippet of code that reproduces the > problem, instead of describing it in English :) Testcase attached. With valgrind 1:3.7.0-6 and gcc 4:4.7.2-1 on amd64: $ gcc -Wall -W -g vg-zero-mul.c vg-zero-mul.c: In function ‘main’: vg-zero-mul.c:5:11: warning: ‘x’ is used uninitialized in this function [-Wuninitialized] $ valgrind ./a.out ==10770== Memcheck, a memory error detector ==10770== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. ==10770== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info ==10770== Command: ./a.out ==10770== ==10770== Use of uninitialised value of size 8 ==10770== at 0x4E70FCB: _itoa_word (_itoa.c:195) ==10770== by 0x4E72FA6: vfprintf (vfprintf.c:1622) ==10770== by 0x4E7C279: printf (printf.c:35) ==10770== by 0x400532: main (vg-zero-mul.c:5) ==10770== ==10770== Conditional jump or move depends on uninitialised value(s) ==10770== at 0x4E70FD5: _itoa_word (_itoa.c:195) ==10770== by 0x4E72FA6: vfprintf (vfprintf.c:1622) ==10770== by 0x4E7C279: printf (printf.c:35) ==10770== by 0x400532: main (vg-zero-mul.c:5) ==10770== ==10770== Conditional jump or move depends on uninitialised value(s) ==10770== at 0x4E730BA: vfprintf (vfprintf.c:1622) ==10770== by 0x4E7C279: printf (printf.c:35) ==10770== by 0x400532: main (vg-zero-mul.c:5) ==10770== ==10770== Conditional jump or move depends on uninitialised value(s) ==10770== at 0x4E730D8: vfprintf (vfprintf.c:1622) ==10770== by 0x4E7C279: printf (printf.c:35) ==10770== by 0x400532: main (vg-zero-mul.c:5) ==10770== 0 ==10770== ==10770== HEAP SUMMARY: ==10770== in use at exit: 0 bytes in 0 blocks ==10770== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==10770== ==10770== All heap blocks were freed -- no leaks are possible ==10770== ==10770== For counts of detected and suppressed errors, rerun with: -v ==10770== Use --track-origins=yes to see where uninitialised values come from ==10770== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 4 from 4) And much the same if you compile with clang instead. I think that "wontfix" is the appropriate response though. Cheers, Olly
#include <stdio.h> int main() { int x; int y = 0; printf("%d", x * y); return 0; }
signature.asc
Description: Digital signature