可以使用 C 中的宏从各种结构构建预编译时间的任意字节数组吗?

标签 c arrays struct literals

我们都知道我们可以在 C 中将字符串文字“混合”在一起,而大多数编译器不会打扰我们,例如 char[] result = "a""b";//结果 = "ab"。我想将这个想法推广到结构。

假设我有以下结构:

typedef struct s1 {
 char a;
 int b;
} s1_t;

typedef struct s2 {
 int c;
} s2_t;

实际上,我想声明的字节数组是 s1_ts2_t 的任意组合。这合理吗?我宁愿不使用 union 。结构的内容将在编译时已知。

最佳答案

We all know that we can "mash" together string literals in C without most compilers troubling us

事实上,没有符合标准的 C 编译器会提示,因为此类结构的语义由标准明确定义。我提到这一点是为了强调结果不是偶然的,取决于运气或编译器的突发奇想,或任何类似的事情,正如您的评论似乎允许的可能性。

Effectively I want to declare byte arrays that are arbitrary combinations of [two structure types]. Is this reasonably possible? I would prefer not to use unions.

严格来说,这是不可能的。您不能以任何组合使用 struct 文字来初始化字节数组。您可以在 C99 或更高版本中使用 union 实现一些相当接近的东西,如果您希望从 struct 文字进行编译时初始化,那么我看不到任何其他选项。它看起来像这样:

typedef union {
    s1_t s1;
    s2_t s2;
} s_u;

s_u array[] = {
    { .s1 = (s1_t) { 'a', 42 } },
    { .s1 = (s1_t) { 'b', 17 } },
    { .s2 = (s2_t) { 1856 } },
    { .s1 = (s1_t) { 'Q', -1 } }
};

unsigned char *byte_array = (unsigned char *)array;

但是,我想,您想要避免 union 的原因是将不同大小的 struct 表示打包在一起而不进行填充。这不可能。事实上,即使只有 one 结构类型,也不一定可以在一个实例的最后一个元素和下一个实例的第一个元素之间没有任何填充的情况下安排实例。即使使用 memcpy() 强制执行它也可能并不容易,因为您的 struct 的表示可以同时具有尾部填充和内部填充,所有这些都以它们的大小计算。并且不要忘记任何填充字节的值都是未定义的。

您将所追求的结果描述为“顺序字节码”和“序列化 结构”(强调已添加)。我不确定在这种情况下“序列化”对您意味着什么,但对我来说它通常意味着与“内部表示”完全不同的东西。事实上,避免对内部表示的依赖是序列化的主要原因之一。

如果您的目标符合我的序列化理念,那么避免让您的用户编写字节码的最佳选择是为他们提供一个字节码编译器,以最方便的任何形式输入和输出。

关于可以使用 C 中的宏从各种结构构建预编译时间的任意字节数组吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30357607/

相关文章:

C错误: `arithmetic on pointer to an incomplete type`

c - 数组指针和返回类型

c 程序显示二叉树,但它没有显示任何输出,即使它没有显示任何错误。这个程序有什么错误

Javascript,for 循环将不起作用

c - 如何不使用方括号而是使用指针在数组中存储一组值

c++ - 结构比较器访问 C++ 中的另一个字段

c - C++ 中的简单逻辑。不允许使用 IF 语句

c - 为什么我的函数表示不是反向复制数据?

php - 如何替换多维数组中的键并保持顺序

c - 一对变量/结构的偏移量是否相同?