Нахождение наибольшего размера 100 структур во время компиляции в C - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть 100 структур, которые выглядят примерно так:

struct s00 { char   data[30]; };
struct s01 { char   data[30]; };
struct s02 { int    data[10]; };
struct s03 { double data[5];  };
struct s04 { float  data[20]; };
struct s05 { short  data[15]; };
struct s06 { char   data[7];  };
struct s07 { int    data[19]; };
struct s08 { double data[11]; };
struct s09 { float  data[5];  };
struct s10 { char   data[52]; };
//...
struct s99 { char   data[12]; };

typedef struct s00 s00;
typedef struct s01 s01;
typedef struct s02 s02;
//...
typedef struct s99 s99;

Я хочу найти самый большой sizeof из этих структур во время компиляции.Я попытался использовать макрос сравнения следующим образом:

 #define LARGER(a, b) ((a) > (b) ? (a) : (b))

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

#define MAX_SIZEOF (LARGER(sizeof(s00), \
                    LARGER(sizeof(s01), \
                    LARGER(sizeof(s02), \
                    LARGER(sizeof(s03), \
                    LARGER(sizeof(s04), \
                    LARGER(sizeof(s05), \
                    LARGER(sizeof(s06), \
                    LARGER(sizeof(s07), \
                    LARGER(sizeof(s08), \
                    LARGER(sizeof(s09), \
                    LARGER(sizeof(s10), \
                    //...
                    sizeof(s99))) /*...*/ ))

Однако компилятору не хватает места:

Ошибка Компилятор C1060 находится вне пространства кучи

Это имеет смысл, учитывая, что этот #define должен отслеживать множество чисел, поскольку он просто заменяеттекст.В частности, число целых чисел, найденных в MAX_SIZEOF, является экспоненциальным и может быть описано как:

number of numbers

, где x равно количеству структуручаствует.Предполагая 4 байта для целого числа, компилятору потребуется выделить 30,4 терабайта секстиллиона для вычисления этого макроса (если мои вычисления верны).Максимум, что моя система могла обработать, было 17 структур (786430 номеров, 3,14 мегабайта).

Я не уверен, как найти эффективное решение в C.

В C ++ я мог бы добиться этого с помощью constexpr довольно легко, без каких-либо проблем с компиляцией:

constexpr size_t LARGER(size_t a, size_t b) {
    return a > b ? a : b;
}
constexpr size_t MAX_SIZEOF() {
return 
    LARGER(sizeof(s00), \
    LARGER(sizeof(s01), \
    LARGER(sizeof(s02), \
    LARGER(sizeof(s03), \
    LARGER(sizeof(s04), \
    LARGER(sizeof(s05), \
    LARGER(sizeof(s06), \
    LARGER(sizeof(s07), \
    LARGER(sizeof(s08), \
    LARGER(sizeof(s09), \
    LARGER(sizeof(s10), \
    //...
    sizeof(s99))/*...*/)));

Но да, я должен использовать C только здесь.... Спасибо за любые идеи!

Ответы [ 2 ]

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

Как я уже упоминал, другой ответ намного приятнее, но, как я и просил, это работает для меня (в режиме компилятора AtmelStudio 6.2 C):

typedef struct { char   data[30]; }s00;
typedef struct { char   data[30]; }s01;
typedef struct { int    data[10]; }s02;
typedef struct { double data[5];  }s03;
typedef struct { float  data[20]; }s04;
typedef struct { short  data[15]; }s05;
typedef struct { char   data[7];  }s06;
typedef struct { int    data[19]; }s07;
typedef struct { double data[11]; }s08;
typedef struct { float  data[5];  }s09;
typedef struct { char   data[5]; }s10;
typedef struct { char   data[5]; }s11;
typedef struct { char   data[5]; }s12;
typedef struct { char   data[5]; }s13;
typedef struct { char   data[5]; }s14;
typedef struct { char   data[5]; }s15;
typedef struct { char   data[2]; }s16;
typedef struct { char   data[5]; }s17;
typedef struct { char   data[5]; }s18;
typedef struct { char   data[5]; }s19;
typedef struct { char   data[3]; }s20;
typedef struct { char   data[5]; }s21;
typedef struct { char   data[5]; }s22;
typedef struct { char   data[5]; }s23;
typedef struct { char   data[5]; }s24;
typedef struct { char   data[5]; }s25;
typedef struct { char   data[5]; }s26;
typedef struct { char   data[4]; }s27;
typedef struct { char   data[5]; }s28;
typedef struct { char   data[5]; }s29;
typedef struct { char   data[5]; }s30;
typedef struct { char   data[5]; }s31;
typedef struct { char   data[5]; }s32;
typedef struct { char   data[5]; }s33;
typedef struct { char   data[5]; }s34;
typedef struct { char   data[5]; }s35;
typedef struct { char   data[5]; }s36;
typedef struct { char   data[5]; }s37;
typedef struct { char   data[5]; }s38;
typedef struct { char   data[99];}s39;

#define sm(a0,a1) (sizeof(a0)>sizeof(a1)?sizeof(a0):sizeof(a1))
#define mm(a0,a1) (a0>a1?a0:a1)
#define s_10 sm(sm(sm(sm(sm(sm(sm(sm(sm(s00,s01),s02),s03),s04),s05),s06),s07),s08),s09)
#define s_20 sm(sm(sm(sm(sm(sm(sm(sm(sm(s10,s11),s12),s13),s14),s15),s16),s17),s18),s19)
#define s_30 sm(sm(sm(sm(sm(sm(sm(sm(sm(s20,s21),s22),s23),s24),s25),s26),s27),s28),s29)
#define s_40 sm(sm(sm(sm(sm(sm(sm(sm(sm(s30,s31),s32),s33),s34),s35),s36),s37),s38),s39)
const int s_size=mm(mm(mm(s_10,s_20),s_30),s_40);

Однострочная версия не работает, но если я разделюзначение в несколько строк (s_10,s_20,...), тогда я могу использовать даже 40 struct с с правильным выводом 99.Не пробовал больше, потому что мне лень копировать и вставлять другие ... Я не думаю, что проблема с его размещением у вас больше похожа на максимальный предел длины строки препроцессора ...

Выходное значениеs_size и может быть также #define ...

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

Вы можете объявить объединение всех структур

union allstructs {
    struct s00 s00val;
    struct s01 s01val;
    /* ... */
    struct s99 s99val;
}

и получить размер объединения

sizeof(union allstructs)

Когда вы хотите передавать структуры по сети, вам также следует подумать оупаковка / заполнение структур, порядок байтов и реализация с плавающей запятой.

...