逗号运算符和赋值

Comma Operator and assignment

考虑以下语句:

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))。请告诉我这里到底发生了什么?

这个:

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;
              ^

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

2 The left operand of a comma operator is evaluated as a void expression; there is a sequence point between its evaluation and that of the right operand. Then the right operand is evaluated; the result has its type and value

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

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;

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

也就是说,你可以这样写

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

b 的值为 3,而 a 为 1。

评价2从不有影响。您是否拒绝了编译器警告?

当你这样做时

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

Full compiler log 编译器只会做

     mov dword ptr [rbp - 4], 1 

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