If we have
int a = 123
int b = 123
will we end up with two distinct memory bocks allocated for the integer 123 or we only end up with one memory block allocated for 123?
What about
int a = 123
int b = a
Does this change the answer?
CodePudding user response:
C and C programs have dual natures. The meaning of a program is described using a theoretical model with an abstract computer that executes the program literally as the source describes it. In this model, each object has different memory from every other object, because an object is by definition reserved memory, associated with a type. (Note that string literals in source code may overlap, referring to one common array.)
However, a compiler is not required to produce assembly code that executes this meaning literally. It may produce any program that has the same observable behavior as the original source code. Observable behavior includes the output the program writes the files, input/output interactions, and accesses to volatile objects. In between observable behavior, the compiler can optimize the program, including eliminating unnecessary memory use.
Whenever you define an object, the compiler might not reserve memory for it at all if it is able to make your program work without using such memory. For example, in:
int main(void)
{
int a = 123;
int b;
scanf("%d", &b);
printf("%d\n", a b);
}
the compiler is likely to perform the calculation by loading the constant 123 as an immediate operation of an instruction, without reserving separate memory for it.
If the compiler does need memory, perhaps because it does not have enough processor registers to keep everything it is working with in registers, then it might keep only one copy of a constant that is used to initialized two objects which are never changed and whose addresses are not taken.
If you pass the objects by address to other routines or give them different values, the compiler is more likely to reserve separate memory for them, depending on circumstances.
CodePudding user response:
will we end up with two distinct memory bocks allocated
As far as the abstract machine is concerned: Yes, the variables have overlapping storage duration, so they must have distinct memory addresses.
As far as the language implementation is concerned: It depends. There could even be no memory used at all if isn't needed.
Does this change the answer?
No.
CodePudding user response:
Eric's answer is already a great answer, I will complement that with a simple practical case, take the following code:
#include <stdio.h>
int main() {
int a = 123;
int b = 123;
printf("%d", a);
printf("%d", b);
}
If you compile this code with gcc 11.2 x86-64 C compiler the following assembly is produced:
.LC0:
.string "%d"
main:
push rbp
mov rbp, rsp
sub rsp, 16
mov DWORD PTR [rbp-4], 123
mov DWORD PTR [rbp-8], 123
mov eax, DWORD PTR [rbp-4]
mov esi, eax
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
mov eax, DWORD PTR [rbp-8]
mov esi, eax
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
mov eax, 0
leave
ret
As you can see storage is provided for the 2 variables.
Now, if I use optimization -O flag, then the following assembly is produced:
.LC0:
.string "%d"
main:
sub rsp, 8
mov esi, 123
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
mov esi, 123
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
mov eax, 0
add rsp, 8
ret
As you can see the compiler just uses the 123 literal, because no changes are made to those variables, they can be treated as constant values.
So the answer is it depends, we might even end up with no storage for any of the variables.
The assignment of a to b by itself changes nothing.
