GCC 和 Clang 在与 __builtin_constant_p 相关的 static_assert 方面有所不同

aaf*_*lei 5 c++ g++ static-assert constexpr clang++

我碰巧发现GCC和Clang在以下代码的编译上有所不同:

struct Foo
{
    int mem = 42;
};

int main()
{
    constexpr Foo foo;
    static_assert(__builtin_constant_p(foo));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我用g++ -std=c++17和编译clang++ -std=c++17

特别是,

  • 加++ g++-9 (Homebrew GCC 9.3.0_1) 9.3.0编译,而
  • clang++Apple clang version 11.0.3 (clang-1103.0.32.62)无法编译,抱怨说
error: static_assert failed due to requirement '__builtin_constant_p(foo)'
    static_assert(__builtin_constant_p(foo));
    ^             ~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

我没有发现任何关于__builtin_constant_p.

为了 __builtin_constant_p

海湾合作委员会

您可以使用内置函数 __builtin_constant_p 来确定某个值在编译时是否已知为常量...

叮当

Clang 支持许多与 GCC 语法相同的内置库函数,包括 __builtin_nan、__builtin_constant_p、__builtin_choose_expr、__builtin_types_compatible_p、__builtin_assume_aligned、__sync_fetch_and_add 等。

问题:虽然我知道__builtin_constant_p是一个编译器扩展,但哪个应该是正确的?

NoS*_*tAl 1

两者的记录都很少,所以我怀疑您的问题是否有正确的答案。

如果您需要解决方法:如果参数不是 int,则 clang 似乎会放弃。

所以这有效:

struct Foo
{
    int mem = 42;
};

int main()
{
    constexpr Foo foo;
    static_assert(__builtin_constant_p(foo.mem));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)