[c++] 원자 벡터의 초기화

치다:

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

foo의 내용이 이제 유효합니까? 아니면 명시 적으로 반복하고 초기화해야합니까? 나는 Godbolt를 확인했는데 괜찮아 보이지만이 시점에서 표준이 매우 혼란스러워 보입니다.

표준 : : 벡터 생성자는 삽입 말한다 기본 삽입 의 인스턴스 std::atomic<int>이며, 초기화 값 배치를 통해를 new.

가치 초기화의이 효과가 적용된다고 생각합니다.

2) T가 사용자 제공 또는 삭제되지 않은 기본 생성자를 가진 클래스 유형 인 경우 (즉, 암시 적으로 정의되거나 기본 기본 생성자를 가진 클래스 일 수 있음), 객체는 0으로 초기화 된 다음 사소한 기본 생성자가 있으면 기본값으로 초기화됩니다.

그래서 원자는 0으로 초기화 된 것 같습니다. 문제는, std::atomic<int>결과를 0으로 초기화 하면 유효한 객체가됩니까?

나는 대답이 “실제로 그렇지만 실제로 정의되어 있지는 않다”고 추측 할 것입니다.

참고 : 이 답변 은 0으로 초기화되었음을 동의하지만 객체가 유효하다는 것을 실제로 말하지는 않습니다.



답변

당신은 걱정하는 것이 맞습니다. 표준에 따르면 원자는 기본 생성자라고하지만 초기화 되지 않았습니다. 기본 생성자가 원자를 초기화하지 않기 때문입니다.

기본값으로 초기화 std::atomic<T>T개체 에는 개체 가 포함되어 있지 않으며 std :: atomic_init에 의한 유일한 사용은 소멸 및 초기화입니다.

이것은 다소 일반적인 언어 규칙을 위반하는 것이며, 일부 구현은 어쨌든 초기화합니다 (알다시피).

즉, 표준에 따라 올바르게 초기화되었는지 100 % 확인하기 위해 추가 단계를 수행하는 것이 좋습니다. 결국 버그를 추적하기가 매우 어려운 동시성을 처리합니다.

래퍼 사용을 비롯하여 여러 가지 방법으로 문제를 피할 수 있습니다.

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


답변

기본 생성자가 호출 된 경우에도 (사소하지 않기 때문에) 실제로 아무것도하지 않습니다 .

제로 초기화는 분명히 유효한 원자를 생성한다고 보장 할 수 없습니다. 우연히 모든 멤버를 0으로 초기화하여 유효한 원자가 생성 된 경우에만 작동합니다 .

또한 원자는 복사 할 수 없으므로 벡터 생성자에 초기화 값을 제공 할 수 없습니다.

이제 컨테이너와 std::atomic_init각 요소를 반복해야합니다 . 이 문제를 해결해야하는 경우, 같은 이유로 이미 벡터 생성을 동기화하고 있기 때문에 좋습니다.


답변