我想以#if预定义变量的浮点(或字符串)值为条件。
正如我所见,如果预定义变量的值是整数,则#if效果很好。但是,如果它是浮点数或字符串,则 if 无法按预期工作。
例如:
#define _VER_ = 103
#if _VER_ == 103
//Do somthing
#endif
Run Code Online (Sandbox Code Playgroud)
上面的代码按预期工作,#if根据_VER_值变为活动/不活动。但是,如果_VER_将该值设置为1.0.3或 则"1.0.3"不会#if按预期工作。
例如:
#define _VER_ = 1.0.3
#if _VER_ == 1.0.3
//Do somthing
#endif
Run Code Online (Sandbox Code Playgroud)
或这个:
#define _VER_ = "1.0.3"
#if _VER_ == "1.0.3"
//Do somthing
#endif
Run Code Online (Sandbox Code Playgroud)
两个代码示例均未按预期工作,无论值#if如何,它们都保持不活动状态_VER_。
如何使其正常工作?
预处理器根本无法进行字符串比较,并且#if标准也不支持指令中的浮点值。但即使他们比较浮点数,由于舍入问题始终很关键(请记住,您甚至无法准确地表示许多像 0.1 这样的简单数字,因为它们在二进制中是周期性的),请参见例如此处或此处,因此您无法比较也可以安全地浮点(很可能这就是不支持它们的原因......)。
不过,您可以做的是拥有三个不同的整数值:
\n#define MAJOR 1\n#define MINOR 0\n#define REVISION 3\nRun Code Online (Sandbox Code Playgroud)\n现在您可以分别对这些单个值进行比较,例如:
\n#if MAJOR > 1 || MAJOR == 1 && MINOR > 0\n// anything after 1.0.x \nRun Code Online (Sandbox Code Playgroud)\n您还可以做的就是通过适当移动这些值将它们组合成一个整数值,例如
\n#define VERSION MAKE_VERSION(MAJOR, MINOR, REVISION)\n#define MAKE_VERSION(X, Y, Z) MAKE_VERSION_(X, Y, Z)\n// intermediate step necessary to resolve the version parts correctly\n#define MAKE_VERSION_(X, Y, Z) (X ## lu << 16 | Y ## lu << 8 | Z ## lu)\nRun Code Online (Sandbox Code Playgroud)\n添加lu后缀:long标准保证足够大,以便移位 16 位将适合该类型(这不能保证int!)。您可以尝试使用其他偏移量以使结果适合 int,然后省略后缀(例如移位 8 或 12 而不是 16)或允许更多子版本(例如移位 20 而不是 16)。
乘以 10000 和 100 也能达到目的,并产生更多人类可读的版本号(至少以十进制表示)。
\n最后,您可以通过另一个宏创建版本字符串:
\n#define VERSION_STRING MAKE_VERSION(MAJOR, MINOR, REVISION)\n#define MAKE_VERSION(X, Y, Z) MAKE_VERSION_(X, Y, Z)\n// intermediate step needed for correct stringification\n#define MAKE_VERSION_(X, Y, Z) #X "." #Y "." #Z\nRun Code Online (Sandbox Code Playgroud)\n边注:
\n#define _VER_ = 103\nRun Code Online (Sandbox Code Playgroud)\n显然是错误的,原因有二:
\n=) 将包含在您使用它的任何地方的文本替换中(因此#if _VER_ == 103将扩展为#if = 103 == 103)。| 归档时间: |
|
| 查看次数: |
167 次 |
| 最近记录: |