構造体の初期化
幾つかの Windows API を呼び出す所を書き換えていて,
RECT や POINT の構造体の初期化で色々と気になり少し調べたことのまとめ.
class として書く場合は,コンストラクタで初期化しているので意識しない.
struct Vector2 { // Vector2 () {} Vector2 (T v=0) : x(v), y(v) {} Vector2 (T x, T y) : x(x), y(y) {} // ... T x ; T y ; } ;
MFC を使用している時も同様.
CRect rect(0,0,0,0) ;
他の Win32 の構造体だと
MEMORYSTATUSEX memStat ; memset(&memStat,0,sizeof(MEMORYSTATUSEX)) ; memStat.dwLength= sizeof(MEMORYSTATUSEX) ; ::GlobalMemoryStatusEx(&memStat) ;
Windows では ::ZeroMemory を使っていることもあり.
#define ZeroMemory(pb,cb) memset((pb),0,(cb))
これまで RECT を 0 にする場合,次の様にも書いていた.
RECT rect = { 0,0,0,0 } ;
次の様に省略する方法もあるのは知っていたがあまり使っていない.
RECT rect = { 0 } ;
K & R 2nd の A8.7 に書かれている.
Web で検索すると ” RECT rect = { } ; ” の様な記述もあったが,これはどうかと…
構造体のコピーや戻り値は悩む所.
RECT の様な単純な構造では特に問題ないと思う.
XML などのツリー構造の場合はデータにより時間がかかるので注意が必要.
2020/10/13
次の様なコードで動作 を確認.
struct strct_c { i__8 i1 ; i_32 i4 ; i_16 i2 ; i_64 i8 ; } ; bool test_struct (void) { strct_a sa_rn ; strct_b sb_rn ; strct_c sc_rn ; strct_a sa_f0 = {1,2,3,4} ; strct_b sb_f0 = {1,2,3,4} ; strct_c sc_f0 = {1,2,3,4} ; strct_a sa__0 = {0} ; strct_b sb__0 = {0} ; strct_c sc__0 = {0} ; strct_a sa_m0 ; memset(&sa_m0,0,sizeof(sa_m0)) ; strct_b sb_m0 ; memset(&sb_m0,0,sizeof(sb_m0)) ; strct_c sc_m0 ; memset(&sc_m0,0,sizeof(sc_m0)) ; ::dump_mem(&sc_rn,sizeof(sc_rn)) ; ::dump_mem(&sc_f0,sizeof(sc_f0)) ; ::dump_mem(&sc__0,sizeof(sc__0)) ; ::dump_mem(&sc_m0,sizeof(sc_m0)) ; return true ; }