#include <stdio.h>
struct Header
{
unsigned long long int alignment;
};
int main(void)
{
struct Header header; // note: we can loose the 'struct' in C++
struct Header* pheader = &header;
return 0;
}
Программа выше прекрасно компилируется как на C, так и на C ++.
Но когда я изменяю структуру заголовка на:
struct {
unsigned long long int alignment;
} Header;
это терпит неудачу со следующим сообщением в C:
error: storage size of ‘Header’ isn’t known
и в C ++:
error: aggregate ‘main()::Header header’ has incomplete type and cannot be defined struct Header header;
Аналогичная структура используется в реализации Storage Allocator в книге C Language Language by K&Р. Я думал, что это то же самое, но я узнаю, что это не так. С тех пор я видел и в других местах. Я конечно больше знаком с первой версией. Что означает второй и почему он вообще существует? В чем разница?
struct Header {};
вводит struct
тип по имени Header
,
typedef struct {} Header;
вводит анонимный тип структуры и псевдоним Header
для этого анонимного типа.
struct {} Header;
вводит как анонимный тип структуры, так и переменную с именем Header
анонимного типа.
Когда нет названного типа Header
(последний случай), struct Header header;
вводит struct
тип по имени Header
без тела, затем пытается создать переменную header
этого типа.
Когда вы компилируете ниже часть
struct {
unsigned long long int alignment;
} Header;
struct
не имеет тег, это называется анонимная структура тип. делая
struct Header header;
компилятор выдаёт ошибку вроде
Заголовок заголовка имеет неполный тип и не может быть определен struct Header
заголовок
Следовательно, в этих случаях лучше typedef
struct
, Например,
typedef struct {
unsigned long long int alignment;
} Header;
Проще говоря, компилятор видит «Заголовок» и не имеет предыдущего или встроенного типа данных «Заголовок», поэтому он не знает, что это такое. Когда вы используете
typedef struct header {
....
} Header;
Компилятор может сказать, эй, пользователь сказал мне определенный тип данных, и теперь у меня может быть что-то, на что я буду ссылаться позже в коде.