1

uint_fast64_t をインデックス タイプとして使用する行列関連のコードを含む大きなコードベースがあります。GMMをソルバー バックエンドとして利用するには、次のベクトルを変換 (キャスト!) する必要があります。

std::vector<uint_fast64_t, std::allocator<uint_fast64_t>>

GMMの内部フォーマットへ

std::vector<unsigned long long, std::allocator<unsigned long long>>

MSVC2012 では、uint_fast64_t は unsigned long long に typedef されているため、両方の式は「同じ」です。

unsigned long long は正確に 64 ビットの長さ (long) (実装で定義されているため) であり、uint_fast64_t は少なくとも 64 ビットの長さであるため、実際にはそれらが同じ型ではないことをよく知っています。( -- 嫌いじゃない ;) )

悲しいことに、GCC4.7 と Clang 3.4 は uint_fast64_t を内部型として認識していたため、どの型のキャストも不可能でした。

さらに、ある時点で、clang は uint_fast64_t を unsigned long として解釈し、unsigned long long 定義との互換性をさらに損なうようです。

私の惨めさからどのように見えますか?

GMM コードの unsigned long long を手動で置き換える唯一のオプションはありますか?

4

2 に答える 2

1

以下は、実際には移植可能ではありませんが、機能するソリューションです。

static_assert(sizeof(uint_fast64_t) == sizeof(unsigned long long), "This code relies on equivalence of uint_fast64_t and unsigned long long");

std::vector<uint_fast64_t, std::allocator<uint_fast64_t>> src;

std::vector<unsigned long long, std::allocator<unsigned long long>> &after_cast = 
  *reinterpret_cast<std::vector<unsigned long long, std::allocator<unsigned long long>> *>(&src);

厳密な型のエイリアシングをオフにしてこれをコンパイルする必要があります (Clang など-fno-strict-aliasing)。

標準で定義されていない動作に依存していますが、適切なコンパイラ フラグを渡すことで、実際にコンパイラに一貫した定義を提供させることができます。

于 2013-09-13T17:10:59.303 に答える