Thread: anonymous unions

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    330

    anonymous unions

    Are anonymous unions standard C?

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,334
    The rules for unions and structs are the same, so yes.

  3. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Are anonymous unions standard C?
    No.
    My best code is written with the delete key.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Right, so one person says yes, and the other says no.

    I'd be inclined to believe Prelude is right - but I have a feeling it may be "confusion" about the concept of anonymous struct/union's here:
    Code:
    struct {
       // stuff goes here
    } blah;
    Is definitely allowed in the standard [I just looked it up]. Which is what I think tabstop meant.

    However, another usage of "anynymous struct/union" is this one:
    Code:
    struct something 
    {
       int x;
       int y;
    };
    
    struct someother
    {
        struct something;    
        int z;
    };
    
    ...
       struct someother a;
       a.x = 1;
       a.y = 2;
       a.z = 3;
    This isn't allowed in the standard, but several mainstream compilers (gcc, MS) support this.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I have a feeling it may be "confusion" about the concept of anonymous struct/union's
    Quite likely. I was referring to the actual anonymous union extension in your second example. The first example I would call unnamed rather than anonymous. I'd also accept "anonymous" as a variant term for a compound literal in C99:
    Code:
    foo ( (struct bar) { .a = 0, .b = 1 } );
    But that's a bit of a stretch.
    My best code is written with the delete key.

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,334
    Quote Originally Posted by matsp View Post
    Right, so one person says yes, and the other says no.

    I'd be inclined to believe Prelude is right - but I have a feeling it may be "confusion" about the concept of anonymous struct/union's here:
    Code:
    struct {
       // stuff goes here
    } blah;
    Is definitely allowed in the standard [I just looked it up]. Which is what I think tabstop meant.
    I concur. I had never heard/of or seen that second usage -- the definition of someother is valid (you're not obligated to give a member variable a name), but it's use is not.

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Here's another fun one, the infamous struct hack:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct foo {
      int a;
      int b[1];
    };
    
    int main ( void )
    {
      struct foo *p = malloc ( sizeof *p + 10 * sizeof ( int ) );
      int i;
    
      p->a = 10;
    
      for ( i = 0; i < p->a; i++ )
        p->b[i] = i * i;
    
      for ( i = 0; i < p->a; i++ )
        printf ( "%d\n", p->b[i] );
    
      free ( p );
    
      return 0;
    }
    Sadly, this abomination has been standardized in C99:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct foo {
      int a;
      int b[];
    };
    
    int main ( void )
    {
      struct foo *p = malloc ( sizeof *p + 10 * sizeof ( int ) );
      int i;
    
      p->a = 10;
    
      for ( i = 0; i < p->a; i++ )
        p->b[i] = i * i;
    
      for ( i = 0; i < p->a; i++ )
        printf ( "%d\n", p->b[i] );
    
      free ( p );
    
      return 0;
    }
    My best code is written with the delete key.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
      struct foo *p = malloc ( sizeof *p + 10 * sizeof ( int ) );
    In your first example, should that be:
    Code:
      struct foo *p = malloc ( sizeof *p + 9 * sizeof ( int ) );
    ??


    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    And does "int b[]" contribute anything to the "sizeof *p" under C99?

    gg

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,334
    The standard says that sizeof should return the offset of the flexible array member, so I'm pretty sure the answer is no. The example they give (involving doubles with sizeof(double)==8) malloc's sizeof() plus 64 to get an 8-element array.

  11. #11
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >In your first example, should that be:
    Not if you want to be absolutely safe across all implementation. I've seen a case where the implementation assumes a trailing array of size 1 is the struct hack (stupid, I know), and doesn't include it in the result of sizeof.

    >And does "int b[]" contribute anything to the "sizeof *p" under C99?
    No, "sizeof ( struct foo )" is equivalent to "offsetof ( struct foo, b )".
    My best code is written with the delete key.

  12. #12
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Prelude View Post
    >In your first example, should that be:
    Not if you want to be absolutely safe across all implementation. I've seen a case where the implementation assumes a trailing array of size 1 is the struct hack (stupid, I know), and doesn't include it in the result of sizeof.
    GCC has allowed zero length arrays for a while to facilitate this "hack." Do you know if C99 supports it officially?

    Code:
    struct some_blob
    {
        int type;
        int stuff;
        char data[0]; /* Contiguous data */
    }
    EDIT: Hey look, I'm a moron who doesn't read threads. Sorry.

  13. #13
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Quote Originally Posted by KIBO View Post
    Are anonymous unions standard C?
    Anonymous unions are standard C++, but not standard C.
    Code:
    #include <iostream>
    
    int main() {
        union {
            int n;
            char c;
        };
        
        std::cin >> c;
        std::cout << n;
    
        return 0;
    }
    Basically, you declare a union with no tag and no instances, and you can access all members of the union by name with no prefix. In addition, the members behave like ordinary union members in that they occupy the same memory.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Structures - Unions
    By AProg in forum C Programming
    Replies: 16
    Last Post: 05-27-2003, 12:43 AM
  2. Unions - Understanding
    By Vber in forum C Programming
    Replies: 2
    Last Post: 04-14-2003, 08:16 AM
  3. Unions and Structures
    By C-Struggler in forum C Programming
    Replies: 4
    Last Post: 03-06-2003, 11:28 AM
  4. unions problems!
    By nextus in forum C++ Programming
    Replies: 3
    Last Post: 01-12-2003, 04:04 AM
  5. Unions in c++
    By The Gweech in forum C++ Programming
    Replies: 5
    Last Post: 08-06-2002, 08:14 AM