2012-07-11 55 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