JavaScript には (C に似た) 未定義の動作がありますか、それとも仕様によって完全に明確に定義されており、決定論的ですか?
実装のバグと仕様の相違を破棄していることに注意してください。Math.random()
やのようなものも破棄してDate.now()
います。
JavaScript の仕様によって動作が完全に決定されておらず、「未定義の動作」をしている JavaScript コードはありますか?
JavaScript には (C に似た) 未定義の動作がありますか、それとも仕様によって完全に明確に定義されており、決定論的ですか?
実装のバグと仕様の相違を破棄していることに注意してください。Math.random()
やのようなものも破棄してDate.now()
います。
JavaScript の仕様によって動作が完全に決定されておらず、「未定義の動作」をしている JavaScript コードはありますか?
仕様には、実装に明示的に任されていることがたくさんあります。特にホストオブジェクトに関しては、多くの癖があります。ホストオブジェクトとは関係のない例:
グローバルオブジェクトの[[Prototype]]および[[Class]]内部プロパティの値は、実装に依存します。
15.1.2.2 parseInt(string、radix)
[有効数字が多すぎる場合]mathIntは、基数R表記のZで表される数学的整数値の実装に依存する近似値である可能性があります。
15.3.4.2Function.prototype.toString
関数の実装に依存する表現が返されます。
ほぼすべての日付解析/文字列アルゴリズムは実装に依存します。これにはtoLocaleString
、、、およびコンストラクターtoString
が含まれます。parse
Date
15.4.4.11 Array.prototype.sort(comparefn) -おそらく最良の例:
comparefnが未定義ではなく、この配列の要素の一貫した比較関数でない場合、ソートの動作は実装定義です。
[…]protoがnullでなく、以下のすべての条件が満たされるような整数jが存在する場合、ソートの動作は実装によって定義されます。
- objはスパースです(15.4)
- 0≤j<len
objがスパースであり、次の条件のいずれかが真である場合、ソートの動作も実装によって定義されます。
- objの[[Extensible]]内部プロパティはfalseです。
- 名前がlen未満の非負の整数であるobjの配列インデックスプロパティは、[[Configurable]]属性がfalseであるデータプロパティです。
ソートの動作は、名前がlen未満の非負の整数であるobjの配列インデックスプロパティがアクセサプロパティであるか、[[Writable]]属性がfalseであるデータプロパティである場合にも実装によって定義されます。
そして最も前向きに:
実装に依存する一連の呼び出しを実行します[…]
15.5.4.9 String.prototype.localeCompare(that)
2つの文字列は、実装定義の方法で比較されます
15.5.4.11 String.prototype.replace [置換シンボルでは、数がグループの数より大きい場合]、結果は実装定義です。
ここにリストするのをやめます。仕様を検索できます。他の注目すべき場所は、toLocaleString
メソッド、またはメソッドによって返される実装依存の近似Math
である可能性があります。
ECMAScript言語仕様の引用(私の強調)の例はほとんど見つかりませんでした。
一部の実装では、外部コードがさまざまなNot-a-Number値の違いを検出できる場合がありますが、そのような動作は実装に依存します。ECMAScriptコードでは、すべてのNaN値は互いに区別できません。
toFixedメソッドが複数の引数を指定して呼び出された場合、動作は未定義です(15節を参照)。
toExponentialメソッドが複数の引数を指定して呼び出された場合、動作は未定義です(15節を参照)。
toPrecisionメソッドが複数の引数を指定して呼び出された場合、動作は未定義です(15節を参照)。
UTC関数が2つ未満の引数で呼び出された場合、動作は実装に依存します。
見つけた
Array.sort(compareFunction);
compareFunctionが適切に動作しない場合(つまり、同じ入力に対して一貫した結果を返す場合)。
仕様から:
comparefnが未定義ではなく、この配列の要素の一貫した比較関数ではない場合(以下を参照)、ソートの動作は実装によって定義されます。
入力に応答して C スタイルの未定義の動作を呼び出すプログラムは、信頼できない入力での使用には適していません。ECMAScript 仕様が正確な動作を指定していない状況は数多くありますが、C コンパイラが Undefined Behavior で持っている時間と因果関係の法則を否定する自由を実装に与えていません。