C ++ Получение размера типа в макросе условно - PullRequest
8 голосов
/ 02 августа 2009

Есть ли какой-нибудь способ сделать что-то подобное в c ++, кажется, что sizeof не может быть использован по какой-то причине?

#if sizeof(wchar_t) != 2
#error "wchar_t is expected to be a 16 bit type."
#endif

Ответы [ 7 ]

14 голосов
/ 02 августа 2009

Нет, этого нельзя сделать, потому что все макроразложение (# ... вещи) выполняется на этапе предварительной обработки, который ничего не знает о типах кода C ++ и даже не должен ничего знать о языке! Он просто расширяет / проверяет # ... вещи и ничего больше!

Существуют и другие распространенные ошибки, например:

enum XY
{
  MY_CONST = 7,
};

#if MY_CONST == 7
  // This code will NEVER be compiled because the pre-processor does not know anything about your enum!
#endif //

Вы можете получить доступ и использовать только те вещи в #if, которые определены с помощью параметров командной строки для компилятора или через # define.

7 голосов
/ 02 августа 2009

Препроцессор работает, ничего не зная о типах, даже встроенных.

Кстати, вы все еще можете выполнить проверку, используя функцию, подобную static_assert (например, у boost есть одна, в C ++ 0X будет такая).

Редактировать: C99 и C ++ 0X также имеют макросы WCHAR_MIN и WCHAR_MAX в <stdint.h>

4 голосов
/ 02 августа 2009

Я думаю, что такие вещи, как BOOST_STATIC_ASSERT могут помочь.

3 голосов
/ 02 августа 2009

Разве вы не получили бы в основном то, что хотите (ошибка компиляции без необычного сообщения), используя C_ASSERT?

#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
3 голосов
/ 02 августа 2009

sizeof () - это время выполнения функция времени компиляции. Вы не можете назвать это в директиве препроцессора. Не думаю, что вы можете проверить размер wchar_t во время предварительной обработки. (см. Редактирование 2)

Редактировать: Как указано в комментариях, sizeof () , в основном , рассчитывается во время компиляции В C99 может использоваться во время выполнения для массивов .

Редактировать 2: Вы можете делать утверждения во время сборки, используя методы, описанные в этой теме .

1 голос
/ 02 августа 2009
char _assert_wchar_t_is_16bit[ sizeof(wchar_t) == 2 ? 1 : -1];
0 голосов
/ 27 мая 2017

Я разработал несколько макросов, которые позволят вам эффективно использовать sizeof в условии макроса. Они находятся в заголовочном файле, который я загрузил здесь (лицензия MIT).

Это разрешит такой код:

#include <iostream>
#include "SIZEOF_definitions.h"

//You can also use SIZEOF_UINT in place of SIZEOF(unsigned, int)
// and UINT_BIT in place of SIZEOF_BIT(unsigned, int)
#if SIZEOF(unsigned, int) == 4
int func() { return SIZEOF_BIT(unsigned, int); }
#elif SIZEOF(unsigned, int) == 8
int func() { return 2 * SIZEOF_BIT(unsigned, int); }
#endif

int main(int argc, char** argv) {
  std::cout SIZEOF(unsigned, long, int) << " chars, #bits = " << SIZEOF_BIT(unsigned, long, int) << '\n'
         << SIZEOF(unsigned, int)       << " chars, #bits = " << SIZEOF_BIT(unsigned, int)       << '\n'
         << SIZEOF(int)                 << " chars, #bits = " << SIZEOF_BIT(int)                 << '\n';
  std::cout << func() << std::endl;
  return 0;
}

Обратите внимание на запятые в SIZEOF(unsigned, long, int).

...