2

I heard several times that if you do not initialise a variable then garbage value is stored in it.
Say

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

The above code prints any garbage value, but I want to know that what is the need for storing garbage value if uninitialized?

Cloud
  • 18,753
  • 15
  • 79
  • 153
kevin gomes
  • 1,775
  • 5
  • 22
  • 30

5 Answers5

8

The value of an uninitialized value is not simply unknown or garbage, but indeterminate and evaluating that variable may invoke undefined behavior or implementation-defined behavior.

One possible scenario (which is probably the scenario you are seeing) is that the variable, when evaluated, will return the value that was previously present in that memory address. Therefore, it's not like garbage is explicitly written to that variable.

It's worth noting that languages (or even C implementations) that do not exhibit the behavior you're seeing, do so by explicitly writing zeroes (or other initial values) to that area, before allowing you to use it.

Theodoros Chatzigiannakis
  • 28,773
  • 8
  • 68
  • 104
  • why there is a pre-stored value at that address. Why it is not empty? – kevin gomes Feb 14 '14 at 17:55
  • 1
    @kevingomes: It is not possible for a variable to be "empty" on most architectures. Every memory location has a value. – Dietrich Epp Feb 14 '14 at 17:56
  • @kevingomes Memory cannot be empty. Every value a memory address can contain may also be interpreted as a value of some type (an int, a float, a boolean - whatever you declare it as). The reason your memory address doesn't have a zero value is because memory addresses are reused all the time and the value contained in that address is probably the value assigned to it by a previous use. For example, this address could have been previously used by a local variable of another function (and you get to reuse it because that function has already returned/ended by now). – Theodoros Chatzigiannakis Feb 14 '14 at 18:00
  • If you start with “Strictly speaking”, please be precise and accurate. Strictly speaking, if an automatic object that has not had its address taken is used for its value, the behavior is undefined (C 2011 [N1570] 6.3.2.1 2). Otherwise, for an automatic object, the value is indeterminate (6.7.9 10), and the behavior is a consequence of several things, such as the representation of types (6.2.6), which have several possible results, such as implementation-defined behavior. (This is distinct from undefined behavior. Stating that evaluating the variable invokes undefined behavior is incorrect.) – Eric Postpischil Feb 14 '14 at 18:09
  • @TheodorosChatzigiannakis : If the scope of a variable is ended, then that variable will be removed, but will the value of that variable persist at that location? – kevin gomes Feb 14 '14 at 18:10
  • 1
    @kevingomes Any memory address that is not explicitly rewritten, typically retains its state (I don't know of any examples where this isn't the case - under normal operation of the computer, at least). Thus, after a function ends, any memory it wrote will still contain these last values, until something else comes along to rewrite them. – Theodoros Chatzigiannakis Feb 14 '14 at 18:21
  • @TheodorosChatzigiannakis : But why the previous values are not removed? – kevin gomes Feb 14 '14 at 18:31
  • 1
    @kevingomes Because the C language doesn't demand that they are removed and there are a few reasons for this. One reason is that it simply doesn't matter: a well-written C program should not depend on (practically unknown) leftover values of its memory addresses. Another reason is that the designers of C wanted to leave some space for the compiler implementers to define their own behavior there and possibly put some optimizations in place (if applicable). And there may be other reasons I can't think of. =) – Theodoros Chatzigiannakis Feb 14 '14 at 18:37
  • 1
    @kevingomes Why *would* previous values be "removed," and what would that even mean? Do you expect them to be set to 0? Then there'd be a value of 0 stored there. And I really do mean stored--the bits recording that "0" is the value at that memory location would be faithfully holding on to that information until they are set to something else. For the hardware-level explanation of why it doesn't make sense to talk about "removing" memory values, look into what a memory bit actually is at the hardware level (google "memory flip-flop"). – Kyle Strand Feb 14 '14 at 18:38
7

It is not storing garbage, it prints whatever happens to be there in memory at that address when it is running. This is in the name of efficiency. You don't pay for what you didn't ask for.

EDIT

To answer why there is something in memory. All sort of program runs and need to share memory. When memory is allocated to your process, it is not reset, again for performance reason. Since the variable we are observing is declared on the stack, it could even be your program that put the value there in a previous function call.

Eric Fortin
  • 7,533
  • 2
  • 25
  • 33
  • why there is a pre-stored value at that address. Why it is not empty? – kevin gomes Feb 14 '14 at 17:56
  • 2
    @kevingomes: You cannot have empty memory. There are physical objects that make up the bits. They have some physical state. The physical state of each bit is interpreted by the computer hardware to be zero or one. (You could design hardware to have extra bits that indicate whether the regular bits are in use or not, and those bits could tell you that the regular bits are “empty”, but that costs more work and more manufacturing and more energy. It is generally not done. But HP has a computer which has such bits for some of its registers.) – Eric Postpischil Feb 14 '14 at 17:57
  • @EricFortin: Actually, I just compiled source code with these statements using Apple LLVM version 5.1 and `-O3`, and it did not print whatever happened to be in memory at the location allocated for `i`. The compiler recognized that `i` was not initialized and did not bother to load the memory to pass to `printf`. It simply left the register used to pass the argument uninitialized. I even added a second, identical, `printf` statement, and they printed two different values. – Eric Postpischil Feb 14 '14 at 17:59
  • @EricPostpischil Yes with optimization I can see that happening. – Eric Fortin Feb 14 '14 at 18:00
  • @EricPostpischil: Technically, the second argument to `printf()` is passed in memory on the stack rather than in a register. But yes, it would simply be uninitialized. – Dietrich Epp Feb 14 '14 at 18:04
  • @EricPostpischil : If the scope of a variable is ended, then that variable will be removed, but will the value of that variable persist at that location? – kevin gomes Feb 14 '14 at 18:12
  • @DietrichEpp: In the implementation I used, the second argument is passed in `%RSI`, per *System V Application Binary Interface: AMD64 Architecture Processor Supplement*. – Eric Postpischil Feb 14 '14 at 18:12
  • @kevingomes: Nothing in C deliberately alters the contents of an object when its lifetime ends. But nothing preserves it, either. The bits used for the object will simply happen to be reused for another purpose **at any time convenient to the C implementation**. Maybe when another function is called, maybe when another object is declared, maybe never. You simply should **never** rely on it. But, more than that, the C model of computation, where objects are represented by bytes in memory, **is just a model**. Compilers usually include a process called optimization, which, among other things,… – Eric Postpischil Feb 14 '14 at 18:16
  • @EricPostpischil : In simple language you mean to say that the value will persist. – kevin gomes Feb 14 '14 at 18:17
  • … transforms sequences of explicit operations in the model into possibly completely different instructions in the computer that are intended to have the same effect. However, **they are only guaranteed to have the same effect if you have obeyed the rules**. If you violate the rules, such as using an uninitialized variable in a way that may produce undefined behavior, then the transformation **may completely alter your program** in unrecognizable ways. – Eric Postpischil Feb 14 '14 at 18:17
  • @EricFortin: when memory is allocated to a process it *is* reset to zero, for security reasons. – markgz Feb 14 '14 at 18:17
  • 1
    @kevingomes: No, I do not mean to say that, specifically because optimization makes it not true. Yes, the memory persists in the C model. However, once optimization is applied, objects do not actually have “memory” any more; they are not necessarily made out of bytes and are not necessarily concrete things with any independent existence. The actual instructions that implement your program may be completely different. – Eric Postpischil Feb 14 '14 at 18:19
  • @markgz: That depends on the operating system. The computers most people are familiar with do so with user programs, for security purposes. However, special-purpose operating systems do not always erase memory. If you are writing a C program to be portable, you should not expect that memory newly acquired from the operating system will be set to zero. – Eric Postpischil Feb 14 '14 at 18:21
  • @EricPostpischil : but why the previous values are not removed? – kevin gomes Feb 14 '14 at 18:35
  • @kevingomes: It would require extra instructions (and time and energy) to “remove” previous values. C is designed to be an efficient language. – Eric Postpischil Feb 14 '14 at 19:15
5

C only does what you tell it to. The standard defines reading an uninitialized variable as undefined behavior.

This question elaborates: (Why) is using an uninitialized variable undefined behavior?

The accepted answer has a very good explanation.

EDIT:

A funny sidenote though, if you declare the variable static it is guaranteed to be initialized to zero per the standard. Can't find a quote right now, working on it..

EDIT2:

I left my C reference at work and CBA to download one. This answer elaborates on the initial values of variables, whether they be local/auto, global, static or indeterminate: https://stackoverflow.com/a/1597491/700170

Community
  • 1
  • 1
Morten Jensen
  • 5,818
  • 3
  • 43
  • 55
2

The other answers point out (correctly) that what's being printed is whatever's already in memory in the memory location that happens to have been assigned to i.

They don't, however, clarify why there are any values stored in these locations in the first place, which is perhaps what you're really asking.

There are two reasons for this: first, upon startup, we can't be sure exactly how the memory circuits will initialize themselves. So they could be set to any arbitrary value. The second (and, in general, more likely reason, unless you just restarted your computer) is that before you started your program, that memory location had been used by another program, which stored something there--something that wasn't garbage at the time, since it was stored intentionally. From the perspective of your program, however, it is garbage, since your program has no way of knowing why that particular value was stored there.

EDIT: As I mentioned in a comment on another answer, even if the value stored in memory under some uninitialized variable is actually 0, that's not the same thing as "not having a value stored." The value stored is 0, which is to say, the physical hardware that represents one bit of memory is faithfully storing the value 0. As long as a circuit is active (i.e. turned on), the memory cells must store something; for an explanation of why this is, look into flip-flop gates. (There's a decent overview here, assuming you already understand a little bit about NAND gates: http://computer.howstuffworks.com/boolean4.htm)

Kyle Strand
  • 15,941
  • 8
  • 72
  • 167
  • Of course, there's sort of a possibility 2B, which is that the previous program intentionally stored random numbers in random memory locations just for kicks. :D – Kyle Strand Feb 14 '14 at 17:54
  • @KyleStrand I think the OpenBSD operating system initializes its stack memory randomly, so in a way that scenario DO happen some places :D – Morten Jensen Feb 14 '14 at 17:58
  • @MortenJensen True, and I'm pretty sure some compilers offer debug options that explicitly initialize memory values randomly, which, prima facie, sounds even *more* absurd. (I guess that's actually a third option, so maybe I'll edit the question.) – Kyle Strand Feb 14 '14 at 18:42
  • On second thought, I can't find any evidence to back that up, so maybe it's not true after all. – Kyle Strand Feb 14 '14 at 18:44
  • @KyleStrand a lot of implementations for embedded targets have memory-fill options for the linker at least :) I know Texas Instruments has that option for their linkers – Morten Jensen Feb 16 '14 at 20:42
2

It's happens only in case of local varibales. As memory for local variables are allocated on stack and while allocating the memory the runtime system does not clear the memory before allocating it to the variable unlike in case of allocating memory in heap for global and static variables. Hence the default value of local varibles beomes the content of its memory on stack while that of constant and static variables is 0.