ARRAYSIZE

最近阅读代码时看到一个很好玩的宏——ARRAYSIZE,定义在winnt.h里。

最终展开之后是这样的:

帮助01020304050607080910111213141516171819202122232425262728 // // RtlpNumberOf is a function that takes a reference to an array of N Ts. // // typedef T array_of_T[N]; // typedef array_of_T &reference_to_array_of_T; // // RtlpNumberOf returns a pointer to an array of N chars. // We could return a reference instead of a pointer but older compilers do not accept that. // // typedef char array_of_char[N]; // typedef array_of_char *pointer_to_array_of_char; // // sizeof(array_of_char) == N // sizeof(*pointer_to_array_of_char) == N // // pointer_to_array_of_char RtlpNumberOf(reference_to_array_of_T); // // We never even call RtlpNumberOf, we just take the size of dereferencing its return type. // We do not even implement RtlpNumberOf, we just decare it. // // Attempts to pass pointers instead of arrays to this macro result in compile time errors. // That is the point. // extern "C++" // templates cannot be declared to have 'C' linkage template <typename T, size_t N> char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N]; #define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A))) #define ARRAYSIZE(A)    RTL_NUMBER_OF_V2(A)

第一个点在于数组的引用
strcpy_s已经有如下这个版本的定义了

帮助12345 templateerrno_t strcpy_s(  char (&strDestination)[size],  const char *strSource ); // C++ only

第一个参数就是数组的引用。模板机制在这里用来帮助获取数组的大小,C里面要想把数组的大小传递给函数只有再加上一个参数来表示数组的大小。而且这种方式是类型安全的,只能传递一个char类型的数组,传递指针都会引发编译错误。

第二个点在于指向数组的指针
char (*p)[20];
char q[20];
p = &q;

此时,p是一个指针,可是它指向的类型是20个char的数组。
因此sizeof(p) == 4, sizeof(*p) == 20, p++将会让p向后移动20个字节。
明白了这2点,ARRAYSIZE宏就容易理解了。正如注释里所说RtlpNumberOf这个函数既没有定义也没有被调用过,其实下面这个模板函数也可以达到效果,但是效率就不如了。

帮助12345 template <typename T, size_t N> size_t RtlpNumberOf( UNALIGNED T (&)[N] ) {     return N; }

 

摘自:http://xiaop.me/archives/date/2008/12

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值