2010-12-11 91 views

Répondre

4

Ceci?

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

+3

qui serait dangereux lorsqu'un est un pointeur (par rapport à un tableau). la macro _countof est sûre. – Uri

5

Je ne suis pas au courant d'un pour GCC, mais Linux utilise GCC's __builtin_types_compatible_p builtin pour rendre leur ARRAY_SIZE() macro plus sûr (il va provoquer une rupture de construction si elle est appliquée à un pointeur):

/* &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)) 

note: Je pense que la macro BUILD_BUG_ON_ZERO() a un nom trompeur (il provoque un échec de construction si l'expression est pas zéro et retourne 0 autre):

/* 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); })) 

Je pense que le nom de cette macro vient de la regarder en deux parties: BUILD_BUG_ON est ce que la macro fait lorsque l'expression est vraie, et ZERO est la valeur «retournée» par la macro (s'il n'y a pas une construction Pause).

10

en C++ 11, la forme non-macro est:

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

Et extent se trouvent dans l'en-tête type_traits.

Ou si vous voulez regarder un peu plus agréable, l'envelopper dans ceci:

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

Et il devient alors:

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 

Edit: Je viens de remarquer le "C" drapeau plutôt que "C++". Donc, si vous êtes ici pour C, s'il vous plaît veuillez ignorer ce poste. Merci.

+0

Une différence: au moins sur MSVC, std :: extent :: valeur renvoie 0, tandis que _countof renvoie le nombre approprié. – Ash

+0

Également testé sur GCC et cela aussi, renvoie 0. – Ash

+3

Vous devez faire votre countof fonction constexpr, sinon cela ne fonctionnera pas. De plus, il est plus simple de "retourner N". au lieu de "std :: extent < T[ N ] > :: value;". – prgDevelop

2

Vous pouvez utiliser boost::size() à la place:

#include <boost/range.hpp> 

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

Boost est C++, tandis que les questions sont marquées comme C. – tambre

+0

Top a voté réponse est également C++, de même que l'implémentation '_countof' dans MSVC – KindDragon

+1

Je ne considérerais pas une justification de l'affichage d'une réponse pour une autre langue sur une question non étiquetée avec cette langue. – tambre