gpt4 book ai didi

c - 我需要在 C 预处理器 #if 中测试一个值是否会创建一个 0 大小的数组

转载 作者:行者123 更新时间:2023-12-04 04:26:13 24 4
gpt4 key购买 nike

我有一个结构必须填充到 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];
};
这在很长一段时间内一直有效,直到突然我们在某些构建配置中根本不需要垫,因为它已经正好是 64k。这会导致代码失败,因为我们的编译器(不是 GCC)不允许 pad[0] .
我尝试了各种方法来创建可以在 #if 中使用的预处理器值。检测到此情况时声明,但它总是失败,因为虽然 sizeof()#define 中是合法的, 在 #if 中是不合法的.

最佳答案

借助 C11 中引入的匿名结构,无需任何预处理器即可解决此问题。
将 flash 类型定义为包含嵌入匿名结构的成员的 union 。制作 char _pad[0x10000] union 的另一个成员强制引入类型的总大小。

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
编辑
  • 正如评论中建议的 union 成员 _pad可以重命名为 _rawData因为 _pad 的语义不同于 pad在问题中。
  • 如果是成员(member)pad在类型中是必需的,然后可以将其添加为匿名结构末尾的灵活成员。
  • typedef union { struct { ...; uint8_t pad[]; }; char _rawData[0x10000]; } flash_t;

    关于c - 我需要在 C 预处理器 #if 中测试一个值是否会创建一个 0 大小的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66992575/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com