LINUX.ORG.RU

union { double, struct {} }

 


0

2

Занимался археологией, обноружил монструозную конструкуию

union
{
 double dummy;
 struct {
   int;
   void *;
 }
}

Чтот это за особый вид извращения? Чего пытается добиться автор сих строк?

★★★★★

Возможно, это такой способ обеспечить выравнивание структур по sizeof(double)

XMs ★★★★★
()
Ответ на: комментарий от legolegs

Так как ТС занимался археологией, я допустил, что код писался до массового распространения 64-битных машин

XMs ★★★★★
()
Ответ на: комментарий от invy

Ну а какая ещё может быть цель… Скорость.

fornlr ★★★★★
()
Ответ на: комментарий от invy

Ты это вывел из контекста использования, либо из названия?

По поводу причин. Очевидно, что данный кон не сишка и его писала обезьяна. А обезьяна не руководствуется какой-то логикой и искать её бессмысленно. Там всё сводится к шанским обрядам.

Причин может быть много. Нужно смотреть контекст использования. Самое адекватное - это выравнивание, что уже было сказано выше. Так же это могут быть всякие шаманские практики. Допустим, адепт мог верить в то, что добавив эту херню он сделает так, что структура всегда будет 8 байт. Такой себе шаманский pack.

Там среди обезьян много подобных практик. И само подобное «выравнивание» - это шаманизм. Потому как человек на подобном дерьме писать не будет.

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

Из контекста.

На шампнизм похоже,да. Там ещё volatile кругом натыканы в надежде «синхронизировать» :D

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

Я тоже считаю что это непонятно что, но я стараюсь перепроверить, прежде чем безвозвратно выкинуть это г.

invy ★★★★★
() автор топика

У меня еще есть подозрение что это выдрано с stackoverflow, но поиски пока успехом не увенчались :D

invy ★★★★★
() автор топика

На 32 битной машине запихивать указатель на данные и число обозначающее тип данных в double, затем этот double извлекается и записывается в функцию которая принимает даблы, функция снова запаковывает этот double в union смотрит через swith() что там в int если там -1 например значит это не указатель на данные (я зх конечно но может там битовая магия между делом ещё что бы это провернуть =) И гарантировать что значение дабла как данных не затрёт биты значения типа ой всюооо хехехе), а сами данные в виде double изначального, производит расчёты возвращает результат если в int числа 1,2,3,4… то узнавая тип извлкает указатель и приводит к нужному значению целому/вещественному/иной структуре или массиву чего угодно, производит расчёты и возвращает резуальтат, ооочень часто в эту функцию приходят double просто как данные, а иногда как вот такая вундервафля. Это я всё придумал конечно, но чем чёрт не шутит. А вообще без контекста не понять. Нужны 2 места первое где и как и что в этот юнион суётся и где как и что извлекается. Ты вероятно, да что вероятно ты сто пудов знаешь, но решил лулзы половить послушав наши догадки =)

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

Какое у тебя сложное построение. А ведь

double dummy;

подразумевает, что это значение никак не используется.

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

Подразумевает одно, а делает другое. Ой чё не видали что-ли. Я с гитхаба чёт собирал помню, падало, падало. Всё проверял, ну блин думаю чё такое. а такое было это что в конце структуры был char padding[10]; А падало потому что в другом месте оказывается блок выравнивания структуры использовался как счётчик, а изначально не был инициализирован естесна и данным задавался индекс от балды и всё падало. Вот те и dummy вот те и padding =)

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

функция снова запаковывает этот double в union смотрит через swith() что там в int если там -1 например

В С++ это UB конечно.

It’s undefined behavior to read from the member of the union that wasn’t most recently written

В С хотя такое можно, но у темы тег С++

If the member used to access the contents of a union is not the same as the member last used to store a value, the object representation of the value that was stored is reinterpreted as an object representation of the new type (this is known as type punning). If the size of the new type is larger than the size of the last-written type, the contents of the excess bytes are unspecified (and may be a trap representation)

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

В С++ это UB

Ааа, ну я не знал. Я плюсы только на картинках видел. Ну ладно =) Всё равно интересно ::) Высказывайте свои мысли пока ТС все карты не выложил! Во весело =)

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2)
Ответ на: комментарий от LINUX-ORG-RU

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

Вот так и живём. Вроде как человек всё это создал, всё известно и описано. Но рядовые адепты деградировали до уровня средневековых магических обрядов.

anonymous
()

Чтот это за особый вид извращения? Чего пытается добиться автор сих строк?

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

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

и тем не менее при правильном касте это все еще возможно, непонятно кого это должно было остановить по мнению крестян с колхоза имени Бьярне.

anonymous
()
Ответ на: комментарий от LINUX-ORG-RU

Да все там можно, просто крестьяне кидаются под колеса телеги, и метают те ломы в те колеса тех телег. Кому нужно такое сравнение просто кастанет или в int* или в void* или свой int* приведет к int. Крестьяне опять браги перехлебали и сочинили это недоразумение которое должно было кого-то от чего-то защитить.

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

непонятно кого это должно было остановить по мнению крестян с колхоза имени Бьярне.

Вот бумага в которой описываются причины изменения:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3478.html

Так-то не часто встретишь сравнение указателей и чисел, просто сегодня в багрепорте к Visual C++ увидел, типа MSVC не соблюдает стандарт, а clang и gcc соблюдают, и ссылку на бумагу дали, с просьбой пофиксить баг…

fsb4000 ★★★★★
()
Ответ на: комментарий от anonymous

Да ладно, многие вещи именно таким образом и делаются явными и красивыми, например узнать значения бита числа минуя битовые операции, положил структуру с битовыми полем и число в объединение и читай значения битов, всё цивильно, красиво именованно, никаких масок, никаких сдвигов. Или удобно заполнить структуру из массива или массив из структуры за раз. Понятное дело что можно и шаманить. Но что бы шаманить это надо либо что бы реально приперло и по иному херня выходит. Или если … со стак оверфлов магию к себе копипастить, типа робит и норм, а то что там может половина лишнего, ну и хер с ним :D Вот во втором случае да, это жопа. Новый человек придёт такой и репу до дырки чесать будет пытаясь опстичь тайный смысл переменной которая нигде более не используется ))))))) и боясь её удалить, а если там ещё и макрогенерация то и удалять будет нечего ибо даже не увидит скорее всего ))))))

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от fsb4000

Бумага из райцентра пришла, теперь велено в свинарник заходить из одного входа, а выходить из другого.

Учитывая что С и С++ это про мятежный дух и противоречия, видимо участники торжества с этой бумагой в сельский нужник сходят.

По поводу того часто или не часто, если есть такая задача, то это сравнение будет произведено и наворачивание этой бессмысленной крестьяно-защиты ведь никак от этого не убережет, зачем вообще тогда ее вводить, может достаточно просто оставлять дисклеймер по типу «ОСТАНОВИСЬ, ПОДУМОЙ!».

anonymous
()
Ответ на: комментарий от LINUX-ORG-RU

Если и писать хаки то их надо документировать хотя бы комментариями, если этого не делать это не просто говнокод, а неоправданный говнокод.

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

Ну там топик стартеру не задонатили комментом в исходник, чво поделать либо разбираться ему, а нам тут фантазировать ибо инфа околонулевая. Либо фтопку удалить и смотреть что будет :D

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Как и большинство вопросов на форумах, проверять и разбираться лень, вдруг кто-то знает что это такое.

anonymous
()
Ответ на: комментарий от LINUX-ORG-RU

Битовые поля сейчас уже не модно, так как разные компиляторы их могут понимать по разному. Так что таки битовые операции и макросы на них.

slapin ★★★★★
()

Автор просто говнокодер и пытался в выравнивание, а может какие-то отладочные костыли не убрал при релизе.

peregrine ★★★★★
()
Ответ на: комментарий от anonymous

И тем не менее за подобные извращения, как и за всю преждевременную оптимизацию надо бить по рукам, больно. Чтобы всякие клоуны не творили говнокод.

peregrine ★★★★★
()
Ответ на: комментарий от invy

По «union «double dummy»» находится несколько ссылок на SO где сказано, что это делается для выравнивания. Пусть и остальное содержимое юниона не такое.

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

В С хотя такое можно

Все говорят, но никто пока не мог показать где «можно». В стандарте есть только одно подстрочное примечание, которое это разрешает. Но подстрочные примечания не нормативны.

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

If T is a union type, the first non-static named data member is zero-initialized and all padding is initialized to zero bits.

Ну и работало оно на x86 навернре у как раз пару полей без конструктора инициализировало.

На x64 ..uh oh.

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

Вот посмотрите код из harbour

// --- Items hold at the virtual machine stack
//
typedef struct _HB_ITEM {

 HB_TYPE  type;                                            // Тип элемента

 union {

  hb_struArray     asArray;
  hb_struBlock     asBlock;
  hb_struDateTime  asDateTime;
  hb_struDouble    asDouble;
  hb_struInteger   asInteger;
  hb_struLogical   asLogical;
  hb_struLong      asLong;
  hb_struPointer   asPointer;
  hb_struHash      asHash;
  hb_struMemvar    asMemvar;
  hb_struRefer     asRefer;
  hb_struEnum      asEnum;
  hb_struExtRef    asExtRef;
  hb_struString    asString;
  hb_struSymbol    asSymbol;
  hb_struRecover   asRecover;

 } item;

_HB_ITEM() {                                               // Default constructor

  type = HB_IT_NULL;

}                                                          // _HB_ITEM() {

} HB_ITEM,  *PHB_ITEM;

Надеюсь понятно, зачем нужен union?

В

union
{
 double dummy;
 struct {
   int;
   void *;
 }
}

что-то из этой серии …
Что касаемо dummy, то скорее всего в исходниках имеются переменные типа double, которые по существу являются значениями структуры

struct { int; void *; }

Владимир

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

на x86_64 и arm64 не должен

Update: а, вру, как раз на них и должен

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

попытка выравнять на 64 байта во времена С++03 и ниже, на типичных процессорах смысла от сего шаманства в районе 0-я

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

Про какое выравнивание то вы всё толкуете?

У

union D
{
 double dummy;
 struct {
   int a;
   void * b;
 };
};

и

 struct A{
   int a;
   void * b;
 };

Выравнивание абсолютно одинаковое, что на 32 bit, что на 64 bit.

https://gcc.godbolt.org/z/o5hWf7

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

Выравнивание абсолютно одинаковое, что на 32 bit, что на 64 bit

Возможно, это просто частные случаи. Я тоже за вариант «для выравнивания».

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

Попробовал на OpenWatcom, но программа не собралась, так как компилятор не поддерживает alignof.

Посмотрел в доках(http://download.xskernel.org/docs/compilers/c_cpp/watcom/1.5/cguide.pdf), пишут что для 16 bit по умолчанию используется режим zp2. Но можно компилятору указать любой режим. Так что с указанием режима, этот трюк с union double можно использовать для выравнивания…

таблица режимов:

                   zp1     zp2     zp4     zp8     zp16
sizeof(member)  \---------------------------------------
        1       |   0       0       0       0       0
        2       |   0       2       2       2       2
        4       |   0       2       4       4       4
        8       |   0       2       4       8       8
        16      |   0       2       4       8       16
fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

шланг-о проблемы :) ГСС компиляет и оно даже работает:)

Так что единственное что ты узнал - шланг шлак

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

шланг-о проблемы :) ГСС компиляет и оно даже работает:)

то есть ты не переходил по ссылкам на godbolt? Там же написано что ошибки компиляции и на gcc trunk и на clang.

Да в gcc 10 и раньше был баг, что тот код компилился, но он исправлен, и как видишь в trunk выдаёт ошибку компиляции, а значит и в gcc 11 будет ошибка компиляции.

Бумаги комитета должен исполнять любой компилятор C++…

fsb4000 ★★★★★
()
Ответ на: комментарий от anonymous

А что им запретили сравнивать поинтеры? А чего так?

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