When Initializing variables in C I was wondering does the compiler make it so that when the code is loaded at run time the value is already set OR does it have to make an explicit assembly call to set it to an initial value?
The first one would be slightly more efficient because you're not making a second CPU call just to set the value.
e.g.
void foo() {
int c = 1234;
}
If it's a variable with static lifetime, it'll typically become part of the executable's static image, which'll get memcpy
'ed, along with other statically known data, into the process's allocated memory when the process is started/loaded.
void take_ptr(int*);
void static_lifetime_var(void)
{
static int c = 1234;
take_ptr(&c);
}
x86-64 assembly from gcc -Os:
static_lifetime_var:
mov edi, OFFSET FLAT:c.1910
jmp take_ptr
c.1910:
.long 1234
If it's unused, it'll typically vanish:
void unused(void)
{
int c = 1234;
}
x86-64 assembly from gcc -Os:
unused:
ret
If it is used, it may not be necessary to put it into the function's frame (its local variables on the stack)—it might be possible to directly embed it into an assembly instruction, or "use it as an immediate":
void take_int(int);
void used_as_an_immediate(int d)
{
int c = 1234;
take_int(c*d);
}
x86-64 assembly from gcc -Os:
used_as_an_immediate:
imul edi, edi, 1234
jmp take_int
If it is used as a true local, it'll need to be loaded into stack-allocated space:
void take_ptr(int*);
void used(int d)
{
int c = 1234;
take_ptr(&c);
}
x86-64 assembly from gcc -Os:
used:
sub rsp, 24
lea rdi, [rsp+12]
mov DWORD PTR [rsp+12], 1234
call take_ptr
add rsp, 24
ret
When pondering these things Compiler Explorer along with some basic knowledge of assembly are your friends.