スタッフブログ

スタッフブログ

c言語の汎整数拡張

2011.04.21

弊社が開発・検証を行うソフトウェアは組み込み系分野が大半を占めています。
この分野ではc言語、c++などがまだまだ現役で使われていますので、検証業務にあたらせて頂くシステムがc言語によって開発されている事が非常に多いです。
検証作業の一工程として、ソフトウェアの静的解析を行うのですが、この「汎整数拡張」という挙動をあまり意識出来ていない(または存在を知らない?)ソースコードを見かける事が多いように思います。

ちなみに、汎整数拡張とは
int型あるいはunsigned int型を使用できる式の中では、char,short,int,intビットフィールドの符号付き符号無しにかかわらず、それらをint型で元の型の全ての値を表現できるならばint型に、それ以外はunsigned int型に変換するということである。
Wikipediaより引用

というものです。
unsigned char型で定義していた変数が、式(演算)の中で実はint型で処理されていたりする訳です。
例えば、a=b+c という単純な式があった場合、変数b,cともにunsigned charで定義されていても、変数aに代入される直前まではint型で計算されています。
よって、b+cの結果がunsigned charの上限値(255)を超えた場合でも、その値は切り落とされる事無く演算されます。
b=128,c=128 の場合・・・
aの型がunsigned charであれば、結果的にaの値は0になりますが、もし、aがint型であったとすれば、その結果は256となります。

上記は非常に単純で極端な例ですし、aがint型である時点でトリッキーなソースなのですが、もちろん汎整数拡張は代入演算を行う時だけに限った話しではありません。
if文での比較の中で演算を行っている場合や、switch case文、またbit演算を行う場合や、関数への引数として演算した結果を渡す場合などもそうです。
特に、符号無しから符号ありの状態へと変換される場合には、比較文などでは注意が必要ですね。

そもそもunsigned char型なんて使わないよ・・・なんてプログラマの方もおられるかもしれませんが、ハードウェアと密に関わる組み込み系分野では、8bit,16bit,32bit・・・
はたまたbitを論理積したりだ、反転したり・・・と言った操作を行う事が往々にしてあると思います。
汎整数拡張によってどのように処理されるか、使用している処理系のint型のサイズはいくつか、符号指定無しのchar型はどのように解釈されるのか・・等など見た目に気付きにくい箇所が大きな不具合となりかねませんので皆様お気をつけ下さい。

ソースコードの解析で品質向上を
<a href="../../">01フィラメント株式会社</a>

アバター画像
記事作成者

社長

アーカイブ