¿Equivalentes a _countof de MSVC en otros compiladores?

3 minutos de lectura

avatar de usuario
carpintero mate

¿Existen equivalentes incorporados a _countof proporcionada por otros compiladores, en particular GCC y Clang? ¿Hay alguna forma que no sea macro?

avatar de usuario
kurt hutchinson

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

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

Y extent se puede encontrar en el type_traits encabezamiento.

O si quieres que se vea un poco mejor, envuélvelo en esto:

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

Y luego 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: Acabo de notar la bandera “C” en lugar de “C++”. Entonces, si está aquí por C, ignore amablemente esta publicación. Gracias.

  • Una diferencia: al menos en MSVC, std::extent< decltype( "Character Literal" ) >::value devuelve 0, mientras que _countof devuelve el recuento adecuado.

    – Ceniza

    10 de julio de 2013 a las 1:01


  • También lo probé en GCC y eso también devuelve 0.

    – Ceniza

    10 de julio de 2013 a las 1:14

  • Tienes que hacer que tu función countof sea constexpr, de lo contrario no funcionará. Además, es más sencillo “devolver N;” en lugar de “std::extent< T[ N ] >::valor;”.

    – prgDevelop

    14 de febrero de 2014 a las 9:31

  • Eso es bonito, lo uso con tanta frecuencia que un countof realmente debería ser parte de la biblioteca estándar. @Ash ¿Qué versión? MSVC 2013 devuelve 6 para countof(“Hello”) en lugar de 0.

    –Dwayne Robinson

    2 de noviembre de 2014 a las 9:04

  • curioso si ‘return N’ es una forma más simple de implementar la plantilla countof ()

    – Asistente MT

    11 de enero de 2019 a las 0:08

avatar de usuario
TipoDragón

Actualización: compatibilidad con C++ 17 std::size() (definido en el encabezado <iterator>)

Puedes usar boost::size() en lugar de:

#include <boost/range.hpp>

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

  • Boost es C++, mientras que las preguntas están etiquetadas como C.

    – tamborilear

    23 de septiembre de 2017 a las 10:41

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

    – Dragón amable

    25/09/2017 a las 17:32


  • No lo consideraría una justificación para publicar una respuesta para otro idioma en una pregunta que no esté etiquetada con ese idioma.

    – tamborilear

    25/09/2017 a las 17:35


  • @tambre, entonces se debe anotar en el encabezado o cuerpo de la pregunta al menos

    – Serguéi Krivonos

    18 de febrero de 2019 a las 10:53

  • Me encanta cuando las personas ofrecen soluciones de impulso incluso para las preguntas de una sola línea más triviales, sin tener en cuenta que si alguien aún no está usando impulso (y hay razones perfectamente válidas para no usarlo), se supone que debe obtener más de 300 MB biblioteca sólo por eso.

    – Ígor Levicki

    1 de septiembre de 2020 a las 13:22

avatar de usuario
miguel rebabas

No conozco uno para GCC, pero Linux usa GCC __builtin_types_compatible_p incorporado para hacer su ARRAY_SIZE() macro más seguro (provocará una interrupción 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 la BUILD_BUG_ON_ZERO() macro tiene un nombre engañoso (provoca un error de compilación si la expresión es no cero y vuelve 0 de 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 el nombre de esta macro proviene de mirarla 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 interrupción de compilación).

¿Esta?

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

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad