warning: padding struct to align ‘i2’
警告:i2′ を整列するため構造体に詰め物した
[-Wpadded]
■1.境界調整のために穴が開く
構造体のメンバの割り付けはコンパイラ任せなので
各メンバがピッタリ隙間なく割り付けられるとは限りません。
境界調整のために穴が開く場合があり
穴に何が書かれているかは誰もわかりません。
■2.構造体パディングの例
#include <stdio.h>
#include <string.h>
#include <stdint.h>
struct hole {
uint32_t i1 ;
uint8_t c ;
//3byteの穴
uint32_t i2 ;
} g = {
.i1 = 0x12345678,
.c = 0xab,
.i2 = 0x87654321
};
//自動変数領域をFFで汚す
//最適化されないよう自動変数を使う
static char gbuf[sizeof(struct hole)];
static void ff(void)
{
uint8_t buf[sizeof(struct hole)];
memset(buf,0xFF,sizeof(buf));
memcpy(gbuf,buf,sizeof(buf));
}
//構造体をダンプする
static void memdmp(void *d1,void *d2,size_t size)
{
uint8_t *aptr = d1;
uint8_t *gptr = d2;
for(size_t i = 0 ; i < size ;i++){
printf("%x %x\n",aptr[i],gptr[i]);
}
}
//メンバの内容が同じ構造体を比較する
static void memcmp_auto_global(void)
{
struct hole a = {
.i1 = 0x12345678,
.c = 0xab,
.i2 = 0x87654321
};
printf("比較結果=%d\n",memcmp(&a,&g,sizeof(a))) ;
memdmp(&a,&g,sizeof(g));
}
int main(void)
{
ff(); //自動変数領域をFFで汚す
memcmp_auto_global() ;
}
構造体の詰め物(=穴=パディング)の内容は
未規定(=コンパイラ依存)なので、
このプログラムの7行目の【穴】に何が入っているのか
わかりません。
実験ではこのプログラムは gcc と clang で実行結果が違い、
同じ gcc でも最適化レベルを変えると実行結果が変わりました。
この警告は -Wall -Wextra には含まれず、 -Wpadded を指定する必要があります。
参考:
EXP04-C. 構造体を含むバイト単位の比較を行わない
https://www.jpcert.or.jp/sc-rules/c-exp04-c.html
C-FAQ 2.8: なぜ構造体を比較することはできないのか。
http://www.kouno.jp/home/c_faq/c2.html#8