C прямое объявление для typedef struct - PullRequest
0 голосов
/ 29 декабря 2018

Я пытаюсь переслать объявление колес типа typedef.

typedef struct wheels wheels;

typedef struct car {
  float topSpeed;
  wheels w;
} car;

typedef struct wheels {
  int frontWheels;
  int backWheels;
} wheels; 

int main() {
  car c = {
    .topSpeed = 255.0,
    .w = {
      .frontWheels = 2,
      .backWheels = 2,
    }
  };

  return 0; 
}

Это дает мне следующие ошибки:

ошибка: поле 'w' имеет колеса неполного типа w;

ошибка: имя поля отсутствует в инициализаторе записи или объединения .frontWheels = 2

ошибка: имя поля отсутствует в инициализаторе записи или объединения .backWheels = 2

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

Как мне правильно объявить правильные колеса структуры?

Ответы [ 2 ]

0 голосов
/ 29 декабря 2018

Вот соответствующие разделы из стандарта C (выделение добавлено):

§6.2.5p1

В различных точках в единице перевода тип объекта может быть неполным (не хватает достаточной информации для определения размера объектов этого типа) или полной (имеющей достаточную информацию).

§6.7.2p3

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

Первый typedef объявляетнеполный тип с именем wheels.Структура car использует этот неполный тип в качестве члена.Это явно запрещено стандартом.

Вот что говорит вам первое сообщение об ошибке.Два других сообщения об ошибках - просто шум.Они являются результатом того, что у компилятора не было достаточно информации для завершения структуры car.

Как уже упоминалось в другом ответе, одним из применений неполных типов является объявление указателей.Например, узел в связанном списке, где структура содержит указатель на себя:

typedef struct node Node;   // struct node and Node are incomplete types here

struct node
{
    int value;
    Node *next;             // using an incomplete type to declare a pointer
};                          // struct node and Node are complete from here forward
0 голосов
/ 29 декабря 2018

Вы можете иметь только указатель на неполную заранее определенную структуру или объединение

...