2012-07-11 93 views
3

在Objective-C編譯我試圖編譯在Ubuntu Linux的12 Objective-C代碼時「結構StructName」消息的重新定義。錯誤:在Linux上

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 

我讀過這可以通過重新定義結構由遞歸引入使用時會導致兩次,或包括替代進口。

grep -r "struct StructName" * 

只顯示清晰度的一個發生。

我也搜索過項目中的每個包含語句,並且沒有發現包含vs導入,或者其他包含/導入CEFoo.h的明顯用途(包含正在定義/導入的結構的文件不止一次)。

我怎樣才能進一步追捕的原因呢?我假設我正在導入它兩次 - 如果是,有沒有辦法通過首次定義的冗長或日誌來查看它?

任何其他的想法我能做些什麼來解決這個?

TIA

+1

這將有助於查看更多CEFoo.h,特別是發生錯誤的第93行。 – Darren 2012-07-11 06:49:56

+0

此外,您可能希望將'gnustep'標記添加到您將來的問題中,但在這個*特殊*情況下,它可能不相關。 – andyvn22 2012-07-11 07:28:05

+0

@Darren我用第86-92行編輯了代碼示例。 TIA – Geremy 2012-07-11 18:16:19

回答

3

定義一個類意味着爲其創建一個結構體。而且你碰巧有一個和你的類完全一樣的結構。例如,檢查下面的代碼「活」在http://ideone.com/7kvFa

#import <objc/objc.h> 

struct name {}; 

@interface name 
@end 

int 
main() { 
    return 0; 
} 
+1

謝謝你幫助我! – Geremy 2012-07-11 18:56:43

1

這是因爲GCC處理Objective-C的對象的方式。 GCC(在版本4.2.1中;我不知道更新的版本)將對象視爲指向不透明結構的指針。

當你聲明一個名爲StructName類,GCC隱含執行以下操作:

struct StructName; 
typedef struct StructName StructName;

你可以看到這種行爲,當您試圖初始化一個NSArray對象指針與NSString對象指針:

NSArray *array = @"Hello world";

GCC發出以下警告:

warning: incompatible Objective-C types initializing ‘struct NSString *’, expected ‘struct NSArray *’

因此,即使您只聲明struct StructName一次,GCC也會看到兩個聲明,並且因此無法編譯該文件。

我建議您重新命名結構或使用其他編譯器(例如LLVM)。

+0

因此,具有相同名稱的結構和對象應該是合法的,這只是我看到的gcc特定的行爲? – Geremy 2012-07-11 19:08:29

+1

Objective-C沒有正式的書面標準,但據我所知,在C標準,GNUStep或Apple Objective-C文檔中都沒有禁止使用'struct StructName'和'StructName'作爲兩種截然不同的類型。所以我認爲,GCC應該允許這個。 – 2012-07-11 19:29:35