The preprocessor won't be able to figure out structure offsets, so no amount of macro magic alone will dump your offsets for you.
If you are building for embedded targets, you will probably be able to create .bin files (not elf, coff, mach-o). If you use each of your target compilers to create an array of offsets in an object file and then dump it to a bin file, it should be possible to compare the bin files for each of your targets. It would be a good idea to automate the process for build time checks.
Here is an example of what I'm talking about:
#include <stdint.h>
#include <stddef.h>
typedef struct s1{
uint16_t f1;
uint32_t f2;
uint64_t f3;
int8_t f4[5];
uint32_t f5[2];
}s1;
#define o(f) ((int32_t)offsetof(s1,f))
int32_t offsets[]={
o(f1),
o(f2),
o(f3),
o(f4),
o(f5)
};
This just creates a table of offsets. Build this for a mipsel and x86_64 and compare. Here is a make file:
T1:=x86_64-linux-gnu
CC1:=$(T1)-gcc
OBJCPY1:=$(T1)-objcopy
T2:=mipsel-linux
CC2:=$(T2)-gcc
OBJCPY2:=$(T2)-objcopy
.PHONY: all cmp clean hexdumps
all: hexdumps
hexdumps: hexdump.$(T1).txt hexdump.$(T2).txt
hexdump.$(T1).txt: offsets.$(T1).bin
hexdump -C $< > $@
hexdump.$(T2).txt: offsets.$(T2).bin
hexdump -C $< > $@
offsets.$(T1).bin: offsets.$(T1).o
$(OBJCPY1) -j.data -O binary $< $@
offsets.$(T2).bin: offsets.$(T2).o
$(OBJCPY2) -j .data -O binary $< $@
offsets.$(T1).o: offsets.c
$(CC1) -Wall -c -o $@ $<
offsets.$(T2).o: offsets.c
$(CC2) -Wall -c -o $@ $<
clean:
-rm -f offsets.$(T1).o offsets.$(T2).o
-rm -f offsets.$(T1).bin offsets.$(T2).bin
-rm -f hexdump.$(T1).txt hexdump.$(T2).txt
Now, comparing the offsets is pretty easy:
evaitl@evbb ~/se $ cat hexdump.mipsel-linux.txt
00000000 00 00 00 00 04 00 00 00 08 00 00 00 10 00 00 00 |................|
00000010 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020
evaitl@evbb ~/se $ cat hexdump.x86_64-linux-gnu.txt
00000000 00 00 00 00 04 00 00 00 08 00 00 00 10 00 00 00 |................|
00000010 18 00 00 00 |....|
00000014
The mips emits a 32 byte data section instead of the x86 20 byte. If you set the size of offsets
, you should be able to use cmp
to compare the two in your build.
If your targets have different endianess, you may need to change the o
macro to use ntohl
or some such to get both compilers to emit integers in the same format.
offsetof()
instddef.h
. See en.wikipedia.org/wiki/Offsetof – Comnenuspack
width for your structure and force the same value on both projects. – Apology<stdint.h>
will probably help) — but as soon as you hit a structure packing issue, you're hosed again, unless you're using serialization. – Buyer