代码块中的警告,"operation may be undefined"
warning in codeblocks, "operation may be undefined"
我收到警告,而不是错误,当我忽略警告并且 build/run 无论如何,我的代码似乎工作正常。不过我还是很担心,因为警告,或者我只是想了解一下。
此函数将单个字符附加到字符串的开头。
void s_pfx(char pf, char *s){
i = -1;
while(s[++i]);
s[i + 1] = '[=11=]';
while(i)
s[i] = s[--i];
s[i] = pf;
}
当我预先递减 i 时,警告出现在 while 循环中。 (我将 i 作为全局变量。)
警告是"warning: operation on 'i' may be undefined [-Wsequence-point]"
我可以使用
修复它
while(i){
s[i] = s[i - 1];
i--;
}
但我为什么要那样做呢?这似乎会耗尽时间,也许是纳秒,但它会加起来。
我不明白为什么编译器无法理解代码。这对我来说似乎很明确。我看了一些其他类似的 questions/answers 但这看起来简单多了。
求助!谢谢
错误确实在表达式 s[i] = s[-- i]
.
C 规范要求某些运算符充当 "sequence points" — 也就是说,它们的第一个操作数在第二个操作数之前被完全评估。但是,=
运算符不是 — 这意味着编译器可以按任何顺序计算表达式。
当您执行类似 i = i + 3
的操作时,这不是问题,因为不会评估赋值的左侧符号(它被写入,而不是读取)。但是你在那里使用指针。 s[i]
在 C 中的真正意思是 *(s + i)
;括号是语法糖。
所以你真的有 *(s + i) = *(s + --i)
在那里。该表达式在左侧读取 i
(它必须计算总和以计算存储数据的地址)并在右侧写入 i
(--i
).并且没有固定的求值顺序,因为=
不是一个序列点。
这意味着读取可以在写入之前或之后进行。在那些情况下,C 标准表示该操作是 未定义,这意味着编译器可以使该代码分支执行任何操作。
我收到警告,而不是错误,当我忽略警告并且 build/run 无论如何,我的代码似乎工作正常。不过我还是很担心,因为警告,或者我只是想了解一下。
此函数将单个字符附加到字符串的开头。
void s_pfx(char pf, char *s){
i = -1;
while(s[++i]);
s[i + 1] = '[=11=]';
while(i)
s[i] = s[--i];
s[i] = pf;
}
当我预先递减 i 时,警告出现在 while 循环中。 (我将 i 作为全局变量。)
警告是"warning: operation on 'i' may be undefined [-Wsequence-point]"
我可以使用
修复它while(i){
s[i] = s[i - 1];
i--;
}
但我为什么要那样做呢?这似乎会耗尽时间,也许是纳秒,但它会加起来。
我不明白为什么编译器无法理解代码。这对我来说似乎很明确。我看了一些其他类似的 questions/answers 但这看起来简单多了。
求助!谢谢
错误确实在表达式 s[i] = s[-- i]
.
C 规范要求某些运算符充当 "sequence points" — 也就是说,它们的第一个操作数在第二个操作数之前被完全评估。但是,=
运算符不是 — 这意味着编译器可以按任何顺序计算表达式。
当您执行类似 i = i + 3
的操作时,这不是问题,因为不会评估赋值的左侧符号(它被写入,而不是读取)。但是你在那里使用指针。 s[i]
在 C 中的真正意思是 *(s + i)
;括号是语法糖。
所以你真的有 *(s + i) = *(s + --i)
在那里。该表达式在左侧读取 i
(它必须计算总和以计算存储数据的地址)并在右侧写入 i
(--i
).并且没有固定的求值顺序,因为=
不是一个序列点。
这意味着读取可以在写入之前或之后进行。在那些情况下,C 标准表示该操作是 未定义,这意味着编译器可以使该代码分支执行任何操作。