以下代码如何打印到控制台?
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() 被调用现在是 1m[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 次 |
| 最近记录: |