当前位置: 首页 > 知识库问答 >
问题:

我需要一种方法在一个C预处理器#if来测试一个值是否会创建一个0大小的数组

裴英锐
2023-03-14

我有一个结构,必须扩展到64K,以完美地适合嵌入式项目,使它填补一个闪存块。因此有一个#define,它使用sizeof()将结构中的元素相加,并确定末端的pad[]需要多大才能使总大小达到64K。

例如,

#define SIZE_OF_MY_PAD (0x10000 - (sizeof(uint16_t) + sizeof(uint8_t)*32 + ... ))

typedef struct {
  uint16_t firstElement;
  uint8_t  secondElementArray[32];
  ...
  uint8_t pad[SIZE_OF_MY_PAD];
};

这已经工作了很长一段时间,直到突然间,我们在某些构建配置中根本不需要pad,因为它已经完全是64K了。这会导致代码失败,因为我们的编译器(不是GCC)不允许pad[0]。我尝试了各种方法来创建一个预处理器值,当检测到这个值时可以在#if语句中使用,但总是失败,因为虽然sizeof()在#define中是合法的,但在#if中是不合法的。

共有1个答案

锺离昂然
2023-03-14

在C11中引入的匿名结构的帮助下,这个问题可以在不需要任何预处理器的情况下得到解决。

将flash类型定义为包含嵌入到匿名结构中的成员的联合。使charpad[0x10000]成为联合的另一个成员,以强制引入类型的总大小。

typedef union {
    struct {
        uint16_t firstElement;
        uint8_t  secondElementArray[32];
        float thirdElement;
    };
    char _pad[0x10000];
} flash_t;

此解决方案对结构成员布局的任何修改都是健壮的。此外,这避免了定义零长度数组的问题,这在技术上被C标准所禁止(尽管在GCC中允许)。此外,还可以添加一个静态断言来检查闪存的最大大小是否溢出。

示例程序:

#include <stdio.h>
#include <stdint.h>
#include <stddef.h>

typedef union {
    struct {
        uint16_t firstElement;
        uint8_t  secondElementArray[32];
        float thirdElement;
        // int kaboom[20000]; // will trigger assert if uncommented
    };
    char _pad[0x10000];
} flash_t;

_Static_assert(sizeof(flash_t) == 0x10000, "Oops, flash_t got too large");

int main() {
    flash_t flash;
    printf("offsetof(flash.firstElement) = %zi\n", offsetof(flash_t, firstElement));
    printf("offsetof(flash.secondElementArray) = %zi\n", offsetof(flash_t, secondElementArray));
    printf("offsetof(flash.thirdElement) = %zi\n", offsetof(flash_t, thirdElement));
    printf("sizeof(flash) = %zi\n", sizeof flash);
    return 0;
}

产生预期输出:

offsetof(flash.firstElement) = 0
offsetof(flash.secondElementArray) = 2
offsetof(flash.thirdElement) = 36
sizeof(flash) = 65536
 类似资料:
  • 我有一个结构,必须垫出来64K,以完美地适应一个嵌入式项目,所以它填充了一个闪存块。所以有一个,它使用将结构中的元素相加,并确定末尾的需要多大才能使总大小64K。 例如: 这在很长一段时间内都非常有效,直到突然我们在某些构建配置中根本不需要pad,因为它已经精确到64k了。这会导致代码失败,因为我们的编译器(不是GCC)不允许。 我尝试了各种方法来创建一个预处理器值,当检测到该值时,我可以在语句中

  • 基本上,我需要这样的行列表: [0,0] [1,0],[0,1] [2,0],[1,1],[0,2] [3,0],[2,1],[1,2],[0,3] [4,0],[3,1],[2,2],[1,3],[0,4] 最多可添加任意数量的元素,然后再返回 [4,1],[3,2],[2,3],[1,4] [4,2],[3,3],[2,4] [4,3],[3,4] [4,4] 我只是希望所有这些对都在一个大的

  • 我需要创建一个带有签名的方法 此方法访问数组中的每个对象,并对属性租金求和并返回总金额。报税表:总租金 这是我的密码: 这是正确的吗?它一直说没有使用total变量,所以我不确定我是否做对了。

  • 问题内容: 基本上,我想对给定的值检查两个整数,因此,按照惯例,您将要执行以下操作: 但是,有没有更简洁的格式可以执行此操作?可能与此类似(返回错误的操作数类型): 问题答案: 不幸的是,Java中没有这样的构造。 如果这种比较在您的代码中很常见,则可以实现一个小的函数来为您执行检查: 然后,您可以像这样使用它: 如果您不想将自己限制为整数,可以使上述函数通用: 请注意,在这种情况下,Java运行

  • 我可以检查一个帐户是否是一个广告组的成员,但有没有办法告诉一个帐户是否属于一个OU?我想搜索由你而不是由广告组,我不确定如果这是可能的。下面是我如何搜索一个广告组。

  • 对于我正在做的一些测试,我需要一个执行时间约为10秒的C#函数。它将从ASPX页面调用,但我需要该函数消耗服务器上的CPU时间,而不是呈现时间。对Northwinds数据库的缓慢查询或一些非常缓慢的计算将会工作。有什么想法吗?