Bug 24956 - Optimizer and uninitialised variables.
Summary: Optimizer and uninitialised variables.
Status: RESOLVED DUPLICATE of bug 22266
Alias: None
Product: gcc
Classification: Unclassified
Component: regression (show other bugs)
Version: 4.0.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-11-20 11:21 UTC by Simon White
Modified: 2005-11-20 15:18 UTC (History)
2 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Simon White 2005-11-20 11:21:25 UTC
#include <stdint.h>
#include <stdio.h>

void test (int c)
{
    uint8_t a[4] = {0, 1, 2, 3};
    uint_least32_t b;
    b &= (uint_least32_t) 0xffffff00;
    b |= (uint_least32_t) a[3];
    b &= (uint_least32_t) 0xffff00ff;
    b |= (uint_least32_t) (a[2] << 8);
    b &= (uint_least32_t) 0xff00ffff;
    b |= (uint_least32_t) (a[1] << 16);
    b &= (uint_least32_t) 0x00ffffff;
    b |= (uint_least32_t) (a[0] << 24);

    printf ("b=%08x\n", b);
    if (c)
    {
        printf ("here\n");
        b = ~0;
        printf ("here2\n");
    }
    printf ("b=%08x\n", b);
}

int main ()
{
    test (0);
    return 0;
}


Output of gcc -O0 bug.cpp -o bug -lstdc++ is:

b=00010203
b=00010203

Output of gcc -O2 bug.cpp -o bug -lstdc++ is:

b=00010203
b=ffffffff

Doing either of these obtains the correct output:

-    uint_least32_t b;
+    uint_least32_t b = 0;

or

-        b = ~0;


System: Fresh install of Mandriva Linux Free 2006.0 with all
        patches applied as of 19/11/2005
gcc -v reports:

Using built-in specs.
Target: i586-mandriva-linux-gnu
Configured with: ../configure --prefix=/usr --libexecdir=/usr/lib --with-slibdir=/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --enable-languages=c,c++,ada,f95,objc,java --host=i586-mandriva-linux-gnu --with-system-zlib --enable-long-long --enable-__cxa_atexit --enable-clocale=gnu --disable-libunwind-exceptions --enable-java-awt=gtk --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --enable-gtk-cairo --disable-libjava-multilib
Thread model: posix
gcc version 4.0.1 (4.0.1-5mdk for Mandriva Linux release 2006.0)
Comment 1 Falk Hueffner 2005-11-20 13:33:09 UTC
There is no "correct" output when you use a variable uninitialized. It's 
undefined behavior. Printing any number, or crashing, would be completely
valid behaviors as far as gcc is concerned.
Comment 2 Paolo Carlini 2005-11-20 13:37:35 UTC
(In reply to comment #1)
> There is no "correct" output when you use a variable uninitialized. It's 
> undefined behavior. Printing any number, or crashing, would be completely
> valid behaviors as far as gcc is concerned.

Falk, of course you are right. However, when I saw the PR coming, I wondered
whether the point was also that it would be nice having the warning emitted
also at low optimization levels. Other compilers can do that, AFAIK. Maybe
we already have something open about that, tough, as enhancement request.
Comment 3 Simon White 2005-11-20 14:15:26 UTC
Sorry the summary may not be 100% correct, but it is related to the variable never being directly assigned.

I do understand that using (i.e. assigning from an unintialised variable) will give you random junk, etc.  However if you look at the example below you'll see the variable becomes fully assigned (the result is always known given a uint_least32_t being 32 bits).  And indeed the first printf does display the correct answer.

However whats happened is that some of the code inside the if statement has executed, which is should never have!

Please if this code is actually invalid... and indeed somehow the code inside the if statement can legally be executed please could you reclose the bug and drop me a note on why?  So far have never seen even highly optimising compilers (e.g. TI c6x, etc) do this.
Comment 4 Falk Hueffner 2005-11-20 14:35:37 UTC
I already explained this. Using an uninitialized variable invokes undefined 
behavior. This means that producing random junk, executing random if statements,
executing random if statements 17 times, formatting your hard disk, and making
demons fly out of your nose are all perfectly valid results. The concept of
"undefined behavior" should be explained in any C book.
Comment 5 Andrew Pinski 2005-11-20 15:18:14 UTC
Reopening to ...
Comment 6 Andrew Pinski 2005-11-20 15:18:51 UTC
Mark as a dup of bug 22266.

*** This bug has been marked as a duplicate of 22266 ***