2010-12-11 23 views

回答

4

This?

#define _countof(a) (sizeof(a)/sizeof(*(a)))

+3

这将是不安全的,当是一个指针(相对于阵列)。宏_countof是安全的。 – Uri 2013-01-07 09:59:55

5

我不知道一个GCC的,但Linux使用GCC's __builtin_types_compatible_p builtin,使他们ARRAY_SIZE()宏更安全(它会导致如果应用于一个指针构建破裂时):

/* &a[0] degrades to a pointer: a different type from an array */ 
#define __must_be_array(a) \ 
BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0]))) 

#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]) + __must_be_array(arr)) 

注意:我认为BUILD_BUG_ON_ZERO()宏有一个令人误解的名称(如果表达式为而不是为零并且返回0,则会导致构建失败):

/* Force a compilation error if condition is true, but also produce a 
    result (of value 0 and type size_t), so the expression can be used 
    e.g. in a structure initializer (or where-ever else comma expressions 
    aren't permitted). */ 
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); })) 

我认为这个宏的命名来自两部分:BUILD_BUG_ON是宏在表达式中的作用,而ZERO是宏返回的值(如果没有构建的话打破)。

10

用C++ 11,非宏形式是:

char arrname[5]; 
size_t count = std::extent< decltype(arrname) >::value; 

extent可以在type_traits报头中找到。

或者,如果你希望它看起来更好一点,在此把它包:

template < typename T, size_t N > 
size_t countof(T (& arr)[ N ]) 
{ 
    return std::extent< T[ N ] >::value; 
} 

然后它变成:

char arrname[5]; 
size_t count = countof(arrname); 

char arrtwo[5][6]; 
size_t count_fst_dim = countof(arrtwo); // 5 
size_t count_snd_dim = countof(arrtwo[0]); // 6 

编辑:我只注意到了 “C”标志而不是“C++”。所以如果你在C这里,请不要理睬这篇文章。谢谢。

+0

一个区别:至少在MSVC上,std :: extent :: value返回0,而_countof返回适当的计数。 – Ash 2013-07-10 01:01:38

+0

也在GCC上测试过它,返回0. – Ash 2013-07-10 01:14:12

+3

你必须让你的countof函数constexpr,否则它将无法工作。而且,“返回N”更简单。而不是“std :: extent < T[ N ] > :: value;”。 – prgDevelop 2014-02-14 09:31:41

2

您可以使用boost::size()代替:

#include <boost/range.hpp> 

int my_array[10]; 
boost::size(my_array); 
+1

Boost是C++,而问题被标记为C. – tambre 2017-09-23 10:41:38

+0

Top voteed答案也是C++,MSVC中的'_countof'实现为 – KindDragon 2017-09-25 17:32:54

+1

我不会考虑在没有用该语言标记的问题上发布另一种语言的答案的理由。 – tambre 2017-09-25 17:35:26