本文介绍了宏定义 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(!(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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 07:27