3

Boost ICL では、間隔セットで cardinality() または size() 関数を呼び出すと、戻り値の型は間隔の型に関係なく size_t になります。32 ビット マシンでは、これは 32 ビットの符号なし整数です。ただし、間隔が int64_t 型の場合、カーディナリティは 32 ビット整数を簡単にオーバーフローさせる可能性があります。ここで明らかな何かが欠けていますか、それともこのライブラリの重大な欠陥ですか?

編集:例が追加されました

次のコードは、64 ビットではエラーなしでコンパイルおよび実行されますが、アサーションをスローする 32 ビット マシンではエラーが発生しません。

#include <boost/icl/interval_set.hpp>

int main()
{
    boost::icl::interval_set<int64_t> is;
    is.add(boost::icl::interval<int64_t>::closed(1, 4294967297LL));
    assert(boost::icl::cardinality(is) == 4294967297LL);
}

編集: Ubuntu 13.10 で boost::icl バージョン 1.49.0 を使用しています

編集:

次のコードは 64 ビットでも動作しないため、これは特に 32/64 ビットの問題ではありません。

#include <boost/icl/interval_set.hpp>
int main()
{
    boost::icl::interval_set<double> is;
    is.add(boost::icl::interval<double>::closed(1, 1.5));
    assert(boost::icl::cardinality(is) == 0.5);
}
4

1 に答える 1

2

Ubuntu 14.04.1 LTS の Boost 1_54 で再現

これは確かにバグのようです。修正する特化は

template <class Type> 
struct get_size_type<Type, false, false, false>
{ 
    typedef std::size_t type; 
};

icl/type_traits/size_type_of.hpp。どういうわけか、ICL 開発者は最近 -m32 でテストしていないようです。

私はそれを置き換えることに成功しました

// BEGIN SEHE WAS HERE
template <class Type> 
struct get_size_type<Type, std::enable_if<not boost::is_arithmetic<Type>::value, mpl::false_>::type::value, false, false>
{ 
    typedef std::size_t type; 
};

template <class Type> 
struct get_size_type<Type, std::enable_if<boost::is_arithmetic<Type>::value, mpl::false_>::type::value, false, false>
{ 
    typedef typename std::common_type<Type, std::size_t>::type type; 
};
// END SEHE WAS HERE

このトレイトは残念ながら SFINAE にあまり適していないため、boolSFINAE の最初のテンプレート引数を使用するためのハックです。改善点は次のとおりです。

  • boost型特性のみを使用する
  • common_type<...>整数型ではなく、Boost Integer からの整数値控除を使用します

g++ -m32 および -m64 とinterval_set<double>同様に、これを DoTheRightThing(TM) に対してテストしました。interval_set<uint64_t>


これをメーリングリストで報告します。

于 2014-12-01T09:46:18.457 に答える