私は、バージョン管理システム (VCS) とは異なる 3 つのタイプの競合を区別したいと考えています。
- 原文
- 構文上の
- セマンティック
テキストの競合は、マージまたは更新プロセスによって検出されるものです。これは、システムによってフラグが立てられます。結果のコミットは、競合が解決されるまで VCS によって許可されません。
VCS は構文上の競合にフラグを立てませんが、結果はコンパイルされません。したがって、これは少し注意深いプログラマーでも理解できるはずです。(単純な例としては、Leftによる変数の名前変更と、その変数を使用してRightによるいくつかの行の追加が考えられます。マージにはおそらく未解決のシンボルが含まれます。あるいは、変数の隠蔽によるセマンティックコンフリクトが発生する可能性があります。)
最後に、セマンティックコンフリクトは VCS によってフラグが立てられず、結果はコンパイルされますが、コードの実行に問題がある可能性があります。軽度の場合、誤った結果が生成されます。深刻なケースでは、クラッシュが発生する可能性があります。これらであっても、コード レビューまたは単体テストを通じて、非常に注意深いプログラマーがコミットする前に検出する必要があります。
セマンティック コンフリクトの私の例では SVN (Subversion) と C++ を使用していますが、これらの選択は質問の本質とはあまり関係がありません。
ベースコードは次のとおりです。
int i = 0;
int odds = 0;
while (i < 10)
{
if ((i & 1) != 0)
{
odds *= 10;
odds += i;
}
// next
++ i;
}
assert (odds == 13579)
左 ( L
) と右 ( R
) の変更は次のとおりです。
Leftの「最適化」(ループ変数が取る値の変更):
int i = 1; // L
int odds = 0;
while (i < 10)
{
if ((i & 1) != 0)
{
odds *= 10;
odds += i;
}
// next
i += 2; // L
}
assert (odds == 13579)
右の「最適化」(ループ変数の使用方法の変更):
int i = 0;
int odds = 0;
while (i < 5) // R
{
odds *= 10;
odds += 2 * i + 1; // R
// next
++ i;
}
assert (odds == 13579)
これはマージまたは更新の結果であり、SVN (VCS の正しい動作) によって検出されないため、テキストの競合ではありません。コンパイルされるため、構文上の競合ではないことに注意してください。
int i = 1; // L
int odds = 0;
while (i < 5) // R
{
odds *= 10;
odds += 2 * i + 1; // R
// next
i += 2; // L
}
assert (odds == 13579)
は37 でassert
あるため失敗します。odds
だから私の質問は次のとおりです。これより簡単な例はありますか?コンパイルされた実行可能ファイルに新しいクラッシュが発生する簡単な例はありますか?
二次的な質問として、実際のコードでこれに遭遇したケースはありますか? 繰り返しになりますが、簡単な例は特に歓迎されます。