54

Anthony Williams の「C++ Concurrency in Action」と、新しいマルチスレッド対応メモリ モデルとアトミック操作について説明している第 5 章を読んでいて、彼は次のように述べています。

std::atomic<UDT>一部のユーザー定義で使用するにはUDT、この型に自明なコピー代入演算子が必要です。

私が理解しているように、これはstd::atomic<UDT>、以下が true を返す場合に使用できることを意味します。

std::is_trivially_copyable<UDT>::value

このロジックでは、 をstd::stringテンプレート引数として使用してstd::atomic正しく動作させることはできません。

ただし、次のコードはコンパイルおよび実行され、期待される出力が得られます。

#include <atomic>
#include <thread>
#include <iostream>
#include <string>

int main()
{
    std::atomic<std::string> atomicString;

    atomicString.store( "TestString1" );

    std::cout << atomicString.load() << std::endl;

    atomicString.store( "TestString2" );

    std::cout << atomicString.load() << std::endl;

    return 0;
}

これは、たまたま期待どおりに動作する未定義の動作の場合ですか?

前もって感謝します!

4

2 に答える 2

60

標準は の特殊化を指定していないstd::atomic<std::string>ため、ジェネリックtemplate <typename T> std::atomic<T>が適用されます。29.5 [atomics.types.generic] p1 の状態:

ジェネリック クラス テンプレート アトミックがあります。テンプレート引数 T の型は自明にコピー可能でなければならない (3.9)。

実装がこの要件の違反を診断する必要があるというステートメントはありません。したがって、(a) を使用するとstd::atomic<std::string>未定義の動作が呼び出されるか、(b) 実装std::atomic<std::string>が準拠する拡張として提供されます。

std::atomic<T>( http://msdn.microsoft.com/en-us/library/vstudio/hh874651.aspx )のMSDNページを見ると、T自明にコピー可能であるという要件が明示的に言及されており、std::atomic<std::string>. 拡張機能の場合は、文書化されていません。私のお金は未定義の動作にあります。

具体的には、17.6.4.8/1 が適用されます (私を正してくれた Daniel Krügler に感謝します):

場合によっては (置換関数、ハンドラー関数、標準ライブラリ テンプレート コンポーネントのインスタンス化に使用される型の操作)、C++ 標準ライブラリは C++ プログラムによって提供されるコンポーネントに依存します。これらのコンポーネントが要件を満たさない場合、標準は実装に要件を課しません。

std::stringstd::atomic<T>テンプレートパラメータが簡単にコピー可能であるという要件を確実に満たしていないTため、標準は実装に要件を課していません。static_assert(std::is_trivially_copyable<T>::value, "std::atomic<T> requires T to be trivially copyable");実装の品質の問題として、この違反を検出するための簡単な診断方法であることに注意してください。


2016 年 4 月 19 日更新: 変更がいつ発生したかはわかりませんが、VS2015 Update 2 では次のように診断されstd::atomic<std::string>ます。

エラー C2338: アトミックには、T が自明にコピー可能である必要があります。
于 2013-06-01T22:10:08.317 に答える
13

いいえ、これは未定義の動作です。さらに、 std::string は自明にコピー可能ではないため、準拠するコンパイラは「少なくとも 1 つの診断メッセージ」を発行する必要があります。

29.5 アトミック型

ジェネリック クラス テンプレート アトミックがあります。テンプレート引数 T の型は自明にコピー可能でなければならない (3.9)。

1.4 実装のコンプライアンス

— プログラムに診断可能なルールの違反が含まれている場合 [...] 適合する実装は、少なくとも 1 つの診断メッセージを発行する必要があります。

于 2014-01-23T14:34:59.033 に答える