-
Notifications
You must be signed in to change notification settings - Fork 5
Takym QA NoAlign
Takym (たかやま) edited this page Oct 6, 2024
·
4 revisions
VC++ でも GCC でも #pragma pack(1)
に対応している。
アラインメントの無効化にはこれを使うべき。
// 現在のアラインメント設定をバックアップする
#pragma pack(push)
// アラインメントを 1 に設定する(つまり、アラインメントを無効化する)
#pragma pack(1)
// 構造体を定義する
typedef struct _STRUCT_A_
{
// 任意のフィールド変数
} StructA;
// アラインメント設定をバックアップから復元する
#pragma pack(pop)
// GCC g++ -m64 -o noalign.elf noalign.cpp; ./noalign.elf
// VC++ cl noalign.cpp & noalign
#define STRUCT_DATA { int data1; char data2; long long data3; char data4; }
struct A STRUCT_DATA;
#pragma pack(push)
#pragma pack(1)
struct B STRUCT_DATA;
#pragma pack(pop)
struct C STRUCT_DATA;
#ifdef __GNUC__
#define NOALIGN __attribute__((packed))
#else
#define NOALIGN __declspec(align(1))
#endif
struct D1 STRUCT_DATA NOALIGN;
struct NOALIGN D2 STRUCT_DATA;
struct alignas(1) E STRUCT_DATA;
#include <stdio.h>
int main(int argc, char *argv[], char *envp[])
{
A a;
B b;
C c;
D1 d1;
D2 d2;
E e;
printf("A : %4zd (data4: %016llX)\r\n", sizeof(A ), ((long long)(&a .data4 - ((char *)(&a )))));
printf("B : %4zd (data4: %016llX)\r\n", sizeof(B ), ((long long)(&b .data4 - ((char *)(&b )))));
printf("C : %4zd (data4: %016llX)\r\n", sizeof(C ), ((long long)(&c .data4 - ((char *)(&c )))));
printf("D1: %4zd (data4: %016llX)\r\n", sizeof(D1), ((long long)(&d1.data4 - ((char *)(&d1)))));
printf("D2: %4zd (data4: %016llX)\r\n", sizeof(D2), ((long long)(&d2.data4 - ((char *)(&d2)))));
printf("E : %4zd (data4: %016llX)\r\n", sizeof(E ), ((long long)(&e .data4 - ((char *)(&e )))));
return 0;
}
それぞれの指定方法で異なる動作になったり、環境によって機能しなかったりする場合がある。
筆者の環境では #pragma pack(1)
を指定した struct B
で想定通りに機能した。
GCC を使う時は、個人的には、__attribute__((packed))
を多用していたが今後は控える事にする。