I have been learning C++ for a while, but currently I know nearly nothing about assembly/machine language and how compiler and hardware work. Sorry if this question is really naive...
Consider the following very simple code:
#include <iostream>
using namespace std;
int main()
{
int x = 0;
cout << &x << endl;
}
In my current understanding, the first line in main()
asks the compiler to reserve enough memory to hold an int
, associate it with the identifier x
, and put 0
into that memory location. And the second line in main()
prints out the address of the start of that memory location.
I run the above code twice (consecutively), and I got different outputs as follows:
0000002EECAFFB84 // first time
0000007F1FAFF854 // second time
It is also in my current understanding that (please correct me if I have any misunderstandings):
- when I first run the program, C++ compiler translate my source code directly into machine code (or also called object code, the code that runs directly on hardware).
- since I modified nothing between my first run and my second run, the compiler will NOT generate machine code again, and thus the machine code used in the second run is the same as in the first run.
If my above understandings are correct, then the memory address of x
is not determined in the machine code generated by the compiler (otherwise the outputs would be the same), and there must be some intermediate mechanism (between executing the machine code generated by the compiler and creating the int
on memory) which decides on the exact memory address where the int
will reside.
Is such mechanism done directly by the hardware (e.g. CPU?)? Or is it done by the operating system (so can I say OS is a kinda "virtual machine" for C++?)? May I ask who determines the exact memory address of x
and how?
May I also ask how exactly does the compiler generates machine code for &x
at compile-time, so that the memory address which hasn't been determined yet can be ensured to be retrieved successfully at a later point in runtime?