cdarwinmachxnu

why is this pointer Typedef'd to a struct


I've been looking through the code for various IPC systems and I happen to come across these lines in Mach(xnu-123.5/osfmk/ipc/ipc_port.h)

typedef port_name_t          mach_port_name_t;
typedef mach_port_name_t    *mach_port_name_array_t;

where the definition of port_name_t is a struct.

I have yet to come across any usage of *mach_port_name_array_t and was just a little surprised to see a pointer typedef'd to a struct, any insight into why this was done? or just some sample code showing *mach_port_name_array_t in action would be much appreciated.


Solution

  • I [...] was just a little surprised to see a pointer typedef'd to a struct

    That's not how I would describe the declaration you presented. Consider the code

    typedef mach_port_name_t    *mach_port_name_array_t;
    

    If the typedef keyword were absent then it would declare mach_port_name_array_t as a pointer to an object of type mach_port_name_t, which happens to be a structure type. Pointers to structures are utterly routine in C, to the extent that C has a built-in operator (->) for accessing structure members via a pointer.

    The addition of typedef simply makes the declared identifier (mach_port_name_array_t) a type alias for that type, instead of an object of that type. You can do this to create a type alias for any type, so creating an alias for a pointer-to-structure type is perfectly valid.

    On the other hand, although creating such type aliases is not so uncommon, it is poor style. In most cases, typedefs that hide a type's pointer nature produce more confusion than clarity. Naming conventions can help with that, but not as much as avoiding such typedefs altogether does.

    Furthermore, in this particular case, the name is misleading. It suggests that the type is an array type, when it is not. It is, however, the correct pointer type for a function parameter whose actual argument is expected to be an array:

    void do_something_with_ports(mach_port_name_array_t port_names);
    
    // ...
    
    mach_port_name_t ports[3];
    
    // ...
    
    do_something_with_ports(ports);
    

    As I said, however, using a typedef'd pointer type is poor style. The function would be better declared like so:

    void do_something_with_ports(mach_port_name_t *port_names);
    

    or, equivalently,

    void do_something_with_ports(mach_port_name_t port_names[]);