質問

次のコードでは、G ++ 4.1.1および -Wall.

int octalStrToInt(const std::string& s)
{    
    return strtol(s.c_str(), 0, 8);
}

Strtolが返されたため、警告を期待していました long int しかし、私の機能は平野を返すだけです int. 。他のコンパイラはここで警告を発するかもしれませんか? この場合、良い実践としてINTに戻り値をキャストする必要がありますか?

役に立ちましたか?

解決

これらの警告をオンにするには、-wonversionフラグが必要になる場合があります。ただし、警告しません 長いです -> int, 、GCCと同じサイズであるため(変換のために値は変わりません)。ただし、たとえば変換する場合になります 長いです -> 短い

単にキャストを行うことは推奨されないと思います。なぜなら、それはバグの可能性を隠すだけだからです。そのようなキャストがコンパイラをなだめるために値を変更しないことを確認した後は大丈夫でしょう。

他のヒント

最良のアプローチは次のとおりです。

long x = strtol(...); assert(x <= INT_MAX); return (int)x;

あなたが必要です limits.hassert.h

アクセスできない場合 boost::numeric_cast, 、簡単な模倣を書くことができます:

template <typename T, typename S>
T range_check(const S &s) {
    assert(s <= std::numeric_limits<T>::max());
    assert(s >= std::numeric_limits<T>::min());
    return static_cast<T>(s); // explicit conversion, no warnings.
}

return range_check<int>(strtol(some_value,0,8));

実際には、フローティングポイントの宛先タイプでは機能しないため、それはちょっとしたチートです。 min() 整数型と同じように彼らと同じ縛られていないので、+/-に対してチェックする必要があります max(). 。読者のための運動。

Assertまたは他のエラー処理を使用するかどうかは、無効な入力について実際にやりたいことに依存します。

あります boost::lexical_cast (手元には、その読み物をOctalにする方法がわかりません)とStrings-stream。必要なタイプを読んでください。たまたまCライブラリ関数があるタイプではありません。

プラットフォーム上の「int」と「long int」データタイプには同じサイズと範囲があるため、ここでは警告が表示されません。アーキテクチャに応じて、それらは異なる可能性があります。

奇妙なエラーから身を守るには、範囲チェックを使用してください。 std :: numeric_limits :: min/maxを使用することをお勧めします(参照)。

範囲チェック後、Static_castまたはCスタイルのキャストを安全に使用できます。

一方、STD :: StringsStreamクラスで実装されているのと同じ機能に頼ることができます。 STD :: StringsStreamとの変換は、デフォルトでプラットフォームセーフとタイプセーフになります。

ほとんどの最新のコンパイラは、構成した警告レベルに応じて、変換と可能な切り捨てについて警告します。警告レベル4であるMSVC。

ベストプラクティスは、関数から長い時間を返し、呼び出しコードに変換の処理方法を決定させることです。それを除いて、少なくともstrtolから戻ってきた値が、ret_me_beが示唆するように、戻る前にintに収まることを確認してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top