問題タブ [language-lawyer]
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++ - POD プリインクリメントの結果を「読み取っても、未定義の動作は発生しません。なぜ正確に?
これはばかげた質問です。:)
[編集: バカかどうかは別として、これは C++ 特有の質問であることが判明しました。UPDATE_2 を参照してください]
次があるとします。
2行目で何が起こるか(注、数字は単なるマーカーであり、正確な順序を指定するものではありません):
(4) の「書き込み」は、(3) の「読み取り」の前に「順序付け」され、その間にシーケンス ポイントがないため、副作用が (3) の前に発生することは保証されません (「 (4) 自体の中で "read" を実行しますが、"write" の前に順序付けされるため、UB は生成されません)。
では、上記のエラーはどこにあるのでしょうか?
[更新、熟練していないシーケンスポイント弁護士を対象としています:)]
つまり、問題は次のとおりです。
左辺値から右辺値への変換 (「読み取り」) またはインクリメント (「書き込み」) の副作用が最初に発生するかどうかという「競合」があるようです。
C では、JTC1/SC22/WG14 N926 "Sequence Point Analysis" *に従ってUB が得られます (たとえば、EXAMPLE 5: を参照)。
int x,y; (x=y) + x; // UB
(3) と (4) は単一の[(3): "a" の左辺値を取り、それを右辺値に変換し、その右辺値を返す] 「書き込み」の副作用は、次のシーケンス ポイントの前のどこかまで遅延します
_
(*) これは、C99 標準委員会のメンバーによって与えられた、このトピックに関する最も明確な体系的根拠のように見えます。
[UPDATE_2]
教訓: C のルールで C++ を判断しないでください :))。N926 (C99 のやり方をきれいに説明している) が、左辺値を生成する事前増分のトピックについて「十分に明確ではない」理由を疑問に思いました。
C の場合でも、標準を解釈するだけでもかなり難しく、C++ 言語標準ははるかに複雑でわかりにくいため、C++ に同様の理論的根拠を構築するにはどうすればよいかという疑問が生じます。
[UPDATE_3]
"The undefinedness of a common expression." で、いくつかの関連トピック (少なくとも後半) を扱った議論があります。さらに、この問題はここで委員会の人々によって議論されています(「222. シーケンスポイントと左辺値を返す演算子」を参照してください)。
python - Python のインスタンス メソッドに名前付き引数として self を渡すことができないのはなぜですか?
これは機能します:
そして、これは機能します:
そして、これでも機能します:
しかし、これが Python 2.x で機能しないのはなぜでしょうか?
これにより、特殊なケースの処理が必要になるため、メタプログラミングがより困難になります。Python のセマンティクスによって何らかの形で必要なのか、それとも単なる実装のアーティファクトなのか、興味があります。
c++ - nullインスタンスでメンバー関数を呼び出すと、未定義の動作が発生するのはいつですか?
次のコードを検討してください。
nullポインタに(b)
対応するメンバーがないため、クラッシュすることが予想されます。x
実際には、ポインタが使用されることはない(a)
ため、クラッシュしません。this
nullの逆参照は常に未定義の動作であると言われるため(b)
、this
ポインタ((*this).x = 5;
)を逆参照し、 this
nullであるため、プログラムは未定義の動作に入ります。
(a)
未定義の動作になりますか?両方の関数(およびx
)が静的である場合はどうでしょうか?
c++ - C++ 標準のどの文言で static_cast が許可されるか(malloc(N)); 働く?
5.2.9 静的キャストの文言を理解している限り、void*
-to-to-object-pointer 変換の結果が許可されるのはvoid*
、最初に逆変換の結果であった場合のみです。
void
標準全体を通して、ポインターの表現や、ポインターの表現と同じポインターの表現などへの参照がたくさんありますが、任意のポインターをキャストするとポインターが生成char
されると明示的に述べているようには見えません。void
メモリ内の同じ場所に、異なる型で、オブジェクトの実際の型に戻らないタイプのパニングが未定義であるのと同じように。
そのため、適切なメモリのアドレスなどをmalloc
明確に返しますが、私が見た限りでは、実際にそれを移植可能に利用する方法はないようです。
c - 構造体内で未定義の型を参照することはどのように合法ですか?
別の質問への回答の一環として、このようなコードに出くわしました。これは、gcc が問題なくコンパイルします。
これは、自分自身を指す型 (リンクされたリストなど) を構築するために常に使用してきた手段ですが、自己参照を使用できるように構造体に名前を付ける必要があると常に考えていました。xyz *z
つまり、その時点では typedef がまだ完成していないため、構造内で使用できませんでした。
ただし、この特定のサンプルでは構造体に名前が付けられておらず、それでもコンパイルされます。構造体と typedef の名前が同じだったため、上記のコードを自動的に変換するコンパイラで黒魔術が行われていると最初は思っていました。
しかし、この小さな美しさも同様に機能します。
ここで何が欠けていますか?struct NOTHING_LIKE_xyz
どこにもタイプが定義されていないため、これは明らかな違反のようです。
ポインターから実際の型に変更すると、予想されるエラーが発生します。
また、 を削除するとstruct
、エラー ( parse error before "NOTHING ...
) が表示されます。
これはISO Cで許可されていますか?
更新: Astruct NOSUCHTYPE *variable;
もコンパイルされるため、有効と思われる構造内だけではありません。c99 標準には、構造体ポインターに対してこの寛大さを許すものは何も見つかりません。
c++ - 配列へのbraced-init-listの割り当ては正しいですか?
標準では、5.17/9 の下で
- スカラーへの代入 [...] -
ユーザー定義の代入演算子によって定義された代入 [..]
GCC 4.5.1-pre9999 では、これをコンパイルできます (-std=gnu++0x ではなく、-std=c++0x を使用)
そしてそれは印刷し123456
ます。ここでGCCは正しいですか?
fortran - Fortran: integer*4 vs integer(4) vs integer(kind=4)
私は Fortran を学ぼうとしていますが、多くの異なる定義が渡されているのを見て、それらが同じことを達成しようとしているのだろうかと思っています。次の違いは何ですか?
integer*4
integer(4)
integer(kind=4)
c++ - typedef と単純でない型指定子
このコードが無効なのはなぜですか?
次のコードは有効です
?
私の理解によると、コードは形式が正しくunsigned int
ありません。"simple type specifier"
よくわかりませんが。
Standard
最初のコードを無効にする(および2番目のコードを有効にする)の関連セクションを誰かが指摘できますか?
編集
Johannes Schaubの答えは正しいように見えましたが、ポイントまで(彼は答えを削除しました)、James Curranの答えの正確さと正確さを受け入れました。
c++ - C ++の別の名前空間に列挙型をインポートするにはどうすればよいですか?
名前空間に列挙型があり、別の名前空間にあるかのように使用したいと思います。直感的には、「using」または「typedef」を使用してこれを実現できると思いましたが、どちらも実際には機能しません。それを証明するコードスニペット。GCCとSunCCでテストされています。
問題は、列挙型自体はインポートされますが、その要素はインポートされないことです。残念ながら、他の多くの既存のコードを壊さずに、元の列挙型を変更して、追加のダミーの名前空間またはクラスに含めることはできません。私が考えることができる最善の解決策は、列挙型を手動で再現することです。
しかし、それはDRYの原則に違反しています。もっと良い方法はありますか?
c++ - 衒学者:ソースファイルとは何ですか?ヘッダーとは何ですか?
この質問の目的のために、私は標準に準拠したC ++のみに関心があり、CまたはC ++ 0xには関心がなく、実装固有の詳細には関心がありません。
との違いについては、時々質問#include ""
があり#include <>
ます。議論は通常、2つの違いに要約されます。
- 特定の実装では、2つの形式の異なるパスを検索することがよくあります。これはプラットフォーム固有であり、この質問の範囲には含まれません。
- 標準
#include <>
では、「ヘッダー」用であるのに対し#include ""
、「ソースファイル」用であるとされています。関連するリファレンスは次のとおりです。
ISO / IEC 14882:2003(E)
16.2ソースファイルのインクルード[cpp.include]
1 #includeディレクティブは、実装で処理できるヘッダーまたはソースファイルを識別します。
2フォームの前処理ディレクティブ
実装で定義された場所のシーケンスで、<と>の区切り文字の間の指定されたシーケンスによって一意に識別されるヘッダーを検索し、そのディレクティブをヘッダーのコンテンツ全体に置き換えます。場所の指定方法または識別されるヘッダーの方法は、実装によって定義されます。3フォームの前処理ディレクティブ
b>そのディレクティブを、「区切り文字」の間の指定されたシーケンスで識別されるソースファイル のコンテンツ全体に置き換えます。指定されたソースファイルは、実装定義の方法で検索されます。この検索がサポートされていない場合、または検索が失敗した場合、ディレクティブは読み取りのように再処理されます 元のディレクティブからの同一の含まれるシーケンス(存在する場合は>文字を含む)。
(上記の引用の強調は私のものです。)この違いの意味は、標準が「ヘッダー」と「ソースファイル」を区別することを意図しているようですが、ドキュメントはこれらの用語のいずれかまたはそれらの違いをどこにも定義していません。
ヘッダーやソースファイルについても言及されている場所は他にほとんどありません。いくつか:
158)ヘッダーは必ずしもソースファイルである必要はなく、ヘッダー名で区切られたシーケンスは必ずしも有効なソースファイル名ではありません(16.2)。
ヘッダーがファイルシステムに存在しない可能性があることを示唆しているようですが、ソースファイルにも存在するとは言えません。
2字句規則[lex]
1プログラムのテキストは、この国際規格ではソースファイルと呼ばれる単位で保持されます。前処理ディレクティブを介してインクルードされたすべてのヘッダー(17.4.1.2)およびソースファイル(16.2)
#include
と、条件付きインクルード(16.1)前処理ディレクティブのいずれかによってスキップされたソース行を除いたソースファイルは、変換ユニットと呼ばれます。[注:C++プログラムをすべて同時に翻訳する必要はありません。]
これは私が定義に最も近いものであり、ヘッダーが「プログラムのテキスト」ではないことを意味しているようです。しかし、あなた#include
がヘッダーなら、それはプログラムのテキストの一部になりませんか?これは少し誤解を招く恐れがあります。
では、ヘッダーとは何ですか?ソースファイルとは何ですか?