调用不完整类型的成员函数在gcc中编译,在clang和msvc中不编译

问题描述 投票:0回答:1

这是一个例子:

struct TestClass {
  void testFinction() {}
  static TestClass* ptr_;
  constexpr static auto funcPtr = +[](){ ptr_->testFinction(); };
};

TestClass* TestClass::ptr_ = new TestClass();

int main() {
  TestClass::funcPtr();
  delete TestClass::ptr_;
  return 0;
}

这会在

gcc
中编译,但不会在
clang
msvc
中编译。哪个编译器是正确的?这是
gcc
的bug吗?

这是

clang
错误消息:

<source>:4:46: error: member access into incomplete type 'TestClass'
    4 |   constexpr static auto funcPtr = +[](){ ptr_->testFinction(); };
      |                                              ^
<source>:1:8: note: definition of 'TestClass' is not complete until the closing '}'
    1 | struct TestClass {
      |        ^
1 error generated.
Compiler returned: 1

msvc
错误信息如下:

example.cpp
<source>(4): error C2027: use of undefined type 'TestClass'
<source>(1): note: see declaration of 'TestClass'
<source>(4): error C2131: expression did not evaluate to a constant
<source>(4): note: failure was caused by call of undefined function or one not declared 'constexpr'
<source>(4): note: see usage of 'TestClass::<lambda_bdad2d00eade3d9eccb85c581305196c>::operator void (__cdecl *)(void)'
Compiler returned: 2
c++ visual-c++ g++ clang++
1个回答
2
投票

这似乎是一个 gcc 错误,因为 lambda 的主体不被视为完整的类上下文

类(模板)的完整类上下文是

  • 功能体,
  • 默认参数,
  • 默认模板参数,
  • noexcept 说明符 ([ except.spec]),或
  • 默认成员初始值设定项 在类或类模板的成员规范内。

如果 C 的定义可以从 P ([module.reach]) 到达,或者如果 P 位于 C 的完整类上下文中,则类 C 在程序点 P 处是完整的。 否则,C 在 P 处是不完整的。

© www.soinside.com 2019 - 2024. All rights reserved.