I have a nested data structure containing arrays of bit fields which I need to compile with SDCC for the MCS-51 target.
This is a simplified example:
example.c
struct data {
unsigned char a : 1;
unsigned char b : 2;
};
struct data dummy[8];
void main()
{
}
Since struct data
contains 3 bits, 8 instances contain 24 bits in total, so 3 bytes of memory would be sufficient to store them.
But SDCC allocates 8 bytes, as we can see in the resulting example.asm
:
$ sdcc -c example.c
$ cat example.asm
[…]
; File Created by SDCC : free open source ANSI-C Compiler
; Version 3.5.0 #9253 (Mar 19 2016) (Linux)
[…]
.module example
.optsdcc -mmcs51 --model-small
[…]
.area DSEG (DATA)
_dummy::
.ds 8
Is there a way to get SDCC to allocate only 3 bytes for dummy
?
As a workaround I am currently not using a struct
at all, but instead use some macros for calculating the total size of the data structure, allocating a flat array of bytes, and generating the indices and bit masks for accessing the individual members. I would like to use syntax like dummy[5].b
instead.
Some compilers seem to have options to enable packing of bit fields (like #pragma pack
), but I did not find anything like that in the SDCC manual.
It is not possible in any compiler I afraid. It will allocate at least one byte for every struct
I would do something like this:
typedef struct {
unsigned char a0 : 1;
unsigned char b0 : 2;
unsigned char a1 : 1;
unsigned char b1 : 2;
unsigned char a2 : 1;
unsigned char b2 : 2;
unsigned char a3 : 1;
unsigned char b3 : 2;
unsigned char a4 : 1;
unsigned char b4 : 2;
unsigned char a5 : 1;
unsigned char b5 : 2;
unsigned char a6 : 1;
unsigned char b6 : 2;
unsigned char a7 : 1;
unsigned char b7 : 2;
}data;
data dx;
#define GT(dt,member,bit) ((dt).member ##bit)
void foo()
{
GT(dx,b,5) = 2;
}