説明されているようないくつかのケースでは、C ++標準により、コンパイラーは、動作が予測可能である必要なしに、顧客が最も有用であると思う方法で構文を処理することができます。言い換えると、このような構成は「未定義の動作」を呼び出します。ただし、C ++標準では、整形式プログラムが実行を「許可」されている対象に対する管轄を明示的に放棄しているため、そのような構成が「禁止」されることを意味しているわけではありません。C ++標準の公開されたRationaleドキュメントには気づいていませんが、C89が定義するように未定義の動作を説明しているという事実は、意図された意味が似ていることを示唆します。診断する。
何かを処理するための最も効率的な方法は、ダウンストリームコードが気にしない構造の部分を書くことを含み、ダウンストリームコードが気にしないそれらを省略する多くの状況があります。プログラムが構造体のすべてのメンバーを初期化することを要求することは、何も気にしないものも含めて、不必要に効率を妨げます。
さらに、初期化されていないデータを非決定論的な方法で動作させることが最も効率的な状況がいくつかあります。たとえば、次の場合:
struct q { unsigned char dat[256]; } x,y;
void test(unsigned char *arr, int n)
{
q temp;
for (int i=0; i<n; i++)
temp.dat[arr[i]] = i;
x=temp;
y=temp;
}
下流のコードがの要素の値x.dat
またはにy.dat
リストされていないインデックスの値をarr
考慮しない場合、コードは次のように最適化される可能性があります。
void test(unsigned char *arr, int n)
{
q temp;
for (int i=0; i<n; i++)
{
int it = arr[i];
x.dat[index] = i;
y.dat[index] = i;
}
}
プログラマがのすべての要素を明示的に書き込む必要がある場合、効率を向上させることは不可能です。これにはtemp.dat
、ダウンストリームが気にしない要素も含めて、それをコピーする前に記述します。
一方、データ漏洩の可能性を回避することが重要なアプリケーションもあります。このようなアプリケーションでは、ダウンストリームコードがそれを参照するかどうかに関係なく、初期化されていないストレージをコピーする試みをトラップするように装備されたバージョンのコードを用意するか、実装がストレージを保証するように実装すると便利かもしれません内容が漏えいする可能性のあるものは、ゼロ化されるか、機密情報以外のデータで上書きされます。
私が言うことができることから、C ++標準は、これらの動作のいずれも、それを強制することを正当化するために他の動作よりも十分に有用であるとは言いません。皮肉なことに、この仕様の欠如は最適化を容易にすることを目的としている可能性がありますが、プログラマーがあらゆる種類の弱い動作保証を活用できない場合、最適化は無効になります。