ide*_*n42 6 c static-code-analysis cppcheck
最近cppcheck在一些C代码中引发了一个错误,它具有以下结构:
((void)(value_prev = value), value = new_value())
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,这可以拆分为2行,但是在某些情况下,这在单个语句中很有用.
在实践中,我发现这适用于流行的编译器(GCC/Clang/MSVC),它们不会发出任何警告(即使警告级别设置为最高).
示例代码:
#include <stdio.h>
int get_next(int i);
int main() {
int i = 0, i_prev = 10;
do {
printf("%d\n", i);
} while ((void)(i_prev = i),
(i = get_next(i)) != 10);
}
Run Code Online (Sandbox Code Playgroud)
CppCheck 1.73 (撰写本文时的最新版本)给出了以下代码的错误:
(error) Expression '(void)(i_prev=i),(i=get_next(i))!=10'
depends on order of evaluation of side effects`
Run Code Online (Sandbox Code Playgroud)
虽然代码可以更改为安静警告,但订单是否真的未定义?
定义了顺序,因为它们之间存在序列点.见ISO/IEC 9899 6.5.17:
逗号运算符的左操作数被计算为void表达式; 评估后有一个序列点.然后评估右操作数; 结果有它的类型和价值.95)如果尝试修改逗号运算符的结果或在下一个序列点之后访问它,则行为未定义.
然后他们给出一个明确的例子:
在函数调用中
f(a, (t=3, t+2), c)
,函数有三个参数,第二个参数的值为5.
我不完全确定为什么CppCheck会标记它.