【问题标题】:How to check whether two structure types are equal in c?如何在c中检查两种结构类型是否相等?
【发布时间】:2019-07-10 05:48:41
【问题描述】:

我有一个大小为 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 编译器,它们实际上是两种不同的结构,它们之间根本没有关系。这当然意味着如果它们不匹配,就没有办法得到构建错误。
  • 您可以使用某种diff 工具,但我认为语言本身没有任何方法。
  • 这个struct* err 不是有效的C,顺便说一句。
  • if (((*err_ptr) & ERR_MASK) != 0U) 不可移植。您正在假设实际上依赖于实现的位布局。顺便说一句,检查此类事情的一种方法是依靠手动和可靠的(是否存在)版本控制。

标签: c


【解决方案1】:

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

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

【讨论】:

  • 感谢您的回答。我忘了澄清“struct errors”和“struct copy_errors”的大小总是1字节。我想确定它的元素是否已被替换或替换为新元素。
  • @GirishOnte 好吧,忘记copy_errors,它对你没有任何帮助。您想要/需要的所有检查都可以直接在struct errors 上完成——但除了大小检查之外,它们都不能直接在 C 中进行。不支持。句号。因此,您需要一个单独的工具,例如前面提到的 python 脚本(或任何其他脚本语言,甚至是用 C 编写的 separate 可执行文件)。
  • @GirishOnte 大小将始终为 1 字节?你确定吗?这个怎么样:struct errors { unsigned char err0:1; /* ... */ unsigned char err5:1; unsigned char err6:1; unsigned char err7:1; unsigned char err8:1; /* and a bunch of reserved bits */ };...
  • 是的。我知道这在 C 语言中是不可能的。我将按照您的建议检查工具解决方案。谢谢。为了澄清您的大小,结构元素的数量在我的应用程序中始终是固定的。他们不会改变。但是现有元素的位置可以在结构内部改变。希望很清楚。
猜你喜欢
  • 2017-02-01
  • 2018-04-05
  • 1970-01-01
  • 1970-01-01
  • 2019-05-19
  • 2011-09-10
  • 1970-01-01
  • 2015-10-18
  • 1970-01-01
相关资源
最近更新 更多