Ответ 1
Это невырожденный синтаксис, который разрешен, но не дает никакой пользы. Большинство современных компиляторов могут быть спровоцированы предупреждением об этом; по умолчанию они не могут. Без имени typedef ключевое слово typedef
является излишним; в вашем примере это полностью эквивалентно:
enum test { one };
Другое место, где это может произойти, со структурой:
typedef struct SomeThing { int whatever; };
Это эквивалентно:
struct SomeThing { int whatever; };
Обратите внимание, что typedef
официально (или синтаксически) является "спецификатором класса хранения", например static
, extern
, auto
и register
.
C Стандарт
В ИСО/МЭК 9899: 1999 (что стандарт С) мы находим:
§6.7 Объявления
Синтаксис
декларация:
Объявление-спецификаторы init-declarator-list opt;
декларирование спецификаторы:
спецификация-спецификатор хранилища opt
спецификатор типа объявления-спецификаторы opt
type-qualifier объявления-спецификаторы opt
function-specifier объявления-спецификаторы opt
INIT-описатель-лист:
init-declarator
init-declarator-list, init-declarator
INIT-описателя:
declarator
declarator = initializer
И (по запросу):
§6.7.1 Спецификаторы класса хранения
Синтаксис
хранения класса спецификатор:
typedef
extern
static
auto
register
Если вы отслеживаете этот синтаксис, существует множество вырожденных возможностей, и то, что вы показали, является одним из многих.
Стандарт С++
Возможно, что С++ имеет разные правила.
В ISO/IEC 14882: 1998 (исходный стандарт С++) мы находим в §7.1.1 "Спецификаторы класса хранения", что С++ не рассматривает typedef
как класс хранения; список добавляет mutable
и исключает typedef
. Итак, грамматическая спецификация typedef
в С++ определенно отличается от спецификации C.
§7 Объявления
В объявлениях указывается, как следует интерпретировать имена. Объявления имеют форму
Заявление-сл:
Объявление
декларация объявления-seq
декларация:
объявление блока
определение функции
объявление шаблона
Явное-представление
Явная спецификация
спецификация привязки
namespace-definition
блок-декларация:
простейшая декларация
asm-definition
namespace-alias-definition
using-declaration
с использованием директивы
простое декларирование:
decl-specifier-seq opt init-declarator-list opt;
...
¶5 Если decl-specifier-seq содержит спецификатор
typedef
, декларация называется объявлениемtypedef
и имя каждогоinit-declarator
объявляется как typedef-name, синонимом связанного с ним типа (7.1.3).§7.1. Спецификаторы [dcl.spec]
Спецификаторами, которые могут использоваться в объявлении, являются
Децл-спецификатора:
спецификатор класса хранения
спецификатор типа
function-specifier
friend
typedef
Децл-спецификатор-сл:
decl-specifier-seq opt
decl-specifier
§7.1.1 Спецификаторы класса хранения [dcl.stc]
хранения класса спецификатор:
auto
register
static
extern
mutable
§7.1.2 Спецификаторы функций [dcl.fct.spec]
функция спецификатор:
inline
virtual
explicit
§7.1.3 Спецификатор typedef [dcl.typedef]
Объявления, содержащие спецификатор decl
typedef
объявлять идентификаторы, которые могут быть использованы позже для именования фундаментальных (3.9.1) или сложных (3.9.2) типов. Спецификаторtypedef
не должен использоваться в определении функции (8.4), и он не должен объединяться в спецификаторе decl-seq с любым другим спецификатором, кроме спецификатор типа.ЬурейеЕ-имя:
идентификатор
...
В заданной области спецификатор typedef может использоваться для переопределения имени любого типа, объявленного в этой области для обозначения того типа, к которому он уже относится. [Пример:
typedef struct s { /* ... */ } s; typedef int I; typedef int I; typedef I I;
-end пример]
§7.1.4 Спецификатор друга [dcl.friend]
Спецификатор друга используется для указания доступа к членам класса; см. 11.4.
§7.1.5 Спецификаторы типа [dcl.type]
тип спецификатор:
спецификатор простого типа
class-specifier
enum-specifier
специфицированный тип-спецификатор
cv-qualifier
Так как в § 7 ¶5 говорится, что имена typedef
приходят из init-declarator, а в списке init-declarator помечен 'opt', я думаю, это означает, что имя typedef
можно опустить на С++, просто как в C.