2016-04-12 13 views
0

GCC固有のように思われる最も厄介なバインディングの問題が見つかりました。これが私がconst auto&バインディングのルールを理解していないかどうか、または問題がgccコンパイラ固有のバグを指摘しているかどうかはわかりません。対照的に、Visual Studio 2015のC++コンパイラ(この記事の執筆時点では、Update 2)は、この予期しない動作を示しません。私は最小限のlive coliru demoで問題を再現することができました。gcc 4.9.1 constの自動参照へのC++ローカル変数のバインド

自動変数を 'const auto &'にバインドすると問題が発生します。この場合、バインドされた変数const auto&はガーベジにバインドされているようです。これがユーザーエラー(私はルールを理解していない)の場合、誰かがこのような予期しない動作を避けるためにこれをどうすべきかについてのルールを説明することができます。ライブデモではバグが発生した場所の例を示していますが、可能であればconst auto&バインディングを使用する傾向があるため、この問題が他の場所で発生しているかどうかはわかりません。

OptPairWrapper wrapper; 
wrapper.setOptPair(std::make_pair(1,2)); 
const auto& badConstAutoRefBind = wrapper.getOptPair().get(); 
const auto goodConstAutoBind = wrapper.getOptPair().get(); 
// This line prints garbage 
std::cout << badConstAutoRefBind << std::endl; 
// This line predictably prints (1,2) 
std::cout << goodConstAutoBind << std::endl; 

これはautoとは何の関係もありません、次の出力

g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp -lrt && ./a.out 
(32767, 0) 
(1, 2) 
+0

破壊された一時的な値への参照を試みようとしています。値を返すのを恐れないでください。ほとんどの場合、 'const Class var = someMethod();'は、コピー/移動コンストラクタや代入演算子ではなく、コピーelisionによって最適化されます。 –

答えて

6

を生産しました。

const参照は、バインドされている一時的な存続期間を延長することができます。しかし、これだけの作品は、一時的に結合するとき直接

int foo() { ... } 

int main() { 
    int const &i = foo(); // Fine 
} 

をあなたの例では、左辺値参照を返しget()機能、boost::optional<...>さん呼んでいます。この参照は一時的ではないため、生涯は延長されません。

+0

'boost :: optional <...> :: get()'がメンバへの左辺値の参照を返した場合、それはその一時的なオブジェクトのサブオブジェクトなので、完全なオブジェクトの存続期間も延長する必要があります。 –

+1

@PiotrSkotnicki実際には非常に便利ですが、残念ながらそうではありません。そのような 'get()'関数がアウトラインで定義された(テンプレートではない)クラスを考えてみましょう。返されたリファレンスが外部からの一時的な '* this'のサブオブジェクトにバインドされているかどうかを知る方法はありません。 – Quentin

+1

@PiotrSkotnickiをさらに明確にするには、そのメンバの1つを直接命名するだけで、外部オブジェクトの存続期間を延長することができます。 – Quentin

関連する問題