【问题标题】:GCC constexpr allows add but not bitwise-or with addressGCC constexpr 允许添加但不允许按位或与地址
【发布时间】:2020-03-14 12:08:32
【问题描述】:

考虑这段代码:

#include <cstdint>

static int x = 0;

const uintptr_t arithmetic()
{
    static constexpr uintptr_t result = ((uintptr_t)&x) + 1u;
    return result;
}

const uintptr_t bitwise()
{
    static constexpr uintptr_t result = ((uintptr_t)&x) | 1u;
    return result;
}

GCC(所有版本 4-9)编译 arithmetic() 很好,但拒绝 bitwise()

<source>: In function 'const uintptr_t bitwise()':
<source>:13:57: error: '(((uintptr_t)(& x)) | 1)' is not a constant expression
   13 |     static constexpr uintptr_t result = ((uintptr_t)&x) | 1u;
      |                                         ~~~~~~~~~~~~~~~~^~~~

为什么?请注意,按位或在其他 constexpr 用例中工作正常,但不是这个。

演示:https://godbolt.org/z/x5jbuU

【问题讨论】:

  • 可能是因为这个特定的uintptr_t 的基因起源于一个指针。您可以向指针添加内容,但不能按位或向指针添加任何内容;对于constexpr,编译器实际上会尝试评估内容。
  • static constexpr uintptr_t result = (uintptr_t)&amp;x; 也失败了。
  • @Evg:确实如此。我现在想知道 GCC 是否试图拒绝 constexpr 中指针的所有使用,而 + 不知何故让它忘记了。
  • 我觉得this 也很有趣。 + 1u 编译,+ 0u 不编译。

标签: c++ c++11 gcc g++ constexpr


【解决方案1】:

您根本不能在常量表达式中使用reinterpret_cast(或执行此操作的 C 样式转换)。 GCC 要么有执行此操作的错误,要么试图帮助支持一些与 + 相关但与 | 无关的实际用例。

【讨论】:

  • GCC 根本不强制执行这样的限制(Clang 会,但我不是在询问 Clang)。这是一个愚蠢的演示:godbolt.org/z/suehtD
  • @JohnZwinck:这只是显示了永远不能在常量表达式中调用的 constexpr 函数的无诊断要求;尝试这样的调用被拒绝。
  • 有参考吗?
  • @tigertang:你的意思是definition of a constant expression吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-19
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多