CPP C++ logo

Наверняка многие «плюсовыми» используют макрос, подобный нижеприведенному:

#define countof(array) (sizeof(array)/sizeof(array[0]))

Он хорош до тех пор, пока в качестве array в него не будет передан указатель на array. Компилятор проглотит и ничего не скажет, а результат будет совсем не тот, которого ожидает разработчик.

Благодаря constexpr появившемуся в C++11 есть возможность сделать безопасный countof.

template <class T, size_t N>
constexpr size_t countof(const T (&)[N]) noexcept {
   return N;
}

Теперь на этапе компиляции произойдет ошибка:

const int values[] = { 42, 76, 16, 11, 31 };
 
void foo(const int v[])
{
   for (size_t i = 0; i < countof(v); ++i) // <-- compilation error!
   {
      bar(v[i]);
   }
}

Версия для C++98 может быть такой:

template <typename T, size_t N>
char (&CountOfHelper(T(&)[N]))[N];
#define countof(x) sizeof(CountOfHelper(x))