宏定义 ARRAY_SIZE
在谷歌V8 项目.
// The expression ARRAY_SIZE(a) is a compile-time constant of type
// size_t which represents the number of elements of the given
// array. You should only use ARRAY_SIZE on statically allocated
// arrays.
#define ARRAY_SIZE(a)
((sizeof(a) / sizeof(*(a))) /
static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
我的问题是后半部分:static_cast.我想到的一件事是:由于后半部分将始终计算为 1,其类型为 size_t,因此整个表达式将提升为 size_t.
My question is the latter part: static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))). One thing in my mind is the following: Since the latter part will always evaluates to 1, which is of type size_t, the whole expression will be promoted to size_t.
如果这个假设是正确的,那么还有一个问题:既然 sizeof 运算符的返回类型是 size_t,那么为什么需要这样的提升呢?以这种方式定义宏有什么好处?
If this assumption is correct, then there comes another question: since the return type of sizeof operator is size_t, why is such a promotion necessary? What's the benefit of defining a macro in this way?
推荐答案
后面的部分将始终计算为 1,即 size_t 类型,
latter part will always evaluates to 1, which is of type size_t,
理想情况下,后面的部分将评估为 bool(即 true/false)并使用 static_cast<>,它被转换为size_t.
Ideally the later part will evaluate to bool (i.e. true/false) and using static_cast<>, it's converted to size_t.
为什么需要这样的推广?定义一个有什么好处这样宏?
why such promotion is necessary? What's the benefit of defining a macro in this way?
我不知道这是否是定义宏的理想方式.但是,我在评论中找到了一个灵感://您应该只在静态分配的数组上使用 ARRAY_SIZE.
I don't know if this is ideal way to define a macro. However, one inspiration I find is in the comments: //You should only use ARRAY_SIZE on statically allocated arrays.
假设,如果有人传递一个指针,那么 struct(如果它大于指针大小)数据类型将失败.
Suppose, if someone passes a pointer then it would fail for the struct (if it's greater than pointer size) data types.
struct S { int i,j,k,l };
S *p = new S[10];
ARRAY_SIZE(p); // compile time failure !
[注意:如前所述,此技术可能不会对 int*、char* 显示任何错误.]
[Note: This technique may not show any error for int*, char* as said.]
相关文章