3

これは不自然な例ですが、核となる問題を表しています。既存のコード ベースから同じネストされた構造を持つユニオンと構造があります。

typedef union _MyUnion
{
  unsigned int A;
  struct _MyNestedStruct
  {
    int field
  } MyNestedStruct;
} MyUnion;

typedef struct _MyStruct
{
  struct _MyNestedStruct
  {
    int field
  } MyNestedStruct;
} MyStruct;

これを Green Hills Compiler (GHC) でコンパイルすると、問題はありません。GCC でコンパイルすると、「エラー: 'struct _MyStruct' の再定義」というエラーが発生します。

まず、名前付き構造体を入れ子構造として正常にコンパイルできたのはなぜですか? GHC がいくつかの C++ ルールでコンパイルされているか、ネストされた構造で名前付き構造をサポートしていると思われます。

次に、コードを大幅に変更せずにコンパイルを成功させるにはどうすればよいでしょうか? ネストされた構造から _MyNestedStruct を削除するだけでよいことはわかっていますが、何か影響はありますか?

4

1 に答える 1

9

C には、暗黙的または明示的な名前空間スコープがないため、すべての構造体名が同じ名前空間を共有します。したがって、struct _MyNestedStructは 2 回定義されており、エラーです。GCC は正しく、GHC は正しくありません。

C++ の場合、各構造体が異なる名前空間スコープを作成し、名前の衝突がないため、コードは正しいでしょう。

私が考えることができる解決策:

A) 構造が実際に同じである場合は、他の構造の外側で 1 回だけ定義します (最初の構造の内側に置くこともできますが、それは奇妙です)。

struct _MyNestedStruct
{
    int field
};

typedef union _MyUnion
{
  unsigned int A;
  struct _MyNestedStruct MyNestedStruct;
} MyUnion;

typedef struct _MyStruct
{
  struct _MyNestedStruct MyNestedStruct;
} MyStruct;

B) 2 つの構造に異なる名前を付けます。C では、定義が同一である限り、名前はそれほど重要ではありません。

C) 名前のない構造を使用します。これらの名前をまったく使用しないと思います。

typedef union _MyUnion
{
  unsigned int A;
  struct
  {
    int field;
  } MyNestedStruct;
} MyUnion;

typedef struct _MyStruct
{
  struct
  {
    int field;
  } MyNestedStruct;
} MyStruct;

ところで、アンダースコアと大文字で始まる名前は実装用に予約されており、ユーザーが定義するべきではないことに注意してください。

于 2012-11-06T00:23:41.400 に答える