2010-12-11 5 views

Respuesta

4

Esto?

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

+3

que sería peligroso cuando a es un puntero (frente a matriz). el macro _countof es seguro. – Uri

5

No estoy al tanto de uno por GCC, sino que Linux utiliza GCC's __builtin_types_compatible_p builtin para hacer su ARRAY_SIZE() macro más seguro (que va a causar una ruptura de compilación si se aplica a un puntero):

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

Nota: creo que el BUILD_BUG_ON_ZERO() macro tiene un nombre engañoso (que causa una falla de generación si la expresión es no cero y vuelve 0 lo contrario):

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

creo que la nomenclatura para esta macro viene de mirarlo en dos partes: BUILD_BUG_ON es lo que hace la macro cuando la expresión es verdadera, y ZERO es el valor 'devuelto' por la macro (si no hay una acumulación descanso).

10

Usando 11 C++, la forma no macro es:

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

Y extent se pueden encontrar en la cabecera type_traits.

O si usted quiere que se vea un poco más agradable, lo envuelve en esto:

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

Y entonces se convierte en:

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 

Editar: me he dado cuenta de la "C" bandera en lugar de "C++". Entonces, si estás aquí por C, por favor amablemente ignora esta publicación. Gracias.

+0

Una diferencia: al menos en MSVC, std :: extent :: value devuelve 0, mientras _countof devuelve el conteo apropiado. – Ash

+0

También lo probó en GCC y eso también devuelve 0. – Ash

+3

Tiene que hacer su recuento de constexpr de función, de lo contrario no funcionará. Además, es más simple "devolver N"; en lugar de "std :: extent < T[ N ] > :: value;". – prgDevelop

2

Se puede utilizar en lugar boost::size():

#include <boost/range.hpp> 

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

Boost es C++, mientras que las preguntas se etiquetan como C. – tambre

+0

La respuesta más votada también es C++, al igual que la implementación '_countof' en MSVC – KindDragon

+1

No lo consideraría que una justificación de publicar una respuesta para otro idioma en una pregunta no etiquetada con ese idioma. – tambre