3

Ubuntu 12 Linux で Objective-C コードをコンパイルしようとしています。

main.m は次のようになります。

#import <Foundation/Foundation.h>
#import "CEFoo/CEFoo.h"

int main (int argc, const char * argv[])
 {
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  NSLog (@"hello world");
  [pool drain];
  return 0;
 }

CEFoo.h には、次の定義があります。

struct StructName{  // line 86
 BOOL first; 
 ...
 ...
};

@interface StructName :NSObject  // line 92
BOOL first; // line 93
...
...
@end  // 96

コンパイルに行くとき

gcc main.m  `gnustep-config --objc-flags` -lgnustep-base -o main.bin

次のメッセージが表示されます。

Foo/CEFoo.h:93:1: error: redefinition of ‘struct StructName’
Foo/CEFoo.h:86:8: note: originally defined here

これは、構造体を2回再定義するか、インポートの代わりにインクルードを使用する場合の再帰インポートによって引き起こされる可能性があることを読みました。

grep -r "struct StructName" *

定義の 1 つのオカレンスのみを表示します。

また、プロジェクト内のすべてのインクルードステートメントを検索しましたが、インクルードとインポートの明らかな使用、または CEFoo.h のデュアルインクルード/インポート (複数回定義/インポートされている構造を含むファイル) は見つかりませんでした。 .

この原因をさらに突き止めるにはどうすればよいでしょうか。私はそれを2回インポートしていると思います-もしそうなら、初めて定義された詳細またはログを介してそれを見る方法はありますか?

これをトラブルシューティングするために私ができる他のアイデアはありますか?

ティア

4

2 に答える 2

1

これは、GCC が Objective-C オブジェクトを処理する方法によるものです。GCC (バージョン 4.2.1 ; 最近のバージョンについてはわかりません) は、オブジェクトを不透明な構造へのポインターとして扱います。

という名前のクラスを宣言するとStructName、GCC は暗黙的に次のことを行います。

struct StructName;
typedef struct StructName StructName;

NSArrayオブジェクト ポインターを使用してオブジェクト ポインターを初期化しようとすると、その動作を確認できNSStringます。

NSArray *array = @"Hello world";

GCC は次の警告を発行します。

警告: 'struct NSString *' を初期化する、互換性のない Objective-C 型、予期される 'struct NSArray *'</pre>

そのため、1 回だけ宣言した場合でもstruct StructName、GCC は 2 つの宣言を認識し、その理由でファイルのコンパイルに失敗します。

構造の名前を変更するか、別のコンパイラ (LLVM など) を使用することをお勧めします。

于 2012-07-11T18:55:21.270 に答える