clang + libc++:make_tuple 与 make_shared 的组合导致对象过早销毁
clang + libc++: combination of make_tuple with make_shared leads to early object destruction
我的程序几乎整天都在跟踪错误。出于某种原因,我在 c++11 方面的 std::apply
实现是错误的:底层函数的参数在调用过程中以某种方式得到了 empty。一个很好的例子是 std::unique_ptr
在调用一个临时函数(下面,foo()
)之后总是 empty()
在被调用函数的主体中。
我已将我的代码简化为一个简单的测试用例:
#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;
}
如果用 clang 和 libc++ (-stdlib=libc++) 一起编译,结果是:
Foo()
Point #1
~Foo()
Point #2
上的实例
结果显然不正确。如果用clang, but without libc++, or if compiled with gcc编译,结果如预期:
Foo()
Point #1
Point #2
~Foo()
我找到了 clang 和 libc++ 组合的可笑解决方法,替换为:
auto && packaged_args = std::make_shared<TupleType>(std::make_tuple(std::forward<Args>(args)...));
与:
std::shared_ptr<TupleType> packaged_args{new TupleType(std::make_tuple(std::forward<Args>(args)...))};
它再次按预期工作。
上的实例
问题是:它是一个 UB,所以两个编译器都是正确的错误代码,或者代码没问题,这是一个错误?
这似乎是 libc++ 的元组实现中的一个错误。
该错误存在于 Libc++ <= 3.8 中,但已通过我在 3.9 中重写的元组修复。
很抱歉这个错误;似乎 best/only 避免它的方法是升级。
我的程序几乎整天都在跟踪错误。出于某种原因,我在 c++11 方面的 std::apply
实现是错误的:底层函数的参数在调用过程中以某种方式得到了 empty。一个很好的例子是 std::unique_ptr
在调用一个临时函数(下面,foo()
)之后总是 empty()
在被调用函数的主体中。
我已将我的代码简化为一个简单的测试用例:
#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;
}
如果用 clang 和 libc++ (-stdlib=libc++) 一起编译,结果是:
Foo()
Point #1
~Foo()
Point #2
上的实例
结果显然不正确。如果用clang, but without libc++, or if compiled with gcc编译,结果如预期:
Foo()
Point #1
Point #2
~Foo()
我找到了 clang 和 libc++ 组合的可笑解决方法,替换为:
auto && packaged_args = std::make_shared<TupleType>(std::make_tuple(std::forward<Args>(args)...));
与:
std::shared_ptr<TupleType> packaged_args{new TupleType(std::make_tuple(std::forward<Args>(args)...))};
它再次按预期工作。
上的实例
问题是:它是一个 UB,所以两个编译器都是正确的错误代码,或者代码没问题,这是一个错误?
这似乎是 libc++ 的元组实现中的一个错误。
该错误存在于 Libc++ <= 3.8 中,但已通过我在 3.9 中重写的元组修复。
很抱歉这个错误;似乎 best/only 避免它的方法是升级。