問題タブ [lvalue-to-rvalue]
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++ - 配列と右辺値
$4.2/1 - 「「N T の配列」型または「T の境界が不明な配列」の左辺値または右辺値は、「T へのポインター」型の右辺値に変換できます。結果は、配列の最初の要素へのポインタです。」
初期化/宣言時以外に配列型の右辺値を取得する方法がわかりません。
c++ - ISOCでの配列の左辺値から右辺値への変換
C ++ ANSI ISO IEC 14882 2003 Annex C.1(668ページ):
変更:条件式、代入式、またはコンマ式の結果は、左辺値である可能性があります
。理論的根拠:C + +はオブジェクト指向言語であり、左辺値に比較的重点を置いています。たとえば、関数は左辺値を返す場合があります。
元の機能への影響:明確に定義された機能のセマンティクスに変更します。左辺値から右辺値への変換に暗黙的に依存する一部のC式では、異なる結果が得られます。例えば、
C++およびCで100を生成しsizeof(char*)
ます
。..。
私はちょうど今日これを読んでいて、数ヶ月前に私の友人が問題を提案したことを思い出しました。それは、C ++でコンパイルされた場合は0を返し、Cでコンパイルされた場合は1を返す関数を書くことでした。これは、Cでは構造体が外部スコープにあるという事実を利用しています。したがって、この新しい情報を考慮して、これはMicrosoft Visual Studio 2008で試した上記の問題の別の解決策になると判断しましたが、CまたはC ++コードとしてコンパイルされているかどうかに関係なく、sizeof(0, arr)
常に4が生成されます。
1.ISO Cとは何ですか?それは現在のC標準ですか?それだけですか(Cは急速に進化していると聞きました)2。これはMicrosoft C ++のバグですか?
TIA
編集:申し訳ありませんが、出力と混同して編集しました:
c++ - 配列型の右辺値の例を思いついたのではないかと思います
C ++03§4.2N°1:
「NTの配列」または「Tの未知の境界の配列」タイプの左辺値または右辺値は、「Tへのポインター」タイプの右辺値に変換できます。結果は、配列の最初の要素へのポインターです。
このステートメントで長い間混乱していたのは、配列型の右辺値が何を意味するのかよく理解していなかったということです。つまり、型が配列で結果が右辺値である式を思い付くことができませんでした。私はこのスレッドを読みました。これは基本的に同じ質問をし、受け入れられた答えは「いいえ、配列型の右辺値はありません」です。これには矛盾があるのではないかと思います。
C ++03§5.2.5N°4:(式E1.E2に関するもの)
E2が非静的データメンバーであり、E1のタイプが「cq1vq1 X」であり、E2のタイプが「cq2」である場合vq2 T」、式は、最初の式で指定されたオブジェクトの指定されたメンバーを指定します。E1が左辺値の場合、E1.E2は左辺値です。
それ以外の場合は右辺値であると思います(E2が参照ではない場合、その場合はでカバーされ§5.2.5 N°3
ます)。したがって...
ここに2つのオプションがあります。オプション1
:正解です、万歳、イェーイ、かっこいいです。この場合、問題は次のとおりです。他の例はありますか?
オプション2:私は間違っています。この場合の質問は次のとおりです。これは標準の欠陥ですか?
1についてはわかりませんが、2については本当に疑問です。なぜなら、関数からポインターへの変換について話すとき、関数型の左辺値だけに言及しているからです(明らかに、そのような右辺値がないことを認めています)。したがって、彼らは配列型の右辺値を考えていた可能性が非常に高いです。
ですから、基本的に私の質問は、配列型の右辺値の例を思いついたかどうかです。そうでない場合は、有効なものを提供してください。
c++ - 左辺値から右辺値への変換について
「単項 & 演算子のオペランドでは、左辺値から右辺値への変換は行われません。」
それが何を意味するのか知っていますか>誰か説明できますか..それをお願いします
元:
c++ - 左辺値から右辺値への変換について、いつ必要ですか?
私はインターネットでかなり多くのことを読んでいますが、多くの人が次のルールについて言及しているようです(しかし、私はそれを標準で見つけることができませんでした)、
加算演算子+(および他のすべての二項演算子)では、両方のオペランドが右辺値である必要があり、結果は右辺値になります。等々..
C ++標準を確認したところ、(3.10 / 2節)と明確に述べられています。
prvalueが期待されるコンテキストでglvalueが表示されると、glvalueはprvalueに変換されます。
(5/9節)、
glvalue式が、そのオペランドのprvalueを期待する演算子のオペランドとして表示される場合は常に、左辺値から右辺値(4.1)、配列からポインター(4.2)、または関数からポインター(4.3)の標準変換が行われます。式をprvalueに変換するために適用されます。
これは、オペランドがprvalueを「期待する」という用語を使用します。ただし、加算演算子、乗算演算子などを調べると、結果はprvalueであるとしか言及されていませんが、オペランドが「期待される」ものについては何も述べられていません。
二項演算子が実際にオペランドがprvalueであることを期待しているかどうかは、次の場合に違いがあります。
bがprvalueであると予想される場合、ここで左辺値から右辺値への変換が行われ、次にprvalue + prvalueが実行され、prvalueが返され、結果のprvalueが左辺値aに割り当てられます。
ただし、bがprvalueである必要がない場合は、lvalue + prvalueになり、結果はprvalueになります。
標準が明示的または暗黙的にさまざまな演算子のルールについて言及している場所を本当に知りたいですか?私はすべての演算子のセクションをチェックし、オペランドと結果が左辺値か右辺値かを標準で明示的に言及している演算子はごくわずかです。ほとんどの演算子の場合、標準では結果のみが記載されており、オペランド要件は記載されていません。
ありがとう。
ところで、定数式に関する標準5.19で、二項演算子がオペランドで左辺値から右辺値への変換を必要とすることを非常に「暗黙的に」暗示している可能性があることを発見しました。詳細については、前の質問を参照してください。
条件式は、評価される可能性のある部分式として次のいずれかが含まれない限り、定数式です(3.2)。
..。
—左辺値から右辺値への変換(4.1)
————定数式で初期化された、先行する初期化を伴う不揮発性constオブジェクトを参照する整数型または列挙型のglvalue
読んでくれてありがとう。
c++ - 左辺値から右辺値への変換
4.1/2から
左辺値によって示されるオブジェクトに含まれる値は、右辺値の結果です。左辺値から右辺値への変換が sizeof (5.3.3) のオペランド内で発生する場合、その演算子はそのオペランドを評価しないため、参照されるオブジェクトに含まれる値はアクセスされません。
好奇心から、if、for、while ステートメントにも同じことが当てはまるのではないかと考えていました。つまり、ステートメントの結果が評価されるときに左辺値が右辺値に変換されるのでしょうか。
c++ - 左辺値から右辺値への変換は行われますか?
C ++標準(4/5)単項&演算子のオペランドでは、左辺値から右辺値への変換は行われません。
例えば:
上記の場合、両方の左辺値p
はありますか?&x
または適切な例は何でしょうか?
編集:
これはどうですか?
このステートメントには変換がないことは確かですが、&operatorがこれにどのように関与するのか混乱していますか?
c++ - C++ での右辺値バインディングの混乱
(ほぼ) 同じように扱われるべきだと思う 3 つの関数呼び出しがありますが、明らかにそうではありません。3 つのうちの 1 つがコンパイルされない理由を理解しようとしています (g++ -std=c++0x)。
この質問は C++0x rvalue references - lvalues-rvalue bindingの行に少し沿っていますが、そこに回答がある場合は、申し訳ありませんが、抽出できませんでした。
私が望むのは、関数 bar() を任意の種類の文字列で呼び出して、それを機能させることです。を定義するだけで十分void barR(const string &x)
ですが、その理由を本当に理解したいです。
3 番目の呼び出しが異なる理由を理解していただき、ありがとうございます。
c - Cで正確にL値からR値への変換が発生する場合
コンパイラが右辺値を予期している状況で左辺値が現れると、コンパイラは左辺値を右辺値に変換します。
T が関数または配列型でない場合、型 T の左辺値 e は右辺値に変換できます。変換後の e の型は T になります。
コンパイラがいつ右辺値を期待するのか、または左辺値に還元される式が右辺値に変換されるような正確な規則とは何かを誰かが知ることができますか? Cで可変サイズの配列を宣言しようとすると
しかし、私がするとき
左辺値から右辺値への変換が発生したときに誰かが詳しく説明してください?? 私の混乱は、最初のケースでは配列添字で左辺値から右辺値への変換が(宣言時に)発生しないが、2番目のケースでは発生することです
c++ - 標準では、間接参照を適用するときにポインター変数の左辺値から右辺値への変換が義務付けられていますか?
TL;DR
次のコードがあるとします。
インダイレクションを適用する前にの左辺値から右辺値への変換が*ptr
必要ですか?ptr
標準は、多くの場所で左辺値から右辺値へのトピックをカバーしていますが、 * 演算子がそのような変換を必要とするかどうかを判断するのに十分な情報を指定していないようです。
詳細
左辺値から右辺値への変換については、N3485のセクション左辺値から4.1
右辺値への変換パラグラフ1で説明されており、次のように述べられています ( employment mine going forward ):
非関数型、非配列型 T の glvalue (3.10) は prvalue に変換できます。glvalue が参照するオブジェクトが T 型のオブジェクトではなく、T から派生した型のオブジェクトでもない場合、またはオブジェクトが初期化されていない場合、この変換を必要とするプログラムの動作は未定義です .[...]
それで*ptr = 0;
、この変換が必要ですか?
4
セクションパラグラフ1に行くと、次のように書かれています。
[...]必要に応じて、式を 必要な変換先の型に変換するために、標準の変換シーケンスが式に適用されます。
では、いつ必要なのですか?セクション5
Expressionsを見ると、左辺値から右辺値への変換はパラグラフ9で言及されています。
glvalue 式が、そのオペランドの prvalue を予期する演算子のオペランドとして現れるときはいつでも、左辺値から右辺値へ (4.1)、配列からポインターへ (4.2)、または関数からポインターへ (4.3) の標準変換が行われます。式を prvalue に変換するために適用されます。[...]
そしてパラグラフ11には次のように書かれています:
一部のコンテキストでは、式はその副作用のためにのみ表示されます。このような式は破棄値式と呼ばれます。[...] 左辺値から右辺値への変換 (4.1) は、式が volatile 修飾された型の左辺値であり、次のいずれかである場合にのみ適用されます [ ...]
どちらの段落もこのコード サンプルには適用されないようで、5.3.1
単項演算子の段落1には次のように書かれています。
単項 * 演算子は間接参照を実行します。それが適用される式は、オブジェクト型へのポインター、または関数型へのポインターであり、結果は、式が指すオブジェクトまたは関数を参照する左辺値になります。式の型が「T へのポインタ」の場合、結果の型は「T」になります。[ 注: 不完全な型 (cv void 以外) へのポインタによる間接化は有効です。このようにして得られた左辺値は、限られた方法で使用できます (たとえば、参照を初期化するため)。この左辺値は、prvalue に変換してはなりません。4.1 を参照してください。—終わりのメモ]
ポインターの値を必要としないようで、ポインターの変換の要件が見当たりません。何か不足していますか?
なぜ私たちは気にするのですか?
インダイレクションを適用する前に左辺値から右辺値への変換が必要なため、初期化されていないポインターの使用は未定義の動作であると主張する他の質問の回答とコメントを見てきました。ptr
例: C++ 標準は、初期化されていないポインターの逆参照が未定義の動作であると正確にどこで言っていますか? はこの議論を行っており、標準の最近のドラフト バージョンのいずれにも示されている内容と議論を一致させることはできません。私はこれを数回見たので、明確にしたいと思いました。
上記のリンクされた質問で指摘したように、未定義の動作に到達する他の方法があるため、未定義の動作の実際の証明はそれほど重要ではありません。