【问题标题】:sdcc not accepting codesdcc 不接受代码
【发布时间】:2012-12-30 09:46:16
【问题描述】:

我对 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 似乎是相关的。有人可以解释一下是不是以及如何?

【问题讨论】:

    标签: c compiler-construction z80 sdcc


    【解决方案1】:

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

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

    【讨论】:

    • 优秀。 SDCC 文档充其量是很差的,而 GCC 接受该声明使我更加困惑。非常感谢!
    【解决方案2】:

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

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

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

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

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

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

    【讨论】:

      【解决方案3】:

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

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

      这将使您可以使用索引来寻址字符串中的任何字符,即str[10] 和字符*ptr=str 也会为您提供正确的结果。

      【讨论】:

        猜你喜欢
        • 2012-07-10
        • 2016-11-24
        • 2019-12-08
        • 1970-01-01
        • 1970-01-01
        • 2014-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多