Assuming a purely non-optimizing compiler, is there any difference in
machine code between initializing a variable and assigning it a value
after declaration?
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?
Why is it then that a distinction is often made between initialization
and assignment if the resulting machine code is the same?
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).
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?
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
and bar
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.