Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extern function pointer declaration and type inferred definition

I recently received a code that is accepted by clang++ but not by g++ and I would like to know which one is right.

The minimalist code reproducing the behavior is very short and talk by itself so I think an explanation would be unnecessarily complicated.

Here is a header containing an extern pointer declaration :

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

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

extern ptr_func pointer;

And here is the source implementing the needed pointed function :

#include "function.hh"

void foo() {}

auto pointer = &foo;

The error generated by gcc is as follows :

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 accepts this code without any error/warning. And replacing the pointer definition by :

decltype(foo)* pointer = &foo;

is accepted by gcc.

In my opinion, clang is right, but I am not sure so I would like to know if clang is too permissive or if gcc should accept it.

like image 281
Ksass'Peuk Avatar asked Mar 03 '15 15:03

Ksass'Peuk


1 Answers

This is definitely a bug in gcc. Here's a minimal example:

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

Interestingly, gcc is happy if the extern and auto declarations are reversed.

This seems to be the same as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60352, reported last year.

The relevant clause is [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.

like image 63
ecatmur Avatar answered Nov 06 '22 22:11

ecatmur