我试图在结构中分配一个int16_t变量。此结构保留在磁盘中并在重新引导时加载回来。 旧结构
struct details
{
int a;
int16_t var1;
int16_t b;
} details_t
我更改的新内容是
struct details
{
int a;
int16_t var1:15;
unit16_t var2:1;
int16_t b;
}details_t;
新的更改在reboot之间正常工作。但这是正确的做法吗? 我想要达到的目的是具有基于 var2 的变量 var1 的双重含义 set 或已清除。由于 var2 存储二进制值,我将其声明为uint16_t。分离变量并将其声明为两种不同的数据类型(int16_t和uint16_t)是合法的。这将是现有堆栈中的更新,它应该在更新后无缝地工作。 此外,我无法在这些分开的变量 var1 和 var2 上使用set_bit和clear_bit等内核函数。我的机器是小端
答案 0 :(得分:0)
您希望保持向后兼容性。但不幸的是,C标准为实现提供了很多空间来处理位字段。 var1
和var2
最终可能会成为2个16位变量,这些变量可能是您不想要的。
我建议使用手动位屏蔽和移位。使用位移时,请注意带符号的变量。如有必要,请使用无符号临时变量。
答案 1 :(得分:0)
但这是正确的做法吗?
比特字段几乎肯定是做任何的错误方式,特别是在需要可移植性的情况下。 Please read this。
如果您声明标准未指定int16_t var1:15;
会发生什么,则无法确定符号位将在何处结束,msb将在何处,或其他任何内容。甚至没有指定该位字段是被视为有符号还是无符号。
分离变量并将其声明为两种不同的数据类型
是否合法
它将编译,但结果将取决于系统和编译器。基本上你只是创建了一个16位的随机goo,除非一个特定的编译器文档另有说明,否则你无法预测任何给定的行为。
这将是现有堆栈中的更新,它应该在更新后无缝地工作。
然后不要这样做。您可能会破坏该计划或至少引入漏洞以备将来维护。相反,忘了你曾经看过一些叫做位域的东西,并使用逐位运算符来操纵原始的int16_t
。
如果在这种数据类型的中间走私布尔标志是有意义的,我不知道,但这取决于你的程序要处理。