Reputation: 107
I have a bit-field structure "struct errors" of size 1 byte and I am using its data using a mask "ERR_MASK" as shown in below code. My requirement is that if the type of the structure is changed, the mask need to be adapted accordingly.
Since I am importing this structure type from another component or module (file1.h in below code), I want to define a copy of this structure type "struct copy_errors" in my source file (file2.c in below code) and check if it has got changed with original type in file1.h, If there is a mismatch, I want to throw an compilation error from file2.c. Can anyone tell me how do I achieve this? Or is there any other way to do this? Note: I don't want to access "struct errors" with its elements.
/*file1.h*/
struct errors
{
unsigned char err0 :1;
unsigned char err1 :1;
unsigned char err2 :1;
unsigned char err3 :1;
unsigned char err4 :1;
unsigned char err5 :1;
unsigned char reserved1 :1;
unsigned char reserved2 :1;
};
/*file2.c*/
#include "file1.h"
#define ERR_MASK 0xFCU
struct copy_errors
{
unsigned char err0 :1;
unsigned char err1 :1;
unsigned char err2 :1;
unsigned char err3 :1;
unsigned char err4 :1;
unsigned char err5 :1;
unsigned char reserved1 :1;
unsigned char reserved2 :1;
};
bool function(struct err*)
{
bool ret=0;
unsigned char * err_ptr;
err_ptr = (unsigned char *) err;
if (((*err_ptr) & ERR_MASK) != 0U)
{
ret = 1;
}
return ret;
}
Upvotes: 0
Views: 353
Reputation: 25518
C doesn't support anything equivalent. If you have a tool chain that supports custom build events, you could introduce a pre-build step calling e. g. a python script (or any other language you prefer). This script then would:
If your tool chain stops, if the pre-build task fails, you are out already (just return 0 on success and anything else on failure), otherwise you could create a simple C-File, empty on success and containing an #error
directive on failure.
Within your C code, you could additionally assure that the size of your struct matches:
#define CONCATENATE(X, Y) CONCATENATE_(X, Y)
#define CONCATENATE_(X, Y) X##Y
#define STATIC_ASSERT(CONDITION) \
typedef int(CONCATENATE(_static_assert_, __LINE__))[(CONDITION)? 1 : -1]
STATIC_ASSERT(sizeof(struct errors) == sizeof(unsigned char));
The macro is defined to be re-usable, as is, though, might produce additional warnings if used within function body (because of unused local type).
Upvotes: 2