Источник, скомпилированный как ObjC, имеет те же правила, что и C в этом отношении.
В этом отношении источник, скомпилированный как ObjC ++, имеет те же правила, что и C ++.
@class MONClass;
- это предварительное объявление типа ObjC. Не используйте его для структур.
struct t_mon_struct;
является предварительным объявлением структуры с именем C или C ++ struct. Не используйте его для типов ObjC. Технически, компилятор позволяет вам также объявить класс C ++ как структуру (при условии, конечно, что класс также объявлен в глобальном пространстве имен).
Таким образом, корень семантики все сводится к C (при условии, что это перевод ObjC). Я перестану упоминать ObjC и C ++.
Здесь есть несколько общих источников сложности:
- Пространство имен структуры
- объявление структуры
- избегая нескольких определений меток
struct t_mon_struct;
является предварительным объявлением теговой структуры. В частности, это то, чье имя существует в пространстве имен struct.
теговая структура, которая существует в пространстве имен struct:
struct t_mon_struct { int a; };
анонимная структура с typedef в глобальном пространстве имен:
typedef struct { int a; } t_mon_struct;
теговая структура с typedef в глобальном пространстве имен:
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
объявить его или разработать обходной путь.
Сложности ухудшаются, когда typedef структуры отличается от ее тега. Вы не можете связать или переопределить typedef (в C). Однако вы можете обойти его, используя имя в пространстве имен struct - которое некоторые авторы библиотеки считают закрытым.