首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在C中计算赋值运算符的左操作数有什么意义?

在C中计算赋值运算符的左操作数有什么意义?
EN

Stack Overflow用户
提问于 2016-08-20 15:09:53
回答 5查看 1.4K关注 0票数 17

根据ISO C11 - 6.5.16.3,它说

  1. 赋值操作符将一个值存储在由左操作数指定的对象中。赋值表达式具有赋值后的左操作数的值,但不是左值。赋值表达式的类型是左操作数在左值转换后的类型。更新左操作数的存储值的副作用在左操作数和右操作数的值计算之后排序。操作数的计算是无序的。

所以我猜这意味着,例如,

int x = 10;
x = 5 + 10;

  1. 左操作数x的计算结果为10,右操作数的计算结果为15。
  2. 右操作数的值存储在由左操作数x.

指定的对象中

但是如果赋值的目的是存储右操作数的赋值(就像在step2中一样),那么为什么需要计算左操作数呢?计算左操作数的意义是什么?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-08-20 15:14:37

x被计算为lvalue时,它的计算结果不是10。它的计算结果是一个lvalue,其中可以存储RHS值。如果LHS的计算结果不是lvalue,则该语句将是错误的。

来自C99标准(6.3.2.1/1):

左值是一个可能指定对象的表达式(对象类型不是void);如果左值在求值时未指定对象,则行为未定义。

当您有一个简单的变量时,将LHS计算为lvalue是微不足道的,例如

 x = 10;

但是,它可以更复杂。

 double array[10];
 int getIndex();   // Some function that can return an index based
                   // on other data and logic.

 array[getIndex()+1] = 10.0;

 // This looks like a function call that returns a value.
 // But, it still evaluates to a "storage area".
 int *getIndex2() { return(&array[0]); }
 *getIndex2()=123.45; // array[0]=123.45

如果getIndex()返回5,那么LHS的计算结果是一个左值,指定数组的第7个元素。

票数 27
EN

Stack Overflow用户

发布于 2016-08-20 15:16:30

“左操作数”可能比示例中的简单x复杂得多(诚然,这并不是一个真正难以评估的挑战):

*(((unsigned long*)target)++) = longValue;

绝对需要对LHS进行一点评估。你引用的句子指的是在赋值的左边需要做什么,以便找到合适的左值来接收赋值。

票数 15
EN

Stack Overflow用户

发布于 2016-08-20 15:17:23

只是为了从“犹大”的角度说服我自己(如果还没有做到的话),这证明了我的帖子只回答了你简单案例中的简单问题。

小证明表明,在您的简单示例中,gcc只做了需要做的事情,而不是更多:

代码:

int main()
{
int x = 10;
x = 5 + 10;

return x;
}

使用debug进行构建

K:\jff\data\python\stackoverflow\c>gcc -g -std=c11 -c assign.c

混用C/asm代码的objdump

K:\jff\data\python\stackoverflow\c>objdump -d -S assign.o

assign.o:     file format pe-x86-64


Disassembly of section .text:

0000000000000000 <main>:
int main()
{
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 30             sub    $0x30,%rsp
   8:   e8 00 00 00 00          callq  d <main+0xd>
int x = 10;
   d:   c7 45 fc 0a 00 00 00    movl   $0xa,-0x4(%rbp)
x = 5 + 10;
  14:   c7 45 fc 0f 00 00 00    movl   $0xf,-0x4(%rbp)

return x;
  1b:   8b 45 fc                mov    -0x4(%rbp),%eax
}
  1e:   90                      nop
  1f:   48 83 c4 30             add    $0x30,%rsp
  23:   5d                      pop    %rbp
  24:   c3                      retq
  25:   90                      nop
  26:   90                      nop
  27:   90                      nop
  28:   90                      nop
  29:   90                      nop
  2a:   90                      nop
  2b:   90                      nop
  2c:   90                      nop
  2d:   90                      nop
  2e:   90                      nop
  2f:   90                      nop

正如在其他(很好的)答案中所述,不愿意转述,但如果表达式更复杂,则必须计算用于存储值的地址,因此需要某种类型的计算。

编辑:

使用一些稍微复杂的代码:

int main()
{
int x[3];
int i = 2;
x[i] = 5 + 10;

return x[i];
}

拆卸:

Disassembly of section .text:

0000000000000000 <main>:
int main()
{
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   48 83 ec 30             sub    $0x30,%rsp
   8:   e8 00 00 00 00          callq  d <main+0xd>
int x[3];
int i = 2;
   d:   c7 45 fc 02 00 00 00    movl   $0x2,-0x4(%rbp)
x[i] = 5 + 10;
  14:   8b 45 fc                mov    -0x4(%rbp),%eax  <== hey, could be more optimized here: movl   $0x2,%eax covers line+above line :)
  17:   48 98                   cltq
  19:   c7 44 85 f0 0f 00 00    movl   $0xf,-0x10(%rbp,%rax,4)  <== this line holds the left-operand evaluation, in a way, %rax is used to offset the array address
  20:   00

return x[i];
  21:   8b 45 fc                mov    -0x4(%rbp),%eax
  24:   48 98                   cltq
  26:   8b 44 85 f0             mov    -0x10(%rbp,%rax,4),%eax
}
  2a:   90                      nop
  2b:   48 83 c4 30             add    $0x30,%rsp
  2f:   5d                      pop    %rbp
  30:   c3                      retq
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39051512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档