Enforce two structs have same size at compile time?

  • A+
Category:Languages

I have defined two data structures that must remain the same size as each other for the application to function properly. The struct's are used to communicate between a PC and a DSP. The DSP code is in 'C', the PC side in C++.

for example:

struct inbound_data{     int header[5];     float val1;     float val2;     int trailer[3]; };  struct outbound_data{     int header[5];     int reply1;     int reply2;     float dat1;     float dat2;     int filler[1]; } 

later I will do something like:

int tx_block[sizeof(outbound_data)]; int rx_block[sizeof(inbound_data)]; 

These arrays will be passed to the communication peripherals to transmit and receive between the devices.

Because of how the hardware works, it is essential that the size of the two structs match, so that the buffers are of equal size. This is easy enough to assure with proper care, but occasionally through the design cycle, the data structures get modified. If one is not extremely careful, and aware of the requirement that the structures stay the same size (and be reflected in the PC side code as well), chaos ensues.

I would like to find a compile time way to have the code not build if one of the structures gets modified so that it does not match the size of the other structure.

Is this possible somehow in 'standard' C to check the sizes at compile time and fail if they are different? (I think my compiler is at least C99, maybe not 11).

 


If you must use C99, then I too like Swordfish would suggest a macro. The way to make one which can appear anywhere, and would not introduce any objects for the optimizer to remove, is to put the invalid array in a typedef. So a more general purpose static assertion would look this:

#define CONCAT_(A,B) A##B #define CONCAT(A,B) CONCAT_(A,B) #define MY_STATIC_ASSERT(p, msg) typedef char CONCAT(dummy__,__LINE__) [(p) ? 1 : -1] 

It's designed to mimic _Static_assert. The message is passed in with the hopes of a compiler diagnostic showing it. An example for its usage is here.

Which produces:

main.cpp:4:54: error: size of array 'dummy__13' is negative  #define MY_STATIC_ASSERT(p, msg) typedef char CONCAT(dummy__,__LINE__) [(p) ? 1 : -1]                                                       ^~~~~~~ main.cpp:2:22: note: in definition of macro 'CONCAT_'  #define CONCAT_(A,B) A##B                       ^ main.cpp:4:47: note: in expansion of macro 'CONCAT'  #define MY_STATIC_ASSERT(p, msg) typedef char CONCAT(dummy__,__LINE__) [(p) ? 1 : -1]                                                ^~~~~~ main.cpp:13:1: note: in expansion of macro 'MY_STATIC_ASSERT'  MY_STATIC_ASSERT(sizeof(struct foo) == sizeof(struct baz), "Do not match!"); 

And all the way down there you can see the static assertion with the message.


As an afterthought, you can change dummy__ to please_check_line_ will will produce the more descriptive please_check_line_13 above.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: