Обязателен ли `synonym` в` typedef`? - PullRequest
8 голосов
/ 14 января 2011

Я столкнулся с этим в обзоре кода:

typedef struct C { int i; };

Он компилируется.

Помимо того, что это стиль C, где структуры находятся в отдельном «пространстве имен», и нужнобыть дешифрованным для последующего использования, я нахожу странным, что с этим typedef ничего не определено ...

Итак: typedef не требуется аргумент типа и аргумент псевдонима?

Ответы [ 6 ]

5 голосов
/ 14 января 2011

Быстрый взгляд на n3225 не показывает никакого требования, что имя должно присутствовать.Текст, который находится ближе всего, просто говорит:

В простом объявлении необязательный список инициализатора-объявления можно опустить только при объявлении класса (пункт 9) или перечисления (7.2),это, когда decl-specier-seq содержит либо спецификатор класса, либо сложный спецификатор типа с ключом класса (9.1), либо спецификатор перечисления.

Итак, ваш код кажется верным, но я думаю, что он плохо пахнет.

2 голосов
/ 14 января 2011

Скорее всего, вы используете очень старый компилятор, который позволяет вам скомпилировать эту строку.Используя g ++ 4.3.0 (который уже довольно старый), без каких-либо дополнительных опций, получите следующее:

g++ dfg.cpp
dfg.cpp:2: warning: ‘typedef’ was ignored in this declaration

Итак, попробуйте скомпилировать его с помощью компилятора, более совместимого со стандартом c ++.

2 голосов
/ 14 января 2011

Да, typedef требует другого аргумента. Это typedef ничего не сделает.

В любом случае, это не ошибка, просто не рекомендуется использовать typedef.


Стандарт

C (n1256 в 6.7.7) говорит о typedef. Это не говорит, что это использование устарело, но компиляторы сообщают об этом, так как такое утверждение не имеет никакого эффекта.

2 голосов
/ 14 января 2011
Thank you for testing your code with Comeau C/C++!
Tell others about http://www.comeaucomputing.com/tryitout !

Your Comeau C/C++ test results are as follows:


Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.  All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 1: warning: declaration requires a typedef name
  typedef struct C { int i; };
                             ^
1 голос
/ 16 января 2011

Рассмотрим параллели между:

typedef struct C { int i; };
extern  struct P { int i; };

GCC 4.2.1 без явных предупреждений (gcc -c xxx.c) говорит о первом:

xxx.c:1: warning: useless storage class specifier in empty declaration
xxx.c:2: warning: useless storage class specifier in empty declaration

Обратите внимание, что они толькопредупреждения;они не являются ошибкой, потому что стандарт допускает обозначения, хотя он не делает очень много.В каждом случае в примере просто объявляется тип структуры, который может использоваться именем struct C или struct P.Классы хранения не имеют значения, потому что ни один объект не назван.В C ++ эти объявления также объявляют типы C и P (но это также может произойти, если typedef или extern was not there); in C, those types ( C and P`) не объявлены.

ВВ стандарте C typedef рассматривается как класс хранения, как extern и static - классы хранения.Это означает, что следующий код является допустимым:

typedef struct C { int i; } name1;
extern  struct P { int i; } name2;

Он объявляет те же два типа структуры, что и раньше, но теперь typedef объявляет псевдоним для struct C, который равен name1, и *В строке 1026 * указано, что другая единица перевода (TU) определяет переменную с именем name2 типа struct P.Ни один из них не является пустым (за исключением того, что определения не используются позже в показанном двухстрочном TU).

Стандарт C допускает много странных вещей.Например:

int unsigned typedef u;

Это совершенно правильный, но совершенно ненормальный способ написания:

typedef unsigned int u;

В C99 есть раздел §6.11.5 (в разделе «Будущие языковые инструкции»)которая гласит:

6.11.5 Спецификаторы класса хранения

Размещение спецификатора класса хранения, отличного от начала описателей объявления в объявлении, является устаревшей функцией.

Это делает мой странный пример с нарушением §6.11.5.

Резюме

  • Рассмотренный код синтаксически корректен в C, как C89, так иC99.
  • Кроме того, AFAIK синтаксически допустим в C ++ - но это даже более бессмысленно, чем в C, поскольку struct C { int i; }; без typedef вводит тип C (а также struct C).
  • Рассмотренный код не должен приниматься - разумно требовать его исправления.

Правильным исправлением может быть удаление класса хранения (typedef) или егоможет быть, ввести имя в качестве псевдонима для struct C,Поскольку код компилируется без псевдонима, правильнее удалить класс хранилища.

1 голос
/ 14 января 2011

Действительно, это не верно.Вы используете ключевое слово typedef для создания псевдонима, а не указываете, каким должен быть псевдоним!

(Строго говоря, он устарел, не недействителен. Но эй.)

...