Y a-t-il des équivalents internes à _countof
fournis par d'autres compilateurs, en particulier GCC et Clang? Existe-t-il des formulaires non-macro?Equivalents à _countof MSVC dans d'autres compilateurs?
Répondre
Ceci?
#define _countof(a) (sizeof(a)/sizeof(*(a)))
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).
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.
Une différence: au moins sur MSVC, std :: extent
Également testé sur GCC et cela aussi, renvoie 0. – Ash
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
Vous pouvez utiliser boost::size() à la place:
#include <boost/range.hpp>
int my_array[10];
boost::size(my_array);
Boost est C++, tandis que les questions sont marquées comme C. – tambre
Top a voté réponse est également C++, de même que l'implémentation '_countof' dans MSVC – KindDragon
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
qui serait dangereux lorsqu'un est un pointeur (par rapport à un tableau). la macro _countof est sûre. – Uri