【发布时间】:2012-10-11 22:44:02
【问题描述】:
在 C 中获取数组元素计数的常用方法如下:
#define COUNTOF(arr) (sizeof(arr) / sizeof(arr[0]))
这会产生一个整数常量表达式,这也是一个很好的加分项。
问题在于它不是类型安全的:int* i; COUNTOF(i); /* compiles :( */。在实践中,这应该很少出现,但为了正确起见,最好让这个类型安全。
在 C++03 中这很容易(而在 C++11 中则更简单,留给读者作为练习):
template <typename T, std::size_t N>
char (&countof_detail(T (&)[N]))[N]; // not defined
#define COUNTOF(arr) (sizeof(countof_detail(arr)))
这使用模板推导得到N,即数组的大小,然后将其编码为类型的大小。
但是在 C 中我们没有那种语言特性。这是我制作的小框架:
// if `condition` evaluates to 0, fails to compile; otherwise results in `value`
#define STATIC_ASSERT_EXPR(condition, value) \
(sizeof(char[(condition) ? 1 : -1]), (value))
// usual type-unsafe method
#define COUNTOF_DETAIL(arr) (sizeof(arr) / sizeof(arr[0]))
// new method:
#define COUNTOF(arr) \
STATIC_ASSERT_EXPR(/* ??? */, \
COUNTOF_DETAIL(arr)) \
我可以在/* ??? */ 中输入什么来获得我想要的行为?或者这是不可能的?
我更喜欢 MSVC(即 C89)中的答案,但出于好奇,任何明确的答案都可以。
【问题讨论】:
-
如果你想要类型安全,也许 C 语言不适合你。 :P
-
@cHao:这不是我的语言。 :)
-
我只能想办法做相反的事情,检查它是否是一个指针。
-
以防万一它可以帮助某人想出一种相反的方法... #define COUNTOF(arr) (arr=arr)?(sizeof(arr) / sizeof(arr [0])) : 0
-
@Sebastian "sizeof 运算符不得应用于具有函数类型或不完整类型的表达式,..."。这将需要诊断,很可能是编译失败。但是,如果您将数组声明并初始化为
int arr[] = {0,2,3};,它将起作用,并且应该arr的类型为int[3]。
标签: c arrays visual-c++ c89