问题描述
在谷歌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(!(sizeof(a) % sizeof(*(a)))))
.我想到的一件事是:由于后半部分将始终计算为 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?
推荐答案
理想情况下,后面的部分将评估为 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
.
为什么需要这样的推广?定义一个有什么好处这样宏?
我不知道这是否是定义宏的理想方式.但是,我在评论中找到了一个灵感://您应该只在静态分配的数组上使用 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.]
这篇关于宏定义 ARRAY_SIZE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!