Недавно я получил код, принятый clang++, но не g++, и я хотел бы знать, какой из них правильный.
Минималистский код, воспроизводящий поведение, очень короткий и говорит сам по себе, поэтому я думаю, что объяснение было бы излишне сложным.
Вот заголовок, содержащий объявление указателя extern:
//(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 должен его принять.