简体   繁体   English

原子向量的初始化

[英]Initialisation of vector of atomics

Consider:考虑:

void foo() {
  std::vector<std::atomic<int>> foo(10);
  ...
}

Are the contents of foo now valid? foo 的内容现在有效吗? Or do I need to explicitly loop through and initialise them?还是我需要显式循环并初始化它们? I have checked on Godbolt and it seems fine, however the standard seems to be very confused on this point.我已经检查过 Godbolt 并且看起来不错,但是在这一点上标准似乎很混乱。

The std::vector constructor says it inserts default-inserted instances of std::atomic<int> , which arevalue initialised via placement new . std::vector构造函数说它插入 默认插入std::atomic<int>实例,这些实例是通过放置new初始化的值

I think this effect of value initialisation applies:我认为值初始化的这种效果适用:

2) if T is a class type with a default constructor that is neither user-provided nor deleted (that is, it may be a class with an implicitly-defined or defaulted default constructor), the object is zero-initialized and then it is default-initialized if it has a non-trivial default constructor; 2) 如果 T 是一个 class 类型,其默认构造函数既不是用户提供也不是被删除(也就是说,它可能是一个 class 具有一个隐式定义或默认的默认构造函数),则 ZA8CFDE6331BD59EB2AC96F89111C4 是零初始化的,然后它如果它具有非平凡的默认构造函数,则默认初始化;

So it seems to me that the atomics are zero-initialised.所以在我看来,原子是零初始化的。 So the question is, does zero-initialisation of a std::atomic<int> result in a valid object?所以问题是, std::atomic<int>的零初始化是否会导致有效的 object?

I'm going to guess that the answer is "yes in practice but it's not really defined"?我猜答案是“在实践中是的,但它并没有真正定义”?

Note: This answer agrees that it is zero-initialised, but doesn't really say if that means that the object is valid.注意:这个答案同意它是零初始化的,但并没有真正说明这是否意味着 object 是有效的。

You are correct to be worried.你担心是对的。 According to standard the atomics has the default constructor called, however they have not been initialized as such.根据标准,原子具有调用的默认构造函数,但是它们还没有被初始化。 This is because the default constructor doesn't initialize the atomic:这是因为默认构造函数没有初始化原子:

The default-initialized std::atomic<T> does not contain a T object, and its only valid uses are destruction and initialization by std::atomic_init默认初始化的std::atomic<T>不包含T object,其唯一有效用途是由std::atomic_init进行破坏和初始化

This is somewhat in violation of the normal language rules, and some implementations initialize anyway (as you have noted).这在某种程度上违反了正常的语言规则,并且某些实现无论如何都会初始化(正如您所指出的)。

That being said, I would recommend taking the extra step to make 100% sure they are initialized correctly according to standard - after all you are dealing with concurrency where bugs can be extremely hard to track down.话虽如此,我建议采取额外的步骤来确保 100% 确保它们根据标准正确初始化 - 毕竟您正在处理并发问题,其中错误可能非常难以追踪。

There are many ways to dodge the issue, including using wrapper:有很多方法可以避免这个问题,包括使用包装器:

struct int_atomic {
   std::atomic<int> atomic_{0};//use 'initializing' constructor
};

Even if the default constructor were called (it isn't, because it's trivial) it doesn't really do anything .即使调用了默认构造函数(不是,因为它很简单) ,它也没有真正做任何事情

Zero-initialisation obviously cannot be guaranteed to produce a valid atomic;零初始化显然不能保证产生一个有效的原子; this'll only work if by chance a valid atomic is created by zero-initialising all its members.这只有在偶然通过对其所有成员进行零初始化来创建有效原子时才有效。

And, since atomics aren't copyable, you can't provide a initialisation value in the vector constructor.而且,由于原子不可复制,因此您不能在向量构造函数中提供初始化值。

You should now loop over the container and std::atomic_init each element.您现在应该遍历容器和std::atomic_init每个元素。 If you need to lock around this, that's fine because you're already synchronising the vector's creation for the same reason.如果您需要锁定这一点,那很好,因为您已经出于同样的原因同步了向量的创建。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM