или нет?
#define RG_ADDR 0xA8800800
struct RG_Params_s
{
uint32_t:12;
uint32_t PAR_1:1;
uint32_t PAR_2:1;
uint32_t PAR_3:1;
uint32_t :1;
uint32_t PAR_4:16;
};
void InitRG()
{
RG_Params_s OutCfg;
memset(reinterpret_cast<void*>(RG_ADDR),0,sizeof(RG_Params_s));
OutCfg.PAR_1=1;
OutCfg.PAR_2=0;
OutCfg.PAR_3=1;
OutCfg.PAR_4=0;
memcpy(reinterpret_cast<void*>(RG_ADDR),&OutCfg,sizeof(RG_Params_s));
}
(где здесь с++? Ну, в этой функции его в общем-то нет, согласен, ибо тут он не нужен, он есть в окрестностях, которые к вопросу не имеют отношения)
Если тут UB нет, тогда продолжим.
Собственно, в чём вопрос. В результате компиляции этого под MIPS32 я получил такой "выхлоп":
_Z6InitRGv:
lui $v0, 0xA880
li $v1, 0x5000
sw $v1, 0xA8800800
sh $zero, 0xA8800802
jr $ra
nop
но только есть одна загвоздка: в эту зону памяти можно писать только 32-х разрядными словами. Соответственно, инструкция sh вместо обнуления того, что она хочет обнулить, стирает всё, что было записано.
В общем, с этим можно как-то бороться стандартными средствами, например "объяснив" компилятору/линкеру, что на этом участке запрещены некоторые операция с памятью? Или шансов нет, и нужно такое писать на ассемблере?
Это не уб вроде
Чеза зона такая, уверен что компилятор умеет вобще в такое?
#вопрос из цикла "поюби моё UB"
Обсуждают сегодня