ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
18 июля
624674
VVB (13.10.2015 12:01 - 13:25, просмотров: 2075)
Господа, подскажите по C++ касательно конструктора Есть рабочий код { const VFPguard g; other_code(); } В данном случае используется принцип RAII (захват ресурса есть инициализация), переменная g хранит в себе контекст VFPv3-D16: extern "C" void vPortSaveVFP(VFPguard *s); extern "C" void vPortRestoreVFP(VFPguard *s); struct VFPguard { private: struct { uint64_t d[16]; uint32_t s; } d; public: VFPguard() {vPortSaveVFP(this);} ~VFPguard() {vPortRestoreVFP(this);} }; Ну и сами функции сохранения контекста:
    .syntax unified
    .cpu cortex-r4
    .fpu vfpv3-d16

    .text
    .arm
    .section .text, "ax" 
    .global vPortSaveVFP
    .global vPortRestoreVFP

/* Сохранение контекста VFP в указанном месте */
    .func vPortSaveVFP
    .type vPortSaveVFP, "function"
vPortSaveVFP:
    VSTM    R0!, {D0-D15}
    VMRS    R1, FPSCR
    STR     R1, [R0]
    bx      lr
    .size vPortSaveVFP, . - vPortSaveVFP
    .endfunc

/* Восстановление контекста VFP из указанного места */
    .func vPortRestoreVFP
    .type vPortRestoreVFP, "function"
vPortRestoreVFP:
    VLDM    R0!, {D0-D15}
    LDR     R0, [R0]
    VMSR    FPSCR, R0
    bx      lr
    .size vPortRestoreVFP, . - vPortRestoreVFP
    .endfunc

    .end
Компилятор gcc справедливо ругается на тот факт, что нет инициализации переменных класса: src/irq.cpp: In constructor 'VFPguard::VFPguard()': src/irq.cpp:42:1: warning: 'VFPguard::d' should be initialized in the member initialization list [-Weffc++] VFPguard::VFPguard() {vPortSaveVFP(this);} Однако, если я конструктор напишу подобным образом VFPguard::VFPguard() : d() {vPortSaveVFP(this);} то компилятор будет удовлетворён и вставит вызов memset для инициализации 0 всех 132 байт структуры d, что занимает лишних 320 тактов процессора на 200 МГц (видимо, memset из newlib неоптимально написана). Вызов абсолютно бесполезный, потому что в функции vPortSaveVFP() будет сразу же переписано содержимое структуры d. Если же я напишу VFPguard::VFPguard() : d() {vPortSaveVFP(this);} и изменю структуру d нижепоказанным образом, то компилятор продолжает быть удовлетворённым и всё равно обнуляет переменную d.s (ненужная операция). extern "C" void vPortSaveVFP(VFPguard *s); extern "C" void vPortRestoreVFP(VFPguard *s); struct VFPguard { private: struct regs { uint64_t d[16]; uint32_t s; regs() : s() {} } d; public: VFPguard() : d() {vPortSaveVFP(this);} ~VFPguard() {vPortRestoreVFP(this);} }; Как заставить компилятор компилировать без предупреждений (кроме отключения флага -Weffc++) ? Вот такой код с магическими числами делает то что надо struct VFPguard { private: uint32_t regs[16 * 2 + 1]; public: VFPguard() {vPortSaveVFP(this);} ~VFPguard(){vPortRestoreVFP(this);} }; Других вариантов нет?