在C中,我们有指向数组对象和arrays of constant known size的指针
NetBSD定义了一个__arraycount宏,定义为~/.python-global/python3
我想要定义自己的#define __arraycount(x) (sizeof(x)/sizeof(x[0]))
宏,当给定指向数组的指针时,它不会编译。要做到这一点,我需要一个__arraycount
宏
我想有一个宏是一个编译时常量,对于常量已知大小的数组将返回true /非零,对于指向数组对象(或任何其他指针)的指针将返回false / zero。
这就是我想出的:
__is_array_of_constant_known_size
对于GNUC编译器(clang6.0.0和gcc8.1),测试是可以的,即。包含#if __GNUC__
#define __is_array_of_constant_known_size(x) ( __builtin_constant_p((void*)x == (void*)&x)?1:0 )
#else
#define __is_array_of_constant_known_size(x) ( (void*)&x[0] == (void*)&x )
#endif
// __arraycount may look like this:
#define __arraycount(x) ( sizeof(char[__is_array_of_constant_known_size(x) ? 1 : -1]) ? (sizeof(x)/sizeof(x[0])) : -1 )
// tests:
static char var1[5];
typedef char type1[__is_array_of_constant_known_size(var1)?1:-1];
static const int int1 = __is_array_of_constant_known_size(var1);
static const int sizeof1 = sizeof(char[__is_array_of_constant_known_size(var1)?1:-1]);
static char * var2;
typedef char type2[__is_array_of_constant_known_size(var2)?1:-1]; // should error
static const int int2 = __is_array_of_constant_known_size(var2);
static const int sizeof2 = sizeof(char[__is_array_of_constant_known_size(var2) 1:-1]); // should error
和type2
的行无法使用sizeof2
进行编译
但是当没有定义GNUC时,我得到:
error: size of array is negative
行<source>:8:1: warning: variably modified 'type1' at file scope
typedef char type1[__is_array_of_constant_known_size(var1)?1:-1];
^~~~~~~
<source>:10:21: error: initializer element is not constant
const int sizeof1 = sizeof(char[__is_array_of_constant_known_size(var1)?1:-1]);
^~~~~~
<source>:13:14: error: variably modified 'type2' at file scope
typedef char type2[__is_array_of_constant_known_size(var2)?1:-1];
^~~~~
<source>:4:47: error: initializer element is not constant
#define __is_array_of_constant_known_size(x) ( (void*)&x[0] == (void*)&x )
^
<source>:14:18: note: in expansion of macro '__is_array_of_constant_known_size'
const int int2 = __is_array_of_constant_known_size(var2)?1:-1;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:15:21: error: initializer element is not constant
const int sizeof2 = sizeof(char[__is_array_of_constant_known_size(var2)?1:-1]);
编译没有错误。这意味着,int1 = __is_array_of_constant_known_size(var1)
是一个常量表达式,因为
具有静态的对象的初始值设定项中的所有表达式 存储持续时间应为常量表达式或字符串文字 从6.7.8英寸 C99
但是行__is_array_of_constant_known_size(var1)
无法使用sizeof1 = sizeof(char[__is_array_of_constant_known_size(var1)])
进行编译。那是为什么?
为什么error: initializer is not compile time constant
是常量表达式,但(void*)&var1[0] == (void*)&var1
不是?
有没有更好的方法在sizeof(char[((void*)&var1[0] == (void*)&var1)])
宏内部而不是__arraycount
内实现编译时断言?