Size: a a a

2021 February 11

IZ

Ilia Zviagin in pro.cxx
Переслано от Aidar Fattakhov
тот код что ты скинул применяет этот dat
источник

IZ

Ilia Zviagin in pro.cxx
Переслано от Aidar Fattakhov
он читает его функцией deserialize
источник

AP

Antony Polukhin in pro.cxx
Daniel
тут скорее к писателям gcc, ведь, конечно перегрузка разная выбирается. вот только если включить -O3, то получается так как получилось)
меня во втором примере call вместо jmp сильно смущает

Сейчас попробую повторить на godbolt
источник

D

Daniel in pro.cxx
Antony Polukhin
меня во втором примере call вместо jmp сильно смущает

Сейчас попробую повторить на godbolt
Тут по всей видимости к этой функции идёт вызов в обеих специализациях operator<<. Поэтому получается такая избыточная каша: делается выделение на стеке, чтобы поместить char, и call вместо jmp, чтобы потом освободить. Вопрос почему не используют std::ostream::put, кладя char в регистр.
источник

AP

Antony Polukhin in pro.cxx
Daniel
Тут по всей видимости к этой функции идёт вызов в обеих специализациях operator<<. Поэтому получается такая избыточная каша: делается выделение на стеке, чтобы поместить char, и call вместо jmp, чтобы потом освободить. Вопрос почему не используют std::ostream::put, кладя char в регистр.
Минимизировал https://godbolt.org/z/TbnaWe
источник

AP

Antony Polukhin in pro.cxx
мы трогаем указатель на стек в первом примере и соответственно jmp больше делать нельзя, у нас frame ptr уехал из нужного адресса
источник

D

Daniel in pro.cxx
здесь пропала суть проблемы :)
call делается потому, что нам нужно положить char куда-то, где есть адрес: перед call мы смещаем указатель на вершину стека, после call — должны его вернуть. Во 2м случае строка лежит в отдельной секции, следовательно мы можем просто взять ее адрес. Следовательно, ничего выделять не надо и мы делаем просто jmp.
Здесь лучше рассматривать в контексте вывода: p1 — выводит символ, p2 — строку. Команды процессора, используемые в p1 — подмножество команд p2. Если бы шел вызов std::ostream::put, то аргумент можно было бы положить просто в регистр и ничего этого не делать. Если же оставить "минимизированный" пример, то здесь вроде-бы все как и должно быть :)
источник

EP

Egor Pugin in pro.cxx
внутри фолда можно получить индекс или нужно делать отдельную обёртку на аргументы?
имеем:
auto print = [w](auto && ... e) {
       (std::cout << ... << e) << "\n";
   };
хочется:
auto print = [w](auto && ... e) {
       (std::cout ???<<std::setw(w[field_index])<<??? << ... << e) << "\n";
   };
источник

SS

Sergey Sobolev in pro.cxx
Daniel
здесь пропала суть проблемы :)
call делается потому, что нам нужно положить char куда-то, где есть адрес: перед call мы смещаем указатель на вершину стека, после call — должны его вернуть. Во 2м случае строка лежит в отдельной секции, следовательно мы можем просто взять ее адрес. Следовательно, ничего выделять не надо и мы делаем просто jmp.
Здесь лучше рассматривать в контексте вывода: p1 — выводит символ, p2 — строку. Команды процессора, используемые в p1 — подмножество команд p2. Если бы шел вызов std::ostream::put, то аргумент можно было бы положить просто в регистр и ничего этого не делать. Если же оставить "минимизированный" пример, то здесь вроде-бы все как и должно быть :)
если сделать p1 и p2 возвращающими int и return 0 в конце каждой из них, то jmp пропадет
https://godbolt.org/z/16zMGG
судя по всему, компилятору контекста не хватает, если void
источник

AP

Antony Polukhin in pro.cxx
Daniel
здесь пропала суть проблемы :)
call делается потому, что нам нужно положить char куда-то, где есть адрес: перед call мы смещаем указатель на вершину стека, после call — должны его вернуть. Во 2м случае строка лежит в отдельной секции, следовательно мы можем просто взять ее адрес. Следовательно, ничего выделять не надо и мы делаем просто jmp.
Здесь лучше рассматривать в контексте вывода: p1 — выводит символ, p2 — строку. Команды процессора, используемые в p1 — подмножество команд p2. Если бы шел вызов std::ostream::put, то аргумент можно было бы положить просто в регистр и ничего этого не делать. Если же оставить "минимизированный" пример, то здесь вроде-бы все как и должно быть :)
А, то есть вы про то, что надо вызывать put в operator<<(char) а не запись массива символов
источник

D

Daniel in pro.cxx
Antony Polukhin
А, то есть вы про то, что надо вызывать put в operator<<(char) а не запись массива символов
да, выходит так, что делать std::cout << " "; выгоднее (по крайней мере по инструкциям) чем std::cout << ' ';
источник

AP

Antony Polukhin in pro.cxx
Хм, спасибо, я тогда завтра заведу тикет
источник

D

Daniel in pro.cxx
Antony Polukhin
А, то есть вы про то, что надо вызывать put в operator<<(char) а не запись массива символов
Я оказался неправ насчёт put: это будет неравнозначная замена. Put сделает неформатированную вставку.
Но всё-таки ситуация получается странная: при использовании std::cout << " " используется подмножество действий, осуществляемых при использовании std::cout << ' '. Получается единственный проигрыш строковой версии, по сравнению с символьной, только в случае, если секция с выводимой строкой даст cache-miss. В противном случае, по инструкциям тяжелее выводить символ. На нижнем уровне как устроено я не знаю, но только если в итоге нужно будет использовать напрямую системный вызов, например, write, которому понадобится адрес на выводимые данные, то тогда регистрами не обойдемся. Но если вывод буфферизированный, то с регистром вполне можно работать по-моему. И странно, что char-specific функция не используется при выводе символов.
источник

D

Danya in pro.cxx
Кажется человек в @supapro нашёл багу в clang. Я её сжал до MRE.
https://godbolt.org/z/E8xrMh
Что думаете?
При этом забавно, что в clang 8 работало ожидаемо, в 9-м кланге поехало неправильно
Лечится так:
class Inner : ::Base<float>

Но это всё равно кажется неправильным
источник

D

Danya in pro.cxx
Danya
Кажется человек в @supapro нашёл багу в clang. Я её сжал до MRE.
https://godbolt.org/z/E8xrMh
Что думаете?
При этом забавно, что в clang 8 работало ожидаемо, в 9-м кланге поехало неправильно
Лечится так:
class Inner : ::Base<float>

Но это всё равно кажется неправильным
Бага ли это или все остальные компиляторы делают неправильно?
источник

SS

Sergey Sobolev in pro.cxx
Danya
Бага ли это или все остальные компиляторы делают неправильно?
если вместо float поставить int, тоже не работает (это просто наблюдение)
https://godbolt.org/z/ah87z7
а вот так работает
источник

SS

Sergey Sobolev in pro.cxx
судя по всему, это бага. Типо после инстанцирования скрывается видимость всего класса - очень странно)
источник

D

Daniel in pro.cxx
Sergey Sobolev
если сделать p1 и p2 возвращающими int и return 0 в конце каждой из них, то jmp пропадет
https://godbolt.org/z/16zMGG
судя по всему, компилятору контекста не хватает, если void
здесь все правильно. Смотрите: jmp он делал только потому, что мог переместить указатель на текущую инструкцию в вызываемую функцию "с концами". Т.е. никакой работы после того, как эта функция отработала, выполнять в нашей функции не нужно было.
В вашем примере необходимо вернуть 0 в конце, поэтому делаем call — после того как вызванная функция завершит работу, мы делаем 0 в eax (здесь хранится наше возвращаемое значение) и выходим.
источник

SS

Sergey Sobolev in pro.cxx
Daniel
здесь все правильно. Смотрите: jmp он делал только потому, что мог переместить указатель на текущую инструкцию в вызываемую функцию "с концами". Т.е. никакой работы после того, как эта функция отработала, выполнять в нашей функции не нужно было.
В вашем примере необходимо вернуть 0 в конце, поэтому делаем call — после того как вызванная функция завершит работу, мы делаем 0 в eax (здесь хранится наше возвращаемое значение) и выходим.
да, я это понимаю) я думал, что вопрос был про сам jmp, но потом понял, что разговор о другом)
источник

В

Виктор in pro.cxx
Ребята, подскажите, первый раз такое вижу.
http://pastie.org/p/4VqRBxkLOF1llG7vJbjb89

Когда я раскоменчиваю строку:
log("proActiveExporter-2");

То всё нормально работает, он входит в условие которое идет дальше. Но если я её закоменчиваю - то он не заходит в условие. Что это за магия?
источник