C++ C语言中的结构填充

C++ C语言中的结构填充,c++,c,structure,qt-creator,C++,C,Structure,Qt Creator,我有一个结构: **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;

我有一个结构:

**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对不完整类型的应用无效”


我需要将其精确包装到45 U。

关于结构包装:

<>为了避免对齐和填充问题,你应该考虑。

  • 重新安排成员

  • 自己添加填充物

  • 告诉编译器将每个成员的边界更改为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 ;
};
该标准不保证默认情况下不会应用填充

你应该确定一件事。在结构的开头将不会有任何填充,在这之后,默认情况下,您可以自己操作。

我不知道如何定义所有用户定义的类型,但您当前的问题似乎是您的处理结构没有完全定义。也许您缺少一个适当的头文件或其他文件的包含。一旦解决了这个问题,如果您需要更多关于编译器如何在内存中布局结构的信息,您可以创建一些临时调试代码,如下所示(请注意,我已经随意添加了类型的定义,这些定义可能与您自己的定义不匹配)

当您运行该命令时,您将看到如下内容:

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

一旦你有了它,你就可以开始想办法让你的结构与你的嵌入式系统的结构布局相匹配,这可能比简单地使结构保持相同的总体尺寸更复杂。但其他人给出的“布拉格”暗示可能是一个良好的开端。注意编译器添加的填充,你可以通过添加“大小”列来计算出来,并将它与“偏移”列进行比较,如果它们不匹配,你就知道编译器插入了一些填充。

为什么这个标记的java?我的想法完全正确,我已经用几个C++框架工作了,像这样的错误总是让我困惑。你需要把它标记为C或C++来获得GCC大师之一。“处理”在其他地方宣布吗?因为您正在定义的结构正在处理。(因此,如果在某个地方有一行“struct Processing;”,并且代码实际上与它读取的一样,您就会得到错误)“sizeof对不完整类型的无效应用程序”意味着编译器已经被告知存在一个类型(通过转发声明),但编译器还没有被告知该类型实际上是什么。。。这就是sizeof()运算符(可能是由PTC_STATIC_ASSERT_SIZE宏以某种方式调用的)无法编译的原因。您可能需要#在上述代码之前包含一个包含处理器或状态或时间等的实际声明的标头(而不是只进行前向声明的标头,或者在该标头之外)。不,该结构没有在程序中的任何其他地方定义,它仍然会抱怨sizeof对不完整类型的应用无效。因此,这1个字节有一些模糊。您计算了字节了吗?
处理器
状态
时间
的大小是多少?如果您在x86机器上,编译器可能会尝试在某些成员之间添加填充,以便CPU每隔
4字节
32位
访问它们。处理器=1字节,状态-1字节,时间-8字节侦听,重新对齐,以便它们可以作为4字节块读取,例如。。。在
处理器之后
添加
字符填充[3]
。。。总共4个字节。剩下的就这么做吧。不要打扰时间:D
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