инициализация структуры с использованием макросов - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть структура, и я использую макрос предварительной обработки для заполнения массивов в структуре.

#include <stdio.h>
void init_data();
typedef struct _abc{
        int a[10][10];
        int b[5][5];
}abc;
static abc q_abc[]= {
                #define XYZ(x,y,z) [x]={.a[y][z]=1,.b[y][z]=1},
                 XYZ(1,2,3)
                 XYZ(1,3,2)

};
static abc q_abc1[5];
void init_data()
{
 #define XYZW(x,y,z) q_abc1[x].a[y][z] =1;
  XYZW(1,2,3)
  XYZW(1,3,2)
}
int main()
{
        printf("\n  %d  %d\n",q_abc[1].a[2][3]);
        init_data();
        printf("\n %d  %d\n",q_abc1[1].a[2][3]);
        return 0;
}

Я инициализирую структуру q_abc с помощью макроса.Но проблема здесь в том, что значение, установленное во время вызова макроса на XYZ(1,2,3), сбрасывается до значения по умолчанию 0 во время вызова следующего вызова макроса XYZ(1,3,2).Я могу понять, что если не указать, что какой-либо явный инициализатор установит для массива значение по умолчанию 0.

Чтобы избежать этого, я использовал подход init_data. Здесь я не инициализирую массив, а присваиваю его, поэтому массивы будут иметь всезначения из всех вызовов макросов не повреждены.но проблема здесь в том, что если данные огромны или количество вызовов макросов огромно, вызов func займет совсем немного времени, что добавляет накладные расходы ко времени выполнения exe.

есть ли способ достичь init_data Какое поведение во время определения самой переменной?какие-либо предложения?

1 Ответ

0 голосов
/ 19 декабря 2018

Это тот случай, когда включение предупреждений помогло бы вам.Компиляция вашего кода с GCC дает мне это:

main.cpp:8:40: warning: initialized field overwritten [-Woverride-init]
                 #define XYZ(x,y,z) [x]={.a[y][z]=1,.b[y][z]=1},
                                        ^
main.cpp:10:18: note: in expansion of macro 'XYZ'
                  XYZ(1,3,2)
                  ^~~
main.cpp:8:40: note: (near initialization for 'q_abc[1]')
                 #define XYZ(x,y,z) [x]={.a[y][z]=1,.b[y][z]=1},
                                        ^
main.cpp:10:18: note: in expansion of macro 'XYZ'
                  XYZ(1,3,2)

И на то есть веские причины.Инициализатор фигурной скобки инициализирует все поля , даже если вы пропустите явные инициализаторы для некоторых (они будут равны нулю).Написав X(1,..) X(1,...), вы инициализируете один и тот же индекс дважды.Вы не можете разделить его на два макроса, как пытаетесь.Это должен быть один, если вы действительно хотите использовать макрос.

Лично я бы не стал возиться с макросами.Назначенные инициализаторы делают код достаточно читабельным, даже не скрывая их за макросом.

...