简体   繁体   中英

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.

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..... . 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.

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. 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}

But if the array is defined by the user it could also be:

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

GCC creates a warning for that and just fills the available parts of the array.

Now I have the following questions:

1) Compiler behavior: What do other compilers do, when I do the thing above? 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?

2) Do you know other possibilities to find out the padding bytes?

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)

3) if there is a struct inside another struct, like the following:

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?

1) Compiler behavior: What do other compilers do, when I do the thing above? 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?

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM