組み込みC/C++

C/C++リテラシー向上のためのページ

ポインタでやってしまうミス④

C++は型Checkが厳密で暗黙の型変換で行けると思っていたらキャストをつけないといけないパターンに良く出くわします。しかし気軽にキャストしていると思わぬ落とし穴がありますので切り取っておきます。

 

Pattern5

#include "stdafx.h"

typedef short LEVEL;
void getLevel( LEVEL *iLev);

int _tmain(int argc, _TCHAR* argv[])
{
	unsigned char iLev = 0;

	getLevel((LEVEL*)&iLev);

	return 0;
}

void getLevel( LEVEL *iLev)
{
	*iLev = 5;
}

 

想定としては、関数getLevelは何かの設定値を教えてくれる隠蔽された関数だとします。データ型のLEVELも良く検索しないとその型は不明なんですが、設定値の上限だけは知っていてuint8で充分な大きさである事を知っているためiLevの型はunsigned char型にしました。

ローカルに宣言した値iLevに設定値をもらいたいのでポインタにして渡しているだけですが、このプログラムを実行すると何が起こるでしょうか?

 

iLevがunsinged char型なので汎用ポインタもしくはStackには1byteだけが割り当てられます。しかしLEVEL型はshortなので*iLev = 5; は 2byteの代入が行われます。という事はiLevの隣のアドレスが00で破壊されてしまいgetLevelを呼び出した後の動作が不定になります。この場合は宣言時にunsigned char iLev; ではなくLEVEL型を使用することが推奨されます。

 

まとめ

キャストを使う前に使用する型に合わせた宣言を心掛ける。