Äquivalente zu MSVCs _countof in anderen Compilern?

Lesezeit: 3 Minuten

Benutzer-Avatar
Matt Tischler

Gibt es eingebaute Äquivalente zu _countof bereitgestellt von anderen Compilern, insbesondere GCC und Clang? Gibt es Nicht-Makro-Formulare?

Benutzer-Avatar
Kurt Hutchinson

Bei Verwendung von C++11 lautet die Nicht-Makroform:

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

Und extent finden Sie in der type_traits Header.

Oder wenn Sie möchten, dass es ein bisschen schöner aussieht, wickeln Sie es hier ein:

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

Und dann wird es:

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

Bearbeiten: Ich habe nur das Flag “C” und nicht “C++” bemerkt. Wenn Sie also wegen C hier sind, ignorieren Sie bitte diesen Beitrag. Vielen Dank.

  • Ein Unterschied: zumindest bei MSVC gibt std::extent< decltype( "Character Literal" ) >::value 0 zurück, während _countof die entsprechende Anzahl zurückgibt.

    – Asche

    10. Juli 2013 um 1:01 Uhr


  • Habe es auch auf GCC getestet und auch das gibt 0 zurück.

    – Asche

    10. Juli 2013 um 1:14 Uhr

  • Sie müssen Ihre countof-Funktion constexpr machen, sonst funktioniert es nicht. Außerdem ist es einfacher, “N zurückzugeben”; statt “std::extent< T[ N ] >::wert;”.

    – prgDevelop

    14. Februar 2014 um 9:31 Uhr

  • Das ist hübsch – ich benutze das oft genug, dass a countof sollte wirklich nur Teil der Std-Bibliothek sein. @Ash Welche Version? MSVC 2013 gibt 6 für countof(“Hello”) statt 0 zurück.

    – Dwayne Robinson

    2. November 2014 um 9:04 Uhr

  • neugierig, ob ‘return N’ eine einfachere Möglichkeit ist, Template countof() zu implementieren

    – MT-Assistent

    11. Januar 2019 um 0:08 Uhr

Benutzer-Avatar
KindDragon

Update: C++ 17-Unterstützung std::size() (definiert im Header <iterator>)

Sie können verwenden boost::size() stattdessen:

#include <boost/range.hpp>

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

  • Boost ist C++, während die Fragen als C gekennzeichnet sind.

    – Tambre

    23. September 2017 um 10:41 Uhr

  • Die am häufigsten bewertete Antwort ist auch C++, so wie es ist _countof Implementierung in MSVC

    – KindDragon

    25. September 2017 um 17:32 Uhr


  • Ich würde dies nicht als Rechtfertigung für das Posten einer Antwort für eine andere Sprache auf eine Frage betrachten, die nicht mit dieser Sprache gekennzeichnet ist.

    – Tambre

    25. September 2017 um 17:35 Uhr


  • @tambre, dann sollte es zumindest in der Frageüberschrift oder im Hauptteil vermerkt werden

    – Sergej Krivonos

    18. Februar 2019 um 10:53 Uhr

  • Ich liebe es einfach, wenn Leute Boost-Lösungen für selbst die trivialsten Einzeiler-Fragen anbieten, wobei völlig außer Acht gelassen wird, dass jemand, der Boost nicht bereits verwendet (und es gibt absolut triftige Gründe, ihn nicht zu verwenden), mehr als 300 MB einziehen soll Bibliothek nur für diese eine Sache.

    – Igor Levicki

    1. September 2020 um 13:22 Uhr

Benutzer-Avatar
Michael Burr

Mir ist keine für GCC bekannt, aber Linux verwendet GCCs __builtin_types_compatible_p eingebaut ihre zu machen ARRAY_SIZE() Makro sicherer (es führt zu einem Build Break, wenn es auf einen Zeiger angewendet wird):

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

Hinweis: Ich denke, die BUILD_BUG_ON_ZERO() Das Makro hat einen irreführenden Namen (es verursacht einen Build-Fehler, wenn der Ausdruck so ist nicht Null und kehrt zurück 0 Andernfalls):

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

Ich denke, die Benennung für dieses Makro kommt von der Betrachtung in zwei Teilen: BUILD_BUG_ON ist, was das Makro tut, wenn der Ausdruck wahr ist, und ZERO ist der vom Makro ‘zurückgegebene’ Wert (wenn es keinen Build-Break gibt).

Dies?

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

1384590cookie-checkÄquivalente zu MSVCs _countof in anderen Compilern?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy