C 在'上的操作;i';可能未定义
我让这个代码取一个字符串,形式为C 在'上的操作;i';可能未定义,c,undefined-behavior,sequence-points,C,Undefined Behavior,Sequence Points,我让这个代码取一个字符串,形式为bla_2,并将其分开: void separate(char* str, char* word, int* n) { int i = 0; while(str[i] != '_') { word[i] = str[i++]; } *n = str[++i] - '0'; } 我得到: warning: operation on ‘i’ may be undefined [-Wsequence-point] 但是
bla_2
,并将其分开:
void separate(char* str, char* word, int* n) {
int i = 0;
while(str[i] != '_') {
word[i] = str[i++];
}
*n = str[++i] - '0';
}
我得到:
warning: operation on ‘i’ may be undefined [-Wsequence-point]
但是我只是通过++
操作符来更改I
,我没有给它赋值
那么,为什么是UB,如果是的话?如果没有,如何消除警告
注意,在我看来,这个问题处理的是另一个问题。
word[i]=str[i++]代码>是一个问题
如果word[i]
中的i
是在i
在str[i++]中递增之前或之后进行访问,这是编译器的选择代码>
完成作业后执行i++
word[i] = str[i];
i++;
进一步的while(str[i]!='''.')
应该是
while(str[i] != '_' && str[i] != '\0')
为了防止缓冲区溢出。原因是赋值的双方都依赖于i
的值,但是,您正在修改语句中的i
,并且i
的两次使用之间没有序列点。根据C标准,这会导致未定义的行为
要修复此警告,请将相关行更改为
word[i] = str[i];
i++;
顺便说一下,您可以使用指针而不是显式索引,这可能会使代码更具可读性:
void separate(char* str, char* word, int* n) {
while(*str != '_') {
*word++ = *str++;
}
*n = *++str - '0';
}
@Rizier123:这不会改变任何关于序列点的事情。通过修复,我的意思是在这种情况下这不是UB,但是的,我得到了要点。>“这是编译器的选择…是访问之前还是之后”严格地说,代码可以做除这两个选项之外的任何事情。而且,这段代码没有在字符串中放置空终止符。我明白你的意思了@AlexD,也谢谢你。@AlexD你这是什么意思,我不明白。@SurajJain是UB,所以所有赌注都输了。+1表示指针建议,但我接受另一个答案,因为它是第一个答案。:)@萨马拉斯谢谢你的链接,很有趣!