Khởi tạo vectơ nguyên tử


12

Xem xét:

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

Các nội dung của foo bây giờ có hợp lệ không? Hay tôi cần phải lặp đi lặp lại một cách rõ ràng và khởi tạo chúng? Tôi đã kiểm tra trên Godbolt và nó có vẻ ổn, tuy nhiên tiêu chuẩn dường như rất bối rối về điểm này.

Hàm tạo std :: vector cho biết nó chèn các thể hiện được chèn mặc định của std::atomic<int>, là giá trị được khởi tạo thông qua vị trí new.

Tôi nghĩ rằng hiệu ứng khởi tạo giá trị này được áp dụng:

2) nếu T là một loại lớp với hàm tạo mặc định không do người dùng cung cấp cũng không bị xóa (nghĩa là nó có thể là một lớp với hàm tạo mặc định được định nghĩa ngầm định hoặc mặc định), thì đối tượng được khởi tạo bằng 0 và sau đó nó là khởi tạo mặc định nếu nó có một hàm tạo mặc định không tầm thường;

Vì vậy, dường như với tôi rằng các nguyên tử là không khởi tạo. Vì vậy, câu hỏi là, không khởi tạo std::atomic<int>kết quả trong một đối tượng hợp lệ?

Tôi sẽ đoán rằng câu trả lời là "có trong thực tế nhưng nó không thực sự được xác định"?

Lưu ý: Câu trả lời này đồng ý rằng nó không được khởi tạo, nhưng thực sự không nói nếu điều đó có nghĩa là đối tượng hợp lệ.

Câu trả lời:


7

Bạn đúng là phải lo lắng. Theo tiêu chuẩn, các nguyên tử có hàm tạo mặc định được gọi, tuy nhiên chúng chưa được khởi tạo như vậy. Điều này là do hàm tạo mặc định không khởi tạo nguyên tử:

Khởi tạo mặc định std::atomic<T>không chứa Tđối tượng và cách sử dụng hợp lệ duy nhất của nó là hủy và khởi tạo bởi std :: atomic_init

Điều này có phần vi phạm các quy tắc ngôn ngữ thông thường và một số triển khai khởi tạo bằng mọi cách (như bạn đã lưu ý).

Điều đó đang được nói, tôi khuyên bạn nên thực hiện bước bổ sung để đảm bảo 100% chúng được khởi tạo chính xác theo tiêu chuẩn - sau tất cả những gì bạn đang xử lý đồng thời, nơi các lỗi có thể cực kỳ khó theo dõi.

Có nhiều cách để tránh sự cố, bao gồm sử dụng trình bao bọc:

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

Hoặc thực sự sử dụng atomic_init. Dù sao thì bạn cũng phải đồng bộ hóa xung quanh mã trong câu hỏi
Các cuộc đua Lightness trong quỹ đạo

Hàm tạo mặc định là tầm thường nên dù sao nó cũng không được gọi (theo trích dẫn trong câu hỏi)
Các cuộc đua Lightness trong Orbit

@LightnessRaceswithMonica cũng có thể, tôi chỉ muốn làm nổi bật trình bao bọc
darune

@LightnessRaceswithMonica đây là một ngoại lệ đối với các quy tắc ngôn ngữ thông thường - mặc dù một số trình biên dịch không thực hiện ngoại lệ này. Tôi không chắc câu trả lời của StoreTeller là chính xác 100%.
darune

2

Ngay cả khi hàm tạo mặc định được gọi (không phải vì nó không quan trọng), nó thực sự không làm gì cả .

Không khởi tạo bằng không rõ ràng không thể được đảm bảo để tạo ra một nguyên tử hợp lệ; điều này sẽ chỉ hoạt động nếu tình cờ một nguyên tử hợp lệ được tạo ra bằng cách không khởi tạo tất cả các thành viên của nó.

Và, vì các nguyên tử không thể sao chép, bạn không thể cung cấp giá trị khởi tạo trong hàm tạo vector.

Bây giờ bạn nên lặp qua container và std::atomic_inittừng phần tử. Nếu bạn cần phải giải quyết vấn đề này, điều đó tốt vì bạn đã đồng bộ hóa việc tạo vectơ vì lý do tương tự.


@darune Tôi coi đó là một loại đồng bộ hóa;)
Các cuộc đua nhẹ nhàng trong quỹ đạo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.