http://en.cppreference.com/w/cpp/atomic/atomic_compare_exchangeでは、次のコード例は、std::atomic_compare_exchange_weak
の使用例として提示されていますcppreferenceの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)
か、何か不足していますか?
UPDATE: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
と比較したことを意味するためにこれを取ったが、更なる研究が実際の意味ことを示唆しています「expected
」は「expected
で示されている」を意味する)と比較して、*object
が*expected
と比較される。これは、私の元の質問への答えが "いいえ、s->head
のアドレスをcppreferenceのサンプルコードで取る必要はない"という意味です。しかし、object
がstd::atomic<T>
を指し、予想される必要があるのはT
であるという事実は、コンパイルするためにcppreferenceでコードを修正する方法を理解することが難しくなります。リストの先頭とリストの先頭のコピーを比較したいが、リストの先頭がstd::atomic<T>*
の場合はstd::atomic_compare_exchange_weak
の呼び出しをコンパイルする場合はコピーはT*
でなければならず、 reinterpret_cast
なしでT*
にstd::atomic<T>*
を割り当てる方法が見つかりません。その場合でも、std::atomic_compare_exchange_weak
の3番目のパラメータはT
のタイプである必要がありますが、cppreferenceの例では、2番目と3番目のパラメータが同じタイプであることが示されています。これは、cppreferenceの例が壊れていることを私に示唆しています。私はそれを修正しようとしましたが、私はreinterpret_cast
を使用する必要性に悩まされました。
興味深いことに、このようなことを理解しようとした私は、msdn page for std::atomic_compare_exchange_weak
をチェックアウトしました。そのページには、std::atomic_compare_exchange_*strong*
のプロトタイプが表示されています。
誰かがstd::atomic_compare_exchange_weak
を使用して単一リンクリストの先頭にノードを挿入するというもっともらしいコードを投稿できますか? ABAの問題を心配する必要はありません。私はちょうどコンパイルする骨格コードを見たいと思う。
'node'はアトミックオブジェクトであると考えられますか? – 0x499602D2
これはcppreferenceの完全なコードスニペットですが、私の質問に対する答えには影響しないと思います。 – KnowItAllWannabe
コードはナンセンスです。 'atomic_compare_exchange_weak'の最初の引数は、アトミック型のオブジェクトへのポインタでなければなりません。 2番目の引数は、対応する値型のオブジェクトへのポインタでなければなりません。 3番目の引数は、対応する値型のオブジェクト(ポインタではありません)です。 –