C.结构填料
Structure packing in C
本文关键字:结构 更新时间:2023-10-16
我有一个结构:
**struct PROCESSING
{
PROCESSOR Byte ;
uint16_t count ;
uint8_t overrange ;
Status status ;
Time timestamp ;
float Field;
float temperature ;
float adc1;
float dac1;
float Field2;
float Temperature;
float adc2 ;
float dac2 ;
};
PTC_STATIC_ASSERT_SIZE(Processing, 45U);**
这个结构的实际结构是45U,但当我构建时,我得到了一个错误:
"sizeof对不完整类型的无效应用"
我需要把它装到45U。
关于结构包装:
为了避免对齐和填充问题,您应该考虑。
-
重新安排成员。
-
自己添加填充物。
-
告诉编译器将每个成员的边界更改为1个字节。
例如:
#pragma pack(push)
#pragma pack(1)
struct PROCESSING
{
PROCESSOR Byte ;
uint16_t count ;
uint8_t overrange ;
Status status ;
Time timestamp ;
float Field;
float temperature ;
float adc1;
float dac1;
float Field2;
float Temperature;
float adc2 ;
float dac2 ;
};
#pragma pack(pop)
重新对齐以尽可能防止填充。
struct PROCESSING
{
PROCESSOR Byte ; // 1 byte
Status status ; // 1 byte
char __padding[2]; // 2 bytes
uint16_t count ; // 2 byte
uint8_t overrange ; // 1 byte
char _padding; // 1 byte
Time timestamp ; // 8 bytes
float Field;
float temperature ;
float adc1;
float dac1;
float Field2;
float Temperature;
float adc2 ;
float dac2 ;
};
标准不能保证默认情况下不应用填充
你应该确信一件事。在结构的开头不会有任何填充,之后你就可以自己了-默认情况下-。
我不知道所有用户定义的类型是如何定义的,但您的直接问题似乎是您的PROCESSING结构在某种程度上没有完全定义。也许您缺少适当头文件的#include或其他内容。一旦解决了这个问题,如果你需要更多关于编译器如何在内存中布局结构的信息,你可以创建一些临时调试代码,比如这样(注意,我已经随意添加了你的类型的定义,这些定义可能与你自己的定义不匹配)。。。。
typedef char PROCESSOR;
typedef char Status;
struct Time
{
char t[8];
};
struct PROCESSING
{
PROCESSOR Byte ;
uint16_t count ;
uint8_t overrange ;
Status status ;
Time timestamp ;
float Field;
float temperature ;
float adc1;
float dac1;
float Field2;
float Temperature;
float adc2 ;
float dac2 ;
};
int main()
{
PROCESSING p;
printf("Member Size Offsetn"
"-------------- ------ ------n");
#define MACROS_MAKE_THE_WORLD_GO_AROUND(structMember)
printf("%14s ", #structMember);
printf(" %3d ", sizeof(p.structMember));
printf(" %3dn", offsetof(PROCESSING,structMember));
MACROS_MAKE_THE_WORLD_GO_AROUND(Byte)
MACROS_MAKE_THE_WORLD_GO_AROUND(count)
MACROS_MAKE_THE_WORLD_GO_AROUND(overrange)
MACROS_MAKE_THE_WORLD_GO_AROUND(status)
MACROS_MAKE_THE_WORLD_GO_AROUND(timestamp)
MACROS_MAKE_THE_WORLD_GO_AROUND(Field)
MACROS_MAKE_THE_WORLD_GO_AROUND(temperature)
MACROS_MAKE_THE_WORLD_GO_AROUND(adc1)
MACROS_MAKE_THE_WORLD_GO_AROUND(dac1)
MACROS_MAKE_THE_WORLD_GO_AROUND(Field2)
MACROS_MAKE_THE_WORLD_GO_AROUND(Temperature)
MACROS_MAKE_THE_WORLD_GO_AROUND(adc2)
MACROS_MAKE_THE_WORLD_GO_AROUND(dac2)
#undef MACROS_MAKE_THE_WORLD_GO_AROUND
printf("n Total size of PROCESSING struct: %d bytesnn", sizeof(p));
}
当你运行它时,你会看到这样的东西:
Member Size Offset
-------------- ------ ------
Byte 1 0
count 2 2
overrange 1 4
status 1 5
timestamp 8 6
Field 4 16
temperature 4 20
adc1 4 24
dac1 4 28
Field2 4 32
Temperature 4 36
adc2 4 40
dac2 4 44
Total size of PROCESSING struct: 48 bytes
一旦你有了这些,你就可以开始弄清楚你可能需要做什么来使你的结构与嵌入式系统的结构布局相匹配,这可能比简单地使结构具有相同的整体尺寸更复杂。但其他人给出的#pragma暗示可能是一个良好的开端。注意编译器添加的填充,您可以通过添加"size"列来计算;将它与"offset"列进行比较,如果它们不匹配,那么就知道编译器插入了一些填充。
相关文章:
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 多成员Constexpr结构初始化
- C++将文本文件中的数据读取到结构数组中
- 如何重构类层次结构以避免菱形问题
- 如何在C++中序列化结构数据
- std::vector的包装器,使数组的结构看起来像结构的数组
- 没有为自己的结构调用列表推回方法
- 奇怪的结构&GCC&clang(void*返回类型)
- 在 c++ 中拥有一组结构的正确方法是什么?
- vscode g++链路故障:体系结构x86_64的未定义符号
- C++概念:如何使用'concept'检查模板化结构的属性?