Здравствуйте, johny5, Вы писали:
J>Нет, т.к. результатом оператора = является l-value ссылка.
buf это тоже lvalue ссылка. buf=777; func(&buf), это то же самое, что func(&(buf=777));
По крайней мере в дизассемлерном листинге, гарантирую, код в обоих случаях будет одинаковым.
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, smeeld, Вы писали:
S>>buf это тоже lvalue ссылка.
U>утверждение не к месту и не верно. это и не lvalue и не ссылка
Если у нас есть некоторая int buf, аналог (наверно) DWORD-a, то для func(int& b) и её вызове func(buf),
параметр buf есть lvalue reference на buf, инфа 100%. И для func(int* b) и int buf, вызов func(&buf)
эквивалентен func(addressof(buf)), а addressof работает с ссылкой, и здесь, в addressof, buf есть
lvalue reference на buf, инфа 100%.
LD>Меня он смущает. Является ли он эквивалентом следующему: LD>
LD>BYTE *ptr;
LD>DWORD buf;
LD>// позже в цикле
LD>buf = 123;
LD>memcpy(ptr, &buf, sizeof(buf));
LD>
LD>Нет ли тут UB?
Насколько я понимаю, речь идет о чистом Си. Существенных отличий от a = b = c не заметно, только в качестве a выступает временный указатель, который инициализируется значением адреса b.
Возможно, это было сделано для какой-то хитрой оптимизации на специфической архитектуре, в которой, например, инициализация локальной переменной как-то связана (через аккумулятор или вспомогательный регистр) с взятием ее адреса без пенальти. Тогда при последовательном сохранении переменных в стек такая совмещенная инициализация даст выигрыш в сравнении с вариантом, когда мы сначала инициализируем, потом сохраняем и загружаем в аккумулятор другую переменную, теряя драгоценный контекст для взятия адреса. Другой вопрос, что сам вызов memcpy для побайтного разбиения 4-байтового числа выглядит на этом фоне оверхедом.
Здравствуйте, visual_wind, Вы писали:
_>Насколько я понимаю, речь идет о чистом Си. Существенных отличий от a = b = c не заметно, только в качестве a выступает временный указатель, который инициализируется значением адреса b.
Нет, это C++. Просто вот так написано. Студентом
ptr на самом деле указывает на начало std::vector<BYTE>)
_>Возможно, это было сделано для какой-то хитрой оптимизации на специфической архитектуре, в которой, например, инициализация локальной переменной как-то связана (через аккумулятор или вспомогательный регистр) с взятием ее адреса без пенальти. Тогда при последовательном сохранении переменных в стек такая совмещенная инициализация даст выигрыш в сравнении с вариантом, когда мы сначала инициализируем, потом сохраняем и загружаем в аккумулятор другую переменную, теряя драгоценный контекст для взятия
адреса. Другой вопрос, что сам вызов memcpy для побайтного разбиения 4-байтового числа выглядит на этом фоне оверхедом.
Это винда. Т.ч. x64. Код выполняет сериализацию std::map<INT, std::vector<BYTE>> в TLV. И таким образом записывается размер данных. Т.е. в коде написано &(buf = it->second.size())
Короче, код правильный (судя по комментам), но дико не симпатичный. Перепишу его пожалуй
Здравствуйте, Mr.Delphist, Вы писали:
MD>Здравствуйте, Lonely Dog, Вы писали:
LD>>Нет ли тут UB?
MD>Ну, Вас же не смущает код вида MD>
MD>if (buf=123)
MD>
MD> или MD>
MD>while ((buf = 123) > 0)
MD>
MD>А то и широко известное в узких кругах MD>
MD>while ( *d++ = *s++ );
MD>
MD>Да, грязноватенько, по рукам бы за такое в продуктовом репозитории. Но... оно валидно ещё со времён бородатого plain C
Не смущает только потому, что часто такое видел в статьях. А мой пример попался в первый раз . По рукам уже некого бить, код писался очень давно.
Здравствуйте, BitField, Вы писали:
BF>А потом на ARM или PowerPC программа упадет, ибо не все процессоры поддерживают unaligned r/w.
Это виндовый код, живущий в сервисе. Т.ч. ARM/PowerPC не мой случай. Но все равно, спасибо.
Здравствуйте, BitField, Вы писали:
BF>Здравствуйте, kov_serg, Вы писали:
_>>Действительно странный. Зачем лишние команды. _>>
_>>BYTE *ptr;
_>>// позже, в цикле
_>>*(DWORD*)ptr=123;
_>>
BF>А потом на ARM или PowerPC программа упадет, ибо не все процессоры поддерживают unaligned r/w.
Вот за это надо руки отрывать тем кто пишет компиляторы C++. Почему я должен решать проблеммы
архетектуры конкретной платформы. Этой ерундой должен заниматься компилятор.