I have various constants. If I define them in a header file like this:

static const int my_thing_a = 3;
static const int my_thing_b = 12345;

then everything is nice, if I use them the compiler knows their value
and uses them as literals and it doesn't actually put them into the
.rodata section (which is important because I have a lot of them and
code space is at premium).

Now these things are very closely related, so it would make the program
much clearer is they could be collected in a structure. That is:

struct things { int a; int b; }; 

and then I could define a global structure

const struct things my_things = { 3, 12345 };

so that I can refer them as my_things.a or my_things.b;

The problem is that I do not want to instantiate the actual "things"
structure, for the same reason I did not want to instantiate the
individual const int definitions. So, I tried the GCC extension of
"compound literals" like this:

#define my_things ((struct things) { 3, 12345 })

int func( int x )
{
   if ( x )
      return my_things.a;
   else
      return my_things.b;
}

If I compile the above with -O2 or -Os, then if the target is AVR or
x86_64 then the result is what I expected, func() just loads 3 or 12345
then returns and that's all. There is no .rodata generated.

However, compiling for the ARM generates the same function code, but it
also generates the image of "things" in the .rodata segment. Twice. Even
when it stores 12345 separatelly. The code never actually references
any of them and they are not global thus it is just wasted memory:

        .section        .rodata
        .align  2
        .type   C.1.1095, %object
        .size   C.1.1095, 8
C.1.1095:
        .word   3
        .word   12345
        .align  2
        .type   C.0.1094, %object
        .size   C.0.1094, 8
C.0.1094:
        .word   3
        .word   12345
        .text
        .align  2
        .global func2
        .type   func2, %function
func2:
        ldr     r3, .L6
        cmp     r0, #0
        moveq   r0, r3
        movne   r0, #3
        bx      lr
.L7:
        .align  2
.L6:
        .word   12345
     
Is there a reason why GCC generates the unused .rodata for the ARM
while for the other two it does not?

I guess I'm doing something fundamentally wrong, as usual...

Thanks,

Zoltan

Reply via email to