gpt4 book ai didi

c++ - 在参数评估顺序中警告 UB

转载 作者:行者123 更新时间:2023-11-30 04:54:37 26 4
gpt4 key购买 nike

我最近在这样的代码中遇到了一个错误

class C
{
public:
// foo return value depends on C's state
// AND each call to foo changes the state.
int foo(int arg) /*foo is not const-qualified.*/ {}

private:
// Some mutable state
};

C c;

bar(c.foo(42), c.foo(43))

最后一次调用在不同平台上的行为不同(由于参数评估顺序未定义,这是完全合法的),我修复了这个错误。

但其余代码库很大,我想找出所有其他此类 UB。

对于这种情况,GCC、Clang 或 MSVS 中是否有特殊的编译器警告?

防止此类错误的思想和轻量级方法是什么?

最佳答案

Argument order evaluation未指定而不是未定义。

Order of evaluation of the operands of almost all C++ operators (including the order of evaluation of function arguments in a function-call expression and the order of evaluation of the subexpressions within any expression) is unspecified. The compiler can evaluate operands in any order, and may choose another order when the same expression is evaluated again.

由于它是未指定的而不是未定义的行为,编译器不需要为其发出诊断。

GCC 和 Clang 没有任何通用的编译器选项来为未指定的行为发出诊断。

在 GCC 中有一个选项 fstrong-eval-order这是这样做的:

Evaluate member access, array subscripting, and shift expressions in left-to-right order, and evaluate assignment in right-to-left order, as adopted for C++17. Enabled by default with -std=c++17. -fstrong-eval-order=some enables just the ordering of member access and shift expressions, and is the default without -std=c++17.

还有选项 -Wreorder(仅限 C++ 和 Objective-C++)执行此操作:

Warn when the order of member initializers given in the code does not match the order in which they must be executed

但我认为这些选项对您的特定情况没有帮助。

在下面的语句中,如果您希望第一个参数在第二个参数之前被求值:

bar(c.foo(42), c.foo(43))

简单的做法是先将c.foo(42)c.foo(43)的结果存入中间变量,然后调用bar ()。 (关闭编译器优化以避免编译器对语句进行任何重新排序!!)

auto var1 = c.foo(42);
auto var2 = c.foo(43);
bar(var1, var2);

我想这就是您修复错误的方式。

关于c++ - 在参数评估顺序中警告 UB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53493041/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com