逗号运算符和赋值
Comma Operator and assignment
考虑以下语句:
int a;
a = 1,2,3;
cout<<a; // prints a = 1
我查阅了 this 网站。现在发生这种情况是因为 comma
运算符的优先级最低。所以它就像 (a=1),2,3
。但是出于好奇,我想知道这之后发生了什么,编译器是否忘记了剩余的数字 2
和 3
。因为我认为如果考虑它们,那么可能首先 1,然后 2,然后 3 将被初始化为 a
(类似于 a = (1,2,3)
)。请告诉我这里到底发生了什么?
这个:
a = 1,2,3;
相当于:
a = 1;
2;
3;
因此,2
和 3
将被评估,但 没有影响。
您可以使用 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 提到的警告
考虑以下语句:
int a;
a = 1,2,3;
cout<<a; // prints a = 1
我查阅了 this 网站。现在发生这种情况是因为 comma
运算符的优先级最低。所以它就像 (a=1),2,3
。但是出于好奇,我想知道这之后发生了什么,编译器是否忘记了剩余的数字 2
和 3
。因为我认为如果考虑它们,那么可能首先 1,然后 2,然后 3 将被初始化为 a
(类似于 a = (1,2,3)
)。请告诉我这里到底发生了什么?
这个:
a = 1,2,3;
相当于:
a = 1;
2;
3;
因此,2
和 3
将被评估,但 没有影响。
您可以使用 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 提到的警告