如何从 #define 中删除 C-style 转换,以便我可以在预处理器 #if 中使用它?

How do I remove a C-style cast from a #define so I can use it in a preprocessor #if?

我想使用以下预处理器定义:

[第3方header(无法修改)]

#define SWCI_VERSION_MAJOR              (unsigned char) 4
#define SWCI_VERSION_MINOR              (unsigned char) 16

这样比较时:

[我的实现]

#if SWCI_VERSION_MAJOR >= 4 && SWCI_VERSION_MINOR >= 16

然后我得到:

fatal error C1017: invalid integer constant expression

我注意到,如果我在没有 (unsigned char) 的情况下定义它们,指令将被接受,但我无法访问这些定义,所以我想解决这个问题如果可能的话。

只需考虑以下几点

#define SWCI_VERSION_MAJOR              (unsigned char) 4
#define SWCI_VERSION_MINOR              (unsigned char) 16

在以下表达式中使用时:

#if SWCI_VERSION_MAJOR >= 4 && SWCI_VERSION_MINOR >= 16

这将(通过预处理器)转换为以下内容 #if (无符号字符) 4 > 4

问题是这个表达式 (unsigned char) 4 > 4 似乎是错误的。

如果无法更改 3rd 方头文件,您可以尝试使用

#undef SWCI_VERSION_MAJOR

但这在很大程度上取决于#include 顺序

问题是您不能将这些宏用作正确的数字。根据您想在 if 块中执行的操作,您可以考虑将其设为非预处理语句:

// Note the next line does not start with a #
if((unsigned int)SWCI_VERSION_MAJOR >= 4 && (unsigned int)SWCI_VERSION_MINOR >= 16) 
{
  // ...
}

但这当然只有在你在函数内部使用它并且 if 块的内容不是像 defines.

这样的预处理器语句时才有效

你可以通过一点预处理器魔法来让它工作。由于预处理器应用宏的方式,您有时可以使用多个宏级别进行一些修改。 Boost.Preprocessor 利用了这种行为。这段代码利用了这样一个事实,即 (unsigned char) 看起来可以通过在宏名称前添加 X 来进行宏调用,它的计算结果为空,只留下尾随数字。

#define SWCI_VERSION_MAJOR              (unsigned char) 4
#define SWCI_VERSION_MINOR              (unsigned char) 16

#define X(unused)
#define APPLY(x) x

#define MAJOR (APPLY(X SWCI_VERSION_MAJOR))
#define MINOR (APPLY(X SWCI_VERSION_MINOR))

#if MAJOR >= 4 && MINOR >= 16
#error "Version is greater or equal to 4.16"
#endif

有关 #if 评估 true 并打印我添加的 #error 消息的示例,请参阅 https://goo.gl/GOsLDL

也许使用 constexpr 函数可以解决问题?像

constexpr bool version_supported(const char major, const char minor)
{
    return major >= 4 && minor >= 16;
}
constexpr VERSION_SUPPORTED = version_supported(SWCI_VERSION_MAJOR, SWCI_VERSION_MINOR);