Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding the largest size of 100 structs at compile time in C

I have 100 structs that look something like this:

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;

I want to find the largest sizeof from among these structs at compile time. I tried using a comparison macro like this:

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

and then use that to construct the final define which will contain the result:

#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))) /*...*/ ))

However, the compiler runs out of space:

Error C1060 compiler is out of heap space

Which makes sense, given that this #define has to keep track of alot of numbers, since it simply replaces text. To be specific, the number of integers found in MAX_SIZEOF is exponential and can be described as:

number of numbers

where x is equal the number of structs involved. Assuming 4 bytes for an integer, the compiler would need to allocate 30.4 sextillion terabytes to compute this macro (if my calculations are correct). The maximum my system could handle was 17 structs (786430 numbers, 3.14 megabytes).

I am not sure how I can find an efficient solution in C.

In C++ I could achieve this with constexpr quite easily without any compiling issues whatsoever:

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))/*...*/)));

But yeah, I have to use C only here. ...Thanks for any ideas!

like image 919
Stack Danny Avatar asked Dec 07 '18 10:12

Stack Danny


People also ask

What is the maximum size of structure in C?

So the maximum size is between 2^30 and (2^31 - 1).

How do you determine the size of a struct byte?

If you want to manually count it, the size of a struct is just the size of each of its data members after accounting for alignment. There's no magic overhead bytes for a struct.

How do you measure the size of a compiler?

You can check the size during compilation: static_assert (sizeof(mystruct) == 1024, "Size is not correct"); You need C++11 for that.

How much space does a struct take?

In 32 bit processor, it can access 4 bytes at a time which means word size is 4 bytes. Similarly in a 64 bit processor, it can access 8 bytes at a time which means word size is 8 bytes. Structure padding is used to save number of CPU cycles.


2 Answers

You can declare a union of all structs

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

and get the size of the union

sizeof(union allstructs)

When you want to transmit structures over the network you should also think about packing/padding of structures, byte order and floating point implementation.

like image 162
Bodo Avatar answered Nov 15 '22 01:11

Bodo


As I mentioned the other answer is way much nicer but as requested this works for me (on AtmelStudio 6.2 C compiler mode):

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

The single line version is not working but if I divide the value into multiple lines (s_10,s_20,...) then I can use even 40 structs with correct output 99. Have not tried more as I am too lazy to copy paste others... I do not think its allocation problem you got there more like the max limit per line length of the preprocessor ...

The output value is s_size and can be also a #define ...

like image 38
Spektre Avatar answered Nov 15 '22 00:11

Spektre