1

変更してはいけないメソッドがあります。このようなメソッドが変更された場合、コンパイル時エラー(またはコンパイル時間が不可能な場合はランタイム)を作成する方法はありますか?スタティックC++でソースコードが変更されないことをアサートします

このような方法には多くの用途があります(初心者の同僚が変更したくない恐れのあるスレッドやセキュリティの問題を考慮してください)。私の特定のユースケースは、永続データデシリアライザなどの古いメソッドを変更してはならない場合に、下位互換性を維持することです。

私は次のようなものを想像しています:

checksumOfBelowFunction()はコンパイル時にチェックサムや機能(好ましくはクロスプラットフォーム)の他のいくつかのユニークな表現を計算し、 0x123は何の既知の基準チェックサムです
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"; 
} 

関数はそのままでなければなりません。擬似コードを使ってかなり自由にしたことに注意してください。しかし、私がやろうとしていることを伝えたいと思います。

+2

は、独自のファイルに入れて、それのハッシュを計算し、次にファイルハッシュが期待されているものと一致しないことがあれば構築それぞれでチェック! – NathanOliver

+3

メソッドを変更する/変更しない方法はどのように定義しますか?変更してはいけないソースコードだけか、それとも_behavior_ですか?メソッドが変更された別の関数を呼び出すが、それ以外は変更されていない場合はどうなるだろうか?とにかく、これはC++コンパイラよりビルド/バージョン管理システムの仕事に似ています。 –

+0

@Sergey Klevstov、好ましくは動作であるがソースコードが受け入れられる。 – chessofnerd

答えて

1

私は変更してはいけない方法があります。このようなメソッドが変更された場合、コンパイル時エラー(またはコンパイル時間が不可能な場合はランタイム)を作成する方法はありますか?

ませんは、(あなたが行動ではなく、ソースコードを気にする場合は特に)方法はありません。 2つの関数の振る舞いの平等は決めることができない問題です(Halting Problemに相当)。言い換えれば、equivalence of lambda terms(つまり、2つのC++プログラムまたはサブプログラムまたは関数の)は、であり、確定できないです。 (「変更しないでください」という関数やメソッドの)

そして、あなたの要件不明確です。 C++のソースファイルを再インデントしただけの場合はどうなりますか?または、いくつかのコメントのタイプミスが修正されていますか?または、いくつかのローカル変数の名前が単に変更されていますか?または、可読性の理由から、forのループがいくつかの同等物に置き換えられますwhile?または、より効率的な二分法アプローチで置き換えられた線形スキャンもあります。等....!

おそらく、その関数を独自のソースファイルに入れ、その暗号化ハッシュを計算し、ビルドプロセスに入れます(のmakeなど)。

あなたは例えば、あなたのg++コンパイラの内側に滞在する必要があり、あなたの関数のGIMPLE ASTのハッシュを計算するために、おそらくGCC MELTでいくつかの拡張または一部のGCC pluginで、あなたのGCCコンパイラをカスタマイズ(もっと派手なアプローチに仕事の数ヶ月を過ごすことができ同じ、など...)。努力する価値があるかどうかはわかりません。


タイムスタンプの機械を使用できます。

私の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 '\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 debtcode refactoringを避けたい)。あなたのチームは良いものを賢明に使用する必要があります。version control software(たとえばgit)、同僚を何とか信頼しなければなりません(有害な有能な開発者が常に悪いことをする可能性があります)。

(一部XY problemのように見える、おそらくあなたは社会的な問題への純粋に技術的な解決策を模索している)

私の特定のユースケースは、永続的なデータデシリアライザなど、一部の古いメソッドの下位互換性を維持することです変更してはいけません。

通常の方法を用いる形式の永続データバージョン(または署名)に記録することです。インスピレーションを得るには、ELFまたは単にXMLのバージョン宣言(XMLDecl)を参照してください。

dynamic software updatingに関する論文があなたに興味ができます)

関連する問題