我对SDCC有疑问。我的代码(我试图从另一个编译器移植)使用具有灵活数组成员的结构。但是,当我尝试编译以下代码时:
/** header of string list */
typedef struct {
int nCount;
int nMemUsed;
int nMemAvail;
} STRLIST_HEADER;
/** string list entry data type */
typedef struct {
int nLen;
char str[];
} STRLIST_ENTRY;
/** string list data type */
typedef struct {
STRLIST_HEADER header;
STRLIST_ENTRY entry[];
} STRLIST; // By the way, this is the line the error refers to.
int main()
{
return 0;
}
SDCC出现以下错误:
$ sdcc -mz80 -S --std-c99 test.c
test.c:18: warning 186: invalid use of structure with flexible array member
test.c:18: error 200: field 'entry' has incomplete type
是什么给出的?这段代码在gcc中编译得很好,更不用说我正在使用的其他z80编译器。
编辑:我发现this SDCC bug似乎与此有关。有人可以解释它是否以及如何?答案 0 :(得分:3)
SDCC就在那里,而gcc-4.6.2也没有“编译好”。好吧,如果你要求它忠实地遵守标准。
使用-std=c99 -pedantic
(或-std=c1x -pedantic
)进行编译,gcc会发出
warning: invalid use of structure with flexible array member
和clang-3.0表现相似,它的警告信息稍微提供一些:
warning: 'STRLIST_ENTRY' may not be used as an array element due to flexible array member
该标准禁止在6.7.2.1(3)中使用
结构或联合不应包含具有不完整或函数类型的成员(因此,结构不应包含其自身的实例,但可包含指向其自身实例的指针),但结构的最后一个成员除外具有多个命名成员可能具有不完整的数组类型; 这样的结构(以及可能递归地包含这种结构的成员的任何联合)不应该是结构的成员或数组的元素。
(重点是我的)
gcc和clang允许将具有灵活数组成员的struct
作为struct
或数组的成员作为扩展名。该标准禁止使用,因此使用该代码的代码不可移植,并且每个编译器都有权拒绝代码。
链接的问题不相关,如果具有灵活数组成员的struct
被实例化为自动,则不会发出警告,这是不符合标准的(但SDCC和其他人接受)作为延伸)。
答案 1 :(得分:1)
想想为什么这是一个错误。
STRLIST_ENTRY的大小未知,因为str []是可变长度。
STRLIST包含一个可变长度的STRLIST_ENTRY数组。
在内存中,数组是一个STRLIST_ENTRY序列,它们紧接着排列。
由于其元素大小未知,如何知道索引指向的偏移量?
char str []应该被赋予固定的大小,或者对数组之外的字符串进行char *。