简体   繁体   English

数组初始化器中多余元素的填充字节发现以及常见和特殊的编译器行为

[英]Padding bytes discovery & common and special compiler behavior on excess elements in array initializer

In my project I am using a union of a struct with a char array to insert bytes into differing struct types. 在我的项目中,我使用带char数组的结构的并集将字节插入不同的结构类型。

There is a array which holds the structure of the specific struct for knowing what kind of variable comes next. 有一个数组保存特定结构的结构,以便知道接下来要使用哪种变量。

For every kind of that structs, one global variable, with type of that struct, is used to find out, where the padding bytes are located. 对于每种类型的结构,都会使用一个具有该结构类型的全局变量来找出填充字节的位置。 Therefor all of it's members are directly initialized with 0xFF..... . 因此,所有成员都直接用0xFF .....初始化。 When the function inserting the bytes, processes a field it always searches for the next byte in the array which is not 0. And inserts the bytes at that location. 当函数插入字节时,将处理一个字段,它总是在数组中搜索不为0的下一个字节。并将该字节插入该位置。

The struct type itself can be created by the user from a macro. 用户可以从宏创建结构类型本身。 Sometimes there are arrays can differ in size and contain also structs. 有时,数组的大小可能有所不同,并且还包含结构。 In normal basic types the first value of the array is initialized also to 0xFF and the insert function knows it's maximum length so it is no problem to determine where the next value starts. 在普通的基本类型中,数组的第一个值也被初始化为0xFF,并且insert函数知道其最大长度,因此确定下一个值从何处开始是没有问题的。 But when there is a struct array, the first initial value can be clearly identified, but the second one is a problem, I then do not know where it starts. 但是,当有一个结构数组时,第一个初始值可以清楚地确定,但是第二个是一个问题,我不知道它从哪里开始。

It could also have padding bytes at the beginning because the struct is nested. 由于该结构是嵌套的,因此开头也可能有填充字节。 Therefor I need to initialize the first two values, to find out the distance between the last member of the first and the first member of the second struct inside the array. 因此,我需要初始化前两个值,以找出数组内部第一个结构的最后一个成员与第二个结构的第一个成员之间的距离。

On a basic type this looks like the following: 在基本类型上,它类似于以下内容:

int array[2]={2,2} 整数数组[2] = {2,2}

But if the array is defined by the user it could also be: 但是,如果数组是由用户定义的,则它也可能是:

int array[0]={2,2} or int array[1]={2,2} int array [0] = {2,2}或int array [1] = {2,2}

GCC creates a warning for that and just fills the available parts of the array. GCC为此创建警告,并仅填充数组的可用部分。

Now I have the following questions: 现在我有以下问题:

1) Compiler behavior: What do other compilers do, when I do the thing above? 1)编译器行为:执行上述操作时,其他编译器会做什么? Is it common standard to only show a warning and skip the values which do not fit in? 仅显示警告并跳过不适合的值是常见的标准吗? Are there compilers (also considering C++ compilers) which raise an error and do not compile or do anything weired? 是否有编译器(也在考虑C ++编译器)引发错误并且没有进行编译或发生任何奇怪的事情?

2) Do you know other possibilities to find out the padding bytes? 2)您知道找出填充字节的其他可能性吗?

Example how it will look like in the code: 示例代码中的外观:

rosc_buildup_t rosc_static_msg_buildup_array_a_test_pkg__gnampf[]=
{
ROS_MSG_BUILDUP_TYPE_ARRAY,
    ROS_MSG_BUILDUP_TYPE_STRING,

ROS_MSG_BUILDUP_TYPE_MESSAGE_END,
}

#define ROSC_USERDEF_STATIC_MSG_a_test_pkg__gnampf(\
USER_TYPE,\
MAX_SIZE_STRING_fest)\
typedef \
struct  /*Main Message Start*/\
{\
struct  /*fest*/\
{\
    uint32_t size;\
    struct  /*fest array data*/\
    {\
        uint32_t size;\
        bool oversize;\
        char str_data[MAX_SIZE_STRING_fest];\
    }data[4];\
}fest;\
}\
uint32_t rosc_static_msg_length_definition__a_test_pkg__gnampf__ ## USER_TYPE[]={\
4,\
MAX_SIZE_STRING_fest};\
union\
{\
const rosc_static_msg__a_test_pkg__gnampf__ ## USER_TYPE msg;\
const char padding_out[ sizeof( rosc_static_msg__a_test_pkg__gnampf__ ##     USER_TYPE     )];\
}rosc_static_msg_lookup__a_test_pkg__gnampf__ ## USER_TYPE ={{ 0xFFFFFFFF, {{     0xFFFFFFFF,0xFF, {0xFF} }} }};

Update(1) 更新(1)

3) if there is a struct inside another struct, like the following: 3)如果另一个结构内部有一个结构,如下所示:

struct
{
   uint8_t foo;
   ... whatever...
   struct
   {
     uint8_t foo1;
     uint16_t foo2;
     uint8_t foo3;
   }b[3];
 }a;

Is foo1, always at the beginning or can there be padding bytes before foo1 starts? 是foo1, 始终在开头吗?还是在foo1开始之前可以有填充字节?

1) Compiler behavior: What do other compilers do, when I do the thing above? 1)编译器行为:执行上述操作时,其他编译器会做什么? Is it common standard to only show a warning and skip the values which do not fit in? 仅显示警告并跳过不适合的值是常见的标准吗? Are there compilers (also considering C++ compilers) which raise an error and do not compile or do anything weired? 是否有编译器(也在考虑C ++编译器)引发错误并且没有进行编译或发生任何奇怪的事情?

int array[1]={2,2}

This is an invalid declaration. 这是无效的声明。 The compiler is required to at least raise a diagnostic and is authorized to stop the compilation. 要求编译器至少提出诊断,并有权停止编译。 Same for a declaration of an array of zero element. 与零元素数组的声明相同。

I found now a better way to skip padding bytes in a struct and find the position of the variables by using the offsetof macro inside stddef.h, which, if it is not available, can be also defined by yourself. 我现在发现了一种更好的方法,可以通过使用stddef.h中的offsetof宏来跳过结构中的填充字节并找到变量的位置,如果不可用,也可以自己定义。

    /* Offset of member MEMBER in a struct of type TYPE. */
    #define offsetof(TYPE, MEMBER)\
    ( (size_t) &( ( (TYPE *) 0 )->MEMBER ) )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 数组初始化程序中的多余元素 - Excess elements in array initializer 聚合初始化程序中的多余元素 - excess elements in aggregate initializer 数组初始化C ++ char Xcode中的多余元素 - Excess elements in array initializer C++ char Xcode 嵌套std :: array时struct initializer中的多余元素 - Excess elements in struct initializer when nested std::array C++ 标量初始值设定项中的多余元素 - C++ Excess elements in scalar initializer 标量初始化程序代码中的多余元素使用gcc但不使用g ++进行编译 - Excess elements in scalar initializer code compiles with gcc but not g++ '结构初始化程序中的多余元素'错误与C ++ 11统一初始化 - 'Excess elements in struct initializer' error with C++11 uniform initialization 使用igraph C库生成具有幂律度分布的网络时,“标量初始化器中的多余元素” - “excess elements in scalar initializer” when using igraph C library to generate a network with power law degree distribution 是否未定义行为来读取和比较POD类型的填充字节? - Is it undefined behavior to read and compare padding bytes of a POD type? 如何使用初始化列表初始化数组元素? - How to initialize array elements by using initializer list?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM