如何从 #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
块的内容不是像 define
s.
这样的预处理器语句时才有效
你可以通过一点预处理器魔法来让它工作。由于预处理器应用宏的方式,您有时可以使用多个宏级别进行一些修改。 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);
我想使用以下预处理器定义:
[第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
块的内容不是像 define
s.
你可以通过一点预处理器魔法来让它工作。由于预处理器应用宏的方式,您有时可以使用多个宏级别进行一些修改。 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);