静态断言,源代码不会在C 中发生变化

Static assert that source code does not change in C++

本文关键字:变化 断言 源代码 静态      更新时间:2023-10-16

说我有一种不得更改的方法。如果这种方法更改,则C 中有没有办法创建编译时间错误(如果不可能编译时间,则运行时)?

这种方法有多种用途(考虑不希望新手同事更改的贴心线程或安全问题)。我的特殊用例是维护向后兼容性,而某些旧方法(例如持续数据避难所)不得更改。

我想象以下内容:

static_assert(chechsumOfBelowFunction() != 0x123,
  "You changed the method! We can't do this because...")
std::string getRelaseDateForVersion3()
{
    // This should never change because "Version 3" was
    // only released once!
    return "2014-Jan-01";
}

checksumOfBelowFunction()在编译时间计算函数(最好是跨平台)的校验和其他独特表示,而0x123是该函数必须保留的已知参考校验和。请注意,我对伪代码进行了很多或自由,但我希望我能传达自己想做的事情。

说我有一种不能改变的方法。如果这种方法更改,则C 中有没有办法创建编译时间错误(如果不可能编译时间,则运行时)?

,没有办法(尤其是当您关心行为而不是源代码时)。请记住,两个函数的行为平等是一个不可避免的问题(相当于停止问题)。换句话说,lambda术语的等效性(即两个C 程序或子程序或功能)是不可否认的

和您的要求("不应更改"的函数或方法)是不确定的。如果C 源文件刚刚重新指出怎么办?还是某些评论中的错别字已得到纠正?还是某些局部变量的名称已更改?还是出于可读性原因,for环路被一些等效的while替换?或一些线性扫描被更有效的二分法方法所取代;等....!

也许您可以将该函数放在其自己的源文件中,计算其中的一些加密哈希,然后将其放在您的构建过程中(例如,您的Makefile用于Make)。

您可以花几个月的时间来进行更精美的方法(例如,自定义GCC编译器,也许在GCC融化或某些GCC插件中进行了一些扩展,以计算您的g++编译器内部的功能中的gimple ast,应该留下同样的等等...)。我不确定是否值得付出努力。


您可能有一些时间戳机械。

在我的许多Makefile -S中,我生成了一个__timestamp.c文件,例如喜欢:

__timestamp.c: Makefile
    @(date +'const char bismon_timestamp[]="%c";';  
     date +'%n const unsigned long bismon_timelong=%sL;' > __timestamp.tmp)
    @(echo -n 'const char bismon_lastgitcommit[]="' ; 
       git log --format=oneline --abbrev=12 --abbrev-commit -q  
         | head -1 | tr -d 'nrf"' ; 
       echo '";') >> __timestamp.tmp
    @(echo -n 'const char bismon_lastgittag[]="'; 
          (git describe --abbrev=0 --all || echo '*notag*') 
          | tr -d 'nrf"'; echo '";') >> __timestamp.tmp
    @(echo -n 'const char bismon_checksum[]="'; cat bismon.h 
      $(BM_HEADERS) $(CSOURCES) | $(MD5SUM) 
     | cut -d' ' -f1 | tr -d 'nrf"' ; echo '";') >> __timestamp.tmp
    @(echo -n 'const char bismon_directory[]="'; 
       /bin/pwd | tr -d 'n\"' ; echo '";') >> __timestamp.tmp
    @(echo -n 'const char bismon_makefile[]="'; 
      echo -n  $(realpath $(lastword $(MAKEFILE_LIST))); 
      echo '";') >> __timestamp.tmp
    @mv __timestamp.tmp __timestamp.c

然后我在可执行文件中链接 __timestamp.o;您也可以配置构建自动化工具。


我有一种不得更改的方法。

请注意,这是A social 要求(与代码评论有关),而不是软件。代码确实会更改(您希望通过重构来避免技术债务)。您的团队应明智地使用一些良好的版本控制软件(例如GIT),您必须以某种方式相信您的同事(恶意胜任的开发人员总是可以做坏事)。

(看起来像XY问题;也许您正在寻求纯技术解决方案)

我的特殊用例是维护向后兼容性,在某些旧方法(例如持续数据避免序列化)的情况下,不得更改。

通常的方法是在使用格式的持久数据a 版本(或签名)中记录。为了了解精灵或简单的XML版本声明(xmldecl)。

(有关动态软件更新的论文可能会让您感兴趣)