确保“未知评估顺序" [英] being sure about "unknown evaluation order"
问题描述
从1.80版开始,Cppcheck告诉我
Since version 1.80, Cppcheck tells me that
表达式'msg [ipos ++] = checksum(& msg [1],ipos-1)'取决于副作用的评估顺序
Expression 'msg[ipos++]=checksum(&msg[1],ipos-1)' depends on order of evaluation of side effects
在此代码序列中(简体,data
是变量)
in this code sequence (simplified, data
is a variable)
BYTE msg[MAX_MSG_SIZE]; // msg can be smaller, depending on data encoded
int ipos = 0;
msg[ipos++] = MSG_START;
ipos += encode(&msg[ipos], data);
msg[ipos++] = checksum(&msg[1], ipos-1); // <---- Undefined Behaviour?
msg[ipos++] = MSG_END; // increment ipos to the actual size of msg
,并将其视为错误,而不是可移植性问题.
and treats this as an error, not a portability issue.
它是C代码(合并到C ++主导的项目中),使用符合C ++ 98的编译器进行编译,并且可以按预期运行数十年. Cppcheck使用C ++ 03,C89,自动检测语言运行.
It's C code (incorporated into a C++-dominated project), compiled with a C++98-complient compiler, and meanwhile runs as expected for decades. Cppcheck is run with C++03, C89, auto-detect language.
我承认最好重写代码.但是在这样做之前,我尝试弄清楚:它真的取决于评估顺序吗?据我了解,正确的操作数首先被求值(在调用之前需要进行评估),然后赋值(到msg[ipos]
),最后以ipos
的增量赋值.
I confess that the code should better be rewritten. But before doing this, I try to figure out: Is it really dependent on evaluation order? As I understand it, the right operand is being evaluated first (it needs to before the call), then the assignment is taking place (to msg[ipos]
) with the increment of ipos
done last.
我对这个假设是错误的,还是只是误报?
Am I wrong with this assumption, or is it just a false positive?
推荐答案
此代码的确确实以一种定义不好的方式依赖于评估顺序:
This code does indeed depend on evaluation order in a way which is not well defined:
msg[ipos++] = checksum(&msg[1], ipos-1);
具体而言,未指定在评估ipos-1
之前或之后ipos++
是否递增.这是因为在=
上没有"序列点",而仅在完整表达式(;
)的结尾.
Specifically, it is not specified whether ipos++
will increment before or after ipos-1
is evaluated. This is because there is no "sequence point" at the =
, only at the end of the full expression (the ;
).
函数调用是一个序列点.但这仅保证ipos-1
发生在函数调用之前.它不保证ipos++
会在此之后发生.
The function call is a sequence point. But that only guarantees that ipos-1
happens before the function call. It does not guarantee that ipos++
happens after.
似乎应该以这种方式重写代码:
It appears the code should be rewritten this way:
msg[ipos] = checksum(&msg[1], ipos-1);
ipos++; // or ++ipos
这篇关于确保“未知评估顺序"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!