在 C 中的编译时查找 100 个结构的最大大小
Finding the largest size of 100 structs at compile time in C
我有 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))) /*...*/ ))
但是,编译器用完了space:
Error C1060 compiler is out of heap space
这是有道理的,因为这个 #define
必须跟踪很多数字,因为它只是替换文本。具体来说,在 MAX_SIZEOF
中找到的整数个数是指数级的,可以描述为:
其中 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。 ...感谢任何想法!
您可以声明所有结构的联合
union allstructs {
struct s00 s00val;
struct s01 s01val;
/* ... */
struct s99 s99val;
}
并获取并集的大小
sizeof(union allstructs)
当您想要通过网络传输结构时,您还应该考虑 packing/padding 结构、字节顺序和浮点实现。
正如我提到的,另一个答案要好得多,但根据要求,这对我有用(在 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
s 和正确的输出 99
。没有尝试更多,因为我懒得复制粘贴其他人...我不认为它的分配问题更像是预处理器每行长度的最大限制...
输出值为s_size
,也可以是#define
...
我有 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))) /*...*/ ))
但是,编译器用完了space:
Error C1060 compiler is out of heap space
这是有道理的,因为这个 #define
必须跟踪很多数字,因为它只是替换文本。具体来说,在 MAX_SIZEOF
中找到的整数个数是指数级的,可以描述为:
其中 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。 ...感谢任何想法!
您可以声明所有结构的联合
union allstructs {
struct s00 s00val;
struct s01 s01val;
/* ... */
struct s99 s99val;
}
并获取并集的大小
sizeof(union allstructs)
当您想要通过网络传输结构时,您还应该考虑 packing/padding 结构、字节顺序和浮点实现。
正如我提到的,另一个答案要好得多,但根据要求,这对我有用(在 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
s 和正确的输出 99
。没有尝试更多,因为我懒得复制粘贴其他人...我不认为它的分配问题更像是预处理器每行长度的最大限制...
输出值为s_size
,也可以是#define
...