我正在研究RAM非常紧张的嵌入式应用程序。为此,我需要创建一个24位无符号整数数据类型。我正在使用一个结构:
typedef struct
{
uint32_t v : 24;
} uint24_t;
但是,当我询问此类型的变量的大小时,它将返回“ 4”,即:
uint24_t x;
x.v = 0;
printf("Size = %u", sizeof(x));
有没有一种方法可以强制此变量具有3个字节?
最初,我认为这是因为它迫使数据类型必须按字对齐,但是例如,我可以这样做:
typedef struct
{
uint8_t blah[3];
} mytype;
在这种情况下,大小为3。
好吧,您可以尝试确保结构仅占用所需的空间,例如:
#pragma pack(push, 1)
typedef struct { uint8_t byt[3]; } UInt24;
#pragma pack(pop)
您可能必须提供那些编译器指令(如#pragma
上面的行)以确保没有填充,但这对于只有八位字段(a)的结构可能是默认的。
然后,您可能必须将实际值打包到结构中或从结构中解压缩出来,例如:
// Inline suggestion used to (hopefully) reduce overhead.
inline uint32_t unpack(UInt24 x) {
uint32_t retVal = x.byt[0];
retval = retVal << 8 | x.byt[1];
retval = retVal << 8 | x.byt[2];
return retVal;
}
inline UInt24 pack(uint32_t x) {
UInt24 retVal;
retVal.byt[0] = (x >> 16) & 0xff;
retVal.byt[1] = (x >> 8) & 0xff;
retVal.byt[2] = x & 0xff;
return retVal
}
请注意,无论您使用的是哪种实际体系结构,这都将为您提供big-endian值。如果只打包和解包,这无关紧要,但是如果您想在特定布局中的其他地方使用内存块,则可能会出现问题(在这种情况下,您可以更改打包/打包代码以使用所需的格式)。
这种方法向您的系统添加了一些代码(可能会降低性能),因此您必须决定是否值得节省使用的数据空间。
(a)例如,对于下面的程序,都显示gcc 7.3
和,clang 6.0
表明3 6
该结构内部或之后没有填充:
#include <stdio.h>
#include <stdint.h>
typedef struct { uint8_t byt[3]; } UInt24;
int main() {
UInt24 x, y[2];
printf("%zd %zd\n", sizeof(x), sizeof(y));
return 0;
}
然而,这是只是一个样品,所以你可能要考虑,在移植代码的兴趣,使用类似#pragma pack(1)
,或将在代码赶上在这可能并非如此环境。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句