In the example below, the initializer is one element smaller than the static array. In this case avr-g++-6.3 as well as avr-g++-7.0 produces code with no elements in the data-section (initializer). That is what I would expect.
#include <stdint.h>
volatile uint8_t x = 0;
volatile uint8_t y = 0;
int main() {
constexpr uint8_t l[4] = {0, 1, 2};
y = l[x];
while(true) {}
}
But, if I change the code to
#include <stdint.h>
volatile uint8_t x = 0;
volatile uint8_t y = 0;
int main() {
constexpr uint8_t l[3] = {0, 1, 2};
y = l[x];
while(true) {}
}
(here the static array length is as smal as possible)
both compiler generate a data section of 4 bytes. Thats very(!) surpising for me. The effect is reproducible with all kinds of static arrays as well as with std::array<>, if the size of the array is the same as the number of initializers.
Whats going on here?
Heres the assembler output for the first case:
.file "bm10a.cc"
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__SREG__ = 0x3f
__tmp_reg__ = 0
__zero_reg__ = 1
.section .text.startup,"ax",@progbits
.global main
.type main, @function
main:
push r28
push r29
rcall .
rcall .
in r28,__SP_L__
in r29,__SP_H__
/* prologue: function */
/* frame size = 4 */
/* stack size = 6 */
.L__stack_usage = 6
std Y+1,__zero_reg__
std Y+2,__zero_reg__
std Y+3,__zero_reg__
std Y+4,__zero_reg__
ldi r24,lo8(1)
std Y+2,r24
ldi r24,lo8(2)
std Y+3,r24
lds r30,x
add r30,r28
mov r31,r29
adc r31,__zero_reg__
ldd r24,Z+1
sts y,r24
.L2:
rjmp .L2
.size main, .-main
.global y
.section .bss
.type y, @object
.size y, 1
y:
.zero 1
.global x
.type x, @object
.size x, 1
x:
.zero 1
.ident "GCC: (GNU) 7.0.1 20170218 (experimental)"
.global __do_clear_bss
And here for the second case:
.file "bm10a.cc"
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__SREG__ = 0x3f
__tmp_reg__ = 0
__zero_reg__ = 1
.section .rodata
.LC0:
.byte 0
.byte 1
.byte 2
.section .text.startup,"ax",@progbits
.global main
.type main, @function
main:
push r28
push r29
rcall .
push __zero_reg__
in r28,__SP_L__
in r29,__SP_H__
/* prologue: function */
/* frame size = 3 */
/* stack size = 5 */
.L__stack_usage = 5
lds r24,.LC0
lds r25,.LC0+1
lds r26,.LC0+2
std Y+1,r24
std Y+2,r25
std Y+3,r26
lds r30,x
add r30,r28
mov r31,r29
adc r31,__zero_reg__
ldd r24,Z+1
sts y,r24
.L2:
rjmp .L2
.size main, .-main
.global y
.section .bss
.type y, @object
.size y, 1
y:
.zero 1
.global x
.type x, @object
.size x, 1
x:
.zero 1
.ident "GCC: (GNU) 7.0.1 20170218 (experimental)"
.global __do_copy_data
.global __do_clear_bss