Czy istnieją jakieś wbudowane odpowiedniki do _countof
dostarczone przez inne kompilatory, w szczególności GCC i Clang? Czy są jakieś formy inne niż makro?Równoważne do _Countof MSVC w innych kompilatorach?
Odpowiedz
To?
#define _countof(a) (sizeof(a)/sizeof(*(a)))
nie jestem świadomy jednej dla GCC, ale Linux używa GCC's __builtin_types_compatible_p
builtin aby ich ARRAY_SIZE()
makro bezpieczniejsze (będzie to powodować przerwy gromadzeniu jeśli zastosowane do wskaźnika):
/* &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))
Uwaga: Myślę, że BUILD_BUG_ON_ZERO()
makro ma mylące nazwy (powoduje awarię gromadzeniu jeśli wyrażenie jest nie zero i zwraca 0
inaczej):
/* 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); }))
Myślę, że nazewnictwo tego makra pochodzi od obejrzenia go w dwóch częściach: BUILD_BUG_ON
to, co robi makro, gdy wyrażenie jest prawdziwe, a ZERO
to wartość "zwrócona" przez makro (jeśli nie ma kompilacji przerwa).
Korzystanie C++ 11, nie-makro forma jest:
char arrname[5];
size_t count = std::extent< decltype(arrname) >::value;
I extent
można znaleźć w nagłówku type_traits
.
Lub jeśli chcesz to wyglądać nieco ładniejszy, zawinąć go w ten sposób:
template < typename T, size_t N >
size_t countof(T (& arr)[ N ])
{
return std::extent< T[ N ] >::value;
}
A potem staje się:
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: Właśnie zauważyłem "C" flagę zamiast "C++". Więc jeśli jesteś tutaj dla C, uprzejmie proszę zignoruj ten post. Dzięki.
Jedna różnica: przynajmniej na MSVC, std :: extent
Testowałem również na GCC i to również zwraca 0. – Ash
Musisz wykonać funkcję countex constexpr, w przeciwnym razie nie zadziała. Ponadto łatwiej jest "zwrócić N;" zamiast "std :: extent < T[ N ] > :: value;". – prgDevelop
Można użyć boost::size() zamiast:
#include <boost/range.hpp>
int my_array[10];
boost::size(my_array);
Zwiększenie to C++, podczas gdy pytania są oznaczone jako C. – tambre
Najlepsza głosowana odpowiedź to także C++, podobnie jak implementacja '_countof' w MSVC – KindDragon
Nie rozważałbym uzasadnienie wysłania odpowiedzi na inny język na pytanie niezaznaczone tym językiem. – tambre
która byłaby niebezpieczna, kiedy to wskaźnik (w porównaniu z tablicy). makro _countof jest bezpieczne. – Uri