【问题标题】:How to time condition at compile time如何在编译时计时条件
【发布时间】:2014-10-20 12:29:21
【问题描述】:

如果头文件过期,我正在寻找一种打印消息或中断编译运行的方法,例如:

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

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

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

注意: 这是一个技术问题,(恕我直言)应该得到技术答案。即使可能不适合所有情况,但这种技术可能会派上用场。

【问题讨论】:

  • 我不确定这是一件好事。如果你真的想要 GCC,你可以使用 MELT 来扩展它
  • 但我真的认为你想要这个是错误的。出于正当理由,有人可能希望在 2016 年编译 2014 年 9 月 11 日版本的源代码。到时候,你甚至可能不在同一个地方工作!

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


【解决方案1】:

您可以使用 __DATE__ 扩展为字符串字面量这一事实,而字符串字面量是常量表达式:

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

Live example

【讨论】:

  • 这几乎是一个成功 :-) 不幸的是 VS2013 给了我一个错误 C2057 “预期的常量表达式”。还没有用clang检查过。
  • @MartinSchlott Works with clang。我怀疑是 VS2013 的错误 - 他们甚至还没有实现 constexpr,因此他们的一般常量表达式支持也可能受到限制。
  • 看来你是对的。 static_assert 不能评估任何常量字符串。对我来说显然也是一个错误。
  • @MartinSchlott GCC 和 Clang 彼此一致,并且阅读 C++11 5.19 (Constant expressions),我找不到任何东西来禁止常量表达式中的字符串文字索引。所以我倾向于认为这是一个 VS 不合格问题。
  • Uups。我之前忘记将 Visual Studio 2013 添加到我的评论中。 XCode (Clang) 完美运行。
【解决方案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

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

顺便说一句,受到Angew's answer 的启发,您或许可以尝试:

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

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

【讨论】:

  • “改变你的构建机器”是这里的问题。标头是我无法更改的过程的一部分。我由此扩展了我的问题。
  • 我的意思是改变你的 Makefile。
  • 不错,但不是。正如您已经提到的,预处理器不喜欢#if 之后的字符串。使用 XCode (Clang) 和 VS2013 进行了尝试。但是谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-21
  • 2020-04-01
  • 2012-10-09
  • 1970-01-01
  • 1970-01-01
  • 2012-04-18
  • 1970-01-01
相关资源
最近更新 更多