Assuming a purely non-optimizing compiler, is there any difference in machine code between initializing a variable and assigning it a value after declaration?
Initialization method:
int x = 2;
Assignment method:
int x;
x = 2;
I used GCC to output the assembly generated for these two different methods and both resulted in a single machine instruction:
movl $2, 12(%esp)
This instruction just sets the memory held by the x
variable to the value of 2
. GCC may be optimizing this because it can recognize the end result of the operations; but I think this is the only way to interpret the two versions. My reasoning is that both version do the same thing: set a part of memory to a specific value.
Why is it then that a distinction is often made between the terms "initialization" and "assignment" if the resulting machine code is the same?
Is the term "initialization" used purely to differentiate variables which have a specific value assigned over those (non-initialized) variables which have whatever garbage value was left in memory?
Computer will create variable x and assign to it value 2 almost at the same moment.
Computer will create variable x. And then it will it assigned to it value 2. It seem that there is no any difference, but...
...let's suppose that your code is like this:
computer may have to access the variable x in order to assign to it value 2. It means that while running program computer will spend more time to access x to assing to it some value unlike if it will create variable and assing this variable at the moment.
Anyway, Deitel HM, Deitel PJ describe this in C How to Program.
Sure.
char fubar[] = "hello world";
is valid.char fubar[]; fubar = "hello world";
is not.More?
int fubar[128] = { [60] = 42 };
is valid.int fubar[128]; fubar = { [60] = 42 };
is not.More?
struct foo bar = { .foo = 13, .bar = 42 };
is valid.struct foo bar; bar = { .foo = 13, .bar = 42 };
is not.More?
const int fubar = 0;
is valid.const int fubar; fubar = 0;
is not.I could go on and on... Hence, machine code might exist for one while it most likely won't for the other. On that note, have you ever heard of an implementation of C that isn't a compiler?
The concept of variables in the C programming language is too high-level for the low-level machine code representation. In machine code, registers don't have scope. C added scope, not to mention type fusion and many of the other variable-related aspects, along with initialisation (which you can see from previous examples is squarely, but unfortunately not the same).
Though a variable that is "initialized" won't contain any "garbage value" (or trap representations), this is not the only affect it has.
In my first example, the initialization will provide the size of the otherwise incomplete array. The equivalent using the assignment operator would require explicitly providing the length of the array and using
strcpy
, which turns out to quite tedious.In my second example, the
int
at index 60 will be initialized to 40 while the remaining, otherwise uninitialized items will be initialized to 0. The equivalent using the assignment operator would also be fairly tedious.In my third example, the members
foo
andbar
will be initialized to 13 and 42 while the remaining, otherwise uninitialized members will be initialized to 0. The equivalent using the assignment operator would be quite tedious, though I occasionally use a compound literal to achieve a similar result.In my fourth example, the initialization sets the value that the variable will contain for it's entire life. No assignment is possible to this variable.
An important distinction comes into play when you add a
const
qualifier:is valid C
isn't. Another important difference is for
static
variables:is invalid C
is valid.
The behavior must be identical, but any differences in the generated code really depend on the compiler.
For example, the compiler could generate this for the initialized variable:
and this for the uninitialized, but later assigned variable:
The C standard does not mandate the generated code to be identical or non-identical in these cases. It only mandates identical behavior of the program in these two cases. And that identical behavior does not necessarily imply identical machine code.