C ++ Получение размера типа в макросе условное

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

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

person Fire Lancer    schedule 02.08.2009    source источник
comment
Узнал, что утверждения времени сборки возможны, благодаря вашему вопросу. Этот метод подробно обсуждается в этой теме: stackoverflow.com/questions/174356/   -  person nagul    schedule 03.08.2009


Ответы (6)


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

person EFraim    schedule 02.08.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.

person mmmmmmmm    schedule 02.08.2009
comment
В настоящее время препроцессора иногда не существует. - person Cole Johnson; 16.01.2013
comment
@ Кол Джонсон: Я никогда не видел, чтобы кто-нибудь полностью отказывался от препроцессора. Вы знаете компилятор C или C ++ без препроцессора? - person mmmmmmmm; 16.01.2013
comment
Не то, что я знаю из. Я имел в виду такие вещи, как #pragma - person Cole Johnson; 16.01.2013

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

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

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

person AProgrammer    schedule 02.08.2009

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

#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
person gatorfax    schedule 02.08.2009

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

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

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

person nagul    schedule 02.08.2009
comment
sizeof () НЕ является функцией времени выполнения. Это выражение времени компиляции, которое вычисляется компилятором во время компиляции (но после времени препроцессора). - person mmmmmmmm; 02.08.2009
comment
Спасибо, не знал об этом. Обновил соответственно. - person nagul; 02.08.2009
comment
@nagul: Хорошо, может быть, не всегда выражение времени компиляции :-) - person mmmmmmmm; 02.08.2009

Я разработал несколько макросов, которые позволят вам эффективно использовать 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).

person Matthew K.    schedule 26.05.2017