error C2233: 'b': Felder aus Objekten dürfen keine Arrays der Größe Null enthalten



  • typedef struct
    {
    	char buf[];
    }TEST;
    
    int main (void)
    {
    	TEST a = { "a" };
    	TEST b[2] = { "b", "b" };
    	return 0;
    }
    

    Hi,
    hab gerade obiges probiert.
    Di Initialisierung von a ist OK, aber beim Initialisieren von b gibts nen Error:

    error C2233: 'b': Felder aus Objekten dürfen keine Arrays der Größe Null enthalten

    Das Feld hat sich aber zwischen der Initialisierung von a und der versuchten Initialisierung von b nicht geändert!



  • Strukturen mit einem flexible array member (also ein Array ohne Größenangabe) dürfen nicht für Arrays oder andere Strukturen verwendet werden. D.h. du kannst kein Array b aus solchen Strukturen machen, eine einzelne Variable a ist aber ok.

    ISO/IEC 9899:TC3, 6.7.2.1 schrieb:

    A structure or union shall not contain a member with incomplete or function type (hence,
    a structure shall not contain an instance of itself, but may contain a pointer to an instance
    of itself), except that the last member of a structure with more than one named member
    may have incomplete array type; such a structure (and any union containing, possibly
    recursively, a member that is such a structure) shall not be a member of a structure or an
    element of an array
    .

    Eigentlich sollte der Compiler auch schon bei der Strukturdefinition meckern, denn buf darf nicht das einzige Element der Struktur sein.

    Edit: Und ich bin mir nicht sicher ob die Initialisierung von a so ok ist.

    Edit2: Nein ist sie tatsächlich nicht, siehe 6.7.2.1.18. Bei der Deklaration von a wird das flexible array member ignoriert, du kannst es also nicht initialisieren oder darauf zugreifen.



  • Wozu ist das eigentlich gut? Warum wird [] nicht wie * behandelt?

    Danke



  • Ein Zeiger in einer Struktur ist ja eben nur ein einzelner Zeiger auf ein Array, das woanders gespeichert ist; ein Array in einer Struktur ist wirklich mit all seinen Elementen in der Struktur enthalten. Normalerweise muss man dazu aber die Größe des Arrays angeben, für das ursprüngliche Beispiel also

    typedef struct
    {
        char buf[10];
    }TEST;
    
    int main (void)
    {
        TEST a = { "a" };
        TEST b[2] = {{"b"}, {"b"}};
        return 0;
    }
    

    Das Array muss natürlich groß genug sein.

    Flexible array members sind neu in C99 und sind Arrays unbekannter Größe, die sozusagen hinten an der Struktur dranhängen, dazu muss man für die Struktur einschließlich des Arrays in der gewünschten Größe genug Speicher reservieren:

    struct test { int length; int array[]; }
    
    int length = 42; /* braucht erst zur laufzeit bekannt sein */
    struct test *t = malloc(sizeof *t + length * sizeof *t->array);
    t->length = length;
    

    Dann kann man auf das Array in t so zugreifen, als ob es in der Struktur gleich als int array[42] deklariert worden wäre.

    Um das zu nutzen, muss man aber das Struktur-Objekt mit malloc erzeugen.



  • Danke. Sollte mich mal wirklich mit den neuen Sprachfeatures von C99 auseinandersetzen. Ich programmier immer noch "altes" C.


Anmelden zum Antworten