2012-04-01 7 views
8

私は修正したいGCCの警告に直面しています。基本的に私はローカル変数へのポインタをメソッドに渡していますが、私の場合は完全にOKです。私はコンパイラがなぜこれが潜在的な問題であると言われているのか理解していますが、私の場合はこれは問題ありません。一時的な回避策のアドレスが必要です

どうすれば解決できますか?コンパイル時に-fpermissiveを渡すと、将来の問題を見つけることができなくなります。私はこの特定の問題を解決したい、または回避する。

コードがここにあります:

#include <cstdio> 

class Integer{ 
public: 
    Integer(int i){ v = i; }; 
    int value(){ return v; }; 
private: 
    int v; 
}; 

int foo(Integer *i); 

int main() 
{ 
    foo(&Integer(12)); 
} 

int foo(Integer *i) 
{ 
    std::printf("Integer = %d\n", i->value()); 
} 

とコンパイルが私を与える:

$ g++ test-reference.cpp -O test-reference 
test-reference.cpp: In function ‘int main()’: 
test-reference.cpp:15:18: error: taking address of temporary [-fpermissive] 

$ g++ --version 
g++ (Ubuntu/Linaro 4.6.3-1ubuntu3) 4.6.3 
Copyright (C) 2011 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

はEDIT:fooを作るのように(constを使用して

はのconstポインタを取り、value()などをマーキングconst)は同じエラーを返します。

+0

理解するために、マットの応答を参照してください@jalf。私の場合は、関数が呼び出されたときに変数が有効範​​囲にあります。 – elcuco

+1

関数のシグネチャを 'int foo(const Integer & i);'? – jrok

答えて

9
Integer i(12); 
foo(&i); 

これは、あなたが持っている「一時的な問題のアドレスを取る」ことを取り除きます。あなたはローカル変数のアドレスを渡していません(上記のことですが、この場合は確かにOKです)。一時的なアドレスを取得しています。

明らかに、fooがそのポインタを一方向に保持しようとすると、その行の下に問題が発生します。私の意見で

+4

*)に変更できませんか?非常に疑わしい一時的なアドレスを取得しようとしていますか?いいえ、疑わしいものではありません。 12.2/3' *テンポラリオブジェクトは、それらが作成されたポイントを(字句的に)含む完全表現を評価する最後のステップとして破棄されます*。 –

+0

右辺値への参照よりも危険ではありません – Puppy

+0

Ok、 – Mat

3
template<typename T> const T* rvalue_address(const T& in) { 
    return &in; 
} 

は、それだけで法的ようconst T&としてconst T*を取るようにする必要がありますが、この些細な機能は手近に変換を行います。

+2

MSVCが警告を発するコードがあります。 :-) –

4

この場合、GCCが間違っています。あなたの整数は右辺値であり、右辺値のアドレスを取ることは不正です。

§5.3.1 Unary operators, Section 3

The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualified-id.

クランは、この場合にエラーを与える:

error: taking the address of a temporary object of type 'Integer' [-Waddress-of-temporary] 
    foo(&Integer(12)); 
     ^~~~~~~~~~~~ 
+3

GCCは間違っていません。不正であるため、 'error:'でGCCを拒否しました。 '-fpermissive'は基本的に「ええ、いいね、あなたが*意味することを知っている」と言っているGCC拡張です。拡張機能では、非標準の拡張機能なので、好きなような非標準のものを何でもできるようになりました。 – ams

+0

特記のない限り、この規格では不正なプログラムの診断が必要です。警告は診断です。 GCCが*パーミッションを持たない警告*を出すとしても、これは適合上の問題ではないでしょう。 –

関連する問題