在其他编译器中等同于MSVC的_countof?

Mat*_*ner 28 c arrays macros gcc clang

是否有_countof其他编译器提供的内置等价物,尤其是GCC和Clang?有没有非宏观形式?

Kur*_*son 15

使用C++ 11,非宏形式是:

char arrname[5];
size_t count = std::extent< decltype( arrname ) >::value;
Run Code Online (Sandbox Code Playgroud)

并且extent可以在type_traits标题中找到.

或者,如果您希望它看起来更好一点,请将其包装在:

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

然后它变成:

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
Run Code Online (Sandbox Code Playgroud)

编辑:我刚注意到"C"标志而不是"C++".所以,如果你来这里是C,请好好忽略这篇文章.谢谢.

  • 你必须使你的countof函数constexpr,否则它将无法正常工作.而且,"返回N"更简单.而不是"std :: extent <T [N]> :: value;". (4认同)
  • 好奇“return N”是否是实现模板 countof() 的更简单方法 (2认同)

Mud*_*Mud 6

这个?

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

  • 当a是指针(对阵数组)时,这将是不安全的.宏_countof是安全的. (5认同)
  • @Uri仅在C ++中。“在C语言中,如果数组是指针,则_countof将产生错误的结果。” -https://docs.microsoft.com/zh-CN/previous-versions/visualstudio/visual-studio-2010/ms175773(v=vs.100) (3认同)

Mic*_*urr 6

我不知道有一个用于GCC,但是Linux使用GCC的__builtin_types_compatible_p内置来使它们的ARRAY_SIZE()宏更安全(如果应用于指针,它将导致构建中断):

/* &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))
Run Code Online (Sandbox Code Playgroud)

注意:我认为BUILD_BUG_ON_ZERO()宏具有误导性名称(如果表达式为零则导致构建失败,0否则返回):

/* 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); }))
Run Code Online (Sandbox Code Playgroud)

我认为这个宏的命名来自于它分为两部分: BUILD_BUG_ON当表达式为true时宏是什么,以及宏ZERO返回的值(如果没有构建中断).


Kin*_*gon 5

更新:C ++ 17支持std::size()(在header中定义<iterator>

您可以boost::size()改用:

#include <boost/range.hpp>

int my_array[10];
boost::size(my_array);
Run Code Online (Sandbox Code Playgroud)

  • Boost是C ++,而问题则标记为C。 (3认同)
  • 我不认为在没有用该语言标记的问题上发布另一种语言的答案的理由。 (3认同)
  • 投票最高的答案也是 C++,MSVC 中的 `_countof` 实现也是如此 (2认同)
  • @tambre,那么至少应在问题标题或正文中注明 (2认同)
  • 我只是喜欢人们为最琐碎的单行问题提供 boost 解决方案,完全无视如果有人还没有使用 boost(并且有完全正当的理由不使用它),他们应该拉入 300+ MB图书馆只是为了这一件事。 (2认同)