Подтвердить что ты не робот

Как это возможно?

В этот вопрос SO Я столкнулся с очень странным typedef:

struct Date {
    int day, month, year;
} typedef date_s;

Я всегда видел typedef после этого "правила":

typedef <existing> <new>;

Например:

typedef unsigned long long ull;
typedef int kph; // speed
typedef void (*alpm_cb_log)(alpm_loglevel_t, const char *, va_list);

typedef int int_t;
typedef char char_t, *char_p, (*fp)(void);

Четвертый из них взят из здесь, пятый и шестой из cppreferenceсуб >


И это, как я мог бы typedef a struct:

typedef struct {
    int a, b, c;
} data;

// and then use it
data Something;

Вопрос в том, как можно даже написать такой typedef? Это даже не имеет смысла (по крайней мере для меня).

clang не дает никаких ошибок или предупреждений даже при -Wall -Wextra.

Бонусный вопрос: должен ли я посоветовать автору вопрос, где этот код можно найти, чтобы избежать использования такого typedef (потому что это очень необычно и может привести к путанице)?

4b9b3361

Ответ 1

Оказывается, что typedef можно разместить после существующего типа (в дополнение к нему). Эта маленькая странность, теперь устаревшая * вызвана тем, как стандарт C "связывает" typedef с спецификаторами класса хранения, такими как static и auto:

Объявление определяется следующим образом:

<declaration> ::=  {<declaration-specifier>}+ {<init-declarator>}*

Это означает, что спецификаторы объявлений могут отображаться в любом порядке. Теперь спецификатор объявления

<declaration-specifier> ::= <storage-class-specifier>
                          | <type-specifier>
                          | <type-qualifier>

И спецификатор класса хранения

<storage-class-specifier> ::= auto
                        | register
                        | static
                        | extern
                        | typedef

Объявление элементов struct является спецификатором типа. Как и ключевое слово typedef, это спецификатор объявления. Поскольку спецификаторы объявлений могут отображаться в любом порядке, оба места размещения typedef (т.е. До и после struct) действительны и идентичны друг другу.

*N1570, 6.11.5: "Размещение спецификатора класса хранения, отличного от в начале деклараций декларации является устаревшей особенностью". Спасибо, Keith Thompson, за отличный комментарий!