gpt4 book ai didi

c++ - 内联 constexpr 函数定义是否合法? gcc (ok) vs clang (error)

转载 作者:IT老高 更新时间:2023-10-28 22:27:00 27 4
gpt4 key购买 nike

我当前的程序被clang拒绝,但用gcc编译得很好。它归结为以下简化示例:

struct A {
static constexpr inline int one();
};

inline constexpr int A::one() { return 1; }

int main() {
return 0;
}

g++ 4.7.2 编译它没有错误(g++ -std=c++11 -Wall -g -o main example.cpp)。 clang++ 3.1 拒绝它:

$ clang++ -std=c++11 -Wall -g -o main example.cpp 
example.cpp:6:25: error: conflicting types for 'one'
inline constexpr int A::one() { return 1; }
^
example.cpp:3:31: note: previous declaration is here
static constexpr inline int one();
^
1 error generated.

我敢打赌 gcc 是对的,而 clang 是错的?程序应该是合法的 C++11。

有趣的旁注。如果 one 在结构中实现,clang 不再提示:

struct A {
static constexpr inline int one() { return 1; }
}

gcc 也接受这个变体。据我了解,根据标准,两个版本应该是相同的。这是一个clang错误还是我错过了什么?

最佳答案

这是一个 Clang 错误(在 Clang 3.2 中修复)。问题在于,在确定函数的重新声明是否与先前的声明匹配时,Clang 没有正确处理隐式 constness 的影响。考虑:

struct A {
int f(); // #1
constexpr int f() const; // #2 (const is implicit in C++11 and can be omitted)
static constexpr int g(); // #3
};

int A::f() { return 1; } // #4, matches #1
constexpr int A::f() { return 1; } // #5, matches #2, implicitly const
constexpr int A::g() { return 1; } // #6, matches #3, not implicitly const

当将类外声明 #5 与 A 的成员匹配时,编译器有一个问题:它不知道 A::f 的新声明是什么类型 还没有。如果A::f是一个非静态成员函数,那么它的类型是int () const,如果它是一个静态成员函数那么它的类型是 int ()(没有隐式 const)。

Clang 3.1 并没有完全正确:它假设如果 constexpr 函数是成员函数,则 constexpr 使其隐含 const,它允许 #4 和 #5 工作,但会破坏 #6。 Clang 3.2 通过两次实现 constexpr-implies-const 规则来解决这个问题:一次在重新声明匹配中(这样 #5 被认为是重新声明 #2 而不是 #1,甚至虽然它还不是隐式 const),并且一旦选择了先前的声明(将隐式 const 添加到#5)。

关于c++ - 内联 constexpr 函数定义是否合法? gcc (ok) vs clang (error),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13907252/

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