2016-07-05 7 views
0

私は未知のtypedef'd数値型を持っています。可能であればsize_tにキャストしたいと思っています(size_tの範囲内であれば読んでください)。さもなければ、エラー処理コードに落ちます。型typedefの数値型をsize_tにキャストすることは、オーバーフローのキャッチオーバー

ポータブルな方法はありますか?効果的

私は何をしたいのは、次のとおりです。

some_int_type val = <blah>; 
if (val < 0 || val > SIZE_MAX) { 
    // handle error 
} else { 
    return (size_t) val; 
} 

valが署名することができるようしかし、これは、動作しません。

私の第二の考えはこれを行うには、次のようになります。

if (val < 0 || (unsigned_some_int_type) val > SIZE_MAX) { 
    // handle error 
} else { 
    return (size_t) val; 
} 

これは、(私が思うに)働くだろう - 私はsome_int_typeの符号なしのバージョンを持っていないことを除いて。 some_int_typesize_tより小さい場合は正しく動作しないことを除いて、私はそれらを両方ともsome_int_typeにキャストすることができます(some_int_typeが署名されていれば正しく動作しません)。私はそれらを両方ともuintmax_tにキャストすることができましたが、一部のコンパイラでは実際にuintmax_tより大きい整数型があります。 (特に、__[u]int128)。

どうすればこのようにすることができますか?負のケースを確認した後、正

if (val >= 0) 
{ 
    if (val <= SIZE_MAX) 
    { 
     return (size_t) val; 
    } 
} 

// Handle error 
return 0; 
+3

なぜ最初のバージョンが機能しないと思いますか? – Olaf

+1

タイプはどのように「不明」ですか? @EugeneSh。 –

+1

コンパイル時にビルドされた外部ライブラリにあるとき。 – TLW

答えて

1
if (val < 0) { 
    // handle error 
} else if ((sizeof(some_int_type) > sizeof(size_t)) && (val > (some_int_type)SIZE_MAX)) { 
    // handle error 
} else { 
    return (size_t) val; 
} 

OPの元のコードは、微細

some_int_type val = <blah>; 
if (val < 0 || val > SIZE_MAX) { 
    // handle error 
} else { 
    return (size_t) val; 
} 

OP commented to @Olaf ":符号付きおよび符号なし整数式との比較の誤差" であるべきです。 OPのいずれかが警告を真に見たか、警告がエラーとして扱われています。 IACでは、Cごとにエラーではありません。

OPが警告/エラーを無視できない場合は、を穏やかにに変換し、必要に応じてに変換してください。未知の型がsize_tより大きい場合、それに(size_t)1を掛けても型は変更されず、比較の警告は発生しません。 IACでは、valの値は変更されません。

#include <stdint.h> 
if (val < 0 || (size_t)1 * val > SIZE_MAX) { 

コンパイラに最適化させます。より少ないコンパイラのみが(size_t)0 + valを使用できます。


はさらに:メッセージ「符号付きと符号なし整数式との比較は、」のみで符号付き整数を選択起動し、符号なし整数を比較します。符号なし整数型を符号付き整数型の範囲に収めるときには、符号なし整数型をより広い符号付き整数型に変換することに問題はないので、符号付き整数は適合しません。

+0

それはキャストをするためのきちんとした方法です。はい、Werrorが有効になっています。 – TLW

0

心配問題の型のサイズがsize_tより大きい場合、確認してください。その場合はSIZE_MAXと入力してsome_int_typeと入力して比較してください。そうでない場合、値はSIZE_MAXより大きくすることはできません。

+1

これは、OPの最初のコードと意味的に異なるわけではありません。 OPはうまくいきますので、これもそうですが、OPにこれを好む理由はありません。 –

+0

純粋に投機的だが深いリンターは、コードが不足していると警告しないかもしれない。コードが値が正であると主張するブロックの中にある場合 – infixed

+0

'val'が' unsigned'タイプの場合、その場合、条件は常に真です。 – user3386109

0

のための試験の内側にそれを引っ張って、符号なしバージョンの欠如について

関連する問題