【发布时间】:2015-09-04 16:56:03
【问题描述】:
我正在向我公司的 C++ 项目添加编译时检查,以确保所有开发机器和构建服务器上的第三方库都是最新的。大多数库定义如下内容,例如3.1.4 版:
#define VERSION_MAJOR 3
#define VERSION_MINOR 1
#define VERSION_BUILD 4
使用static_assert 或预处理器指令很容易检查。
现在我正在寻找一个定义单个宏的第三方库:
#define VERSION 3.1.4
如何在编译时验证此类宏的值?
使用 C++11,我可以使用 constexpr 字符串比较函数,并将宏字符串化以检查它:
constexpr bool static_equal(const char * a, const char * b)
{
return (*a == *b) && (*a == '\0' || static_equal(a + 1, b + 1));
}
// stringification functions
#define str(x) #x
#define xstr(x) str(x)
static_assert(static_equal(xstr(VERSION), "3.1.4"), "incorrect version of libwhatever");
但是我们在 Windows 机器上使用 Visual Studio 2013,所以我只能使用它支持的 C++11 子集。很遗憾,不支持 constexpr。
【问题讨论】:
-
维护另一个文件可能更容易按照您希望的方式拆分版本。
-
恐怕你不能在预处理器中。比较仅适用于整数,无法拆分令牌 3.1.4。它需要是某种外部文本处理步骤,或在运行时检查。 VS2015 rc 已经发布,可能支持 constexpr。
-
@RSahu:这是一个第三方库。如果我想向其中添加文件,我必须创建自定义包并强制开发人员使用这些包。这比从原始来源下载,或者对于 Debian 及其衍生版本,
apt-get libwhatever-dev下载要繁琐得多。 -
顺便说一下,
static_assert(xstr(VERSION)[0] == '3', "..")等因“C2057:预期的常量表达式”而失败。 @jxh:这也是我从你的建议中得到的。 -
@PaperBirdMaster:Visual C++ 12.0(又名 2013)和 g++ 4.8.2。只有当我尝试使用宏而不对其进行字符串化时,才会出现此类错误。
标签: c++ c++11 c-preprocessor