Переменная с тем же именем, что и тип — какой компилятор прав?

В этом коде:

typedef int foo;

struct S
{
foo foo;
};

int main() {}

все версии clang -std=c++14 принять этот код, однако все версии g++ -std=c++14 доклад:

5 : error: declaration of 'foo S::foo' [-fpermissive]
foo foo;
^
1 : error: changes meaning of 'foo' from 'typedef int foo' [-fpermissive]

Код правильный?

13

Решение

Код неверный. typedef это новое имя для существующего типа. Таким образом, вы не можете создать переменную с именем типа, как foo foo; равно int int,

g++ -std=c++14 правильный.

Также отошлите этот вопрос

7

Другие решения

Я бы сказал, что CLang является правильным здесь, даже если бы я никогда использовать этот.

C ++ 14 проект N4296 говорит в 7.1 Спецификаторы [dcl.spec] 3

Если при анализе decl-specier-seq встречается имя типа, оно интерпретируется как часть decl-specier-
seq тогда и только тогда, когда в decl-specier-seq нет предыдущего спецификатора типа, кроме cv-qualifier.
последовательность должна быть самосогласованной, как описано ниже. [ Пример:

typedef char * Pc;

статический ПК; // ошибка: имя отсутствует

Здесь объявление static Pc является неправильно сформированным, поскольку для статической переменной типа Pc не было указано имя.

Чтобы получить переменную с именем Pc, должен присутствовать спецификатор типа (отличный от const или volatile), чтобы указать, что
typedef-name Pc — это объявленное (пере) имя, а не часть последовательности спецификатора decl.

Для другого примера

пустота f (const Pc); // void f (char * const) (не const char *)

void g (const int Pc); // void g (const int)

(подчеркните мой)

Даже если пример не является нормативным, он позволяет думать, что для авторов спецификации C ++ переменная может переопределить имя typedef.

Но g ++ просто более консервативен, что выглядит более разумный. Если я когда-либо увижу такую ​​конструкцию в производственном коде, программист вскоре научится не делать это снова, даже если компилятор принял это …

0

По вопросам рекламы [email protected]