9

Oracle APIを使用してデータベースにアクセスしていますが、このAPIにはreadBuffer(char * buffer, unsigned int size);変更を加えることができない機能があります。

このAPIを使用するクラスがあり、現在、関数のシグネチャはサイズに対してastd::stringとaを取りますunsigned int。問題は、関数のsize引数に渡すと、からへの変換が可能std::string.size()であるという警告をコンパイラから受け取ることです。データ損失を引き起こします。size_tunsigned int

をAPIに渡して、コンパイラから警告を受け取らないようにするための有効な方法があるかどうか疑問に思いました。size_tunsigned int

size_tの目的を理解しており、この変換をGoogleで検索すると、「size_t argを取るように関数を変更する」という結果が多数表示されますが、この場合、APIの署名を変更することはできません。

助言がありますか?

4

5 に答える 5

20

はい、そのような変換が有効かどうかをチェックし、そうでない場合は例外をスローするヘルパー関数を記述します。何かのようなもの:

unsigned int convert( size_t what )
{
    if( what > UINT_MAX ) {
       throw SomeReasonableException();
    }
    return static_cast<unsigned int>( what );
}
于 2011-04-19T10:06:50.407 に答える
5

さて、してくださいstatic_cast<unsigned int>(mystring.size())

その理由は、std::size_t通常はポインタサイズですが、64ビットプラットフォームでintはまだ32ビットであるためです。この場合、データが失われる唯一の理由は、問題の文字列の長さが2^32バイトを超える場合です。

これが起こらないことがわかっている場合は、assertこのケースをキャッチする場所を置きstatic_cast、コンパイラーを沈黙させます。

于 2011-04-19T10:07:03.947 に答える
4
static_cast<unsigned int>(str.size());

妄想的になりたい場合:

if (static_cast<unsigned int>(str.size()) != str.size()) 
  throw ...
于 2011-04-19T10:07:04.087 に答える
1

を使用して変換を強制できます

static_cast<unsigned int>(your_variable)

構築します。もちろん、正しい方法はAPIが受け入れることsize_tです...

于 2011-04-19T10:06:41.660 に答える
1

ここでのリスクは( )size_tよりも大きい可能性があるため、その場合は安全に変換できません。unsignedint

たとえば、int32ビットであるのに対し、size_t64ビットであると考えられます。私は頭のてっぺんからそのようなシステム/構成を知りませんが、それは起こる可能性があります。

ほとんどの「合理的な」システムでは、両方とも少なくとも32ビットであり、単一の4 GB文字列がまだ(おそらく)発生する可能性は低いです。

したがって、キャストするだけで済みます。これは有効ですが、考えられるすべてのシステムやコーナーケースに対して「安全」ではありません。

于 2011-04-19T10:06:42.123 に答える