Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devИли ты мне хочешь рассказать, как компилятор вставляет машинный код, оперирующий регистрами (R/E)SP и (R/E)BP? Не стОит!... Ровно тоже самое делает функция _malloca. Расскажи-ка тогда, почему при /O2 кода больше с alloca? Код здорового человека Код: plaintext 1. 2. 3. 4. 5. 6. 7. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Против Код курильщика Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 13:36 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZ, какая, в данном случае разница, больше кода или меньше или откуда берётся код, выделяющий память на стеке - из библиотечной функции, встроенной функции или, собственно, вставляется компилятором? Речь идёт о ПРИНЦИПАХ размещения и инициализации экземпляра класса на стеке. Нафига тут твои детали, которые к этим принципам никакого прямого отношения не имеют? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 13:58 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devNekZ, какая, в данном случае разница, больше кода или меньше или откуда берётся код, выделяющий память на стеке - из библиотечной функции, встроенной функции или, собственно, вставляется компилятором? Речь идёт о ПРИНЦИПАХ размещения и инициализации экземпляра класса на стеке. Нафига тут твои детали, которые к этим принципам никакого прямого отношения не имеют? Точно того ты мог добиться безо всяких аллокаов Код: plaintext 1. 2. 3. Сдаётся мне, ты просто хочешь поспорить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 14:06 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZТочно того ты мог добиться безо всяких аллокаов Код: plaintext 1. 2. 3. Сдаётся мне, ты просто хочешь поспорить.Мог! И что дальше? Речь не о способе выделения памяти. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 14:19 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
* Есть возможность "сказать" new const Type(), но нет возможности этот const хоть как-то "услышать" в реализации перегруженного оператора new, конструктора или деструктора класса; Оператор NEW выделяет память под объект. Как думаешь, памяти всё равно, какой объект в ней лежит, изменяемый или нет? Всё равно. Должен operator new зависеть от константности объекта, под который выделяется память ? Нет, не должен. авторЗачем возможность писать const, если при создании экземпляра класса в куче этот const, ровным счётом, ни на что не влияет? Ты сможешь этот объект привязать только к константной ссылке или константному указателю , и объект после создания не будет меняться. * Есть возможность переопределить placement new, но компилятор не симулирует его вызов при определении экземпляра объекта на стеке, хотя, такое поведение было бы логичным; placement new -- это способ вызвать конструтор и осуществить инициализацию нового объекта в данной памяти. Создание объекта состоит из двух фаз: выделяется память под объект каким-либо образом в этой памяти инициализируется новый объект с помощью вызова конструктора. На стеке (auto память) это происходит так: выделяется память под объект путём резервирования места определённого объёма в стеке. с помощью вызова конструктора там инициализируется объект. placement new делает РОВНО второй пункт этого плана, т.е. при создании объекта на стеке именно как раз "эмулируется placement new", так что что тебе ещё надо от С++, не понятно. * Можем специализировать шаблоны с дедукцией по параметрам конструктора, но не можем специализировать шаблоны с дедукцией по типу и квалификаторам объявления lvalue; При создании объекта и удалении объекта объект должен быть изменён, в этом суть инициализации. Объект сначала находится в неинициализированном состоянии, вызывается конструктор, и содержимое объекта меняется таким образом, что объект находится уже в инициализированном состоянии. Ключевое тут -- что меняется. ЭТо значит, что не смотря ни на какие квалификаторы, используемые при определении нового объекта, он ОБЯЗАН поменяться. Т.е. квалификаторы не должны и не могут работать в конструкторе. То же самое можно сказать и про разрушение объекта и деструктор. Ну и на самом деле (если подумать) квалификаторами обладают не сами объекты, а ссылки на них (в любом виде). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 17:36 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZrdb_devПри размещении экземпляра класса на стеке компилятор сам выделяет память на стеке и инициализирует там экземпляр класса, что примерно равносильно : Код: plaintext 1. 2. Спасибо, поржал Не, ну он всё верно расписал, именно это и делается. Можно даже такое самому руками делать. Если ты только не ржал над тем, что он не додумал, что это и есть эмуляция placement new, то ржал ты зря. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 17:38 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZivНа стеке (auto память) это происходит так: выделяется память под объект путём резервирования места определённого объёма в стеке. с помощью вызова конструктора там инициализируется объект. placement new делает РОВНО второй пункт этого плана, т.е. при создании объекта на стеке именно как раз "эмулируется placement new", так что что тебе ещё надо от С++, не понятно. В моем понимании, "эмуляция placement new" это когда компилятор создает код вызова placement new независимо от того, создана ли реализация этого оператора компилятором по умолчанию (по моему, она до сих пор не создается по умолчанию и компилятор инициализирует экземпляр на стеке просто пиная конструктор) или же разработчик сделал эту реализацию самостоятельно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 17:49 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZivНе, ну он всё верно расписал, именно это и делается. Можно даже такое самому руками делать. Если ты только не ржал над тем, что он не додумал, что это и есть эмуляция placement new, то ржал ты зря. Ну как сказать. Я поржал над тем, что это данный товарищ посчитал создание объекта на стеке с прямым вызовом аллоки и placement new. С точки зрения результата выполнения кода, наверное, да, это равнозначно, но то, что происходит под капотом, совсем другое, что и было проиллюстрировано выше под спойлерами. Перед вызовом call передвигается sp на размер фрейма вниз, в то время как вызов аллоки двигает sp вниз уже внутри самой функции, т.е. после call и выполняет кучу ненужной работы, так как размер известен на этапе компиляции, поэтому столько кода и нагенерилось ненужного. По той же логике можно точно так же сказать что удаление гланд через ж0пу и через рот -- вещи равнозначные. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 17:55 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZНу как сказать. Я поржал над тем, что это данный товарищ посчитал создание объекта на стеке с прямым вызовом аллоки и placement new. С точки зрения результата выполнения кода, наверное, да, это равнозначно, но то, что происходит под капотом, совсем другое, что и было проиллюстрировано выше под спойлерами.Я не хуже тебя знаю, что происходит под капотом. Ты тут не один "знаток" ассемблера и оптимизации машинного кода. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 18:04 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devЯ не хуже тебя знаю, что происходит под капотом. Ты тут не один "знаток" ассемблера и оптимизации машинного кода. Разве ты не понял в чём суть? В этом. rdb_devТак почему бы компилятору не создавать placement new по умолчанию, если он не переопределен и не симулировать его вызов? Получили бы более управляемое поведение. Ещё раз смотрим в код здорового человека и не видим там operator new, в отличие от нижележащего. Компилятру не нужно это разбивать на отдельные фазы выдениеня памяти на стеке и вызова конструктора через placement new -- это лишние вызовы. Он делает как можно короче и так как он считает нужным. P.S. Забавно, что clang с этим примером справляется лучше VS'а. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.05.2018, 18:31 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZКомпилятру не нужно это разбивать на отдельные фазы выдениеня памяти на стеке и вызова конструктора через placement new -- это лишние вызовы. Он делает как можно короче и так как он считает нужным.То есть компилятор не формирует код для расширения кадра стека при объявлении там экземпляра класса? Это делает конструктор объекта? Фактически мы всё равно имеем "отдельные фазы" - отдельно расширение кадра стека и отдельно вызов конструктора, точно также, как отдельные фазы оператора new - отдельно выделение памяти из кучи и отдельно вызов конструктора. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.05.2018, 23:41 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devТо есть компилятор не формирует код для расширения кадра стека при объявлении там экземпляра класса? Это делает конструктор объекта? Формирует, так и есть. rdb_devФактически мы всё равно имеем "отдельные фазы" - отдельно расширение кадра стека и отдельно вызов конструктора, точно также, как отдельные фазы оператора new - отдельно выделение памяти из кучи и отдельно вызов конструктора. А вот здесь не факт, ведь если бы ты попробовал посмотреть что делают clang или gcc с тем же кодом: Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2018, 08:17 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZ, какая разница, как выглядит вызов, если точкой возврата всё равно будет адрес, запихнутый в стек крайним перед передачей управления на первую команду конструктора или чего-то там еще? Ты можешь вызвать привычно через call, запихать адрес возврата и пнуть через jmp, а можешь извратится, запихать в стек адрес, на который хочешь передать управление и сделать ret. В чем разница-то? Принципиально мы всё равно имеет два этапа - выделение памяти и вызов конструктора. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2018, 19:56 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_dev, Да, два этапа, только если компилятор считает, что не нужно делать никакого call'а, он не будет его делать Код: plaintext 1. 2. 3. 4. 5. 6. 7. clang и gcc сжали это в Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.05.2018, 23:20 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZrdb_dev, Да, два этапа, только если компилятор считает, что не нужно делать никакого call'а, он не будет его делать [src c++] struct MyClass{ int x; MyClass() { x = rand(); } int f() { return x; } }; int main() { MyClass b; return b.f(); } clang и gcc сжали это в Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 09:12 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devС чего ты взял, что перед вызовом jmp на стеке нет адреса возврата из main, который позволяет, в данном случае, делать ret из метода MyClass::f() прямо в точку вызова main возвращая тот же int? Глянь-ка отладчиком! С того, что я привык верить своим глазам. И та заглушка, которая была добавлена линковщиком (аля _start) в счёт не идёт, тупой редирект на другую функцию и больше ничего. Совсем ничего. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 09:46 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZrdb_devС чего ты взял, что перед вызовом jmp на стеке нет адреса возврата из main, который позволяет, в данном случае, делать ret из метода MyClass::f() прямо в точку вызова main возвращая тот же int? Глянь-ка отладчиком! С того, что я привык верить своим глазам. И та заглушка, которая была добавлена линковщиком (аля _start) в счёт не идёт, тупой редирект на другую функцию и больше ничего. Совсем ничего.Конечно тупой редирект! Что же еще? Если функция возвращает тот же самый тип и является результатом main, то из main будет именно тупой "редирект" на MyClass::f(), так как адрес возврата из main уже на стеке, которым и воспользуется ret внутри f(), чтобы вернуть значение main в точку вызова. Это оптимизация данного конкретного случая. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 10:38 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZ, хотя, скорее всего, адрес в jmp указывает непосредственно на библиотечную функцию rand(), а не на MyClass::f(). Компилятор решил, что в данном случае ни экземпляр MyClass, ни его метод f() вообще не нужны. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 11:10 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devКонечно тупой редирект! Что же еще? Если функция возвращает тот же самый тип и является результатом main, то из main будет именно тупой "редирект" на MyClass::f(), так как адрес возврата из main уже на стеке, которым и воспользуется ret внутри f(), чтобы вернуть значение main в точку вызова. Это оптимизация данного конкретного случая. Да, пример чисто академический, и именно наличие вот таких вот случаев показывает, что именно компилятор сам решает что где и как рассматривать, на какие фазы разбивать такие-то операции с объектами, а в каких случаях можно всё заинлайнить, не добавляя лишний вызов, в каких случаях вообще всё выбросить как dead code и т.д. Такие решения принимаются в том числе ещё и на основе целевой архитектуры и многих других факторов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 11:35 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devNekZ, хотя, скорее всего, адрес в jmp указывает непосредственно на библиотечную функцию rand(), а не на MyClass::f(). Компилятор решил, что в данном случае ни экземпляр MyClass, ни его метод f() вообще не нужны. Я до тебя это и пытаюсь донести. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 11:36 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
rdb_devВ моем понимании, "эмуляция placement new" это когда компилятор создает код вызова placement new независимо от того, создана ли реализация этого оператора компилятором по умолчанию (по моему, она до сих пор не создается по умолчанию и компилятор инициализирует экземпляр на стеке просто пиная конструктор) или же разработчик сделал эту реализацию самостоятельно. 0) placement new не переопределяется. 1) код placement new -- это вызов констуктора с указанным placement-у указателем на память в виде this . 2) соответственно, код placement new всегда инлайнится. Это собственно один вызов функции. Что тебе ещё надо эмулировать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 13:14 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZMasterZivНе, ну он всё верно расписал, именно это и делается. Можно даже такое самому руками делать. Если ты только не ржал над тем, что он не додумал, что это и есть эмуляция placement new, то ржал ты зря. Ну как сказать. Я поржал над тем, что это данный товарищ посчитал создание объекта на стеке с прямым вызовом аллоки и placement new. С точки зрения результата выполнения кода, наверное, да, это равнозначно, но то, что происходит под капотом, совсем другое, что и было проиллюстрировано выше под спойлерами. Перед вызовом call передвигается sp на размер фрейма вниз, в то время как вызов аллоки двигает sp вниз уже внутри самой функции, т.е. после call и выполняет кучу ненужной работы, так как размер известен на этапе компиляции, поэтому столько кода и нагенерилось ненужного. По той же логике можно точно так же сказать что удаление гланд через ж0пу и через рот -- вещи равнозначные. Что то ты тут намутил. Он всё там вполне адекватно расписал и дал эквивалентный код. Другое дело, что код этот нафиг не нужен, поскольку можно просто написать автоматическую переменную этого класса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 13:16 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZrdb_devЯ не хуже тебя знаю, что происходит под капотом. Ты тут не один "знаток" ассемблера и оптимизации машинного кода. Разве ты не понял в чём суть? В этом. rdb_devТак почему бы компилятору не создавать placement new по умолчанию, если он не переопределен и не симулировать его вызов? Получили бы более управляемое поведение. Ещё раз смотрим в код здорового человека и не видим там operator new, в отличие от нижележащего. Компилятру не нужно это разбивать на отдельные фазы выдениеня памяти на стеке и вызова конструктора через placement new -- это лишние вызовы. Он делает как можно короче и так как он считает нужным. P.S. Забавно, что clang с этим примером справляется лучше VS'а. Ещё раз, ваш чисто теоретический спор лишён всякого смысла, поскольку все вызовы всего кода создания чего-то на стеке и потом вызова констуктора инлайнятся. Абсолютно по барабану, как это всё происходит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 13:17 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
MasterZivЕщё раз, ваш чисто теоретический спор лишён всякого смысла, поскольку все вызовы всего кода создания чего-то на стеке и потом вызова констуктора инлайнятся. Абсолютно по барабану, как это всё происходит. Я об этом ниже написал, переходя от голой теории к конкретике. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 13:33 |
|
||
|
Константный экземпляр класса. Кто как делает?
|
|||
|---|---|---|---|
|
#18+
NekZMasterZivЕщё раз, ваш чисто теоретический спор лишён всякого смысла, поскольку все вызовы всего кода создания чего-то на стеке и потом вызова констуктора инлайнятся. Абсолютно по барабану, как это всё происходит. Я об этом ниже написал, переходя от голой теории к конкретике. Ну и? Топик закрываю? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.05.2018, 13:36 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=39651052&tid=2017848]: |
0ms |
get settings: |
8ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
55ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
61ms |
get tp. blocked users: |
1ms |
| others: | 312ms |
| total: | 473ms |

| 0 / 0 |
