首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在编译时检查“#DefineVersion3.1.4”这样的值?

如何在编译时检查“#DefineVersion3.1.4”这样的值?
EN

Stack Overflow用户
提问于 2015-06-18 21:02:42
回答 2查看 2.9K关注 0票数 7

我正在为公司的C++项目添加编译时检查,以确保所有开发机器和构建服务器上的第三方库都是最新的。大多数库为3.1.4版本定义了如下内容:

代码语言:javascript
复制
#define VERSION_MAJOR 3
#define VERSION_MINOR 1
#define VERSION_BUILD 4

使用static_assert或预处理器指令来检查这一点很好,也很容易。

现在,我正在查看一个第三方库,它定义了一个宏,而不是:

代码语言:javascript
复制
#define VERSION 3.1.4

如何在编译时验证这样一个宏的值?

使用C++11,我可以使用一个constexpr字符串比较函数,并对宏进行字符串化检查:

代码语言:javascript
复制
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 2013,所以我只能使用它支持的C++11子集。不幸的是,不支持constexpr

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-19 11:00:14

以下是我现在正在做的事情:

代码语言:javascript
复制
#define str(x) #x
#define xstr(x) str(x)

#include xstr(libwhatever.version.is.VERSION.should.be.3.1.4)

除此之外,我还向项目添加了一个名为libwhatever.version.is.3.1.4.should.be.3.1.4的空文件。因此,如果版本正确,预处理器将成功地包含此文件。否则,它将失败,“无法打开'libwhatever.version.is.2.7.2.should.be.3.1.4',没有这样的文件或目录”。最终重要的是,用一些有意义的信息失败构建。

当然,这种方法不是很灵活;例如,我不能检查最低版本或一系列版本。但对我来说,能够检查确切的值就足够了。

这似乎适用于VisualC++和g++。不过,我不确定这种行为是否完全符合标准。

票数 4
EN

Stack Overflow用户

发布于 2015-06-18 22:34:27

如果您右键单击您的项目->Properties-> Build >预构建事件,您将看到一个显示“命令行”的选项。你可以在这里给另一个程序打个电话。

您可以用C++或您喜欢的任何语言编写另一个程序,检查您的文件(或您想要的任何数量的文件)中的“#DefineVersion3.1.4”。您可以中止您的构建,并在该程序中放置任何您想要的警告。

下面是一个教程:https://dillieodigital.wordpress.com/2012/11/27/quick-tip-aborting-builds-in-visual-studio-based-on-file-contents/

相关阅读:https://msdn.microsoft.com/en-us/library/e85wte0k.aspx

我尝试了很长一段时间来处理预处理器命令,但我无法找到一种只使用预处理器命令的方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30925756

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档