Как проверить, равны ли два типа структур в c? - PullRequest
0 голосов
/ 10 июля 2019

У меня есть структура битового поля "struct errors" размером 1 байт, и я использую ее данные, используя маску "ERR_MASK", как показано в приведенном ниже коде.Мое требование заключается в том, что если тип структуры изменяется, маску необходимо соответствующим образом адаптировать.

Поскольку я импортирую этот тип структуры из другого компонента или модуля (file1.h в приведенном ниже коде), я хочу определить копию этого типа структуры "struct copy_errors" в моем исходном файле (file2.c вкод ниже) и проверьте, не изменился ли он с исходным типом в file1.h. Если есть несоответствие, я хочу сгенерировать ошибку компиляции из file2.c.Может кто-нибудь сказать мне, как мне этого добиться?Или есть другой способ сделать это?Примечание: я не хочу получать доступ к «структурам ошибок» с их элементами.

    /*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;
    }

1 Ответ

2 голосов
/ 10 июля 2019

C не поддерживает ничего эквивалентного. Если у вас есть цепочка инструментов, которая поддерживает пользовательские события сборки, вы можете ввести шаг предварительной сборки, вызывающий e. г. скрипт Python (или любой другой язык, который вы предпочитаете). Этот скрипт тогда будет:

  • загрузить заголовочный файл
  • итерация по всем строкам, пока не будет найдена рассматриваемая структура
  • проверка всех известных членов в желаемом порядке (т. Е. Ни один член не заменен)
  • наконец, проверьте, достигнут ли конец структуры (т. Е. Новые члены не добавлены)

Если цепочка инструментов останавливается, если задача перед сборкой завершается неудачно, вы уже ушли (просто верните 0 в случае успеха и все остальное в случае неудачи), в противном случае вы могли бы создать простой C-файл, пустой при успехе и содержащий #error директива о сбое.

В вашем C-коде вы можете дополнительно убедиться, что размер вашей структуры соответствует:

#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));

Макрос определен для повторного использования, так как, однако, может выдавать дополнительные предупреждения, если используется в теле функции (из-за неиспользуемого локального типа).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...