【问题标题】:Extern function pointer declaration and type inferred definition外部函数指针声明和类型推断定义
【发布时间】:2015-05-04 07:18:38
【问题描述】:

我最近收到了一个clang++接受但g++不接受的代码,我想知道哪个是正确的。

重现该行为的极简代码非常简短,并且可以自行说明,因此我认为解释会不必要地复杂。

这是一个包含外部指针声明的标题:

//(guards removed for simplicity) :
#include <type_traits>

using ptr_func = std::add_pointer<void()>::type;

extern ptr_func pointer;

这是实现所需指向功能的源代码:

#include "function.hh"

void foo() {}

auto pointer = &foo;

gcc产生的错误如下:

g++ -c function.cc -std=c++14
function.cc:5:6: error: conflicting declaration ‘auto pointer’
 auto pointer = &foo;
      ^
In file included from function.cc:1:0:
function.hh:5:17: note: previous declaration as ‘void (* pointer)()’
 extern ptr_func pointer;
                 ^

Clang 接受此代码,没有任何错误/警告。并将指针定义替换为:

decltype(foo)* pointer = &foo;

被 gcc 接受。

在我看来,clang 是对的,但我不确定,所以我想知道 clang 是否过于宽松,或者 gcc 是否应该接受它。

【问题讨论】:

  • 究竟是哪个 GCC 版本?
  • 我用g++4.9.1和g++4.9.2测试过
  • 我已经使用std::add_pointer&lt;void (*)()&gt;::type;(对我来说更像是一个有效的函数指针声明)在 Ideone 上测试了代码(认为它至少使用 g++4.9.1)。但它也不接受这一点。看起来 GCC 的 std::add_pointer 实现不适用于函数指针。
  • @πάνταῥεῖ std::add_pointer&lt;void (*)()&gt;::type; 将是指向指针的指针。这里的问题不在于add_pointer 正常工作,而是auto 推断类型与先前声明的类型。
  • 这是一个完全不涉及指针的简单示例:extern int x; auto x = 1; int main() {}。它也适用于 clang 但不适用于 gcc。

标签: c++ c++11 function-pointers


【解决方案1】:

这绝对是 gcc 中的一个错误。这是一个最小的例子:

int foo;
extern int* ptr;
auto ptr = &foo;

有趣的是,如果 externauto 声明被颠倒,gcc 很高兴。

这似乎与去年报道的https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60352 相同。

相关条款是[basic.link]/10:

在所有类型调整之后(在此期间 typedefs (7.1.3) 被它们的定义替换),类型 由引用给定变量或函数的所有声明指定应相同,除了声明 对于数组对象,可以指定因主数组的存在或不存在而不同的数组类型 绑定(8.3.4)。在类型标识上违反此规则不需要诊断。

【讨论】:

  • foo() 实际上是 OP 示例中的函数?这有什么不同吗?
  • @πάνταῥεῖ 我不明白为什么它应该有所作为; void (*)() 是一种数据类型,从所有外观来看 gcc 正在正确执行其类型计算。
  • 如果这是 gcc 中的错误,那么 visual c++ 2017(v19.10.24930) 也有相同的错误。 MSVC 给出error C2373: redefinition; different type modifiers。所以你是说在 3 个主要的编译器实现中,有 2 个犯了这个错误,而且即使在最新版本中,这个 bug 仍然存在。 (测试melpon.org/wandbox
  • @greatwolf 是的,看起来是这样。请注意,icc 与 clang 一致,因此它更像是 50-50 的拆分。
  • @LightnessRacesinOrbit 这是 [dcl.spec.auto]/4,不是吗? (C++11 中的 [dcl.spec.auto]/3)。
猜你喜欢
  • 1970-01-01
  • 2021-05-30
  • 2016-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-20
  • 1970-01-01
相关资源
最近更新 更多