質問
C ++では、コンパイルするコードを書くことができますが、得られる多くの方法があります。 未定義の動作(ウィキペディア). 。 C#に似たようなものはありますか?コンパイルするが未定義の動作があるC#でコードを記述できますか?
解決
他の人が言及したように、「安全でない」ブロックのほとんどのものは、実装定義の動作をもたらす可能性があります。安全でないブロックの悪用により、ランタイム自体を構成するコードのバイトを変更することができ、したがってすべての賭けがオフになります。
整数部門のコーナーケースには、実装定義の動作があります。
例外を投げるとそれをキャッチすることは、実装定義の動作を引き起こします - プロセスを終了し、デバッガーを開始します。
C#には、実装が決定された動作を持つコードを排出することを余儀なくされる他の多くの状況があります。たとえば、この状況:
http://blogs.msdn.com/ericlippert/archive/2006/04/06/odious-ambiguous-overloads-part-two.aspx
ただし、安全で行儀の良いC#プログラムに実装定義の動作がある状況は非常にまれなことです。
他のヒント
はい!安全な文脈でもあります! (まあ、それは少なくとも未定義であると定義されている実装です)
これがマレク・サファーとヴサドフからのものです ロスリンの問題。C#とCLIの間には不一致があります。 bool
.
C#は、1種類しかないと信じています true
, 、そして一種の false
.
Cliはそれを信じています false
0を含むバイトであり、他のすべての値は true
.
この矛盾は、私たちがC#を強制することができることを意味します いくつか (わずかに)興味深い もの もの:
//non-standard bool
//We're setting a bool's value to a byte value of 5.
var a = new bool[1];
Buffer.SetByte(a, 0, 5);
//non-standard bool
//We're setting a bool's value to a byte value of 10.
var b = new bool[1];
Buffer.SetByte(b, 0, 10);
//Both are true.
Console.WriteLine(a[0]);
Console.WriteLine(b[0]);
//But they are not the same true.
Console.WriteLine(a[0] == b[0]);
上記の出力:
true
true
false
興味深いことに、デバッガーは同意しません(真実を異なって評価する必要がありますか?)
とにかく、C#チームが来たと思われる結論はISです(強調追加):
つまり、言語は標準以外のブールについてはまったく無関心になります。特定の実装(CILのMS C#のように)は、非標準のブールの存在を認め、その動作を次のように指定します 未定義
Wikiを見ると、未定義の動作が発生する状況は許可されていないか、C#で例外を投げかけません。
しかし、安全でないコードでは、ポインターなどを使用できるようにするため、未定義の動作は可能だと思います。
編集:私は正しいようです: http://msdn.microsoft.com/en-us/library/aa66471%28vs.71%29.aspx
C#の未定義の動作の例があります
ECMA-334ドキュメント(p。473)によると:
安全でない修飾子の発生を含まないプログラムは、未定義の動作を示すことができません。
最悪の場合に「実装定義」を促進することは、エリック・リパートの答えを参照してください。
多くのサブプログラムには、次のように要約できる要件があります。
有効なデータが与えられたら、有効な出力を生成します。
無効な入力が与えられた場合でも、核ミサイルを発射したり、時間と因果関係の法則を否定したりしないでください。
Javaおよび.NET言語の主要な設計目標の1つは、コードが「安全でない」とマークされている特定を使用しない限り、上記の2番目の制約を満たすために一般的に特別な努力が必要ではないことです[ごみ収集といくつかの動作を満たす必要はありません。 Finalize
時間/因果関係の観点からは少し奇妙になる可能性があります。これらは、それらの完全な取り消しではなく、通常の因果関係の規則の例外として説明できます。その状況は、Cの状況とは大きく異なります。多くの種類のデータ依存エラー(整数のオーバーフローなど)により、オーバーフローを避けるために必要な仮定を作成するなど、コンパイラーが任意の方法で動作する可能性があります。ハイパーモダンC哲学で奨励されている真に恐ろしい種類の未定義の行動は、「安全でない」ブロック以外のC#または他の.NET言語には存在しません。
まさにウィキの意味ではありませんが、私の頭に浮かぶ最も明白な例は、単にスレッドコードを書くことだと思いますが、それはどんな言語でもそうです。
一般的に私はノーと言うでしょう。
初期化する前に自動変数を使用します。
すべての変数を初期化する必要があります。そうでない場合は、例外が発生します。
ゼロによる分割
例外がスローされます。
範囲外の配列のインデックス付け
例外がスローされます
Aequitarum Custosが指摘したように、安全でないコードを使用できます。繰り返しますが、これは実際にはC#ではありません。C#環境から明示的にオプトアウトしています。