Created
April 1, 2019 10:46
-
-
Save BugsBeGone/8bf86685b532492f877a4ed5db7ce128 to your computer and use it in GitHub Desktop.
x86 Android native structure tests (for Java Native Access: https://github.com/java-native-access/jna/issues/1079)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* x86 linux (including Android) structure alignment test for JNA */ | |
#include <assert.h> /* static_assert() */ | |
#include <stddef.h> /* offsetof() */ | |
/* My own simple test struct example: a 4-byte float and an 8-byte double. | |
* With a maximum alignment of 4 bytes, it should not require any padding and | |
* should always take up just 12 bytes, regardless of the order of members. | |
*/ | |
typedef struct BugsBeGoneTestStructure { | |
float field1; /* offset: 0, size: 4, padding: 0 */ | |
double field2; /* offset: 4, size: 8, padding: 0 */ | |
} bbgts; /* Total size: 12 bytes */ | |
bbgts myts; /* Need an instance so we can use sizeof */ | |
/* Test offsets */ | |
static_assert(offsetof(bbgts, field1) == 0, "offsetof float (myts.field1) != 0"); | |
static_assert(offsetof(bbgts, field2) == 4, "offsetof double (myts.field2) != 4"); | |
/* Test sizes */ | |
static_assert(sizeof(myts.field1) == 4, "sizeof float (myts.field1) != 4"); | |
static_assert(sizeof(myts.field2) == 8, "sizeof double (myts.field2) != 8"); | |
/* Test total size */ | |
static_assert(sizeof(myts) == 12, "sizeof struct myts != 12"); | |
/* Test padding */ | |
static_assert((offsetof(bbgts, field2) - offsetof(bbgts, field1) - sizeof(myts.field1)) == 0, "padding for myts.field1 != 0"); | |
static_assert((sizeof(myts) - offsetof(bbgts, field2) - sizeof(myts.field2)) == 0, "padding for myts.field2 != 0"); | |
int main(void) { | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* x86 linux (including Android) structure alignment test for JNA */ | |
#include <assert.h> /* static_assert() */ | |
#include <stddef.h> /* offsetof() */ | |
/* This is the C equivalent of the definition for TestStructure, from method | |
* testGNUCAlignment() in master/test/com/sun/jna/StructureTest.java, line 170+. | |
*/ | |
typedef struct JNATestStructure { | |
char b; /* offset: 0, size: 1, padding: 1 */ | |
short s; /* offset: 2, size: 2, padding: 0 */ | |
int i; /* offset: 4, size: 4, padding: 0 */ | |
long l; /* offset: 8, size: 4, padding: 0 */ | |
float f; /* offset: 12, size: 4, padding: 0 */ | |
double d; /* offset: 16, size: 8, padding: 0 */ | |
} jnats; /* Total size: 24 bytes */ | |
jnats ts; /* Need an instance so we can use sizeof */ | |
/* According to the JNA source, the expected size of the struct is 28 or 32: | |
* "final int SIZE = Native.MAX_ALIGNMENT == 8 ? 32 : 28;" | |
* With NDK r17c (the last revision before gcc was removed), I get neither of | |
* these sizes compiling with i686-linux-android-gcc. Likewise with NDK r19c, | |
* I still get neither of these sizes compiling with i686-linux-android16-clang. | |
* In fact, no matter what NDK cross compiler I use to target x86, I always get | |
* the sizes and offsets in the below asserts, which all pass. | |
*/ | |
/* Test offsets */ | |
static_assert(offsetof(jnats, b) == 0, "offsetof char (ts.b) != 0"); | |
static_assert(offsetof(jnats, s) == 2, "offsetof short (ts.s) != 2"); | |
static_assert(offsetof(jnats, i) == 4, "offsetof int (ts.i) != 4"); | |
static_assert(offsetof(jnats, l) == 8, "offsetof long (ts.l) != 8"); | |
static_assert(offsetof(jnats, f) == 12, "offsetof float (ts.f) != 12"); | |
static_assert(offsetof(jnats, d) == 16, "offsetof double (ts.d) != 16"); | |
/* Test sizes */ | |
static_assert(sizeof(ts.b) == 1, "sizeof char (ts.b) != 1"); | |
static_assert(sizeof(ts.s) == 2, "sizeof short (ts.s) != 2"); | |
static_assert(sizeof(ts.i) == 4, "sizeof int (ts.i) != 4"); | |
static_assert(sizeof(ts.l) == 4, "sizeof long (ts.l) != 4"); | |
static_assert(sizeof(ts.f) == 4, "sizeof float (ts.f) != 4"); | |
static_assert(sizeof(ts.d) == 8, "sizeof double (ts.d) != 8"); | |
/* Test total size */ | |
static_assert(sizeof(ts) == 24, "sizeof struct ts != 24"); | |
/* Test padding */ | |
static_assert((offsetof(jnats, s) - offsetof(jnats, b) - sizeof(ts.b)) == 1, "padding for ts.b != 1"); | |
static_assert((offsetof(jnats, i) - offsetof(jnats, s) - sizeof(ts.s)) == 0, "padding for ts.s != 0"); | |
static_assert((offsetof(jnats, l) - offsetof(jnats, i) - sizeof(ts.i)) == 0, "padding for ts.i != 0"); | |
static_assert((offsetof(jnats, f) - offsetof(jnats, l) - sizeof(ts.l)) == 0, "padding for ts.l != 0"); | |
static_assert((offsetof(jnats, d) - offsetof(jnats, f) - sizeof(ts.f)) == 0, "padding for ts.f != 0"); | |
static_assert((sizeof(ts) - offsetof(jnats, d) - sizeof(ts.d)) == 0, "padding for ts.d != 0"); | |
/* If your compiler passes all of these static asserts with no complaints, that | |
* must mean that the default maximum alignment for linux x86 really is 4 bytes. | |
*/ | |
int main(void) { | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment