LINUX.ORG.RU

Может, я чего-то не понимаю, но ведь трюк с union'ами - это machine-specific behaviour, а не undefined, т.е. единственная проблема - это непереносимость, а не то, что компилятор, следуя стандарту, может любую фигню сотворить, нет?

WizardOfOz
()
Ответ на: комментарий от WizardOfOz

Причем под непереносимостью я имею в виду непереносимость между BE/LE архитектурами, но совместимость внутри класса (при условии использования типов гарантированного размера)

WizardOfOz
()

Не знаю что за трюк, но все-равно сказану что-нибудь в lua структуры можно паковать так. Кажется и сишная либа где-то на просторах итернета есть, от создателя

makoven ★★★★★
()
Последнее исправление: makoven (всего исправлений: 1)
Ответ на: комментарий от WizardOfOz

это machine-specific behaviour, а не undefined

Я и написал: UB/ID, то бишь undefined behaviour/implementation defined.

т.е. единственная проблема - это непереносимость, а не то, что компилятор, следуя стандарту, может любую фигню сотворить, нет?

Вот я и вопрошаю - можно ли написать абсолютно переносимую хреновину без пятидесятистраничных ифдефов, при условии, что мы вызываем функцию для конкретной архитектуры:

SerialiseUINT32_LE(Bytes * bytes, uint32_t value)
SerialiseUINT32_BE(Bytes * bytes, uint32_t value)
someoneelsenotme
() автор топика
Ответ на: комментарий от someoneelsenotme

Я к тому, что если предпосылки, описанные в моем комментарии, правильные (поправьте, если это не так), то в чем вообще проблема юнионов?

WizardOfOz
()
Ответ на: комментарий от WizardOfOz

то в чем вообще проблема юнионов?

Проблема в том, что, например, написав библиотеку для сериализации и использовав ее в одном и том же проекте, но одну часть на ПК а вторую на железке получим UB.

someoneelsenotme
() автор топика

Через memcpy. Например, код

#include <stdint.h>
#include <string.h>

void
pack_uint32(char **buf, uint32_t value)
{
	memcpy(*buf, &value, sizeof(value));
	*buf += sizeof(value);
}
компилируется в
0000000000000000 <pack_uint32>:
   0:	48 8b 07             	mov    (%rdi),%rax
   3:	89 30                	mov    %esi,(%rax)
   5:	48 83 07 04          	addq   $0x4,(%rdi)
   9:	c3                   	retq  

Явного вызова memcpy не остаётся.

i-rinat ★★★★★
()
Ответ на: комментарий от someoneelsenotme

Если ещё добавить переворот be ↔ le, это будет абсолютно переносимо. С оптимизацией могут быть проблемы, да.

i-rinat ★★★★★
()

Используй сетевой порядок в сериализованых данных и функции hton*/ntoh* при сериализации и десериализации соответственно.

Sectoid ★★★★★
()

https://github.com/lattera/glibc/blob/master/sysdeps/ieee754/ieee754.h в глибцах так делают, так что для GCC это не UB

http://stackoverflow.com/a/11640603

Finally, one of the changes from C90 to C99 was to remove any restriction on accessing one member of a union when the last store was to a different one. The rationale was that the behaviour would then depend on the representations of the values. Since this point is often misunderstood, it might well be worth making it clear in the Standard.

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от Sectoid

я тоже к этому варианту склоняюсь. сетевой порядок много где применяется.

Iron_Bug ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.