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

何が得られますか?このコードは、私が使用している他のz80コンパイラーは言うまでもなく、gccで問題なくコンパイルされます。

編集:関連しているように見えるこの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)で次のことを禁止しています。

構造体またはユニオンには、不完全または関数型のメンバーを含めることはできません(したがって、構造体にはそれ自体のインスタンスを含めることはできませんが、それ自体のインスタンスへのポインターを含めることができます)。 1つの名前付きメンバーの配列型が不完全である可能性があります。そのような構造体(および、場合によっては再帰的にそのような構造体であるメンバーを含むユニオン)は、構造体のメンバーまたは配列の要素であってはなりません。

(強調は私のものです)

gccとclangを使用すると、structsのメンバーとして柔軟な配列メンバーを使用しstructたり、拡張機能として配列を使用したりできます。標準ではそれが禁止されているため、それを使用するコードは移植性がなく、すべてのコンパイラーはコードを拒否する権利の範囲内にあります。

リンクされた問題は関係ありませんstruct。柔軟な配列メンバーを持つが自動としてインスタンス化された場合に警告を出さないことです。これは標準では許可されていません(ただし、SDCCなどでは拡張機能として受け入れられています)。

于 2013-01-16T06:52:41.393 に答える
1

これがエラーである理由を考えてください。

str []は可変長であるため、STRLIST_ENTRYのサイズは不明です。

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;

これにより、文字列内の任意のcharをインデックスでアドレス指定できます。つまりstr[10]、char*ptr=strでも正しい結果が得られます。

于 2021-08-18T14:42:14.133 に答える