c预处理器 - 如果在特定日期之后进行编译则失败

MK.*_*MK. 9 c macros

如果在特定日期之后尝试,我想编译某些文件失败.原因是:我发现了几个Y2K38错误,我现在没有时间修复它们,但是想记下它们,我认为如果编译模块之后失败会很好,说,2020年.(我可能会疯了,但这段代码已经20年了,我怀疑它可能会再存活30年)

nel*_*age 5

使用GCC,您可以执行以下操作:

void __attribute__((error("Whoa. It's the future"))) whoa_the_future();

void check_for_the_future() {
    // "Feb  1 2011"
    const char *now = __DATE__;
    if (now[9] >= '2')
        whoa_the_future();
}
Run Code Online (Sandbox Code Playgroud)

这种方法的工作方式是,error如果在所有GCC的常量折叠,死代码消除和类似的传递运行后,在代码中保留对该函数的任何调用,该属性将告诉GCC生成编译时错误.由于DATE是编译时常量,因此GCC可以if在编译时评估该语句并删除该调用.

至少有一个缺点是这取决于GCC的优化过程,所以它不会起作用 gcc -O0

老实说,你可能最好只是在某处添加运行时检查并快速失败.

  • 到2100年,编译器将自动修复2038个错误. (4认同)
  • @aschepler - 希望到2038年他们能自动修复2038个漏洞. (3认同)

dan*_*n04 5

而不是处理__DATE__宏的笨拙格式,为什么不滚动自己的?

gcc -DTHIS_YEAR=`/bin/date +%Y` yourprogram.c
Run Code Online (Sandbox Code Playgroud)

然后你的代码可以使用像#if THIS_YEAR >= 2020.


Chr*_*utz 5

这是一个可怕的解决方案:

  1. 在项目的通用头文件目录中,运行以下(Python)脚本:

    #!/usr/bin/python
    
    months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    
    cutoff = 2020
    #safety = 2025
    
    for year in range(2011, cutoff):
        for month in months:
            for day in range(1, 32):
                t = open("%s %2d %d" % (month, day, year), "w")
                t.write("\n");
                t.close()
    
    #for year in range(2011, cutoff):
    #    for month in months:
    #        for day in range(1, 32):
    #            t = open("%s %2d %d" % (month, day, year), "w")
    #            t.write("#error \"Too old\"\n");
    #            t.close()
    
    Run Code Online (Sandbox Code Playgroud)

    取消注释已注释掉的行以生成更好的诊断消息.

  2. 在截止日期后需要出错的文件中,使用以下命令:

    #include __DATE__
    
    Run Code Online (Sandbox Code Playgroud)

我敢于在生产代码中使用它.