問題タブ [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 - Cでは、ポインタをキャストして逆参照する場合、どちらを最初に行うかは重要ですか?
C ではint
、 、float
、およびこれらへのポインターのような単純なデータ型の両方をキャストできます。
ここで、ある型へのポインターから別の型の値に変換する場合 (たとえば*float
to からint
)、キャストと逆参照の順序は問題ではないと想定していました。つまり、変数の場合float* pf
、 があります(int) *pf == *((int*) pf)
。数学の可換性のようなもの...
しかし、そうではないようです。テストプログラムを書きました:
私のシステムでは、出力は
したがって、ポインターのキャストは、値のキャストとは異なる動作をするようです。
何故ですか?2 番目のバージョンが、私が思っていることをしないのはなぜですか?
そして、これはプラットフォームに依存していますか、それとも未定義の動作を何らかの形で呼び出していますか?
c++ - 未定義の動作とシーケンスポイントがリロードされました
このトピックを次のトピックの続編と考えてください。
前の記事
未定義の動作とシーケンスポイント
この面白くて複雑な表現をもう一度見てみましょう(斜体のフレーズは上記のトピック* smile *から取られています):
これは未定義動作を引き起こすと言います。これを言うとき、私たちは暗黙のうちにタイプが組み込みタイプの1つであると仮定していると思います。i
タイプi
がユーザー定義タイプの場合はどうなりますか?そのタイプは、この投稿の後半で定義されていると言いますIndex
(以下を参照)。それでも未定義動作を呼び出しますか?
はいの場合、なぜですか?それは書くことと同等ではありませんi.operator+=(i.operator++());
か、あるいは構文的に単純 i.add(i.inc());
ですか?または、それらも未定義動作を呼び出しますか?
いいえの場合、なぜですか?結局のところ、オブジェクトは連続するシーケンスポイント間で2回i
変更されます。経験則を思い出してください。式は、連続する「シーケンスポイント間でオブジェクトの値を1回だけ変更できます。また、 が式の場合、undefined-behaviorを呼び出す必要があります。その場合、同等のもので あり、undefined-behaviorを呼び出す必要があります。真実ではないようです!(私が理解している限り)i += ++i
i.operator+=(i.operator++());
i.add(i.inc());
または、そもそも表現i += ++i
ではないですか?もしそうなら、それは何ですか、そして表現の定義は何ですか?
それが式であると同時に、その動作も明確に定義されている場合、式に関連付けられているシーケンスポイントの数は、式に含まれるオペランドのタイプに何らかの形で依存することを意味します。私は(部分的にでも)正しいですか?
ちなみに、この表現はどうですか?
応答でもこれを考慮する必要があります(その動作を確実に知っている場合)。:-)
は
C ++ 03で明確に定義されていますか?結局のところ、これはこれです、
c# - C# での評価の動作と順序
重複の可能性:
C#: 関数評価の順序 (vs C)
コードスニペット:
それらの動作は C# で明確に定義されていますか? C++ では、このようなコードはundefined/unspecified behavior を呼び出します。また、返信で言語仕様の関連セクションを引用してください。
c - 最初の要素を共有する構造体の結合は未定義の動作ですか?
SDL_Eventは、符号なし 8 ビット型と、最初の要素が符号なし 8 ビット型である多くの構造体の和集合です。推奨される使用方法は、共用体の Uint8 要素にアクセスしてイベントの型を判別し、その型に適した要素で共用体にアクセスすることです。
これは明らかに、タイプ識別子用に予約された同じスペースを持つユニオン内のすべてのタイプに依存します。これが事実であると確信できますか、それとも未定義の動作ですか?
編集:タイトルをよりわかりやすいものにしました。
c - + =オペレーターチェーン(UBのダッシュ付き)
セミコロンの前にシーケンスポイントがないことは理解していますが、式で古い値2を使用するための逆参照ポインターのもっともらしい説明はありますか?
それとも、それを未定義の振る舞いとして単純に置くことができますか?
結果:
c - Cでの未定義動作ではなく、ポインタ型間のキャストはいつですか?
Cの初心者として、ポインタをキャストしても実際に問題がないかどうかについて混乱しています。
私が理解しているように、ほとんどすべてのポインター型を他の型にキャストすることができ、コンパイラーはそれを可能にします。例えば:
ただし、一般に、これは未定義の動作を引き起こします(ただし、多くのプラットフォームで機能します)。とはいえ、いくつかの例外があるようです。
void*
自由に行き来できます(?)char*
自由に行き来できます(?)
(少なくとも私はそれをコードで見ました...)。
では、ポインタ型間のキャストはどれがCの未定義動作ではないのでしょうか?
編集:
C標準( http://c0x.coding-guidelines.com/6.3.2.3.htmlのセクション「6.3.2.3ポインター」)を調べてみましたが、についてのビットを除いて、実際には理解していませんでしたvoid*
。
Edit2:
明確にするために:私は明示的に「通常の」ポインターについてのみ質問しています。つまり、関数ポインターについては質問していません。関数ポインタをキャストするためのルールは非常に制限されていることに気づきました。実際のところ、私はすでにそれについて質問しました:-):関数ポインターをキャストし、パラメーターの数を変更するとどうなりますか?
c - sizeof( "" + 0)!= sizeof(char *)バグまたは未定義動作?
次のCプログラム:
1 4 4
LinuxでGCCを使用してコンパイルすると出力されますが、1 1 4
WindowsでMicrosoft VisualC++を使用してコンパイルすると出力されます。GCCの結果は私が期待するものです。MSVCにバグがあるため、またはsizeof(""+0)
定義されていないため、それらは異なりますか?どちらのコンパイラでも、使用する文字列リテラルまたは整数定数に関係なく、動作(つまり、出力される中間値が最初の値と最後の値のどちらに等しいか)は同じです。
ANSI C規格の関連する参照は、6.2.2.1のようです-左辺値と関数指定子:
sizeof演算子のオペランドである場合を除き、「タイプの配列」タイプの左辺値は、配列オブジェクトの初期要素を指し、「タイプへのポインター」タイプの式に変換されます。左辺値。
ただしsizeof(""+0)
、配列/文字列リテラルではnotのオペランドであるため、「Except」は適用され+
ませんsizeof
。
c++ - クラスと構造体の混在
私はclass と struct の違いをよく知っていますが、これが明確に定義されているかどうかを正式に言うのに苦労しています:
これが未定義の動作である場合、誰かが信頼できる (つまり、ISO の章と節) 参照の方向に私を向けることができますか?
これを処理するのに問題のあるコンパイラ ( Carbide 2.7 ) は比較的古く、私が試した他のすべてのコンパイラはこれに完全に満足していますが、明らかにそれは何も証明しません。
私の直感では、これは未定義の動作であるはずでしたが、これを確認するものを見つけることができず、GCC バージョンまたはコモーのどれもそれについて警告していないことに驚いています。
c - 式 x[--i] = y[++i] = z[i++]、どちらが最初に評価されますか?
左辺値の評価が右辺値の評価に先行し、割り当ても値を返す場合、次のうちどれが最初に評価されますか?
注: 左辺値の評価が最初に来る一般的な C ライクな言語。私の教科書から:
C などの一部の言語では、代入は、副作用を生成するだけでなく、その評価によって計算された r 値も返す演算子と見なされます。したがって、Cで書くと:
このようなコマンドの評価は、値 2 を x に代入するだけでなく、値 2 を返します。したがって、C では次のように書くこともできます。
次のように解釈する必要があります。