1

In C a variable of automatic storage class has initial value as garbage value. But the variable declared in the following way gives everytime 0 for all such variables, while it should be a garbage value.

auto int i;
printf("%d",i);
Supriya
  • 13
  • 6
  • 2
    It is undefined. It happens to be a 0. There is no specific "garbage value" as such. – Weather Vane Sep 30 '16 at 17:26
  • Why is zero not a garbage value? – Ed Heal Sep 30 '16 at 17:26
  • 1
    Zero is also a garbage value, it just happens to be a common one. – Hans Passant Sep 30 '16 at 17:27
  • 1
    @WeatherVane: Actually it is indeterminate, not undefined. – too honest for this site Sep 30 '16 at 17:28
  • @Olaf if a value has not been defined, then it is undefined? – Weather Vane Sep 30 '16 at 17:29
  • 1
    @WeatherVane: I strictly refer to the standard. It can be **unspecified** or a trap representation, which is the definition for an indeterminate value. – too honest for this site Sep 30 '16 at 17:30
  • @WeatherVane I guess there is a difference. Undefined behavior can cause nasal demons. indeterminate value cannot... – Eugene Sh. Sep 30 '16 at 17:30
  • @EugeneSh.: That indeed could be the reason to use a different term here. – too honest for this site Sep 30 '16 at 17:31
  • But why everytime the output is zero for all such variables? @HansPassant – Supriya Sep 30 '16 at 17:34
  • I did not tie my shoelaces but I did not fall over. Please explain why. – Weather Vane Sep 30 '16 at 17:35
  • @Olaf Would a `printf` of such a value cause UB? – Eugene Sh. Sep 30 '16 at 17:37
  • @EugeneSh. I was once told it could set my computer on fire. I asked which particular garbage value could do that, and for photographic evidence. – Weather Vane Sep 30 '16 at 17:38
  • @WeatherVane Have you got that value? I wonder how one could determine it out of a burning computer.. – Eugene Sh. Sep 30 '16 at 17:40
  • @EugeneSh.: I thought so once, but I was corrected. IIRC, it is only true if the value has a trap representation. (Sorry, too lazy right now to check myself - long weekend here:-) – too honest for this site Sep 30 '16 at 17:42
  • @EugeneSh. it might happen on some computers when asked to print `-INT_MAX - 1`. – Weather Vane Sep 30 '16 at 17:43
  • @weather vane - perhaps because you are not wearing your shoes at that moment in time – Ed Heal Sep 30 '16 at 17:43
  • @WeatherVane: A device driver could do, if it e.g. messes with power management. An overheated IC can indeed cause burn. Not to forget about burning batteries. Maybe you ask Samsung? (Sony also had some experience with their Vario series). And there were some famous spacecraft disasters due to UB. Not sure if they used C, though. – too honest for this site Sep 30 '16 at 17:44
  • @WeatherVane: On some old computers using ferrite core memory, repeatedly accessing a given memory location in a tight loop could cause a literal core meltdown. – Keith Thompson Sep 30 '16 at 17:51
  • @KeithThompson: Were the cores themselves overheating (parasitic current in the ferrites) or the copper wires through the cores due to the current for the magnetic field? – too honest for this site Sep 30 '16 at 17:55
  • @Olaf one spacecraft disaster was because a certain country was still using 19th century measurement units in their science and technology and failed to realise that most other countries have moved on. – Weather Vane Sep 30 '16 at 17:56
  • @WeatherVane: Living in a country with the SI, I just can agree (I wonder - yet appreciate - a bit you being that clear, though. So there's still hope ;-) But that's not what I meant. I have a faint memory about some problems with type/value conversion. IIRC, that was between 1s and 2s complement device - another reason to define communication protocols very carefully. – too honest for this site Sep 30 '16 at 18:07
  • @Supriya some systems do zero memory to prevent programs snooping on memory that was used by another process, even when they are not required to. Just because the standard says something is not initialised, does not mean the implementation is not allowed to zero it. It means you cannot *assume* it has been initiliased. – Weather Vane Sep 30 '16 at 18:09
  • @Supriya "But why everytime the output is zero for all such variables?" Why not? – too honest for this site Sep 30 '16 at 18:10
  • @Olaf hence my remark about printing `-INT_MAX - 1` which is not guaranteed by the standard? – Weather Vane Sep 30 '16 at 18:12
  • 1
    @WeatherVane: If `INT_MIN == -INT_MAX - 1`, then the behavior is well defined. If not, then just evaluating the expression `-INT_MAX - 1` has undefined behavior, regardless of the presence of absence of trap representations. – Keith Thompson Sep 30 '16 at 18:20
  • @KeithThompson I got that from the accepted answer [here](http://stackoverflow.com/questions/6155784/range-of-values-in-c-int-and-long-32-64-bits) which implies that the calculated value I mentioned is implementation defined, therefore it might cause a burning. – Weather Vane Sep 30 '16 at 18:26
  • 1
    @WeatherVane: Yes, the values of `INT_MIN` and `INT_MAX` are implementation-defined, but the behavior of evaluating `-INT_MAX - 1` is either well defined or undefined, depending on the implementation-defined values of `INT_MIN` and `INT_MAX`. – Keith Thompson Sep 30 '16 at 18:28
  • @KeithThompson isn't that what I was trying to say? In the case of a 32-bit `int`, the standard says the minimum value is `-2**31 + 1` so trying to print `-2**31` on a system that does not support it is UB. I did not mention `INT_MIN`. – Weather Vane Sep 30 '16 at 18:31
  • @WeatherVane: I'm not sure just what you were trying to say. You talked about *printing* the value of `-INT_MAX - 1`. My point is that printing is irrelevant; either it's well defined, or undefined behavior will occur when the expression is evaluated, before you get a chance to print it. (In practice, systems with 32-bit `int` almost always have `INT_MIN` set to -2**32.) I suspect we're not actually disagreeing about anything. – Keith Thompson Sep 30 '16 at 18:38
  • @KeithThompson exactly, I was just trying to avoid being specific about the size of the `int`, which suppose, if 32-bit, had somehow acquired the value `0x80000000` and was sent to a print routine that did not support that. You say "usually" but in other threads commenters will insist our code should be EBCDIC compliant. This all started from a supposition that some uninitialised value of `int` could set the computer on fire, when printed. – Weather Vane Sep 30 '16 at 18:45
  • @WeatherVane: An uninitialized `int` object could in principle set the computer on fire when *accessed*. More precisely, an implementation that sets the computer on fire would not be non-conforming for that reason. – Keith Thompson Sep 30 '16 at 19:15

2 Answers2

4
auto int i;
printf("%d",i);

The keyword auto is unnecessary here; it specifies a storage class that is the default anyway.

The behavior of the above code is explicitly undefined. See N1570 6.3.2.1 paragraph 2. The wording is a bit dense, but it describes how an lvalue (basically an expression that designates an object) is "converted" to the value stored in the object -- in this case, the relevant object is i.

If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.

The value stored in i is arbitrary, and in practice retrieving that value is very likely to give you something that looks like an int value, but the behavior of that access is undefined, which means that the standard says nothing about what actually happens. A compiler can reject the program altogether, or the output of the printf call could in principle be a hyperintelligent shade of the color blue (the latter is admittedly unlikely).

If the access retrieves whatever value is stored in that chunk of memory, then 0 is as likely as any other value, perhaps more so. You might get a different value when you run the same program tomorrow.

(N1570 is the latest publicly available draft of the 2011 ISO C standard.)

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • I ran this program many times with different compilers (gcc and clang), but every time it gives 0 output. – Supriya Oct 02 '16 at 07:16
  • @Supriya: As I said, the behavior is undefined, Printing 0 every time is entirely consistent with that. Literally *any* possible behavior would be valid. – Keith Thompson Oct 02 '16 at 10:17
-1

As per C11 standard (as of N1570):

Section 6.7.9, verse 10

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.

Section 3.19.2

indeterminate value

either an unspecified value or a trap representation

Section 3.19.3

unspecified value

valid value of the relevant type where this International Standard imposes no requirements on which value is chosen in any instance

(This, with only minor changes, is the same wording as in the C99.)

In other words, it's up to compiler or chance what the value can be. It may so happen that the compiler you use imposes additional restrictions on the variables and defaults them to some value.

Community
  • 1
  • 1
Gasper
  • 2,752
  • 1
  • 12
  • 16
  • 1
    C standard is C11, not C99 please reference the standard. – too honest for this site Sep 30 '16 at 17:40
  • @Olaf: I'm fairly sure C11 didn't change that. – Keith Thompson Sep 30 '16 at 17:42
  • 1
    @KeithThompson: Agreed, but ppl could argue there is no evidence C11 did **not** change that. And as the question does not ask about C99, but C, we safely can assume it means standard C, i.e. C11. – too honest for this site Sep 30 '16 at 17:48
  • 1
    In any case, this answer doesn't support the assertion that accessing an object with an indeterminate value has undefined behavior. (Mine does.) – Keith Thompson Sep 30 '16 at 17:50
  • @keithThompson The only standard is c11, all others are not. – Michi Sep 30 '16 at 17:51
  • 1
    @Michi: Then explain why the current ISO C++ standard uses C99 as a normative reference. Yes, ISO says all earlier editions of the standard are obsolete. We are not required to obey what ISO says, and we are free to use the C90 or C99 standard if we want to. To be clear, I am not *advocating* using older editions of the standard, but sometimes it's unavoidable. – Keith Thompson Sep 30 '16 at 17:53
  • @KeithThompson: Re. C++ references C99: Non sequitur. They can reference the Bible if they want to. The C11 standard expicitly states the previous version (C99) is withdrawn with the release of C11 (see the foreword, the same with C99 vs. C90). "We are not required to obey what ISO says ..." No, we are not. But calling something not standard "standard" is incorrect and missleading. You could call it "norm". – too honest for this site Sep 30 '16 at 17:59
  • @keithThompson I'm sorry I can't answer you that. I'm not interested in c++ and I'll probably never be :). Any way this is about C ... I think – Michi Sep 30 '16 at 17:59
  • @Olaf: So the ISO C standard's statement about previous ISO standards is definitive, and the ISO C++ standard's statement about previous ISO standards can be ignored? In the real world, the older editions of the C standard still exist and are still relevant. – Keith Thompson Sep 30 '16 at 18:00
  • @KeithThompson: I did not say that! – too honest for this site Sep 30 '16 at 18:01