読者です 読者をやめる 読者になる 読者になる

とくにあぶなくないRiSKのブログ

危ないRiSKのブログだったかもしれない。本当はRiSKだけどググラビリティとか取得できるIDの都合でsscriskも使ったり。

std::is_trivially_copyableのバグ

Visual Studio 2012(Visual C++ 11.0)のstd::is_trivially_copyableはバグっている。

再現コード

以下の三つのstatic_assertに失敗してしまう。参照型を自明なコピー可能型とみなしてしまっている。さらに、void型を自明なコピー可能型とみなしてしまっている。

#include<type_traits>

static_assert(std::is_trivially_copyable<int&>::value == false, "");
static_assert(std::is_trivially_copyable<int&&>::value == false, "");

static_assert(std::is_trivially_copyable<void>::value == false, "");

int main(){}

std::is_trivially_copyableが内部で使っている組み込みの__is_trivially_copyableに問題があり参照型の判定を間違っているようだ。

また、組み込みの__is_trivially_copyablevoid型の判定を正しく行うにも関わらず、std::is_trivially_copyableの実装コードが余計なことをしているためにvoid型の判定を間違っているようだ。

規格

N3337(PDF) 3.9/9に次のように書かれている。

Scalar types, trivially copyable class types (Clause 9), arrays of such types, and cv-qualified versions of these types (3.9.3) are collectively called trivially copyable types.

参照型およびvoid型は、どれにも該当しないので自明なコピー可能型(trivially copyable types)ではない

他の処理系

[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ

Visual Studio

Visual Studio 2013(Visual C++ 12.0)では、void型についてはバグが修正されており正しい結果。参照型についてはバグが修正されていない可能性あり。*1

GCC

今のところ(4.8.1以下)はstd::is_trivially_copyableを実装していない。

Clang

3.0, 3.1, 3.2, 3.3で正しい結果。