我想声明一个静态分配的数组。 让我们看一下以下代码:
#define MAX(a,b) ((a)>(b)?(a):(b))
#define FAST 16
#define SLOW 6
#define MAX_NUM MAX(FAST,SLOW)
U8* pBuffers[MAX_NUM];
何时由GCC编译器评估MAX_NUM(FAST和SLOW是常量)? 我想确保MAX_NUM是常量,并作为编译的一部分或由预处理程序进行评估。
答案 0 :(得分:2)
启动编译器时,将依次执行以下阶段:
在预处理阶段,预处理器将例如用以下行“替换”您的行:
U8* pBuffers[MAX(FAST,SLOW)]
然后:
U8* pBuffers[((FAST)>(SLOW)?(FAST):(SLOW))]
然后终于:
U8* pBuffers[((16)>(6)?(16):(6))]
实际上,预处理器不是很聪明,并且不会走得更远。
在代码生成阶段,您的行将被解释为:
U8* pBuffers[16]
因为代码生成器非常聪明。
答案 1 :(得分:1)
The C standard要求使用整数常量表达式声明大多数数组的大小,在编译时可以(在这种情况下)必须对其进行充分评估。 (唯一的例外是“可变长度数组”,并且它们必须是具有“自动存储持续时间”的函数局部变量,而不是静态分配的。)
因此,对您的问题的一个答案是您不必为此担心。如果你写
WHATEVER_TYPE variable[SOME EXPRESSION];
在文件范围内,SOME EXPRESSION
在编译时将被评估为常量,否则编译将失败并且您将得到一个错误。
但是更有用的答案是解释在阅读代码时如何亲自查看SOME EXPRESSION
是否为整数常量表达式。首先,您必须在脑子上扩展所有宏。然后,您大概会有某种算术表达式(如果不是,那是语法错误)。
此算术表达式是 constant 表达式,如果它没有副作用,不进行任何函数调用并且不引用任何变量的值(即使它不是const
(enum
常数就可以了,就像字符串文字一样,只要sizeof variable
被完全声明并且不是可变长度数组,就可以使用variable
) 。此外,如果它不尝试执行任何浮点或指针算术(您可以将浮点文字作为强制类型转换的直接操作数),则它是一个 integer 常量表达式。 ,但是;例如((int)3.1415926)
是一个整数常量表达式)。
所以,以你的例子为例,
#define MAX(a,b) ((a)>(b)?(a):(b))
#define FAST 16
#define SLOW 6
#define MAX_NUM MAX(FAST,SLOW)
U8* pBuffers[MAX_NUM];
宏扩展后,我们有了
U8* pBuffers[((16)>(6)?(16):(6))];
方括号内的表达式没有副作用,不进行任何函数调用,不引用任何变量的值,并且不执行任何浮点或指针算术,因此它是整数常量表达式,并且要求编译器在编译时对其进行求值。
相反,如果您使用的是MAX的定义,则:
static inline size_t MAX(size_t a, size_t b)
{ return a > b ? a : b; }
然后将产生宏扩展
U8* pBuffers[MAX(16, 8)];
并且方括号内的表达式将进行函数调用,因此它不是整数常量表达式,甚至不是常量表达式,而且会出现编译时错误。
(仅供参考,C ++中的规则要复杂得多;如果您需要了解这一点,请提出一个新问题。)
答案 2 :(得分:0)
总是在编译过程开始之前评估MACROS。因此,此代码无需担心,它应该可以正常工作。
同时,这整个过程取决于编译器,我相信使用gcc
可以正常工作。也许,对于某些裸机应用,它可能会发出警告。