社区讨论
关于未定义行为的一点疑问
学术版参与者 8已保存回复 17
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 17 条
- 当前快照
- 1 份
- 快照标识符
- @lob69qfp
- 此快照首次捕获于
- 2023/10/29 15:51 2 年前
- 此快照最后确认于
- 2023/11/03 22:18 2 年前
群友提出的弔问题,原问题是这样的:
CPPe[++tot]=(AC){1,a[i],i,0,tot}
这个写法是不是 UB,但是为了去掉一些不必要的因素,问题改为这个:
CPPstruct node{int x;}a[5];
int i=1;
a[++i]=(Node){i};
这个写法是不是 UB。
很显然,根据按顺序早于规则,C++ 11 起到 C++17 前的等于号左右两侧值计算和副作用的顺序没有规定,17 及以后才有先右后左的规定。所以结论是 17 及以后才不是 UB。
但是问题没有这么简单结束,我把这个代码放到 LuoguIDE 的 C++17 上跑,发现输出出现了问题:
CPP#include <cstdio> // LuoguIDE C++17
struct node{int x;}a[5];
signed main(){
int i=1;
a[++i]=(node){i};
for(int i=0;i<5;++i)printf("%d ",a[i].x);}
结果输出了
0 0 2 0 0 ,但是按照先右后左的顺序应该是输出 0 0 1 0 0 才对然后我又测了下这个代码:
CPP#include <cstdio> // LuoguIDE C++17
int a[5];
signed main(){
int i=1;
a[++i]=i;
for(int i=0;i<5;++i)printf("%d ",a[i]);}
这下对了,输出是
0 0 1 0 0然后我去 CF 上用
Clang++17 Diagnostics 测了下还是一样输出 0 0 1 0 0。问了下 @CE_WA_TLE ,他说可能是 GNU 扩展的复合字面量的问题,我测了下这个代码:
CPP#include <cstdio> // CodeForces Clang++17 Diagnostics
struct node{int x;node(){x=0;}node(int _x){x=_x;}}a[5];
signed main(){
int i=1;
a[++i]=node(i);
for(int i=0;i<5;++i)printf("%d ",a[i].x);}
输出
0 0 1 0 0 ,对了。查了下 GNU 文档并没有写这方面关于 UB 的内容,所以有没有老哥能解释一下这是啥原因啊 

回复
共 17 条回复,欢迎继续交流。
正在加载回复...