Обнаружение байтов заполнения & amp; общее и специальное поведение компилятора на избыточных элементах в инициализаторе массива

В моем проекте я использую объединение структуры с массивом char для вставки байтов в различные типы структур.

Существует массив, который содержит структуру конкретной структуры для определения того, какая переменная будет следующей.

Для каждого вида этих структур используется одна глобальная переменная с типом этой структуры, чтобы выяснить, где расположены байты заполнения. Поэтому все его члены непосредственно инициализируются с 0xFF …… Когда функция вставляет байты, обрабатывает поле, она всегда ищет следующий массив в массиве, который не равен 0. И вставляет байты в этом месте.

Сам тип структуры может быть создан пользователем из макроса. Иногда встречающиеся массивы могут различаться по размеру и содержать также структуры. В обычных базовых типах первое значение массива инициализируется также в 0xFF, и функция вставки знает, что это максимальная длина, поэтому нетрудно определить, где начинается следующее значение. Но когда есть массив структур, первое начальное значение может быть четко идентифицировано, но второе является проблемой, тогда я не знаю, с чего оно начинается.

Он также может иметь байты заполнения в начале, потому что структура является вложенной. Поэтому мне нужно инициализировать первые два значения, чтобы узнать расстояние между последним членом первого и первым членом второй структуры внутри массива.

На базовом типе это выглядит следующим образом:

массив int [2] = {2,2}

Но если массив определяется пользователем, он также может быть:

массив int [0] = {2,2} или массив int [1] = {2,2}

GCC создает предупреждение для этого и просто заполняет доступные части массива.

Теперь у меня есть следующие вопросы:

1) Поведение компилятора:
Что делают другие компиляторы, когда я делаю вещи выше?
Является ли общепринятым стандартом показывать только предупреждение и пропускать значения, которые не вписываются?
Существуют ли компиляторы (также учитывающие компиляторы C ++), которые выдают ошибку и не компилируют или делают что-то утомленное?

2) Знаете ли вы другие возможности, чтобы узнать байты заполнения?

Пример того, как это будет выглядеть в коде:

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

Обновление (1)

3) если внутри другой структуры есть структура, например:

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

Это foo1, всегда в начале или могут быть байты заполнения перед запуском foo1?

0

Решение

1) Поведение компилятора: что делают другие компиляторы, когда я делаю это выше? Является ли общепринятым стандартом показывать только предупреждение и пропускать значения, которые не вписываются? Существуют ли компиляторы (также учитывающие компиляторы C ++), которые выдают ошибку и не компилируют или делают что-то утомленное?

int array[1]={2,2}

Это недопустимая декларация. Компилятор обязан по крайней мере вызвать диагностику и авторизован для остановки компиляции. То же самое для объявления массива нулевого элемента.

1

Другие решения

Теперь я нашел лучший способ пропустить байты заполнения в структуре и найти положение переменных с помощью макроса offsetof внутри stddef.h, который, если он недоступен, также можно определить самостоятельно.

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

По вопросам рекламы [email protected]