【问题标题】:error: redefinition of ‘struct StructName’ message when compiling in Objective-C on Linux错误:在 Linux 上的 Objective-C 中编译时重新定义“struct StructName”消息
【发布时间】:2012-07-11 06:42:22
【问题描述】:

我正在尝试在 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

【问题讨论】:

  • 这将有助于查看更多的 CEFoo.h,尤其是第 93 行发生错误的地方。
  • 另外,您可能希望将来在您的问题中添加“gnustep”标签,尽管在这种特定情况下,它可能不相关。
  • @Darren 我已经编辑了第 86-92 行的代码示例。 TIA
  • @andyvn22 会的,谢谢。
  • 我刚刚在示例中添加了更多代码 -- 再次:)

标签: objective-c linux gnustep redefinition


【解决方案1】:

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

#import <objc/objc.h>

struct name {};

@interface name
@end

int
main() {
    return 0;
}

【讨论】:

  • 感谢您帮我解决这个问题!
【解决方案2】:

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

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

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

当您尝试使用 NSString 对象指针初始化 NSArray 对象指针时,您会看到这种行为:

NSArray *array = @"Hello world";

GCC 发出以下警告:

警告:初始化‘struct NSString *’的Objective-C类型不兼容,预期‘struct NSArray *’

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

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

【讨论】:

  • 所以拥有同名的结构和对象应该是合法的,而这只是我看到的 gcc 特有的行为?
  • Objective-C 没有正式的书面标准,但据我所知,C 标准、GNUStep 或 Apple Objective-C 文档中都没有禁止使用 struct StructNameStructName作为两种不同的类型。所以我认为,GCC 应该允许这样做。
猜你喜欢
  • 1970-01-01
  • 2012-07-10
  • 2017-12-08
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 2021-07-07
  • 1970-01-01
相关资源
最近更新 更多