首页 > 解决方案 > 如何在c中检查两种结构类型是否相等?

问题描述

我有一个大小为 1 字节的位域结构“结构错误”,我使用掩码“ERR_MASK”使用它的数据,如下面的代码所示。我的要求是,如果结构的类型发生变化,则需要对掩码进行相应的调整。

由于我从另一个组件或模块(以下代码中的 file1.h)导入此结构类型,我想在我的源文件(以下代码中的 file2.c)中定义此结构类型“struct copy_errors”的副本并检查是否它已更改为 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;
    }

标签: c

解决方案


C不支持任何等效的东西。如果您有一个支持自定义构建事件的工具链,您可以引入一个预构建步骤,调用例如 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));

该宏被定义为可重用,但如果在函数体中使用,可能会产生额外的警告(因为未使用的本地类型)。


推荐阅读