外部函数指针声明和类型推断定义
Extern function pointer declaration and type inferred definition
我最近收到一个代码,clang++ 可以接受,但 g++ 不能接受,我想知道哪个是正确的。
重现行为的极简主义代码非常短,而且本身就很完整,所以我认为解释起来会不必要地复杂。
这是一个包含外部指针声明的 header :
//(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 无需任何 error/warning 即可接受此代码。并将指针定义替换为 :
decltype(foo)* pointer = &foo;
被 gcc 接受。
在我看来,clang是对的,但我不确定所以我想知道clang是否过于宽松或者gcc是否应该接受它。
这绝对是 gcc 中的错误。这是一个最小的例子:
int foo;
extern int* ptr;
auto ptr = &foo;
有趣的是,如果 extern
和 auto
声明颠倒,gcc 会很高兴。
这似乎与去年报道的https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60352相同。
相关子句为[basic.link]/10:
After all adjustments of types (during which typedefs (7.1.3) are replaced by their definitions), the types
specified by all declarations referring to a given variable or function shall be identical, except that declarations
for an array object can specify array types that differ by the presence or absence of a major array
bound (8.3.4). A violation of this rule on type identity does not require a diagnostic.
我最近收到一个代码,clang++ 可以接受,但 g++ 不能接受,我想知道哪个是正确的。
重现行为的极简主义代码非常短,而且本身就很完整,所以我认为解释起来会不必要地复杂。
这是一个包含外部指针声明的 header :
//(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 无需任何 error/warning 即可接受此代码。并将指针定义替换为 :
decltype(foo)* pointer = &foo;
被 gcc 接受。
在我看来,clang是对的,但我不确定所以我想知道clang是否过于宽松或者gcc是否应该接受它。
这绝对是 gcc 中的错误。这是一个最小的例子:
int foo;
extern int* ptr;
auto ptr = &foo;
有趣的是,如果 extern
和 auto
声明颠倒,gcc 会很高兴。
这似乎与去年报道的https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60352相同。
相关子句为[basic.link]/10:
After all adjustments of types (during which typedefs (7.1.3) are replaced by their definitions), the types specified by all declarations referring to a given variable or function shall be identical, except that declarations for an array object can specify array types that differ by the presence or absence of a major array bound (8.3.4). A violation of this rule on type identity does not require a diagnostic.