2016-03-30 20 views
0

32ビットプラットフォームのlibC++では、int64_tは別名long longと定義されています。 64ビットプラットフォーム:longあなたはherelong longが不用意に使用されて見つけることができることをstd::chrono::durationエイリアスの定義における一方ClangのlibC++:std :: chrono :: durationの定義で長いlongを使用

:私は厳密に8バイト長のタイプを必要とする場合

typedef duration<long long,   nano> nanoseconds; 
typedef duration<long long,  micro> microseconds; 
typedef duration<long long,  milli> milliseconds; 
typedef duration<long long    > seconds; 
typedef duration<  long, ratio< 60> > minutes; 
typedef duration<  long, ratio<3600> > hours; 

したがって、たとえば、私は

を期待します
foo(uint64_t); 
    foo(int64_t); 

かなりポータブルソリューションであること。しかしlibC++の場合、chronoはそうではありません。 <cstdint>に似た独自のロジックを書く以外に移植可能な方法はありません。つまり、fooという2つの追加定義を定義すると、long longunsigned long longとなります。

それとも別の例:

foo(int8_t); 
    foo(int16_t); 
    foo(int32_t); 
    foo(int64_t); 

foo(duration.count())を呼び出すと、この場合にはあいまいになります。

long longの使用ポイントはlong以下ですが、ランクはlongよりも大きいので、暗黙的にキャストすることはできません。これはlibc++の開発者が見落とし

ですか?

mongodbのドライバは、x64 FreeBSDのインストール時にコンパイルされないためです。そしてその理由はやや愚かに見えます。例えば、GCCstd::chrono::durationの定義でint64_tを使用すると予想されるように、それは、コンパイル。

+0

'long 'が32ビットの64ビットプラットフォームがあります。 LP64とLLP64プラットフォームの違いを確認してください。特定の規則が通常存在するにもかかわらず、これはプラットフォームだけでなく、コンパイラ固有のものでもあることに注意してください。 –

+0

@UlrichEckhardtもちろんありますが、これはこれをどうやって行うのですか?ライブラリは ''を定義していますので、そのライブラリの別の部分の移植性のために使用しないのはなぜですか? – GreenScape

+0

私の主張は、あなたが主導する文章が両方とも間違っていることです。私があなたの問題を理解すれば、完全に無関係です! "なぜ、' durationは '' uint64_t'で一つのプラットフォームで定義され、 '' long long''で定義されるのでしょうか? BTW:mongodbビルドの問題のリンクがありますか? –

答えて

5

標準では、secondsは、1の比率と少なくとも35ビットの符号付き整数型のdurationのtypedefであることが必要です。したがって、libC++の実装は正しいです。あなたの特定のケースで緩和移植性を持っているでしょうint64_tを使用している間

、それだけで、これまであなたを運ぶでしょう。また、int64_tではなく、long longを使用します。 (その場合は同じ型ですが)標準では持続時間がint64_tであるとは保証されていないため、もう1つの実装で使用してもそれに依存することはできません。

ここでの問題は、libC++の実装が何か悪いことではないということです。問題は、C++の整数型が多少ねじれていることです。intNN_t型は便利ですが、基底型について知ることから完全に解放されるわけではありません。特に、これらのtypedefでfooのために提示されたように、完全なオーバーロードセットを実行しようとすると間違っています。あなたが遭遇した問題のために基礎となる型を正確に調べる必要があります。オーバーロードセットはlong longをカバーすることもカバーしないこともあります。他の状況の代わりにlibC++のduration typedefsで起こったことはちょうど偶然のことです。

はい、それは悪い状況だが、この特定の問題が大きな問題のほんの症状です。

+0

整数型システムの問題について完全に同意します。 'C'のおかげで、それは完全に釘付けになった。一方で、あなたはそのようなプログレッシブライブラリの開発者からより多くの意識を期待するでしょう:( – GreenScape

1

標準では、期間の表現に特定の整数型は必要ありません。タイプがrepのメンバータイプとして利用可能であることが必要なため、値を秒単位で保存するのに適したタイプとして(たとえば)std::chrono::duration::seconds::repを使用できます。

2

私はこのコードを書いた人物だったので、私はこの質問についていくつかの権限をもって話すことができます。他の2つの答えは非常に良いですが、私はそれらをupvotedしました。

はい、私はこれらのタイプにいくつかの考えを与え、int_t*typedefで定義することを検討しました。

私は、32ビット以上でなければならない担当者のためにlong longを選択しました。残りはlongでした。後者は、ターゲットをi386からx86_64に変更するときに、longが32ビットから64ビットに変更されるという知識で行われました。

は、私が代わりにもそのデザインと( foo(int)間と foo(long long)を言う)他の人が曖昧さの問題について訴えているであろうことは十分に可能である int_t* typedef Sを使用していました。 全員を喜ばせるのは難しいです。

私は MongoDBのヘッダモンゴ/ SRC /モンゴ/ utilに/ time_support.hにそれが言うことに注意して

using Microseconds = stdx::chrono::microseconds; 
using Milliseconds = stdx::chrono::milliseconds; 
using Seconds = stdx::chrono::seconds; 
using Minutes = stdx::chrono::minutes; 
using Hours = stdx::chrono::hours; 

これは、同じように簡単に次のようになります。

using Microseconds = stdx::chrono::duration<std::int64_t, stdx::chrono::microseconds::period>; 
using Milliseconds = stdx::chrono::duration<std::int64_t, stdx::chrono::milliseconds::period>; 
using Seconds = stdx::chrono::duration<std::int64_t, stdx::chrono::seconds::period>; 
using Minutes = stdx::chrono::duration<std::int64_t, stdx::chrono::minutes::period>; 
using Hours = stdx::chrono::duration<std::int64_t, stdx::chrono::hours::period>; 

すなわち、 <chrono>ライブラリは、クライアントがカスタムユニットを作成するのを非常に容易にします。これは、mongodbのための良い解決策かもしれないように思えます。

+0

私の主張はこれです:C++ 11委員会では、異なるサイズの移植性の問題を解決するために、 ''を採用することで、さまざまなプラットフォーム上で整数型を使用することができます。同じ理由で、導入された型を使用しないライブラリそのものの実装自体は珍しいことです。 – GreenScape

関連する問題