如何在编译时计时

时间:2014-10-20 12:29:22

标签: templates c++11 gcc visual-studio-2013 clang

如果头文件已过期,我会搜索打印消息或中断编译运行的方法,例如:

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

还是有一些新的模板魔术?

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

注意: 这是一个技术问题,(恕我直言)保留了技术答案。即使可能不适合所有情况,也有理由可以使用这种技术。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

最简单的方法可能是将构建机器更改为使用例如-DCURRENT_BUILD_YEAR=2014。在具有Makefile的Linux上,您可以添加到其中:

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

然后编写类似

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

但是,正如我评论的那样,做恕我直言是件坏事。也许考虑版本控制钩子可能更相关。

如果您坚持在编译器中执行此操作(我认为这是错误的方法),GCC会考虑使用MELT进行扩展

我相信你想要一个技术上唯一的解决社会或管理问题的方法,这总是错误的做法!

BTW,受到Angew's answer的启发,你或许可以尝试:

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

但我想它可能不会起作用,因为我不认为是预处理器 期望在编译时了解[]索引。