Ответ 1
Источник, скомпилированный как ObjC, имеет те же правила, что и C в этом отношении.
Источник, скомпилированный как ObjС++, имеет те же правила, что и С++ в этом отношении.
@class MONClass;
является прямым объявлением типа ObjC. Не используйте его для структур.
struct t_mon_struct;
является прямым объявлением именованной структуры C или С++. Не используйте его для типов ObjC. Технически компилятор позволяет вам также переслать объявление класса С++ как структуры (если конечно класс также объявлен в глобальном пространстве имен).
Таким образом, корень семантики все сводится к C (предполагая, что это преобразование ObjC). Я перестану упоминать ObjC и С++ сейчас.
Здесь есть некоторые общие источники сложности:
- пространство имен struct
- объявление структуры
- избегать множественных определений меток
struct t_mon_struct;
является прямым объявлением тегированной структуры. В частности, это имя, которое существует в пространстве имен struct.
тегированная структура, которая существует в пространстве имен struct:
struct t_mon_struct { int a; };
анонимная структура с typedef в глобальном пространстве имен:
typedef struct { int a; } t_mon_struct;
помеченная структура с типом в глобальном пространстве имен:
typedef struct t_mon_struct { int a; } t_mon_struct;
CMTime
объявляется следующим образом:
typedef struct
{
CMTimeValue value;
CMTimeScale timescale;
CMTimeFlags flags;
CMTimeEpoch epoch;
} CMTime;
В частности, глобальная метка typedef CMTime
привязана к анонимной структуре в пространстве имен struct и может не ссылаться, если только ее объявление не отображается.
Было объявлено CMTime
:
typedef struct CMTime
{
CMTimeValue value;
CMTimeScale timescale;
CMTimeFlags flags;
CMTimeEpoch epoch;
} CMTime;
то вы могли бы получить с помощью форвардного объявления struct CMTime
:
struct CMTime;
void foo(struct CMTime*);
Так как он не был объявлен таким образом, вам нужно #include
его объявление или разработать обходное решение.
Усложнения ухудшаются, когда struct typedef отличается от его тега. Вы не можете связывать или переопределять typedef (в C). Однако вы можете прокрасться вокруг него, используя имя в пространстве имен struct, которое некоторые авторы библиотеки считают закрытыми.