C中的每个表达式都会复制变量吗?

问题描述 投票:1回答:1

我试图了解C中的表达式的R值和L值,并且我知道许多表达式不是有效的L值,因为最终结果的地址未知。这是因为在许多情况下,表达式中使用了变量的副本,因此该副本的地址未知。例如,

    char ch = 'a';
    char *p = &ch;
    p + 1; //This expression can be used as an R-value, but not an L-value

我相信表达式中正在发生的事情(如果我错了,请纠正我)是创建了p的副本,在该副本中添加了1,以便p + 1指向ch之后的char,但是地址这个新的p + 1指针的未知,因此不能用作L值。

对于C中的所有表达式,是否都会制作变量的副本并在表达式中使用副本的行为?例如,如果我有

    int a = 100;
    int b = 25;
    a - b;

是已创建变量a的副本(并存储在未知位置)和已创建变量b的副本(b的副本也存储在未知位置),副本中的数据用于减去,然后减去结果存储在另一个未知位置,还是从原始变量中减去数据,然后将结果存储在未知位置?

c rvalue lvalue
1个回答
0
投票

此类计算的实现不是标准的,因此它们在不同的编译器中可能会有所不同。要了解的重要一点是R值表示临时值。它可以是寄存器或某些已分配的内存。

在CPU中通过寄存器进行计算。因此,编译器会将变量的值移入寄存器,然后计算减法。这是这种计算的集合:

 659:   c7 45 f8 64 00 00 00    movl   $0x64,-0x8(%rbp)
 660:   c7 45 fc 19 00 00 00    movl   $0x19,-0x4(%rbp)
 667:   8b 45 f8                mov    -0x8(%rbp),%eax
 66a:   2b 45 fc                sub    -0x4(%rbp),%eax

您可以看到值100(十六进制为64)和25(十六进制为19)保存在堆栈中相对于基本指针的地址(分别为-0x8,-0x4)。然后将-0x8中的值移到eax寄存器中,然后从寄存器中的值中减去-0x4中的值并存储在寄存器本身中。

如您所见,结果将最终在寄存器中,因此它在存储器中没有地址。

© www.soinside.com 2019 - 2024. All rights reserved.