clang compiler struct packing - always padded to 2bytes
Short: I'm unable to get my clang compiler to pack the packed_struct_test
test struct in lwip to 5 bytes. It always shows 6bytes.
Details:
Here's my test code (start section of lwip/src/core/init.c
), i commented out the original lwip definition in order to be sure that it is compiled, what i need.
#ifndef LWIP_SKIP_PACKING_CHECK
#ifdef PACK_STRUCT_USE_INCLUDES
//# include "arch/bpstruct.h"
#endif
// PACK_STRUCT_BEGIN
// struct packed_struct_test {
// PACK_STRUCT_FLD_8(u8_t dummy1);
// PACK_STRUCT_FIELD(u32_t dummy2);
// } PACK_STRUCT_STRUCT;
// PACK_STRUCT_END
struct __attribute__((packed)) packed_struct_test
{
uint8_t dummy1;
uint32_t dummy2;
};
#ifdef PACK_STRUCT_USE_INCLUDES
//# include "arch/epstruct.h"
#endif
#define PACKED_STRUCT_TEST_EXPECTED_SIZE 5
#endif
The packing check is done here:
#ifndef LWIP_SKIP_PACKING_CHECK
volatile int temp = sizeof(struct packed_struct_test);
LWIP_ASSERT("Struct packing not implemented correctly. Check your lwIP port.", temp == PACKED_STRUCT_TEST_EXPECTED_SIZE);
#endif
With the debugger i see that temp is 6 bytes long. If i remove the __attribute__((packed))
, it is 8.
I tried following:
#pragma pack(1)
(e.g. here)-fpack-struct=1
-O0
My compiler args look like this (removed the secret stuff):
C:/.conan/3535fc1/1/toolchains/tricore/v9.0.0/bin/clang.exe
-g
-Og
-march=tc162
-fno-common
-ffunction-sections
-fdata-sections
-Wall
-save-temps=obj
-MP
-Wno-parentheses-equality
-I...
-std=c99
-MMD
../....../init.c
-c
-o build-debug/....../init.o
Versions:
Here is a minimal reproducible example:
test.c
struct __attribute__((packed)) packed_struct_test
{
unsigned int dummy2;
unsigned char dummy1;
};
int main() {
volatile int temp = sizeof(struct packed_struct_test);
return 0;
}
To build it
clang.exe -g -O1 -march=tc162 -Wall -fpack-struct=1 -save-temps=obj -MP -std=c99 -MMD test.c -c -o test.o
Then in the tests.s in the line mov %d15, 6
it's visible, that the struct size is 6:
.Ltmp0:
.loc 1 9 5 prologue_end # test.c:9:5
mov %d2, 0
.loc 1 8 18 # test.c:8:18
mov %d15, 6
st.w [%a10], 4, %d15
.loc 1 9 5 # test.c:9:5
ret
.Ltmp1:
Got a reply from Hightec support:
You can use
attribute packed
orpragma pack (1)
and the struct internal fields wont be aligned. There is only one limitation with packed structs, that the overall struct size will be aligned to 2.
Seems like the compiler intentionally does that.