size_t の加算でオーバーフローが発生しました
-
03-07-2019 - |
質問
私は、コードを VS.NET と GCC に対して無料で警告しないようにし、コードを 64 ビット対応にしたいと考えています。
今日、私はメモリバッファ内を処理し、ファイルスタイルのインターフェース(例:バイトの読み取り、書き込み、シークアラウンドなどが可能です)。
現在の読み取り位置とサイズのデータ型として、最も自然な選択と思われる size_t を使用しました。警告を回避できたので、64 ビットでも動作するはずです。
念のため:私の構造は次のようになります。
typedef struct
{
unsigned char * m_Data;
size_t m_CurrentReadPosition;
size_t m_DataSize;
} MyMemoryFile;
の署名性 size_t
実際には定義されていないようです。Googleのコード検索でそれが証明されました。
今、私はジレンマに陥っています。追加内容を確認したい size_t
ユーザーが提供したデータを処理する必要があり、サードパーティのライブラリが私のコードを使用するため、オーバーフローが発生する可能性があります。ただし、オーバーフローチェックのためには、符号性を知る必要があります。それは実装に大きな違いをもたらします。
では、プラットフォームやコンパイラに依存しない方法で、一体どのようにしてそのようなコードを書けばよいのでしょうか?
の署名を確認できますか size_t
実行時またはコンパイル時?そうすれば私の問題は解決します。または多分 size_t
そもそもそれは最良のアイデアではありませんでした。
何か案は?
編集:C言語の解決策を探しています。
解決
かどうかについては、 size
_t は署名または未署名、および GCC (古い GCC マニュアルから - まだ存在するかどうかはわかりません):
潜在的な問題があります
size_t
リリース2.4の前にGCCのタイプとバージョン。ANSI C では次のことが要求されますsize_t
常に符号なし型である必要があります。既存のシステムのヘッダーファイルとの互換性のために、GCCは定義しますsize_t
でstddef.h
システムのタイプであればsys/types.h
それを定義します。を定義するほとんどの Unix システムsize_t
でsys/types.h
, 、署名されたタイプであると定義します。ライブラリの一部のコードは依存しますsize_t
である 符号なし型であり、動作しません 署名されていれば正しく。期待する GNU C ライブラリ コード
size_t
署名されていないのが正しいです。の定義size_t
署名されたタイプが間違っているため。バージョン2.4では、GCCが常に定義することを計画していますsize_t
署名されていないタイプとして、および「fixcludes」スクリプトはシステムのマッサージを行いますsys/types.h
これと対立しないように。それまでの間、私たちはGCCに明示的に署名されていないタイプを使用するように伝えることでこの問題を回避します
size_t
GNU Cライブラリをコンパイルするとき。「構成」は、GCCが使用するタイプを自動的に検出しますsize_t
必要に応じて上書きするように手配してください。
署名付きバージョンが必要な場合は、 size_t
使用 ptrdiff_t
または、一部のシステムでは、次の typedef があります。 ssize_t
.
他のヒント
size_t
C++ C 標準に従って、符号なし整数型です。を備えた実装はすべて、 size_t
signed は重大な不適合であり、おそらく他の移植性の問題も抱えています。オーバーフロー時にラップアラウンドすることが保証されているため、次のようなテストを作成できます。 if (a + b < a)
オーバーフローを見つけるために。
size_t
記憶に関係するものに最適なタイプです。あなたは正しくやっています。
size_t
署名されていない必要があります。
通常、unsigned long として定義されます。
それ以外に定義されているのを見たことがありません。 ssize_t
署名された対応物です。
編集:GCC は、状況によっては署名済みとして定義します。ASNI C モードまたは std-99 でコンパイルすると、強制的に署名が解除されます。
C 言語の場合は、次を使用します。 IntSafe. 。これも Microsoft によってリリースされています (C++ ライブラリ SafeInt と混同しないでください)。IntSafe は、数学を実行し、安全に変換を行うことができる C 言語関数呼び出しのセットです。intsafe 関数の URL を更新しました
使用 セーフイント. 。これは Michael Howard によって設計され、Microsoft からオープンソースとしてリリースされたクラスです。オーバーフローがリスクとして認識される場合に整数を操作できるように設計されています。すべてのオーバーフローは例外に変換されて処理されます。このクラスは、正しい使用法を簡単に行えるように設計されています。
例えば :
char CouldBlowUp(char a, char b, char c)
{
SafeInt<char> sa(a), sb(b), sc(c);
try
{
return (sa * sb + sc).Value();
}
catch(SafeIntException err)
{
ComplainLoudly(err.m_code);
}
return 0;
}
また、safeint は Microsoft 社内で Office などの製品によく使用されています。
参照:リンクテキスト
質問を正確に理解したかどうかはわかりませんが、次のようなことができるかもしれません。
temp = value_to_be_added_to;
value_to_be_added_to += value_to_add;
if (temp > value_to_be_added_to)
{
overflow...
}
より低い値に折り返されるため、オーバーフローしたかどうかを簡単に確認できます。