Typedef struct перед объявлением - программирование
Подтвердить что ты не робот

Typedef struct перед объявлением

Я не новичок, я очень хорошо знаком со следующей идиомой:

typedef struct Foo_ Foo;// I know typedef struct Foo Foo is fine, I'm just trying to make it clearer
struct Foo_
{
    int value;
    Foo *link;
};

Я просто внезапно чувствую смущение, потому что я понимаю, что ему не разрешено использовать имя (идентификатор) до его объявления. Но в объявлении typedef struct Foo_ Foo идентификатор Foo_ еще не существует! Почему компилятор разрешает это? Кто-нибудь, пожалуйста, пролил бы свет на это, объясните мне, какое оправдание для такого синтаксиса?

Цитата из Википедии: целью typedef является назначение альтернативных имен для СУЩЕСТВУЮЩИХ типов.

--- > 8 ---

Спасибо всем парням за столь полезную информацию.

4b9b3361

Ответ 1

Это совершенно нормально. Первое использование тега struct, такого как ваш, является прямым объявлением типа struct.

Остерегайтесь, если ваше использование _Foo соответствует не. Идентификаторы с ведущим подчеркиванием и следующей заглавной буквой зарезервированы. Не делай этого. Подчеркивание подчеркивания будет в порядке.

Ответ 2

Это описано в 6.7.2.3p8:

6.7.2.3 Теги

Семантика
[...]

8 - Если спецификатор типа идентификатора структуры или объединения имеет место иначе, чем [определение структуры или объединения] или [структурно-профсоюзная декларация], и никакое другое объявление идентификатор в виде тега, то он объявляет неполную структуру или тип объединения и объявляет идентификатор как тег этого типа.

Спецификатор типа struct Foo в typedef struct Foo Foo не находится в определении (struct Foo {...};) или декларации (struct Foo;), поэтому он подпадает под 6.7.2.3p8.

Обратите внимание, что нет ничего особенного в typedef; вы также можете, например, написать

struct A { struct Foo *p; };

и предыдущее определение или объявление не должны быть видимыми.

Однако в объявлении функции или определении:

void foo(struct Foo *p);

Если struct Foo не объявляется ранее, то область объявления будет просто объявлением или определением функции, и она не будет совместима с типом любого последующего объявления или определения Foo.

Ответ 3

ISO c99 : 6.2.1 Scopes of identifiers

7

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

typedef struct _Foo Foo; // You can do this because it just the typedef the new type

struct _Foo *myfoo ; // It pointer to struct _Foo (an incomplete type)
                      //but make sure before using myfoo->value   
                    // struct definition should be available

struct _Foo MyFoo;  // It  definition of MyFoo but don't forget 
                    // to give the definition of struct _Foo (gcc extension). 

struct _Foo;  // forward declaration

struct _Foo    // It the definition
{
    int value;
    Foo *link;
};

Просто, как и для functions, мы выполняем forward declaration или typedef до фактического определения функции. Поэтому мы также можем сделать это с помощью struct.

void func(int );
typedef void (*func_t)(int);

void func(int x)
{
 //actual definition
}

Ответ 4

typedef используется для создания псевдонима для типа. Но этот тип не обязательно существует, когда typedef'ed.

Например,

если вы просто выполните:

struct Foo;

и вы никогда не определяете struct Foo в любом месте программы, тогда он все равно будет компилироваться. Компилятор предположил, что он определен где-то и продолжается. Только если вы используете его без определения структуры, произойдет ошибка.

Это аналогичный случай с typedef.

Ответ 5

При определенных обстоятельствах допустимо использовать тип struct ... до его объявления. Тогда это так называемый "неполный тип".

Например, допустимо объявить переменную как указатель на "неполную" структуру, а также (как вы можете видеть) a typedef.

Ответ 6

Он вызвал вперед объявление. Объявление вперед позволяет использовать его имя в контексте, где разрешен неполный тип.

Компилятор "увидит" тэг typedef и сохранит его до тех пор, пока тип не будет найден, так как до тех пор, пока у вас есть тип, объявленный там после typedef, но перед любым использованием это прекрасно.

Ответ 7

Объявление typedef позволяет определять собственные идентификаторы, которые могут использоваться вместо спецификаторов типа, таких как int, float и double. Объявление typedef не резервирует хранилище.

для дополнительной информации http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=%2Fcom.ibm.vacpp6m.doc%2Flanguage%2Fref%2Fclrc03typdef.htm