2017-06-06 14 views
1

私のプログラムでは、ほとんどすべての日のトラッキングのバグを逃しました。何らかの理由で、std::applyの実装はC++ 11の面で問題がありました。基本的な関数の引数は何とかが空のになっています。良い例はstd::unique_ptrであり、テイクオフ関数の呼び出し後(以下、foo())は、呼び出された関数の本体では常にempty()でした。clang + libC++:make_tupleとmake_sharedを組み合わせると、オブジェクトが早期に破棄されます

私は簡単なテストケースに私のコードをダウン易しく書き直さました:

#include <tuple> 
#include <memory> 
#include <iostream> 

struct Foo 
{ 
    Foo() 
    { 
     std::cout << "Foo()" << std::endl; 
    } 

    ~Foo() 
    { 
     std::cout << "~Foo()" << std::endl; 
    } 
}; 

template <typename ...Args> 
void foo(Args && ...args) 
{ 
    using TupleType = decltype(std::make_tuple(std::forward<Args>(args)...)); 

    std::cout << "Point #1" << std::endl; 

    /// Package arguments to a function. 
    auto && packaged_args = std::make_shared<TupleType>(std::make_tuple(std::forward<Args>(args)...)); 

    std::cout << "Point #2" << std::endl; 
} 

int main() 
{ 
    std::unique_ptr<Foo> foo_var{new Foo}; 

    foo(std::move(foo_var)); 
    return 0; 
} 

と一緒打ち鳴らすでコンパイルした場合は++のlibc(-stdlib =のlibC++)の結果は次のとおりです。

Foo() 
Point #1 
~Foo() 
Point #2 

ライブサンプルcoliru.stacked-crooked.com


結果は明らかに間違っています。 clang, but without libc++してコンパイル、またはgccでコンパイルした場合に予想されるとして、結果がある場合:

Foo() 
Point #1 
Point #2 
~Foo() 

私は打ち鳴らすのlibC++の組み合わせのためのばかばかしい回避策を見つけ、交換してください:

auto && packaged_args = std::make_shared<TupleType>(std::make_tuple(std::forward<Args>(args)...)); 

with:

std::shared_ptr<TupleType> packaged_args{new TupleType(std::make_tuple(std::forward<Args>(args)...))}; 

これは期待どおりに動作します。


coliru.stacked-crooked.com


のライブの例qustionがある:両方のコンパイラが間違ったコードで正しいですかコードは大丈夫です、これはバグがあるように、それは、UBのですか?

+0

今晩、このデバッグを開始します。 PS私たちもバグージャーを持っています:-P – EricWF

+0

ColiruのClangは3.8です。 Wandboxの3.9.1で修正されているようだ。 –

+0

@EricWF、そこに指揮を掲載して申し訳ありません、私は私のプログラムが欠陥なしであることを100%確信していません。 – GreenScape

答えて

2

これはlibC++のタプル実装のバグです。

LibC++ < = 3.8にバグがありますが、3.9のタプルの書き直しで修正されています。

このバグは残念です。アップグレードを避けるためには最高の/唯一の方法と思われます。

関連する問題