2009-08-02 1 views
7

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

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

Узнал, что утверждения о времени сборки возможны, благодаря вашему вопросу. Этот метод подробно обсуждается в этой теме: http://stackoverflow.com/questions/174356/ways-to-assert-expressions-at-build-time-in-c – nagul

ответ

14

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

Есть некоторые другие распространенные ошибки, например:

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.

+0

В настоящее время препрозавод не существует. –

+0

@Cole Johnson: Я никогда не вижу, чтобы кто-то полностью опускал препроцессор. Вы знаете какой-либо компилятор C или C++ без предварительного процессора? – mmmmmmmm

+0

Не то, чтобы я знал.Я имел в виду вещи вроде '# pragma' –

3

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

Edit: Как было отмечено в комментариях, SizeOf() является основном рассчитывается во время компиляции. В C99, it can be used at runtime for arrays.

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

+7

sizeof() НЕ является функцией времени исполнения. Это выражение времени компиляции, которое оценивается компилятором во время компиляции (но после времени перед процессором). – mmmmmmmm

+0

Спасибо, не знал об этом. Соответственно обновлено. – nagul

+1

@nagul: Ладно, может быть, не всегда выражение времени компиляции :-) – mmmmmmmm

7

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

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

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

1
char _assert_wchar_t_is_16bit[ sizeof(wchar_t) == 2 ? 1 : -1]; 
3

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

#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1] 
0

Я разработал несколько макросов, которые позволят эффективно использовать sizeof в макроэкономическом состоянии. Они находятся в файле заголовка, который я загрузил here (лицензия 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).

Смежные вопросы