How garbage values are assigned to variables in c

Does it mean C first allocates memory to variable 'a' and then what ever there is at that memory location becomes value of 'a'?

Exactly!

Basically, C doesn't do anything you don't tell it to. That's both its strength and its weakness.


Does it mean C first allocates memory to variable 'a' and then what ever there is at that memory location becomes value of 'a'? or something else?

Correct. It is worth mentioning that the "allocation" of automatic variables such as int a is virtually nonexistent, since those variables are stored on the stack or in a CPU register. For variables stored on the stack, "allocation" is performed when the function is called, and boils down to an instruction that moves the stack pointer by a fixed offset calculated at compile time (the combined storage of all local variables used by the function, rounded to proper alignment).

The initial value of variables assigned to CPU registers is the previous contents of the register. Because of this difference (register vs. memory) it sometimes happens that programs that worked correctly when compiled without optimization start breaking when compiled with optimization turned on. The uninitialized variables, previously pointing to the location that happened to be zero-initialized, now contain values from previous uses of the same register.


Initially memory is having some values, those are unknown values, also called garbage values, when ever we declare a variable some memory was reserved for the variable according to datatype we specified while declaring, so the memory initial value is unknown value, if we initialize some other value then our value will be in that memory location.


int a;

While declaring a variable, the memory is allocated. But this variable is not assigned which means the variable a is not initialized. If this variable a is only declared but no longer used in the program is called garbage value. For example:

int a, b;

b=10;
printf("%d",b);
return 0;

Here it's only declared but no longer assigned or initialized. So this is called garbage value.


Does it mean C first allocates memory to variable 'a' and then what ever there is at that memory location becomes value of 'a'?

No, it does not mean that.

When an object is not initialized, the C standard does not provide any plan for how its value is determined. Not only that, the program is not required to behave as if the object has any fixed value. It can vary as if the memory reserved for it were not held in any fixed state, just fluctuating.

Here are the specific C 2018 rules about that:

  • The so-called “value” of an uninitialized object is indeterminate, per 6.2.4 6 for objects with automatic storage duration without variable length array type, 6.2.4 7 for those with variable length array type, 7.22.3.4 2 for objects allocated with malloc, 7.22.3.5 2 for additional space allocated by realloc, and 7.22.3.1 2 for aligned_alloc. Other objects, such as those with static storage duration, are initialized.
  • Per 3.19.2, an indeterminate value is “either an unspecified value or a trap representation”.
  • Per 3.19.3, an unspecified value is a “valid value of the relevant type where this document imposes no requirements on which value is chosen in any instance”.

This means that in each instance an object is used, the C standard does not impose any requirements on which value is used for it. It is not required to be the same as a previous use. The program may behave as if it does not hold any fixed value. When it is used multiple times, the program may act as if it has a different value each time. For example, the C standard would allow printf("%d %d %d\n", a, a, a); to print “34 -10200773 2147483204”.

A way this can happen is that, while attempting to compile the code int a; printf("%d %d %d\n", a, a, a);, the compiler has nowhere to get a from, because it has never been given any fixed value. So, instead of generating useless instructions to move data from uninitialized memory to where the arguments are passed, the compiler generates nothing. Then printf gets called, and the registers or stack locations where the arguments are passed contain whatever data they had from earlier. And that may well be three different values, which printf prints. So it looks to an observer of the output as if a had three different values in printf("%d %d %d\n", a, a, a);.

(In addition, using the value of an uninitialized object with automatic storage duration that has not had its address taken is explicitly undefined behavior, because 6.3.2.1 2, about converting an object to its value, says “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.” So, when there is an object meeting these criteria, using its value can break the program completely; it might not only have different values at different times, but the program might abort, go down a branch different from what you expected, not call printf when there is a printf in the source code, and so on.)