关于未定义操作的编译器警告

时间:2016-11-11 23:19:35

标签: c++

这是我从字节数组中反序列化uint64_t值的代码:

uint8_t* s = blah;

uint64_t output =
     (((uint64_t)*s++) << 56) +
     (((uint64_t)*s++) << 48) +
     (((uint64_t)*s++) << 40) +
     (((uint64_t)*s++) << 32) +
     (((uint64_t)*s++) << 24) +
     (((uint64_t)*s++) << 16) +
     (((uint64_t)*s++) <<  8) +
     (((uint64_t)*s)        );

我正在使用Ubuntu上的g ++版本5.4编译此代码。

虽然代码完全符合预期,但我在最后一行收到编译时警告:

 warning: operation on 's' may be undefined [-Wsequence-point]

想知道可能出现什么问题以及如何解决它。问候。

2 个答案:

答案 0 :(得分:3)

您的代码对变量s进行了无序修改。此行为未定义。您可以通过使用索引而不是推进指针来修复它(我假设您正在读取一个小端变量。这在您的代码中是不明显的):

uint64_t output =
     (((uint64_t)s[0]) << 56) +
     (((uint64_t)s[1]) << 48) +
     (((uint64_t)s[2]) << 40) +
     (((uint64_t)s[3]) << 32) +
     (((uint64_t)s[4]) << 24) +
     (((uint64_t)s[5]) << 16) +
     (((uint64_t)s[6]) <<  8) +
     (((uint64_t)s[7])        );

答案 1 :(得分:1)

您的代码在指令中七次修改s的值,然后第八次使用它。 C标准或C ++标准都没有强加任何要求,如果它接收到可能导致执行此类代码或使其执行不可避免的输入将会执行的操作。但请注意,如果程序从未接收到会导致代码执行不可避免的输入,那么应用程序中此类代码的存在不会影响应用程序的正确性,因此它不是编译错误。使用s [0],s [1],s [2]等调整代码可以使代码更清晰,避免出现此类问题。