2013-11-23 3 views
0

Мне нужно проверить, не указана ли указатель void в 8 байтах, поэтому я проверяю, равна ли его длине 4 или 8. Я знаю только эти значения, я могу использовать _W64, просто любопытный чек.проверить размер указателя void в макросе c

#include <windows.h> 
#if (sizeof(void *) == 4) 
#define IS64 0 
#elif (sizeof(void *) == 8) 
#define IS64 1 
#else 
#error "Pointer size 4 nor 8, make changes in app" 
#endif 
int APIENTRY WinMain(HINSTANCE hInstance, 
     HINSTANCE hPrevInstance, 
     LPTSTR lpCmdLine, 
     int  cmdShow) 
{ 
    if (IS64) MessageBoxA(NULL, "is 64", "info", MB_OK); 
    else MessageBoxA(NULL, "is 32", "info", MB_OK); 
    return(0); 
} 

Этот код не работает, я получил ошибку app.c(2) : fatal error C1017: invalid integer constant expression

Я изменил макрос:

#if (sizeof(void *) == sizeof(int32_t)) 
#define IS64 0 
#elif (sizeof(void *) == sizeof(int64_t)) 
#define IS64 1 
#else 
#error "Pointer size 4 nor 8, make changes in app" 
#endif 

ту же ошибку. Какие-нибудь обходные пути здесь?

+1

'#define IS64 (sizeof (void *) == 8)' – WhozCraig

+0

@WhozCraig - это хороший макрос и хороший обходной путь. Я подозреваю, что он хотел условное выражение препроцессора, что это недопустимо, поскольку sizeof не может быть явно понят препроцессором. – Jekyll

+0

@Jekyll конечно, и, следовательно, это в комментариях, а не в ответе. Я не понимаю, почему он не просто использует предопределенные MS-файлы, но я уверен, что есть причина. О, подожди, сказал он, было просто любопытно, почему это не сработало. nm = P – WhozCraig

ответ

1

Использование оператора sizeof недействительно в макросах, поскольку оно не является частью cpp, это часть языка C. Но вы все равно можете поставить эту проверку во время компиляции без дополнительных затрат, потому что хороший компилятор удалит такой мертвый код. Фактически, это рекомендуется по некоторому стандарту кодирования.

EDIT: Чтобы оставить этот тест компиляции вам нужно что-то вроде этого:

int IS64; 
if (sizeof(void *) == 4) 
IS64 = 0; 
else if (sizeof(void *) == 8) 
IS64 = 1; 
else 
printf ("Pointer size 4 nor 8, make changes in app\n"); 

, а затем:

if (IS64) MessageBoxA(NULL, "is 64", "info", MB_OK); 
    else MessageBoxA(NULL, "is 32", "info", MB_OK); 

Хороший компилятор будет удалить мертвый код, т.е. возвращаемое значение sizeof() (если оно не используется в VLA) всегда является постоянным значением и зависит от того, является ли оно 4 или 8 и компилятор, который вы делаете 4 == 4 или 8 == 8 или 8 == 4 будет выполнять DCE, и у вас будет только MessageBoxA() в вашей программе без проверки if (IS64).

+0

Это только отчасти верно. Препроцессор предоставляет * типичные макросы *, которые * * как-то знакомы с языком. –

+0

Вы говорите о C11 '_Generic()'? Раньше я не знал. –

+0

Мой код также не работает, если я скажу компилятору, чтобы он скомпилировал его как c-код. – BalticMusicFan

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