确保“未知评估顺序" [英] being sure about "unknown evaluation order"

查看:96
本文介绍了确保“未知评估顺序"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆