以下代码如何打印到控制台?
map<int,int> m;
m[0] = m.size();
printf("%d", m[0]);
Run Code Online (Sandbox Code Playgroud)
可能答案:
m[0]
或m.size()
正由编译器首先执行.因此,它可以打印1
以及0
.0
因为首先执行赋值运算符的右侧.它打印1
是因为它operator[]
具有完整语句的最高优先级m[0] = m.size()
.因此,会发生以下事件序列:
m[0]
在地图中创建一个新元素m.size()
被调用现在是 1
m[0]
获得分配先前返回的(由m.size()) 1
真正的答案?,我不知道^^
Ste*_*sop 17
我相信未指定 0或1是否存储m[0]
,但它不是未定义的行为.
LHS和RHS可以按任意顺序出现,但它们都是函数调用,因此它们在开始和结束时都有一个序列点.它们中的两个没有共同的危险,没有中间序列点就可以访问同一个对象.
赋值是实际的int赋值,而不是具有相关序列点的函数调用,因为operator[]
返回T&
.这简直令人担忧,但它并没有修改在本声明中任何其他位置访问的对象,所以这也是安全的.operator[]
当然,它在初始化的位置被访问,但是在返回的序列点之前发生operator[]
,所以没关系.如果不是,m[0] = 0;
也将是未定义的!
但是,操作数的评估顺序operator=
不是由标准指定的,因此调用的实际结果size()
可能是0或1,这取决于发生的顺序.
但是,以下是未定义的行为.它没有进行函数调用,所以没有任何东西可以阻止size
被访问(在RHS上)和修改(在LHS上)没有插入序列点:
int values[1];
int size = 0;
(++size, values[0] = 0) = size;
/* fake m[0] */ /* fake m.size() */
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
436 次 |
最近记录: |