ObjC としてコンパイルされたソースには、この点で C と同じ規則があります。
ObjC++ としてコンパイルされたソースには、この点で C++ と同じ規則があります。
@class MONClass;ObjC 型の前方宣言です。構造体には使用しないでください。
struct t_mon_struct;名前付きC または C++ 構造体の前方宣言です。ObjC タイプには使用しないでください。技術的には、コンパイラでは C++ クラスを構造体として前方宣言することもできます (もちろん、クラスがグローバル名前空間でも宣言されている場合)。
したがって、セマンティクスの根源はすべて C に帰着します (これが ObjC 変換であると仮定します)。ここで、ObjC と C++ について言及するのをやめます。
ここには、複雑さの一般的な原因がいくつかあります。
- 構造体の名前空間
- 構造体の宣言
- ラベルの複数の定義を避ける
struct t_mon_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は構造体名前空間の匿名構造体にバインドされ、その宣言が表示されない限り参照できません。
宣言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 の場合)。ただし、構造体の名前空間で名前を使用することで、こっそり回避できます。これは、一部のライブラリ作成者が非公開と見なすものです。