我需要检查void指针是否适合8个字节,所以我检查它的长度是4还是8.我知道这些值只是,我可以使用_W64
,只是一个好奇的检查。
#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
同样的错误。这里有变通方法吗?
答案 0 :(得分:1)
使用sizeof
运算符在宏中无效,因为它不是cpp的一部分,它是C语言的一部分。但您仍然可以在编译时进行此检查而无需额外成本,因为良好的编译器将删除这样的死代码。事实上,它建议采用一些编码标准。
编辑:要将此测试留给编译,您需要这样的内容:
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)
检查。
答案 1 :(得分:1)
GCC 附带了一堆预处理程序定义;
为解决此特定问题,它提供了__SIZEOF_POINTER__
,其值根据架构而为8或4。
我不是 MS编译器的专家,但我想它们提供了等效的定义;
快速搜索参数(源:https://docs.microsoft.com/it-it/cpp/preprocessor/predefined-macros?view=vs-2019)会显示以下内容:
_M_AMD64 定义为针对x64处理器的编译的整数文字值100。否则,未定义。
_M_ARM 定义为面向ARM处理器的编译的整数文字值7。否则,未定义。
_M_ARM_ARMV7VE 在为目标ARM处理器的编译设置了/ arch:ARMv7VE编译器选项时定义为1。除此以外, 未定义。
_M_ARM_FP 定义为整数文字值,指示为ARM处理器目标设置了哪个/ arch编译器选项。除此以外, 未定义。
_M_ARM64 为面向64位ARM处理器的编译定义为1。否则,未定义。
使用这些信息,您可以为定义分配一个值。