【问题标题】:Comma Operator and assignment [closed]逗号运算符和赋值[关闭]
【发布时间】:2018-03-22 01:28:01
【问题描述】:

考虑一下语句:

int a;
a = 1,2,3; 
cout<<a; // prints a = 1

我咨询了this 网站。现在发生这种情况是因为 comma 运算符的优先级最低。所以它就像(a=1),2,3。但出于好奇,我想知道这之后会发生什么,编译器是否忘记了剩余的数字23。因为我认为如果考虑它们,那么可能首先是 1,然后是 2,然后是 3 将被初始化为a(类似于a = (1,2,3))。请告诉我这里到底发生了什么?

【问题讨论】:

  • 当编译器遇到表达式23 时,它会做同样的事情,就好像你刚刚自己写了2;。也就是说,它什么都不做。
  • 在此上下文中,a=1,2,3; 等效于 a=1; 2; 3;2;3; 无效。
  • 你有 2 和 3 的地方的表达式将被评估,这可能会有副作用。

标签: c++ operators comma comma-operator


【解决方案1】:

这个:

a = 1,2,3;

相当于:

a = 1;
2;
3;

因此,23 将被评估,但没有效果


您可以使用g++ main.cpp -Wall -Wextra 编译并让编译器警告您:

warning: right operand of comma operator has no effect [-Wunused-value]
     a = 1,2,3;
             ^
warning: right operand of comma operator has no effect [-Wunused-value]
     a = 1,2,3;
              ^

【讨论】:

  • 哦!我没有输入Wall 标志来查看警告,这些警告本身就是我的问题的答案!现在我100%清楚了。谢谢!!
  • @Miraj 好吧,你已经知道我之前不知道的事情了:What does i = (i, ++i, 1) + 1; do?,所以我很佩服你,很高兴我能帮上忙!
  • :D ,我知道这样的 cmets(as this) 不受欢迎,但我love这个社区!!
【解决方案2】:

来自 C 标准(6.5.17 逗号运算符)

2 逗号运算符的左操作数被评估为 void 表达;在它的评估和那个之间有一个序列点 的右操作数。然后对右操作数求值;结果 有它的类型和价值

所以一般来说这个表达式语句

a = 1,2,3;

看起来像

( a = 1 ), ( 2 ), ( 3 );

(更准确地说是( ( a = 1 ), ( 2 ) ), ( 3 ),即表达式包含两个逗号运算符)

由于表达式( 2 )( 3 ) 的评估结果未被使用,编译器可以将它们从生成的目标代码中删除。只有表达式( a = 1) 具有更改变量a 的副作用。

所以编译器可以像考虑这个语句一样

a = 1;

另一方面,如果考虑声明

int a = ( 1,2,3 );

那么这里的初始化器是一个带有(两个)逗号运算符的表达式。所以声明等价于

int a = ( ( 1 ), ( 2 ), ( 3 ) );

由于表达式 ( 1 )( 2 ) 被评估为 void 表达式并且没有副作用,编译器可以将它们从生成的目标代码中删除并考虑类似声明

int a = 3;

【讨论】:

    【解决方案3】:

    a = 1,2,3 是一个等于 3 的 表达式,其副作用是将 1 分配给 a

    也就是说,你可以写

    int b = (a = 1, 2, 3);
    

    b 的值为 3,a 的值为 1。

    2的评价从来没有有效果。您是否关闭了编译器警告?

    【讨论】:

      【解决方案4】:

      当你这样做时

      #include<iostream>
      int main()
      {
          int a;
          a=1,2,3;
      }
      

      Full compiler log 编译器只会做

           mov dword ptr [rbp - 4], 1 
      

      将忽略 gsamaras 提到的 2 和 3 以及警告

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-06
        • 2010-10-13
        • 2011-11-16
        • 2015-04-10
        • 2022-08-17
        • 2010-12-15
        相关资源
        最近更新 更多