Constexpr静态数组初始化和使用(使用avr-g ++)

时间:2017-03-01 12:52:46

标签: c++ arrays gcc constexpr

在下面的示例中,初始化程序是一个小于静态数组的元素。在这种情况下,avr-g ++ - 6.3以及avr-g ++ - 7.0会生成数据部分(初始化程序)中没有元素的代码。这就是我所期待的。

#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) {}
}

但是,如果我将代码更改为

#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) {}
}

(这里静态数组的长度尽可能小)

两个编译器都生成一个4字节的数据段。多数人(!)对我来说很惊讶。 如果数组的大小与初始化器的数量相同,则效果可以使用各种静态数组以及std :: array&lt;&gt;重现。

这是怎么回事?

第一种情况下的汇编输出:

    .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

这是第二种情况:

    .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

0 个答案:

没有答案