说我有一个不能改变的方法。如果这样的方法发生变化,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
是函数必须保留的已知参考校验和。请注意,我对伪代码采取了相当多的自由,但我希望我能传达我想要做的事情。
答案 0 :(得分:1)
说我有一个不能改变的方法。如果这样的方法发生变化,C ++中是否有一种方法可以创建编译时错误(如果编译时间不可能,则为运行时)?
没有,没有办法(特别是如果你关心行为,而不是源代码)。请记住,两个函数的行为相等是一个不可判定的问题(相当于Halting Problem)。换句话说,equivalence of lambda terms(即两个C ++程序或子程序或函数)不可判定。
您的要求(“不应更改”的功能或方法)定义错误。如果C ++源文件只是重新缩进怎么办?或者某些评论中的拼写错误会被纠正?或者一些局部变量的名称只是改变了?或者出于可读性原因,for
循环被替换为一些等效的while
?或者用更有效的二分法替代一些线性扫描;等....!
也许您可以将该函数放在自己的源文件中,计算一些加密哈希值,并将其放入构建过程中(例如Makefile
make)。
您可以花费数月的时间研究更奇特的方法(例如,定制您的GCC编译器,可能在GCC MELT或某些GCC plugin中有一些扩展名),以便在g++
编译器中进行计算你函数的GIMPLE AST的哈希应该保持不变,等等......)。我不确定这是值得的。
你可以有一些时间戳机器。
在我的许多Makefile
中,我生成了一个__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 '\n\r\f\"\\\\' ; \
echo '";') >> __timestamp.tmp
@(echo -n 'const char bismon_lastgittag[]="'; \
(git describe --abbrev=0 --all || echo '*notag*') \
| tr -d '\n\r\f\"\\\\'; echo '";') >> __timestamp.tmp
@(echo -n 'const char bismon_checksum[]="'; cat bismon.h \
$(BM_HEADERS) $(CSOURCES) | $(MD5SUM) \
| cut -d' ' -f1 | tr -d '\n\r\f\"\\' ; 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
;您也可以同样配置build automation工具。
我有一个不能改变的方法。
请注意,这是社交要求(与代码审核相关),而非软件要求。代码确实发生了变化(您希望technical debt避免code refactoring)。你的团队应该明智地使用一些好的version control software(例如git),你必须以某种方式信任你的同事(一个有恶意的,有能力的开发人员总能做坏事)。
(看起来像XY problem;也许你正在寻求一个纯粹的技术解决社会问题的方法)
我的特定用例是保持向后兼容性,其中一些旧方法(如持久数据反序列化器)不得更改。
通常的方法是在持久化数据中记录使用格式的版本(或签名)。如需灵感,请查看ELF或仅查看XML版本声明(XMLDecl)。
(关于dynamic software updating的论文可能会让你感兴趣)