Girish Onte
Girish Onte

Reputation: 107

How to check whether two structure types are equal in c?

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

Answers (1)

Aconcagua
Aconcagua

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:

  • load the header file
  • iterate over all lines until it finds the structure in question
  • check for all known members in desired order (i. e. no members replaced)
  • finally check, if end of structure is reached (i. e. no new members added)

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

Related Questions