LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   typedef a union as a struct? (https://www.linuxquestions.org/questions/programming-9/typedef-a-union-as-a-struct-535910/)

KasperLotus 03-09-2007 03:11 AM

typedef a union as a struct?
 
Well, I don't give myself much credit when it comes to C but I'm having a really hard time with this particular problem. Here's the bit of code I'm struggling with, it's from /usr/include/sys/socket.h

Code:

# define __SOCKADDR_ARG        struct sockaddr *__restrict
# define __CONST_SOCKADDR_ARG  __const struct sockaddr *
#else
/* Add more `struct sockaddr_AF' types here as necessary.
  These are all the ones I found on NetBSD and Linux.  */
# define __SOCKADDR_ALLTYPES \
  __SOCKADDR_ONETYPE (sockaddr) \
  __SOCKADDR_ONETYPE (sockaddr_at) \
  __SOCKADDR_ONETYPE (sockaddr_ax25) \
  __SOCKADDR_ONETYPE (sockaddr_dl) \
  __SOCKADDR_ONETYPE (sockaddr_eon) \
  __SOCKADDR_ONETYPE (sockaddr_in) \
  __SOCKADDR_ONETYPE (sockaddr_in6) \
  __SOCKADDR_ONETYPE (sockaddr_inarp) \
  __SOCKADDR_ONETYPE (sockaddr_ipx) \
  __SOCKADDR_ONETYPE (sockaddr_iso) \
  __SOCKADDR_ONETYPE (sockaddr_ns) \
  __SOCKADDR_ONETYPE (sockaddr_un) \
  __SOCKADDR_ONETYPE (sockaddr_x25)

# define __SOCKADDR_ONETYPE(type) struct type *__restrict __##type##__;
typedef union { __SOCKADDR_ALLTYPES
              } __SOCKADDR_ARG __attribute__ ((__transparent_union__));

If I mentally expand all of that I get something like "typedef union { all the sockaddr variations } struct sockaddr *__restrict __attribute__ ((__transparent_union__));" and there are a few things about that that I just don't understand.

I think I understand the transparent union attribute. It seems like it makes it somewhat of an "abstract class" in that any variable of the same type as any member of that union will be treated as that "union's type" without casting. Conceptually that makes sense, although it seems like passing a sockaddr_in as a sockaddr would cause problems unless the user programs are the only ones manipulating the actual structs and the kernel just passes them around, which is what I expect.

Beyond that, I have no idea what __restrict does, so I would appreciate it if someone could explain that to me.

And maybe it's just too late at night for me, but I don't see how (or why) you would typedef a union as a struct. The only thing I can think of is that maybe since the transparent_union attribute makes the union more like a class (of structs) it needs to be "named" a struct.

To help me figure this out, I tried to write a similar program (but much smaller ^_^) so I'll attach that in case I just misinterpreted something that was happening and incorporated it into my program incorrectly.

Code:

#include <stdio.h>

struct punk {
        char *name;
        int len;
};

struct bik {
        //long overmind;
        //int uid;
        char *death;
};

typedef union {
        struct punk *__restrict __punk__;
        struct bik *__restrict __bik__;
} struct punk *__restrict __attribute__ ((__transparent_union__));

int foo(struct punk *boo);

int main()
{
        struct punk lsa = {
                .name = "mugget",
                .len = 7,
        };
        struct bik asd = {
        //        .overmind = 8,
        //        .uid = 4,
                .death = "is coming",
        };
        foo(&asd);
}

int foo(struct punk *boo)
{
        switch(sizeof(boo)) {
                case sizeof(struct punk):
                        printf("I'm a punk");
                        break;
                case sizeof(struct bik):
                        printf("I'm a bik");
                        break;
        }
        return 0;
}

So I would appreciate it if anyone could clear any of those things up for me. And before you ask there's not really a solid goal behind all of this, I just wanted to know more about linux networking (boredom mostly).

Thanks in advance.

P.S. I know my variable names suck.

KenJackson 03-09-2007 05:32 AM

Code:

switch(sizeof(boo))
The sizeof() operator is evaluated at compile-time, not runtime, so this switch won't work. Also, boo is a pointer, not a struct or union, and all pointers have the same size.

I don't know if that's the issue you're looking for or not.

KasperLotus 03-09-2007 09:27 AM

No, that wasn't the issue. I know it doesn't work and why, but 1. I didn't write that function originally to use pointers and 2. I don't care what happens in that function anymore. I was originally hoping to be able to distinguish between the types in the union but then my union wasn't working so I just left that alone.

Thanks for the reply though.

jim mcnamara 03-09-2007 01:10 PM

gcc -E filename.h will show you what the final result of the code is.


All times are GMT -5. The time now is 02:10 PM.