はじめに
オーバーフロー、アンダーフローは意味が曖昧なまま使われているので、
一般的にどのような定義になっているのかまとめて見ました。
注意:
「うちは社内方言でこうだ」と言うのを否定するものではありません。
種類
一般的な定義の有無は対象が整数なのか浮動小数点数なのか、
はたまたバッファなのかによって異なるようです。
いかに示す通り、整数のアンダーフローのみ一般的な定義はありません。
オーバーフロー | アンダーフロー | |
---|---|---|
整数 | YES | NO |
浮動小数点数 | YES | YES |
バッファ | YES | YES |
整数
オーバーフロー
そのビット幅で表現できる範囲の最大値を上回った場合、下限を下回った場合がオーバーフローです。
Wikipedia : https://en.wikipedia.org/wiki/Integer_overflow
8bitの符号なし整数に入る値の範囲は0~255ですが、これを超えた場合が以下の例です。
#include<stdio.h>
#include<stdint.h>
void main(void)
{
uint8_t a = 255;
printf("a:%d\n", a);
a++;
printf("a:%d\n", a);
}
結果:
このようにa++の結果、aは256にはならず0になります。
a:255
a:0
下限を下回った場合も オーバーフロー です。
以下の例は上記と同様ですが、今度は下限値0から更にデクリメントしています。
uint8_t b = 0;
printf("b:%d\n", b);
b--;
printf("b:%d\n", b);
結果:
b:0
b:255
アンダーフロー
整数の場合、一般的な定義は特に無いようです。
浮動小数点数
MSDNの記事が良い感じにまとまっています。
https://msdn.microsoft.com/ja-jp/library/hd7199ke.aspx
オーバーフロー
整数型と同じように、浮動小数点数型にも表現できる最大数があります。
詳しくは上記のMSDNのページをご覧ください。
アンダーフロー
こちらは整数型にはない要素です。
値が限りなく0に近づいて表現しきれなくなると、浮動小数点数で表現しきれなくなります。
Wikipedia : https://en.wikipedia.org/wiki/Arithmetic_underflow
しかし、用途によっては単に0と扱ってしまえば良かったりもします。
バッファ
オーバーフロー
Wikipedia : https://en.wikipedia.org/wiki/Buffer_overflow
確保している領域からはみ出してアクセスしてしまう事です。
PCなどのリッチな環境だとMMUで止めてくれたりしますが、
組み込み系の場合、特にスタックオーバーフローすると被害が甚大です。
ありがちな例:
uint8_t buf[4];
/* Correct condition is "i < 4" */
for(i = 0; i <= 4; i++){
buf[i] = i;
}
アンダーフロー
バッファアンダーランの別名です。
オンラインの動画配信サービスで再生が止まるのは
再生用バッファの枯渇(=アンダーラン)によるものです。
ソース
一応、Githubに上げておきました。
https://github.com/YankeeDeltaBravo225/Overflow_sample
バッファオーバーフローのやつは環境によっては
セグメント違反が起きるかもしれないので要注意です。