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

GCC and Clang differ in static_assert related to __builtin_constant_p

本文关键字:static assert 有所不同 方面 Clang 在与 builtin constant GCC      更新时间:2023-10-16

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

struct Foo
{
int mem = 42;
};
int main()
{
constexpr Foo foo;
static_assert(__builtin_constant_p(foo));
return 0;
}

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

特别是

  • g++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));
^             ~~~~~~~~~~~~~~~~~~~~~~~~~

我没有发现任何迹象表明__builtin_constant_p应该有任何区别。

对于__builtin_constant_p

GCC称

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

Clang表示

Clang支持许多与GCC语法相同的内置库函数,包括__builtin_nan、__builtine_constant_p、__buintin_choose_expr、__buin.types_compatible_p、__buine_assume_aligned、__sync_fetch_and_add等。

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

这两个问题都记录得很差,所以我怀疑你的问题是否有合适的答案。

如果你需要一个变通方法:如果参数不是int,clang似乎会放弃。

所以这是有效的:

struct Foo
{
int mem = 42;
};
int main()
{
constexpr Foo foo;
static_assert(__builtin_constant_p(foo.mem));
return 0;
}