【发布时间】:2015-07-07 14:47:09
【问题描述】:
查找静态数组的大小是一种常见操作。见:C find static array size - sizeof(a) / sizeof((a)[0])
这可以包装成一个宏,例如:
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
但是可能会意外传入常规指针。
例如:void func(SomeArray **foo) { int i = ARRAY_SIZE(foo); }
虽然它的 C 是有效的,但通常以逻辑错误告终。
有可能防止这个错误(利用每个处理器在零长度位字段上失败)。
#define ARRAY_SIZE(a) \
((sizeof(struct { int isnt_array : \
((const void *)&(a) == &(a)[0]); }) * 0) + \
(sizeof(a) / sizeof(*(a))))
我发现此宏适用于 GCC,但不适用于 Clang,用于间接引用的成员。 error: expression is not an integer constant expression
例如:
-
char word[8]; int i = ARRAY_SIZE(word);好的。 -
struct Bar { word[8]; }void func(struct Bar *foo) { int i = ARRAY_SIZE(foo->word); }失败。
有没有更便携的方法来实现这一点? (虽然我对通用的可移植性很感兴趣......其他编译器也是)。
这似乎是一项常见的任务,最好有一个可重复使用的便携式宏。
【问题讨论】:
-
1.这就是宏的问题,也是很多人讨厌它们的原因:它们会导致难以发现的错误。 2. clang 对你的例子有什么看法?
-
我不认为这是宏的具体问题,
sizeof(a) / sizeof((a)[0])的意外误用也可能在没有宏的情况下发生。如果您使用例如参数回复本地固定宽度字符串,则可能会发生这种情况。 (已编辑以包含 Clang 的错误消息) -
@ideasman42:你确定位域长度可以是非常量表达式吗?还是我误读了您的代码?...
-
@Steve Fallows,^^^ 不是重复的,因为它是一种不同的语言,答案涉及使用 C++ 特定功能。
-
@ideasman42 - 哇! - 不仔细阅读。如果未来的读者正在寻找 C++ 解决方案,我会留下评论。
标签: c arrays c-preprocessor