2

我对 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 编译器了。

编辑:我发现这个 SDCC 错误似乎是相关的。有人可以解释它是否以及如何?

4

3 回答 3

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灵活数组成员的structs 作为 s 的成员或作为扩展的数组。该标准禁止这样做,因此使用该代码的代码不可移植,并且每个编译器都有权拒绝该代码。

链接的问题不相关,如果struct具有灵活数组成员的 a 被实例化为自动,则不发出警告,这在标准中是不允许的(但被 SDCC 和其他人作为扩展接受)。

于 2013-01-16T06:52:41.393 回答
1

想想为什么这是一个错误。

STRLIST_ENTRY 的大小未知,因为 str[] 是可变长度的。

STRLIST 包含一个可变长度的STRLIST_ENTRY 数组。

在内存中,数组是一系列STRLIST_ENTRY,一个接一个地排列。

由于其中的元素大小未知,如何知道索引指向的偏移量?

char str[] 应该被赋予固定大小,或者将 char* 设置为数组外部的字符串。

于 2013-07-17T07:58:37.410 回答
0

我知道我已经晚了 8 年 :),但也许它可以帮助别人。这是用于结构末尾数据的技巧(即,当您有一个标题并且最后一个成员是未知大小的数据时):

typedef struct {
    int nLen;
    char str[0];
} STRLIST_ENTRY;

这将允许您使用索引 ie 处理字符串中的任何字符,str[10]并且 char*ptr=str也会为您提供正确的结果。

于 2021-08-18T14:42:14.133 回答