LCC:初始化含有结构的结构?

时间:2011-09-01 17:07:25

标签: c lcc-win32

以下代码片段在Mac OS X上使用gcc编译得很好,但无法在Windows上使用lcc-win32进行编译:

typedef struct Foo Foo;
typedef struct Bar Bar;

struct Bar { int age; int height; };
struct Foo { Bar barOne; Bar barTwo; };

// Elsewhere, in some function:

Bar barOne = { 2, 4 };
Bar barTwo = { 6, 8 };
Foo instance = { barOne, barTwo };

并给出了这个错误:

  

发现'struct Bar'需要'int'

我可以通过这种方式初始化结构来“克服”这个:

Foo instance = { barOne.age, barOne.height, barTwo.age, barTwo.height };

所以,我理解发生了什么......但我觉得这会使我的代码变得更复杂(我需要了解我正在使用的其他结构的实现和布局,而不是简单地使用它们 - 而且如果那个布局发生了变化,我必须将这个更改用于使用结构的其他任何人。

我想知道LCC是“更严格”(坚持某种标准)还是“更愚蠢”(编译器太愚蠢无法处理这种情况)。

感谢。

另外,请参阅我的其他LCC-Win32问题:LCC: Forward Declaration of Typedef'd Enum Failing?

2 个答案:

答案 0 :(得分:3)

正如所写:

typedef struct Foo Foo;
typedef struct Bar Bar;

struct Foo { Bar barOne; Bar barTwo; };
struct Bar { int age, int height };

// Elsewhere, in some function:

Bar barOne = { 2, 4 };
Bar barTwo = { 6, 8 };
Foo instance = { barOne, barTwo };

代码无法在任何地方编译(特别是在带有GCC 4.6.0的MacOS X 10.7.1上失败)以及这些错误(以及其他一些错误):

xx.c:4: error: field ‘barOne’ has incomplete type
xx.c:4: error: field ‘barTwo’ has incomplete type

这是因为您在定义之前尝试使用Bar。颠倒结构定义的顺序,并修复Bar中的语法错误(逗号应该是分号;缺少分号),然后(最后)它在MacOS X上编译。

标准对使用结构作为初始化器有何看法?

  

§6.7.8初始化

     

¶13具有自动存储持续时间的结构或联合对象的初始化程序应为   要么是如下所述的初始化列表,要么是具有兼容性的单个表达式   结构或联合类型。在后一种情况下,对象的初始值包括   未命名的成员,就是表达式。

考虑一个函数的上下文(这段代码可以用GCC设置繁琐编译):

typedef struct Foo Foo;
typedef struct Bar Bar;

struct Bar { int age; int height; };
struct Foo { Bar barOne; Bar barTwo; };

void somefunction(void)
{
    Bar barOne = { 2, 4 };
    Bar barTwo = { 6, 8 };
    Foo instance = { barOne, barTwo };
}

从表面上看,我认为barOnebarTwo不是单一表达。但是,标准继续说:

  

¶16否则,具有聚合或联合类型的对象的初始值设定项应该是元素或命名成员的大括号括起来的初始值设定项列表。

如果聚合必须是括号,那么写这个就行了:

Foo instance = { { barOne }, { barTwo } };
但是,GCC强烈反对这种结构。

i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)

/usr/bin/gcc -g -std=c99 -Wall -Wextra -Wmissing-prototypes -c xx.c
xx.c:8: warning: no previous prototype for ‘somefunction’
xx.c: In function ‘somefunction’:
xx.c:11: error: incompatible types in initialization
xx.c:11: warning: missing initializer
xx.c:11: warning: (near initialization for ‘instance.barOne.age’)
xx.c:11: error: incompatible types in initialization
xx.c:11: warning: missing initializer
xx.c:11: warning: (near initialization for ‘instance.barTwo.age’)
xx.c:11: warning: missing initializer
xx.c:11: warning: (near initialization for ‘instance.barOne’)
xx.c:11: warning: unused variable ‘instance’

总的来说,我倾向于相信海湾合作委员会的判断,并指责LCC没有有效处理案件。争论需要完整解析C标准的§6.7.8,并且我没有提供所有的材料(在开始示例之前它会进入¶23)。

答案 1 :(得分:1)

好吧,它有时候什么都不称为Little C Compiler。它可以处理大多数事情,但为了节省空间和时间,在这些情况下通常会更严格。实现看起来很简单的东西通常不在编译器中。无论是LCC还是LCC都没有更新来处理这些情况。是否有使用LCC而不是Borland,MSVC ++,Cygin / MingW32 gcc的具体原因?