問題タブ [undefined-behavior]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - このシナリオでアクセス違反をキャッチするのは安全ですか?
これは一般的に非常に悪い考えであり、安全に実行できるのはプログラムを終了することだけであることを示唆するSOについても含めて、私は多くのことを読みました。これが本当かどうかはわかりません。
これは、mallocに大量の割り当てを渡すプーリングメモリアロケータ用です。pool_free()中に、ポインターがプールに属しているか、mallocで割り当てられているかを確認する必要があります。アドレスを最も近い1MBの境界に切り捨てることにより、プール内のメモリブロックの先頭へのポインタを取得します。mallocが使用されている場合は未定義です。最初のケースでは、メモリのブロックがプールに属していることを簡単に確認できますが、そうでない場合は、この確認に失敗するか、アクセス違反が発生します(これは読み取り専用プロセスであることに注意してください)。これをSEH(Windows)でキャッチしたり、シグナル(POSIX)を処理して、検証の失敗として処理したりすることはできませんか?(つまり、これはmallocが使用された場合にのみ可能であるため、ptrをfree()に渡します)
編集:人々は上記のORを見逃しているようです。ポインターがmallocで割り当てられた場合、アクセス違反が発生することはないと思いますが、これは考えられる結果の1つです。ブロックの先頭(1MB境界)へのポインタを使用する手順は、マジックナンバーを確認してから、メモリプールへのポインタをたどり、ブロックへの前述のポインタが実際に含まれていることを確認することです。これらの読み取り専用ステップのいずれかがアクセス違反を生成した場合、個々のステップが失敗した場合と同じように確実に検証に失敗します。
ruby - なぜ Ruby では || 1 は、`a` が未定義の場合にエラーをスローしますが、a = a || 1 しませんか?
a
が未定義の場合a || 1
、エラーがスローされますが、スローされa = a || 1
ません。ちょっと矛盾してない?
c++ - ゼロによる除算: 未定義の動作または実装が C および/または C++ で定義されていますか?
ゼロ除算に関して、標準は次のように述べています。
C99 6.5.5p5 - / 演算子の結果は、第 1 オペランドを第 2 オペランドで割った商です。% 演算子の結果は剰余です。どちらの操作でも、2 番目のオペランドの値がゼロの場合、動作は未定義です。
C++03 5.6.4 - 二項 / 演算子は商を生成し、二項 % 演算子は最初の式を 2 番目の式で割った剰余を生成します。/ または % の 2 番目のオペランドがゼロの場合、動作は未定義です。
上記の段落を額面どおりに受け取るとしたら、答えは明らかに両方の言語の未定義の動作です。ただし、C99 標準をさらに下に見ると、矛盾しているように見える次の段落が表示されます(1)。
C99 7.12p4 - マクロ INFINITY は、利用可能な場合、正または符号なし無限大を表す float 型の定数式に展開されます。
標準には、未定義の動作が (潜在的に) 矛盾するステートメントに取って代わられない、ある種の黄金律がありますか? それを除けば、実装で INFINITY マクロが定義されている場合、ゼロによる除算はそのように定義されていると結論付けるのは不合理ではないと思います。ただし、実装でそのようなマクロが定義されていない場合、動作は未定義です。
2 つの言語のそれぞれについて、この問題に関するコンセンサスが (あるとすれば) どのようなものなのか、興味があります。int i = 1 / 0
整数除算と浮動小数点除算について話している場合、答えは変わりfloat i = 1.0 / 0.0
ますか?
注 (1)<cmath>
C++03 標準では、INFINITY マクロを含むライブラリについて言及されています。
c++ - 未定義の動作を見つける方法
仕様全体を記憶する以外に、プログラムが C++ (または C) で未定義の動作をしているかどうかを知る方法はありますか?
私が尋ねる理由は、プログラムがデバッグで動作しているが、未定義の動作が原因でリリースされていないという多くのケースに気付いたからです。少なくとも UB を特定するのに役立つツールがあればいいのですが、問題が発生する可能性があることはわかっています。
c++ - C++ での名前空間のエイリアシング
namespace std
に宣言/定義を追加すると、未定義の動作が発生することは広く知られています。この規則の唯一の例外は、テンプレートの特殊化です。
次の「ハック」はどうですか?
標準に関する限り、これは本当に明確に定義されていますか? この場合、もちろん、実際には何も追加していませんnamespace std
。これをテストしたすべてのコンパイラは、これを喜んで飲み込んでいるようです。
誰かが「どうしてそんなことをするの?」に似たコメントをする前に。-- これは私の好奇心を満たすためです...
c++ - 配列の 1 つ後ろの要素のアドレスを取得できますか?
最後の行は有効か無効か?
visual-c++ - これは ATL::CComVariant の自己割り当てバグですか?
ATL::CComVariant
には少数の代入演算子があります。実装で私が目にするのは、代入演算子が を受け入れるかLPCOLESTR
、最初のアクションが を呼び出すことです。IUnknown*
IDispatch*
Clear()
同じオブジェクトのメンバー変数が渡されるような方法で演算子が呼び出された場合
(同じ効果を持つより愚かな方法があります)Clear()
は、カプセル化されたオブジェクトを解放し、現在ぶら下がっているポインターに対するその後のすべてのアクションは、未定義の動作をもたらします。
私は正しいですか、それとも何か誤解していますか?
c - char 配列を使用した C での未定義の動作 (?)
私が試したとき
とstrlen(bla) < i < 32
、bla[i]
いつものよう\0
です。しかし、これは実際には未定義の動作ではなく、回避する必要がありますか?
c++ - デストラクタを明示的に呼び出すと、ここで未定義動作が発生しますか?
私の意見では、次のコード(C ++の質問から)はUBにつながるはずですが、そうではないようです。コードは次のとおりです。
答えは次のとおりです。
私はフォームc++のFAQライトで、デストラクタを明示的に呼び出すべきではないことを学びました。デストラクタを明示的に呼び出した後、オブジェクトを削除する必要があると思います。プログラムは、終了時に自動的にデストラクタを再度呼び出します。これはUBである必要があります。しかし、g ++で試してみたところ、上記の答えと同じ結果が得られました。
クラスが単純すぎる(新規/削除が含まれない)ためですか?それとも、この場合はUBではありませんか?
c++ - 式の動作:定義済みまたは未定義?
私は次のコードを持っています
私の友人は、それExpression A
は明確に定義された行動をしていると私に言いましたが、彼が正しいかどうかはわかりません。
彼によると、機能はその間にf()
導入するsequence point
ため、動作は明確に定義されています。
誰かが明確にしてください。
PS:実用的な目的でそのようなコードを書くべきではないことを私は知っています。それはただ学ぶことを目的としています。:)