[gcc/c11] Ânonymous struct funktioniert nicht.



  • Guten Morgen!

    Ich bin mir momentan etwas näher C11 am ansehen und habe da etwas feines drin gefunden: "anonymous structs and unions". In der Kompatibilitätsliste vom GCC stand, das dieses Feature ab 4.7 enthalten sein soll, doch leider möchte dieser folgenden Code nicht kompilieren.

    # include <stdlib.h>
    # include <stdio.h>
    
    typedef struct
    {
        int x;
        int y;
    } point2;
    
    typedef struct
    {
        struct point2; // anonymous struct
        int z;
    } point3;
    
    int main()
    {
        point3 p3;
    
        p3.x = 1;   // syntax error
        p3.y = 2;   // syntax error
        p3.z = 3;
    
        printf("%d:%d:%d\n", p3.x, p3.y, p3.z);
    }
    

    Im folgenden die Ausgabe des Compilers:

    Z:\c11\anonymous-structs> gcc --version
    gcc (tdm-1) 4.7.1
    Copyright (C) 2012 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
    Z:\c11\anonymous-structs> gcc --std=c11 main.c
    main.c:12:18: warning: declaration does not declare anything [enabled by default]
    main.c: In function 'main':
    main.c:20:7: error: 'point3' has no member named 'x'
    main.c:21:7: error: 'point3' has no member named 'y'
    main.c:24:28: error: 'point3' has no member named 'x'
    main.c:24:34: error: 'point3' has no member named 'y'
    
    Z:\c11\anonymous-structs>
    

    Weiß jemand spontan wo der Fehler liegt? Bei meiner Suche wurde immer auf --std=c11 verwiesen, um diesen Standard zu unterstützen, doch dies will einfach nicht, wenn ich diesen Schalter setze.

    Bin dankbar für jeden Kommentar 🙂

    Viele Grüße,
    euer CodeFreak


  • Mod

    typedef struct
    {
        int x;
        int y;
    } point2;
    

    Das ist bloss ein unbenanntes struct, kein annonymes.

    n1548 schrieb:

    6.7.2.1/13
    An unnamed member of structure type with no tag is called an anonymous structure; an
    unnamed member of union type with no tag is called an anonymous union. The members
    of an anonymous structure or union are considered to be members of the containing
    structure or union. This applies recursively if the containing structure or union is also
    anonymous.

    Ein annomyes struct/union ist also ein Objekt, das
    - Member eines anderen struct/union ist,
    - keinen Namen hat (unbenannters Objekt), und
    - dessen Typ keinen Tagnamen besitzt (unbenannter Typ).
    Das ist technisch nichts Neues, das gibt es schon seit Ewigkeiten als Compiler-Erweiterung. C++ kennt anonyme unions (aber keine stucts) ebenso.

    ALso z.B.

    typedef struct
    {
        struct
        {
            int x;
            int y;
        }; // anonymous struct
        int z;
    } point3;
    


  • Guten Morgen camper!

    Ich hatte das Beispiel aus dem Buch: 21st Century C

    http://shop.oreilly.com/product/0636920025108.do

    Dort wird auch erwähnt, das dies bisher nur in einer struct selber nur verschachtelt ging, jedoch durch C11 auch das obere möglich sein soll. Wie schon gesagt, es ist aus dem Buch wird dort auch exzessiv benutzt für "Vererbung".

    Im Bugtracker hab ich das gefunden,

    http://gcc.gnu.org/ml/gcc-patches/1999-06n/msg00376.html

    Ist zwar von 1999, doch das dort gezeigte Beispiel geht ebenfalls nicht. Obwohl dies auch jetzt zum neuen anonymus structs aus C11 gehören soll.

    #include <stdio.h>
    
      struct phone 
      {
        int areacode;
        int number;
      };
    
      struct person
      {
        char name[30];
        struct phone;
      } Jim = {"Jim bob", {53706, 123456}};
    
      int
      main ()
      {
        printf ("Jim's name = %s\n", Jim.name);
        printf ("Jim's areacode = %d\n", Jim.areacode);
        printf ("Jim's number = %d\n", Jim.number);
        return 0;
      }
    


  • Hi!

    Also ich habe es jetzt hinbekommen, es war ganz einfach das folgende Testprogramm zu kompilieren:

    # include <stdlib.h>
    # include <stdio.h>
    
    typedef struct
    { 
        int x; 
        int y; 
    } point2d ;
    
    typedef struct 
    {
        point2d;
        int z;
    } point3d;
    
    int main()
    {
        point3d test1 =
            {
                .x = 1,
                .y = 2,
                .z = 3
            };
    
        point3d test2 =
            {
                4, 5, 6
            };
    
        printf("vector1: %d:%d:%d\n", test1.x, test1.y, test1.z);
        printf("vector2: %d:%d:%d\n", test2.x, test2.y, test2.z);
    }
    

    Dafür muss man nur wie im folgenden Beschrieben den Schalter -fms-extensions setzen:
    http://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html#Unnamed-Fields

    Der korrekte Aufruf zum kompilieren lautet also:

    gcc --std=c11 -fms-extensions main.c
    

    Trotzdem vielen Dank für die Hilfe und noch einen schönen Tag 🙂

    Viele Grüße,
    euer CodeFreak


Anmelden zum Antworten