http://en.cppreference.com/w/cpp/atomic/atomic_compare_exchangeでは、次のサンプル コードが の使用例として示されていますstd::atomic_compare_exchange_weak
。
void append(list* s, node* n)
{
node* head;
do {
head = s->head;
n->next = head;
} while(! std::atomic_compare_exchange_weak(s->head, head, n));
}
私が理解しているのは、これには と比較する効果があるという*(s->head)
ことhead
です。この例の最初の引数はである必要がありますか、それとも何か不足していますか?s->head
head
std::atomic_compare_exchange_weak
&(s->head)
更新: の仕様は次のようにstd::atomic_compare_exchange_weak
述べています。
bool atomic_compare_exchange_weak(volatile A* object, C * expected, C desired) noexcept;
bool atomic_compare_exchange_weak(A* object, C * expected, C desired) noexcept;
効果: アトミックに、オブジェクトが指すメモリの内容を比較します...期待される内容と等しいかどうか...
私はこれを*object
と比較されたという意味だと解釈しましexpected
たが、さらなる調査によると、実際の意味は*object
と比較される*expected
(つまり、"in expected
" は "によって指されている" という意味) であることが示唆されていexpected
ます。s->head
これは、私の最初の質問に対する答えが「いいえ、 cppreference のサンプル コードでのアドレスを取得する必要はない」であることを意味します。しかし、が a を指さなければならず、expected がobject
a を指さなければならないという事実により、コンパイルできるように cppreference でコードを修正する方法を理解するのが難しくなります。リストの先頭をリストの先頭のコピーと比較したいのですが、リストの先頭が型である場合、コピーは型でなければなりません。std::atomic<T>
T
std::atomic<T>*
T*
std::atomic_compare_exchange_weak
std::atomic<T>*
コンパイルすることであり、T*
なしでに を割り当てる方法が見つかりませんreinterpret_cast
。その場合でも、 の 3 番目のパラメーターstd::atomic_compare_exchange_weak
は type である必要がありますT
が、cppreference の例では、2 番目と 3 番目のパラメーターの両方が同じ型であることが示されています。これは、cppreference の例が壊れていることを示唆しています。私はそれを修正しようとしましたがreinterpret_cast
、単に間違っていると感じる a を使用する必要性に悩まされました。
興味深いことに、このことを理解しようとして、 のmsdn ページstd::atomic_compare_exchange_weak
std::atomic_compare_exchange_*strong*
を調べたところ、そのページに!のプロトタイプが表示されているのを見てがっかりしました。
std::atomic_compare_exchange_weak
単一リンクリストの先頭にノードを挿入するために使用するもっともらしいコードを誰かが投稿できますか? ABA の問題について心配したり、特別なことをしたりする必要はありません。コンパイルされる骨組みのコードを見たいだけです。