Сообщение Re: Это UB ? от 01.07.2024 15:59
Изменено 01.07.2024 16:00 vsb
Re: Это UB ?
Здравствуйте, LaptevVV, Вы писали:
LVV>А сейчас ?
LVV>Где-то у меня в мозгах зацепилось, что это UB.
И сейчас UB. Хотя, наверное, работать везде будет. Но по правилам — в юнионах можно читать только те поля, куда ранее была запись.
LVV>Размещающий new — не предлагать
LVV>reinterpret_cast — можно попробовать.
LVV>variant ?
LVV>Что-то не совсем то, что мне нужно.
Могу ошибаться, но вроде можно прикастовать int* к char*. В С это должно работать, насчёт С++ не уверен. Тут, правда, тоже нюансы могут быть типа сколько там байтов в int и сколько битов в char — тоже величины не определённые.
А так — 100% правильный вариант это битовая арифметика. Хороший компилятор должен распознать замысел и преобразовать всё в ожидаемый код.
Вот пример с godbolt:
Это скомпилировалось в
То бишь в одну инструкцию. А когда компилятор это инлайнит по месту вызова, там вообще ничего не остаётся.
LVV>А сейчас ?
LVV>Где-то у меня в мозгах зацепилось, что это UB.
И сейчас UB. Хотя, наверное, работать везде будет. Но по правилам — в юнионах можно читать только те поля, куда ранее была запись.
LVV>Размещающий new — не предлагать
LVV>reinterpret_cast — можно попробовать.
LVV>variant ?
LVV>Что-то не совсем то, что мне нужно.
Могу ошибаться, но вроде можно прикастовать int* к char*. В С это должно работать, насчёт С++ не уверен. Тут, правда, тоже нюансы могут быть типа сколько там байтов в int и сколько битов в char — тоже величины не определённые.
А так — 100% правильный вариант это битовая арифметика. Хороший компилятор должен распознать замысел и преобразовать всё в ожидаемый код.
Вот пример с godbolt:
void u32to8(uint32_t u32, uint8_t *u8) {
u8[0] = u32 & 0xff;
u8[1] = (u32 >> 8) & 0xff;
u8[2] = (u32 >> 16) & 0xff;
u8[3] = (u32 >> 24) & 0xff;
}
Это скомпилировалось в
u32to8(unsigned int, unsigned char*):
str r0, [r1] @ unaligned
bx lr
main:
То бишь в одну инструкцию. А когда компилятор это инлайнит по месту вызова, там вообще ничего не остаётся.
Re: Это UB ?
Здравствуйте, LaptevVV, Вы писали:
LVV>А сейчас ?
LVV>Где-то у меня в мозгах зацепилось, что это UB.
И сейчас UB. Хотя, наверное, работать везде будет. Но по правилам — в юнионах можно читать только те поля, куда ранее была запись.
LVV>Размещающий new — не предлагать
LVV>reinterpret_cast — можно попробовать.
LVV>variant ?
LVV>Что-то не совсем то, что мне нужно.
Могу ошибаться, но вроде можно прикастовать int* к char* (но не наоборот). В С это должно работать, насчёт С++ не уверен. Тут, правда, тоже нюансы могут быть типа сколько там байтов в int и сколько битов в char — тоже величины не определённые.
А так — 100% правильный вариант это битовая арифметика. Хороший компилятор должен распознать замысел и преобразовать всё в ожидаемый код.
Вот пример с godbolt:
Это скомпилировалось в
То бишь в одну инструкцию. А когда компилятор это инлайнит по месту вызова, там вообще ничего не остаётся.
LVV>А сейчас ?
LVV>Где-то у меня в мозгах зацепилось, что это UB.
И сейчас UB. Хотя, наверное, работать везде будет. Но по правилам — в юнионах можно читать только те поля, куда ранее была запись.
LVV>Размещающий new — не предлагать
LVV>reinterpret_cast — можно попробовать.
LVV>variant ?
LVV>Что-то не совсем то, что мне нужно.
Могу ошибаться, но вроде можно прикастовать int* к char* (но не наоборот). В С это должно работать, насчёт С++ не уверен. Тут, правда, тоже нюансы могут быть типа сколько там байтов в int и сколько битов в char — тоже величины не определённые.
А так — 100% правильный вариант это битовая арифметика. Хороший компилятор должен распознать замысел и преобразовать всё в ожидаемый код.
Вот пример с godbolt:
void u32to8(uint32_t u32, uint8_t *u8) {
u8[0] = u32 & 0xff;
u8[1] = (u32 >> 8) & 0xff;
u8[2] = (u32 >> 16) & 0xff;
u8[3] = (u32 >> 24) & 0xff;
}
Это скомпилировалось в
u32to8(unsigned int, unsigned char*):
str r0, [r1] @ unaligned
bx lr
main:
То бишь в одну инструкцию. А когда компилятор это инлайнит по месту вызова, там вообще ничего не остаётся.