2014-10-20 67 views
2

我寻找一种方法来打印一个消息或者如果headerfile过期打破编译运行,是这样的:如何时间条件在编译时

#ifndef somemagic(__DATE__ , "2014") 
#pragma message("ALARM! Someone should check this file!") 
#endif 

或者是有一些新的模板的魔力?

更具体一点。我没有办法改变编译器链。解决方案必须是源代码的一部分。编译器开关甚至在makefile中添加一个定义不是一个选项。

注意: 这是一个技术问题,(恕我直言)值得技术答案。即使不适合所有情况,也有理由说这样的技术可能是方便的。

+0

我不知道它是做了一件好事。如果你真的想用GCC的话,你可以用[MELT](http://gcc-melt.org/) – 2014-10-20 12:32:54

+1

来扩展它。但是我真的觉得你错了。有些人可能希望在2016年9月11日版本中编译源代码,并有正当理由。那时候,你甚至可能不在同一个地方工作! – 2014-10-20 12:46:41

回答

4

您可以使用__DATE__扩展为一个字符串的事实,和字符串是常量表达式:

static_assert(
    (1000 * (__DATE__[7] - '0') 
    + 100 * (__DATE__[8] - '0') 
    + 10 * (__DATE__[9] - '0') 
    +  (__DATE__[10] - '0') 
) != 2014, "It's 2014!" 
); 

Live example

+0

这几乎是一个打击:-)不幸的是VS2013给了我一个错误C2057“预期常量表达式”。没有检查它与铿锵尚未。 – 2014-10-20 12:50:15

+1

@MartinSchlott [与clang合作](http://coliru.stacked-crooked.com/a/b8414ca0e1861c7e)。我怀疑一个VS2013的bug - 他们甚至没有实现'constexpr',所以他们的常规表达式支持也可能受到限制。 – Angew 2014-10-20 13:09:23

+0

看起来你是对的。 static_assert不能评估任何常量字符串。看起来对我来说也是一个错误。 – 2014-10-20 13:48:26

2

最简单的方法可能是将您的制造机器更改为使用例如-DCURRENT_BUILD_YEAR=2014。在Linux上用Makefile您可以添加到它:

CPPFLAGS += -DCURRENT_BUILD_YEAR=$(shell date +%Y) 

然后代码类似

#if CURRENT_BUILD_YEAR > 2014 
#error someone should look at this 
#endif 

然而,正如我评论,这是一个坏事情恕我直言。也许考虑一个版本控制钩可能更相关。

如果你坚持在编译器做的(我认为这是错误的做法),与海湾合作委员会考虑MELT

我相信你想一个社会或管理问题,技术只是解决方案来扩展它,而这总是做错事!

BTW,被Angew's answer启发,你也许对这尝试:

#define CURRENT_BUILD_YEAR (1000 * (__DATE__[7] - '0') \ 
           + 100 * (__DATE__[8] - '0') \ 
           + 10 * (__DATE__[9] - '0') \ 
           +  (__DATE__[10] - '0')) 

,但我想它可能是行不通的,因为我不认为预处理器 预计了解[]指数做在编译时。

+0

“改变你的建造机器”是这里的问题。标题是我无法更改的过程的一部分。我通过这个扩展了我的问题。 – 2014-10-20 12:38:19

+0

我的意思是改变你的Makefile。 – 2014-10-20 12:38:54

+0

不错,但不是。正如你已经提到的那样,预处理器不喜欢#if之后的字符串。试用XCode(Clang)和VS2013。但是,thx。 – 2014-10-20 16:14:25