[C++] 引用和地址的区分

引用和地址的区别

  • References have a lifetime only before compilation.

核心区分

  • 引用和指针的区别:也就是引用会在编译后,将引用替换为变量的地址取值形式; int &ref=x; ref编译后被替换为*(&x);所以说ref不用保存地址;而地址需要通过地址显性间接访问变量; 注意在编译阶段,编译器处理ref需要绑定信息:包括:x地址,x类型,连接状态等。但是运行期间,是没有额外占空间保存地址的。
  • from Claude explanation:
Binding:
When a reference is defined, it is bound to a target variable. For example:
`int x = 5;
int &ref = x;`
This establishes ref as an alias for x. The compiler stores the information that ref refers to x. This binding is permanent - ref will always refer to x.
The binding information includes:
- The address of x
- The type of x (int in this case)
- The linkage status of x (external, internal, etc)
This allows the compiler to know exactly which variable ref refers to, and replace ref with x whenever it is used.
Alias:
An alias is simply another name for the same variable. By binding ref to x, ref becomes an alias - another name that refers to the exact same variable.
When we use ref, we are implicitly using x. Any modifications through ref implicitly modify x, and vice versa. ref provides an alternative way to access x without changing its meaning.

Reference lifetime:
- References have a lifetime only before compilation. The compiler binds a reference to its target when the program is built.
- After compilation, references essentially become dereferenced pointers to their target. They no longer have a distinct "reference" type - just an address pointing to their target.
Pointer lifetime:
- Pointers have a lifetime both before and after compilation. They exist as a distinct pointer type in the source code, and as a pointer variable in the compiled program.
- Pointers can be rebound to different targets at runtime, references cannot be rebound after compilation.
Memory usage:
- References do not occupy any more memory than a pointer. At runtime, a reference holds an address, just like a pointer.
- The extra memory used for references exists only at compile time, when the compiler handles binding the reference to its target. No extra information needs to be stored at runtime.

In summary, implicit dereference means the compiler does the work of resolving a reference to its target variable, allowing references to transparently stand in for their underlying object without requiring explicit dereferencing.
  • 然而上面解释,还是不发理解alias是怎样的操作;其实说透了就是,在编译阶段,编译器会维护一个symbol table,这个table就是保存代码中变量名和变量地址映射的;比如声明int x = 5;, 那么‘x’这个name就和存放5的内存比如0x7fffde,进行关联映射;那么就当我们定义一个引用int &y = x;时,name y 也是映射到0x7fffde这个地址。而生成机器码的时候,将这些变量symbol 替换成0x7fffde,实际机器码中没有x,y一说,这些只是抽象概念,在编译后就消失了。 所以关键是理解有一个symbol table在编译器中起作用。而地址则是int *z = &x;,则是symbol table中name z 映射到一个地址 0x55fddd,这个地址中放的是x变量值的0x7fffde。

  • 下面是根据claude 问答出来的 解释。

QA: =========================
how to represent a variable x in C++?
Claude: =======================================
In C++, a variable x can be represented in a few ways:
1. Declaration
To declare a variable x, you specify the type and name:
cpp
int x; 
This declares x as a variable of type int. This allocates memory for an integer value and associates the name "x" with it.
2. Definition
A variable can also be declared and initialized in one line:
cpp  
int x = 5;
This defines x and initializes it to the value 5.
3. Memory representation
In memory, a variable consists of:
- The name "x" that the compiler associates with a memory address.
- The allocated memory at that address used to store the variable's value.
For example, if x is at address 0x7fffde:
0x7fffde: 5
The compiler tracks that the name "x" refers to memory address 0x7fffde.
4. Machine code
In machine code, the compiler converts references to "x" into memory access instructions using the address:
mov eax, [0x7fffde] // Copy value at 0x7fffde into eax register
So in summary, a variable can be declared in code, allocated in memory, and referenced by machine instructions using its memory address. The variable name is an abstraction that refers to the underlying memory. (edited) 
QA: ==================
how to save the name 'x' in C++ program. is it saved by compiler in  compilation, not in the compiled code?
Claude: =============================================
You're correct - the variable name 'x' itself is not saved in the compiled machine code in C++. The name 'x' is an abstraction handled by the compiler.
Here is how it works:
- In the source code, the programmer uses the name 'x' to represent a variable.
- The compiler maintains a symbol table that maps 'x' to a particular memory address, say 0x7fffde.
- When the code refers to 'x', the compiler generates machine code that accesses 0x7fffde directly, instead of using the name 'x'.
- The machine code just contains instructions to access fixed memory addresses like 0x7fffde. It does not contain the name 'x'.
- The symbol table mapping 'x' to 0x7fffde is discarded after compilation.
- Only the executable machine code remains, which accesses the memory location directly.
So in summary:
- The variable name 'x' is only used in the source code during compilation.
- The compiler resolves it to a memory address and generates instructions using the address.
- The variable name itself is not stored in the final compiled program.
- Only the memory addresses and machine instructions remain after compilation.
So the variable name is an abstraction handled by the compiler and not stored in the compiled machine code. The mapping of the name to a memory location is lost after compilation. (edited) 
QA: ===========================
so if y is a reference of x , the y only in the symbol table as a name used in compiler, after compilation, it will discarded.

Claude answer: ===============================================
Yes, that's correct. Since a reference in C++ is essentially just another name for an existing variable, it is handled similarly:
- In the code, y is declared as a reference to x.
- The compiler will add y to its symbol table, mapped to the same memory location as x.
- Any uses of y will be compiled to machine code that accesses the memory for x directly.
- The symbol table entry mapping y to x's location is discarded after compilation.
- In the compiled machine code, there will be no mention of y - just instructions to access x's memory location using its address.
So just like a normal variable name, a reference name like y is an abstraction that is resolved to a memory address during compilation. The reference itself is not preserved or represented in any way in the final compiled program.
After compilation, y essentially "disappears" - the executable code just contains instructions to access x directly, since y refers to the same memory location. (edited) 

QA:====================
 so int *z = &x; , z in symbol table will save a new address to point the address of x 0x7fffde?
Claude answer: =============================
Yes, that's correct. For a pointer variable like z in int *z = &x;, the compiler will handle it differently than a reference:
- z will be allocated its own separate memory location, say 0x7fffe0.
- In the symbol table, z will be mapped to 0x7fffe0.
- The compiler will generate code to store the address of x (0x7fffde) into z's memory location (0x7fffe0) during initialization.
- When z is dereferenced in code, the compiler will generate code to access the address stored in 0x7fffe0.
So the key differences are:
- z gets its own memory location to store the pointer value.
- The pointer value stored in z will be the address of x (0x7fffde).
- The symbol table maps z to its own location (0x7fffe0), not x's location.
So in summary, you are correct that for a pointer, the compiler allocates separate storage to contain the pointer value, which is the address of the variable it points to. This is different from a reference, which does not have allocated storage and instead refers to the original variable directly. (edited) 

参考

  • Symbol Table 符号表是编译器为存储变量名、函数名、对象、类、接口等各种实体的出现情况而创建和维护的一种重要的数据结构。符号表既可用于编译器的分析部分,也可用于编译器的综合部分
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值