-1

I tried the following versions of codes with both GCC and Clang/LLVM:

Version 1

#include <stdio.h>    
main() {
    work();
    return 0;
}
work() {
    int b;
    printf("b: %d \n", b);
}

Version 2

#include <stdio.h>    
main() {
    work();
    return 0;
}
work() {
    int a = 1;
    int b;
    printf("a: %d b: %d \n", a, b);
}

Version 3

#include <stdio.h>    
void work() {
    int a = 1;
    int b;
    printf("a: %d b: %d \n", a, b);
}
int main(int argc, char** argv) {
    work();
    return 0;
}

For GCC,

Version 1 outputs b: 0.

Version 2 outputs a: 1 b: 4195728.

Version 3 outputs a: 1 b: 1742650088.

For Clang (LLVM),

Version 1 outputs b: 0.

Version 2 outputs a: 1 b: -1643302816.

Version 3 outputs a: 1 b: 0.

I ran the same codes on several machines many times. The ones produced "0" always produced "0", that is, in these cases, b was initialized.

Questions:

  1. What makes the GCC and Clang always produce "0" in version 1?

  2. What makes Clang always produce "0" in Version 3?

JackWM
  • 10,085
  • 22
  • 65
  • 92
  • 3
    uninitialized values = undefined behaviour (anything could happen) – David Ranieri Jan 02 '14 at 09:11
  • @AlterMann Theoretically, it is undefined. But it seems not under some conditions. – JackWM Jan 02 '14 at 09:28
  • @JackWM Obtaining 0 does not mean that your program does not invoke undefined behavior. – Pascal Cuoq Jan 02 '14 at 09:40
  • @PascalCuoq Could you please make an example in which some undefined behaviors occur as well as `b == 0`? – JackWM Jan 02 '14 at 09:46
  • @JackWM, compile with `-S` to get assembler output, `b = 0` is the behaviour of clang, (as valid as `b = 1742650088` for gcc) – David Ranieri Jan 02 '14 at 09:49
  • @JackWM Undefined behavior is a property of the source code. Just because with one version of one compiler at one optimization level it seems that you reliably obtain 0, does not mean that undefined behavior has not occurred. The program does not need to crash or behave erratically for undefined behavior to be there. – Pascal Cuoq Jan 02 '14 at 16:00

2 Answers2

4

Reading a variable that is never initialized and for which the address is never taken has undefined behavior. That means that a compiler implementor can chose whatever pleases. So if you'd really interested ask the implementors directly, not us. But as Pascal suggests, I don't think that they will be much interested in your question, and I doubt also that you might find anything interesting about that in their documentation. But since these are open source compilers you may look into the sources to see what they are doing.

In essence you can't expect anything sensible from your code.

If you are seriously be interested in your compilers and what they have to tell you, switch on at least some warnings for your code (use -Wall). The first two versions that you have are not even C according to modern standards.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
0

You are accessing uninitialized variable b. The C++ standard does not specify what the value will be when you read it. It can be different on different runs of the same compiled binary. It all depends what was at the place of memory where the variable "b" will be. The compiler won't initialize it to any value.

In fact I believe this is an "undefined" behavior, which is totally undefined and a compiler, which would format your hard drive or crash the app or crash the OS when this happens would be a valid, standard compliant C++ compiler.

So in short: Don't read uninitialized variables and never expect what value you read when you do that.

Palo
  • 1,051
  • 8
  • 12
  • “The C++ standard does not specify what the value will be when you read it.” 1- the question is not about C++ 2- the C standard says this is undefined behavior, not that the value is unspecified when read. – Pascal Cuoq Jan 02 '14 at 09:37