【问题标题】:static_assert throws error 'non-constant condition for static assertion'static_assert 抛出错误“静态断言的非常量条件”
【发布时间】:2021-06-17 07:46:34
【问题描述】:

为什么这段代码是非常量条件?

static_assert(4294965 * 1000 / 1000 == -2, "overflow occurs");

但这不是:

const int overflowed = 4294965 * 1000 / 1000;
static_assert(overflowed == -2, "overflow occurs");

参见godbolt 上的代码。 注意:使用 gcc

【问题讨论】:

  • 有符号整数溢出是未定义的行为。

标签: c++11 static-assert precompiler


【解决方案1】:

https://en.cppreference.com/w/cpp/language/constant_expression

核心常量表达式是其评估不会评估以下任何一项的任何表达式:

  • [...]
  • 一个表达式,其评估会导致任何形式的核心语言未定义行为(包括有符号整数溢出、被零除、数组边界外的指针算术等)。未指定是否检测到标准库未定义行为。

由于未指定 gcc 是否会检测到未定义的行为,因此它可能会导致一些奇怪的情况,比如你的,当它只检测到某个时候

如果您将const 更改为constexpr,您会得到同样的错误

constexpr int overflowed = 4294965 * 1000 / 1000;

clang 似乎都失败了你的解决方案:https://godbolt.org/z/qocG8xfzb


注意:

即使您找到static_assert 未定义行为的方法并获得您希望的结果这并不意味着您以后可以期待相同的结果在程序中。

见:https://en.cppreference.com/w/cpp/language/ub

UB 和优化

因为正确的 C++ 程序没有未定义的行为,所以当实际具有 UB 的程序在启用优化的情况下编译时,编译器可能会产生意想不到的结果

恕我直言,大多数试图用 UB 适得其反的编译器“智取”的技巧迟早都应该避免

【讨论】:

    猜你喜欢
    • 2016-12-29
    • 1970-01-01
    • 2022-10-15
    • 2020-07-08
    • 2015-03-04
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    • 2019-04-19
    相关资源
    最近更新 更多