[英]std::atomic passed as a const reference to a non-atomic type
假設我有這個應用程序:
#include <atomic>
#include <thread>
#include <iostream>
#include <chrono>
void do_something(const std::atomic<bool>& stop) {
while (!stop) {
std::cout << "Doing stuff..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main() {
std::atomic<bool> stop { false };
std::thread wait([&stop] {
std::this_thread::sleep_for(std::chrono::seconds(10));
stop = true;
});
do_something(stop);
wait.join();
}
這按預期工作。 主線程循環直到wait
線程設置stop
。 據我所知,這個應用程序沒有真正的問題,因為它使用std::atomic<bool>
來實現線程之間的同步。
但是,我可以通過將do_something
的簽名更改為此來破壞應用程序:
void do_something(const bool& stop);
這仍然可以在沒有任何警告的情況下編譯,但是do_something
中的循環永遠不會退出。 從概念上講,我理解為什么會這樣。 do_something
正在接受對非原子值的 const 引用,因此將 function 優化為類似以下內容是合理的:
void do_something(const bool& stop) {
if (!stop) {
while(true) {
std::cout << "Doing stuff..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
}
令我困惑的是為什么修改后的應用程序完全可以編譯。 我不希望能夠將std::atomic
值傳遞到 function 中,期望對非原子類型的 const 引用。 我沒有看過標准,但我在 cppreference 上沒有看到任何表明允許這種轉換的內容。
我在這里誤解了什么嗎? 這只是std::atomic
的一些怪癖,我從文檔中看不出來嗎?
這是因為在傳遞std::atomic<bool>
時調用do_something(const bool &stop)
時存在隱式轉換
它翻譯成:
do_something(static_cast<bool>(stop.operator bool()));
正如您在這里看到的: https://en.cppreference.com/w/cpp/atomic/atomic/operator_T
您實際上告訴編譯器加載一次值,就在調用時。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.