Nested structures

前端 未结 6 2009
旧时难觅i
旧时难觅i 2020-12-03 08:42

The following code compiles on a C++ compiler.

#include 
int main()
{
    struct xx
    {
        int x;
        struct yy
        {
                    


        
6条回答
  •  我在风中等你
    2020-12-03 09:20

    Here are some changes (thanks to AndreyT):

    Obviously you have to change the headers to make this compile. But even then, this seems not to be standard C as AndreyT pointed out. Nonetheless will some compilers like gcc still compile it as expected and only issue a warning. Likewise, Microsoft doesn't seem to interpret the standard too strictly:

    "Structure declarations can also be specified without a declarator when they are members of another structure or union"

    To make it standard C you have to turn your "struct yy" declaration into a definition. Then your code will be valid in C and in C++. To illustrate what is going on, I rewrote it in a, in my opinion, more comprehensible fashion and added a little test on what is going on.

    #include
    #include
    
    typedef struct xx xx;
    typedef struct yy yy;
    
    struct yy{ char s; xx *p;};
    
    struct xx{ int x; yy *q;};
    
    int main(){
        xx test;
        test.q = (yy*)malloc(sizeof(yy));
        test.q->s = 'a';
        test.q->p = (xx*)malloc(sizeof(xx));
        test.q->p->x = 1; 
        test.q->p->q = (yy*)malloc(sizeof(yy));
        test.q->p->q->s = 'b';
        printf("s: %c\n", test.q->s);
        printf("x: %d\n", test.q->p->x);
        printf("s: %c\n", test.q->p->q->s);
        return 0;
    }
    

    You can easily see, that you have a struct yy with a pointer to xx and the struct xx has a pointer to yy. This is equivalent to which can be written as followed in ansi-C:

    #include
    #include
    
    int main(){
        struct xx{
            int x;
            struct yy{
                        char s;
                        struct xx *p;
                } *q;   
                /*Here is the change to your example. You cannot have a structur 
                  without a declactor inside of another structur! 
                  Your version might due to compiler extensions still work*/
        };
        struct xx test;
        test.q = (struct yy*)malloc(sizeof(struct yy));
        test.q->s = 'a';
        test.q->p = (struct xx*)malloc(sizeof(struct xx));
        test.q->p->x = 1; 
        test.q->p->q = (struct yy*)malloc(sizeof(struct yy));
        test.q->p->q->s = 'b';
        printf("s: %c\n", test.q->s);
        printf("x: %d\n", test.q->p->x);
        printf("s: %c\n", test.q->p->q->s);
        return 0;
    }
    

    I compiled it with gcc and the following options:

    gcc -ansi -pedantic -Wall -W -Wshadow -Wcast-qual -Wwrite-strings test.c -o
    

    Both variants will have the same output

    s: a 
    x: 1
    s: b
    

    Now if you want to do the same in c++, your struct doesn't have to change but to use the inner struct you have to call the scope resolution operator (::) as follow:

    test.q = (xx::yy*)malloc(sizeof(xx::yy));
    test.q->s = 'a';
    test.q->p = (xx*)malloc(sizeof(xx));
    test.q->p->x = 1; 
    test.q->p->q = (xx::yy*)malloc(sizeof(xx::yy));
    test.q->p->q->s = 'b';
    printf("s: %c\n", test.q->s);
    printf("x: %d\n", test.q->p->x);
    printf("s: %c\n", test.q->p->q->s);
    

提交回复
热议问题