14

I'm writing an app in C++ that interfaces with some code written in C.

The following is a simplified version of a struct defined in C code that I can't modify.

struct event{
    uint8_t type;
    union {
        struct /* WishThisHadAName */ {
            // ...
        } connect;
        struct {
            // ...
        } disconnect;
    };
};

I'm trying to be able to define functions that take a pointer to the different unnamed structs, connect, disconnect, and all the others not listed above. To look something like the following.

void onConnect( struct WishThisHadAName *evt );

Is it possible to create this prototype without modifying the original C struct? Is there an easy way to create a wrapper for the unnamed structs to give them a name? Am I forced to create named structs that mirror the unnamed ones I'm trying to use?

I know you can get the type of an instantiated variable with decltype but I can't figure out how I could use that or declval in order to create the function prototype I'm looking for.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Aveazey
  • 143
  • 5

2 Answers2

18

Simple as using event_connect_t = decltype(event::connect);.

Then you can use it as void onConnect( event_connect_t *evt );.

You can't declare a compatible type, but you can just extract the existing type declaration from the definition. decltype can resolve static member references just fine.

Ext3h
  • 5,713
  • 17
  • 43
6

If you're using a compiler such as gcc/g++, you can use typeof to create a typedef for the anonymous type:

typedef __typeof__(((struct event){0}).connect) conn_type;
typedef __typeof__(((struct event){0}).disconnect) disconn_type;

Or without compound literals:

struct event e;
typedef __typeof__(e.connect) t1;
typedef __typeof__(e.disconnect) t2;
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
dbush
  • 205,898
  • 23
  • 218
  • 273