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

我读过这可能是由于两次重新定义结构,或者在使用包含而不是导入时递归导入引起的。

grep -r "struct StructName" *

仅显示定义的一次出现。

我还搜索了项目中的每个包含语句,并没有发现包含与导入的明显用途,或者 CEFoo.h 的双重包含/导入(包含多次定义/导入的结构的文件) .

我该如何进一步追查造成这种情况的原因?我假设我要导入它两次——如果是,有没有办法通过第一次定义的详细或日志来观看它?

我可以做些什么来解决这个问题?

TIA

4

2 回答 2

3

定义一个类意味着为它创建一个结构,等等。而且您碰巧有一个名称与您的类完全相同的结构。例如,在http://ideone.com/7kvFa检查以下代码“live”

#import <objc/objc.h>

struct name {};

@interface name
@end

int
main() {
    return 0;
}
于 2012-07-11T18:33:13.770 回答
1

这是因为 GCC 处理 Objective-C 对象的方式。GCC(在 4.2.1 版本中;我不知道更新的版本)将对象视为指向不透明结构的指针。

当您声明一个名为 的类时StructName,GCC 会隐式执行以下操作:

结构结构名称;
typedef struct StructName StructName;

当您尝试使用对象指针初始化NSArray对象指针时,您可以看到该行为NSString

NSArray *array = @"Hello world";

GCC 发出以下警告:

警告:初始化 'struct NSString *' 的 Objective-C 类型不兼容,预期为 'struct NSArray *'</pre>

因此,即使您只声明struct StructName了一次,GCC 也会看到两个声明并因此无法编译文件。

我建议您重命名您的结构或使用其他编译器(例如 LLVM)。

于 2012-07-11T18:55:21.270 回答