1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
#define CONCAT(a, b) a##b
#define CONCAT2(a, b) CONCAT(a, b)
#define STATIC_ASSERT(condition) \
int CONCAT2(some_array, __LINE__)[(condition) ? 1 : -1]
#ifndef __GNUC__
#define __builtin_offsetof(a, b) ((unsigned long long)&(((a *)0)->b))
#endif
#ifdef __GNUC__
struct my_struct1a {
char ch1;
int i; // this would normally be padded, but it won't!
char ch2;
} __attribute__((packed));
STATIC_ASSERT(__builtin_offsetof(struct my_struct1a, i)==1);
STATIC_ASSERT(__builtin_offsetof(struct my_struct1a, ch2)==5);
struct my_struct1b {
char ch1;
// this would normally be padded, but it won't!
int i __attribute__((packed));
char ch2;
};
STATIC_ASSERT(__builtin_offsetof(struct my_struct1b, i)==1);
STATIC_ASSERT(__builtin_offsetof(struct my_struct1b, ch2)==5);
struct my_struct1c {
char ch1;
// this would normally be padded, but it won't!
struct
{
int i;
} sub __attribute__((packed));
char ch2;
};
STATIC_ASSERT(__builtin_offsetof(struct my_struct1c, sub.i)==1);
STATIC_ASSERT(__builtin_offsetof(struct my_struct1c, ch2)==5);
struct my_struct1d {
char ch0;
// the next field isn't padded
struct
{
char ch1;
int i; // this _is_ padded!
} sub __attribute__((packed));
char ch2;
};
STATIC_ASSERT(__builtin_offsetof(struct my_struct1d, sub.ch1)==1);
STATIC_ASSERT(__builtin_offsetof(struct my_struct1d, sub.i)==5);
STATIC_ASSERT(__builtin_offsetof(struct my_struct1d, ch2)==9);
struct __attribute__((packed)) my_struct2 {
char ch1;
int i; // this would normally be padded, but it won't!
char ch2;
};
STATIC_ASSERT(__builtin_offsetof(struct my_struct2, i)==1);
STATIC_ASSERT(__builtin_offsetof(struct my_struct2, ch2)==5);
typedef unsigned int uint32_t;
typedef unsigned long long int uint64_t;
struct formatted {
unsigned short moddate;
uint32_t crc32 __attribute__ ((__packed__));
};
STATIC_ASSERT(__builtin_offsetof(struct formatted, crc32)==2);
typedef struct __attribute__((__packed__))
{
uint32_t version;
} ipc_msg_hdr;
typedef struct
{
ipc_msg_hdr hdr;
uint32_t data_bytes;
uint64_t terminate;
} request_state;
STATIC_ASSERT(sizeof(ipc_msg_hdr)==4);
STATIC_ASSERT(__builtin_offsetof(request_state, data_bytes)==4);
STATIC_ASSERT(__builtin_offsetof(request_state, terminate)==8);
STATIC_ASSERT(sizeof(request_state)==16);
#endif
struct my_struct3 {
char ch1;
char ch2;
int i1; // this should be padded for 4-byte alignment
char ch3;
long long i2; // this should be padded for 8-byte alignment
char ch4;
int bf1 : 1; // MSVC pads this, the gcc/clang do not
int bf2 : 1; // MSVC pads this, the gcc/clang do not
int i3; // this should be padded for 4-byte alignment
};
STATIC_ASSERT(__builtin_offsetof(struct my_struct3, ch1)==0);
STATIC_ASSERT(__builtin_offsetof(struct my_struct3, ch2)==1);
STATIC_ASSERT(__builtin_offsetof(struct my_struct3, i1)==4);
STATIC_ASSERT(__builtin_offsetof(struct my_struct3, ch3)==8);
STATIC_ASSERT(__builtin_offsetof(struct my_struct3, i2)==16);
STATIC_ASSERT(__builtin_offsetof(struct my_struct3, ch4)==24);
#ifdef _MSC_VER
STATIC_ASSERT(__builtin_offsetof(struct my_struct3, i3) == 32);
#else
STATIC_ASSERT(__builtin_offsetof(struct my_struct3, i3)==28);
#endif
int main()
{
}
|