33

§5.3.1 単項演算子、セクション 3

単項 & 演算子の結果は、そのオペランドへのポインターです。オペランドは、左辺値または修飾 ID でなければなりません。

この文脈で「あるべき」とは正確にはどういう意味ですか?一時的なアドレスを取るのはエラーだということですか?g++ は警告のみを表示するのに対し、comeau は次のプログラムのコンパイルを拒否するため、私はただ疑問に思っていました。

#include <string>

int main()
{
    &std::string("test");
}

g++警告:taking address of temporary

コモーエラー: _expression must be an lvalue or a function designator

Microsoft コンパイラまたは他のコンパイラを持っていて、このプログラムをテストできる人はいますか?

4

7 に答える 7

34

標準語の「shall」という言葉は、厳格な要件を意味します。そうです、コードの形式が正しくありません (エラーです)。これは、アドレス演算子を非左辺値に適用しようとするためです。

ただし、ここでの問題は、一時的なアドレスを取得しようとすることではありません。問題は、非 lvalueのアドレスを取得することです。一時オブジェクトは、一時オブジェクトを生成するか一時オブジェクトへのアクセスを提供する式に応じて、左辺値または非左辺値にすることができます。あなたの場合std::string("test")、非参照型にキャストされた機能的なスタイルがあり、定義により非左辺値が生成されます。したがって、エラー。

一時オブジェクトのアドレスを取得したい場合は、これを行うことで制限を回避できます。たとえば、

const std::string &r = std::string("test");
&r; // this expression produces address of a temporary

結果のポインターは、一時が存在する限り有効なままです。一時オブジェクトのアドレスを合法的に取得する方法は他にもあります。あなたの特定の方法がたまたま違法であるというだけです。

于 2010-02-17T15:29:21.360 に答える
6

「しなければならない」という言葉が C++ 標準で使用されている場合、それは「死の苦痛を負わなければならない」という意味です。実装がこれに従わない場合、それは欠陥があります。

于 2010-02-17T12:56:11.240 に答える
3

非推奨の /Ze (拡張機能が有効) オプションを使用して MSVC で許可されます。以前のバージョンの MSVC では許可されていました。すべての警告を有効にして診断を生成します。

警告 C4238: 非標準の拡張子が使用されています: クラスの右辺値が左辺値として使用されています。

/Za オプションを使用しない場合 (ANSI 互換性を強制する)、次のようになります。

エラー C2102: '&' には左辺値が必要です

于 2010-02-17T13:03:56.977 に答える
1

C++ 標準は、実際には適合 C++ 実装の要件です。適合実装が受け入れなければならないコードと、適合実装が診断を提供しなければならないコードを区別するために書かれています。

したがって、この特定のケースでは、右辺値のアドレスが取得された場合、適合コンパイラは診断を提供する必要があります。両方のコンパイラが対応しているため、この点で準拠しています。

標準は、特定の入力が診断を引き起こす場合、実行可能ファイルの生成を禁止していません。つまり、警告は有効な診断です。

于 2010-02-17T15:19:31.943 に答える
1

&std::string("test");関数呼び出しの戻り値のアドレスを要求しています (この関数が ctor であるという事実は無関係として無視します)。何かに割り当てるまで、アドレスはありませんでした。したがって、それはエラーです。

于 2010-02-17T13:05:03.567 に答える
0

私は標準の専門家ではありませんが、間違いのように思えます。g++ は、実際にはエラーである場合にのみ警告を出すことがよくあります。

于 2010-02-17T12:58:07.043 に答える