問題タブ [unspecified-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言語での不特定の動作の例は、関数への引数の評価の順序です。それは左から右または右から左かもしれません、あなたは知らないだけです。foo(c++, c)
これは、評価方法や評価方法に影響しますfoo(++c, c)
。
知らないプログラマーを驚かせる可能性のある他の不特定の動作はありますか?
c - なぜreturnステートメントのないmain関数が値12を返すのですか?
テーブルを印刷するプログラムを作成しました。main関数にreturn構文を含めていませんが、echo $と入力するたびに?12が表示されます。
私のソースコード:
私はreturn12を書いていませんが、それでもプログラムを実行するたびに12を返します。
ありがとう。
c - C99 では、f()+g() は未定義ですか、それとも単に未指定ですか?
f
C99 では、関数とg
干渉の副作用があったとしても、式f() + g()
にシーケンス ポイントが含まれておらず、シーケンス ポイントが含まれている場合でも、その動作は未規定であるf
とg
考えていました: f() が前に呼び出されるg()、または f() の前に g()。
私はもはや確信が持てません。コンパイラが関数をインライン化し (関数が宣言されていなくてもコンパイラが実行することを決定する場合がありますinline
)、命令を並べ替えたらどうなるでしょうか? 上記の2つとは異なる結果が得られるでしょうか? つまり、これは未定義の動作ですか?
これは、私がこのようなことを書こうとしているからではなく、静的アナライザーでそのようなステートメントに最適なラベルを選択するためです。
c - 中間コピーなしで標準 C で memmove を実装する方法は?
私のシステムのmanページから:
void *memmove(void *dst, const void *src, size_t len);
説明
memmove() 関数は、文字列 src から文字列 dst に len バイトをコピーします。
2 つの文字列が重複する場合があります。コピーは常に非破壊的な方法で行われ
ます。
C99 標準から:
6.5.8.5 2 つのポインターを比較すると、結果は、指しているオブジェクトのアドレス空間内の相対位置によって異なります。オブジェクト型または不完全型への 2 つのポインターが両方とも同じオブジェクトを指している場合、または両方が同じ配列オブジェクトの最後の要素の 1 つ後ろを指している場合、それらは等しいと見なされます。指しているオブジェクトが同じ集合体オブジェクトのメンバーである場合、後で宣言された構造体メンバーへのポインターは、構造体で以前に宣言されたメンバーへのポインターよりも大きく、添字値が大きい配列要素へのポインターは、同じ配列の要素へのポインターよりも大きくなります。より低い添字値で。同じ共用体オブジェクトのメンバーへのすべてのポインターは等しいと比較されます。式の場合
P
が配列オブジェクトの要素を指し、式 Q が同じ配列オブジェクトの最後の要素を指している場合、ポインター式はQ+1
より大きいと比較 されますP
。それ以外の場合、動作は undefinedです。
強調は私のものです。
厳密なエイリアシングの問題を軽減するために、引数dst
とsrc
をポインターに変換できますがchar
、同じブロック内を指している場合に正しい順序でコピーを行うために、異なるブロック内を指している可能性のある 2 つのポインターを比較することは可能ですか? ?
明らかな解決策は ですが、 と が異なるブロックを指しているif (src < dst)
場合は未定義です。「未定義」とは、条件が 0 または 1 を返すと想定してはならないことを意味します (これは、標準の語彙では「未指定」と呼ばれていました)。src
dst
代替手段はif ((uintptr_t)src < (uintptr_t)dst)
であり、これは少なくとも指定されていませんが、src < dst
が定義されたときに と同等であることを標準が保証しているかどうかはわかりません(uintptr_t)src < (uintptr_t)dst)
。ポインター比較は、ポインター演算から定義されます。たとえば、加算に関するセクション 6.5.6 を読んだとき、ポインター演算はuintptr_t
演算と逆の方向に進む可能性がp
あるように思えchar*
ます。
これはほんの一例です。一般的に言えば、ポインターを整数に変換するときに保証されることはほとんどないようです。
これはmemmove
、コンパイラと共に提供されているため、純粋に学術的な質問です。実際には、コンパイラの作成者は、未定義のポインタ比較を未指定の動作に単純に促進するか、関連するプラグマを使用してコンパイラにそれらをmemmove
正しくコンパイルさせることができます。たとえば、この実装には次のスニペットがあります。
memmove
標準 C で効率的に実装できないことが本当である場合、標準が未定義の動作で行き過ぎていることの証明として、この例を引き続き使用したいと思います。
c++ - 一般的な未指定の動作をチェックする C++ 用のツールはありますか?
多くの場合、コーディングしている特定のプラットフォームについて仮定を立てます。たとえば、符号付き整数は 2 の補数ストレージを使用する、または(0xFFFFFFFF == -1)
その性質のものを使用します。
これらの種類の最も一般的な違反についてコードベースをチェックできるツールは存在しますか?
(上記の例は符号付き整数に固有のものですが、他のエラー(アライメントやバイトオーダーなど)にも興味があります)
c++ - 未定義、実装定義、未指定の動作のいずれでもない
C++03
$5.3.3/2 - 「最も派生したクラスのサイズはゼロ (1.8) より大きくなければならない」
$1.8/4 - 「それがビット フィールド (9.6) でない限り、最も派生したオブジェクトはゼロ以外のサイズを持ち、1 バイト以上のストレージを占有するものとします。」
私の質問は次のとおりです。
空のクラスのサイズは指定されておらず、実装は定義されていますか? コンパイラのドキュメントで文書化されているはずですか? 私の理解が正しい限り、これらの2つの引用はそれを非常に自由にしています。
c++ - ポインターを異なる配列に比較して同等かどうかは未規定の動作ですか?
等値演算子には、ポインターに対する関係演算子の意味上の制限があります。
== (等しい) および != (等しくない) 演算子には、優先順位が低く、真偽値の結果を除いて、関係演算子と同じ意味制限、変換、および結果の型があります。[C++03 §5.10p2]
また、関係演算子には、ポインターの比較に関する制限があります。
同じ型の 2 つのポインター p と q が、同じオブジェクトのメンバーではない、同じ配列の要素ではない異なるオブジェクト、または異なる関数を指している場合、またはそれらの 1 つだけが null の場合、p<q, p の結果>q、p<=q、および p>=q は指定されていません。[§5.9p2]
これは等値演算子によって「継承」される意味制限ですか?
具体的には、次のとおりです。
(a + 3) < (b + 3) が指定されていないことは明らかですが、(a + 3) == (b + 3) も指定されていませんか?
c++ - C++ コンパイラが異なれば、このコードの結果が異なるのはなぜですか?
私は楽しみと練習のためにいくつかの C++ コードを書いており、言語機能について詳しく学んでいます。再帰関数における静的変数とその振る舞いについてもっと知りたいです。g++ コンパイラでこのコードを試すと、期待される結果が得られます。
しかし、私の友人は Microsoft Visual C++ 6 で同じコード50, 80, 90
をテストしました110, 100, 40
。出力がどのようになるのか理解できません50, 80, 90
...
MSVC の出力が異なるのはなぜですか?
scala - Scala の Map.unzip が返される理由 (Iterable、Iterable)
先日、なぜ scala.collection.Map が unzip メソッドを
このメソッドは Seq のペアではなく Iterable のペアのみを返すため、Iterable はトラバーサルの順序を保証しないため、元のマップのキー/値のペアが返されたシーケンスの一致するインデックスで発生することは保証されません。だから私が持っていたら
、その後呼び出した後
私はで終わるかもしれません
と同様に
この背後にあるストレージ関連の理由は想像できますが (たとえば、HashMaps を考えてみてください)、皆さんはこの動作についてどのように考えているのでしょうか。Map.unzip メソッドのユーザーには、アイテムが同じペアの順序で返されたように見えるかもしれません (そして、これはおそらくほとんどの場合そうであるに違いありません)。ライブラリ ユーザーのコード。
おそらく、その動作は付属の scaladoc でより明示的に表現する必要がありますか?
編集: マップを順序付けられたコレクションと呼んでいないことに注意してください。解凍後のシーケンスの「一致」のみに関心があります。つまり、
すべての i について、(keys(i), values(i)) が元のマッピングの要素であることが保持されます。