Прямое объявление C-структуры приводит к «несовместимым типам»-предупреждение

#c #typedef #forward-declaration

Вопрос:

У меня есть некоторые функции, которые используют тип прямого объявления A :

 typedef struct AImpl A;

void fun(A* a);
 

Позже будет включена библиотека, которая определяет тип B и функцию для его создания:

 struct B {
  /*...*/
};
struct B* newB(void) {
  /*...*/
}
 

Наконец, я определяю тип A как этот тип B и использую его:

 typedef struct B AImpl;

void fun(A* a) {
  a = newB();
}
 

Однако это создает предупреждение:

‘=’: несовместимые типы — от ‘B *’ до ‘A *’

Есть ли способ переадресации-объявить тип, совместимый с B (в этом примере A ), без…

  • вперед-заявляя B о себе
  • включая библиотеку перед объявлением функций, которые используют A
  • необходимость привести результат к newB() A*

?

Комментарии:

1. typedef struct AImpl A; и typedef struct B AImpl; не делайте A и B того же типа. struct AImpl очень отличается от AImpl . B это вообще не тип ( struct B есть).

2. У вас есть struct AImpl то, что вы набрали на другое имя. Тогда у вас есть struct B то, что вы хотите напечатать AImpl . Итак, что есть что?

3. @n.1.8e9 Спасибо за разъяснение моего недопонимания, теперь я понимаю, почему мой подход не сработал. Перефразируя мой вопрос, есть ли способ иметь struct B совместимый тип до struct B того, как он будет определен, без прямого объявления struct B самого себя?

4. Боюсь, что нет. Почему бы просто не заявить об этом прямо?

5. Во-первых, неясно, почему вы хотите объявить fun , прежде чем включать заголовок библиотеки. Просто включите заголовок библиотеки, а затем объявите fun . Во-вторых, если вы хотите fun взять указатель на struct B то, что будет объявлено в заголовке библиотеки , вы можете просто объявить переадресацию struct B; , а затем void fun(struct B *a); . Ты даже мог бы это сделать typedef struct B A; void fun(A *a); .