假设p
是一个整数指针并且i
是一个整数:
*p++
给出一个对应的整数值p
.
i++
给出一个递增1 的整数值
由于按行为,上述两者都产生整数, ++*p++
并且++i++
不应报告相同的错误?但为什么++*p++
工作时 ++i++
会产生编译错误?
int main()
{
int a[10] = {0};
int *p = (int*)&a;
int i = 0;
// printf("%d", ++i++); -- FAILS error: lvalue required as increment operand
printf("%d\n", ++*p++ ); // Prints 1
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑
++ i ++被分解如下:
i++
++(result)
Run Code Online (Sandbox Code Playgroud)
这正是我感到困惑的地方:同样地,我们可以将++*p ++分解为
*p++
++(result).
Run Code Online (Sandbox Code Playgroud)
*p ++返回一个值(rvalue),而不是指针.为什么差异呢?
Jer*_*fin 17
后增量的结果是右值.你不能修改它.++i++
尝试修改编译器拒绝的rvalue.
p ++产生一个rvalue,但它是指针类型.您不能修改它,但您可以取消引用它.*p++
取消引用rvalue.这为您提供了它所指向的值,作为左值.然后,预增量会修改它指向的左值,而不是后增量产生的右值.
编辑:我可能还应该添加一点:即使++i++
编译器允许,结果也是未定义的行为,因为它尝试修改i
两次而没有插入序列点.在++*p++
没有发生这种情况的情况下- 后增量修改指针本身,而预增量修改指针指向的内容(在增加之前).由于我们正在修改两个完全不同的位置,因此结果不是未定义的行为.
如果你想要足够严重,你仍然可以通过初始化指针指向自身来获得未定义的行为,在这种情况下,两个增量都会尝试修改指针.委员会并没有非常努力地防止这种情况,可能是因为只有真正迂腐的人才有可能甚至想到这种疯狂的事情.
底线:在这种情况下,编译器主要是试图保护自己免受伤害,但是如果你努力的话,你仍然可以用脚射击自己.
归档时间: |
|
查看次数: |
1019 次 |
最近记录: |