是否由lambda初始化的函数局部静态函数对象,是否是线程安全的? [英] Function local static function-object that's initialized by lambda, thread-safe or not?

查看:84
本文介绍了是否由lambda初始化的函数局部静态函数对象,是否是线程安全的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下函数是线程安全的吗?而且,如果它不是线程安全的,那么将funImpl设置为非静态真的有任何开销吗?还是编译器实际上内联了该函数对象函数,并完全跳过了创建函数对象的过程?

  int myfun(std :: array< ; int,10>值)
{
static const auto funImpl = [&]()-> int
{
int sum = 0;

for(int i = 0; i< 10; ++ i)
{
sum + = values [i];
}
返还金额;
};

return funImpl();
}

编辑:
我从以下位置编辑了函数签名:

  int myfun(const std :: array< int,10&& values)

至:

  int myfun(std :: array< ; int,10>值)

所以很明显我不是在问胎面值的安全性,但是函数局部静态变量funImpl的线程安全性。

解决方案

不仅不是线程安全的



通过将lambda定义为静态,它捕获(通过引用)第一次调用时传递的数组。不管传入哪个数组,后续调用将继续引用原始数组。



当第一个数组超出范围时,后续调用将调用UB,就像现在这样

编辑:示例 http:// ideone .com / KCcav



注意,即使您按值捕获,您仍然会遇到问题,因为它仍然仅在您首次调用时捕获功能。您没有悬空的指针,但是它仍然只会在第一次时初始化副本。


Is the following function thread-safe? And if it's not thread-safe, then is there really any overhead in making that funImpl non-static? Or does the compiler actually inline that function-object function and skip creating the function object altogether?

int myfun(std::array<int, 10> values)
{
    static const auto funImpl = [&]() -> int
    {
        int sum = 0;

        for (int i = 0; i < 10; ++i)
        {
            sum += values[i];
        }
        return sum;
    };

    return funImpl();
}

EDIT: I edited the function signature from:

int myfun(const std::array<int, 10>& values)

to:

int myfun(std::array<int, 10> values)

so that it is clear that I'm not asking about the tread-safety of values, but the thread-safety of the function local static variable funImpl.

解决方案

Not only is it not thread safe, it doesn't do what you want.

By defining the lambda as static, it captures (by reference) the array passed in the first time it's called. Further calls continue to reference the original array, regardless of which array is passed in.

When the first array goes out of scope, further calls will invoke UB, as it now has a dangling reference.

Edit: An example http://ideone.com/KCcav

Note, even if you captured by value, you'd still have a problem because it would still only capture the first time you invoke the function. You wouldn't have the dangling pointer, but it still would only initialize the copy the first time.

这篇关于是否由lambda初始化的函数局部静态函数对象,是否是线程安全的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆