![]() |
|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
![]() |
|
Опции темы | Поиск в этой теме |
![]() |
#1 |
Регистрация: 15.03.2015
Сообщений: 5
|
![]()
Здравствуйте!
Есть такой код: Код:
|
![]() |
![]() |
![]() |
#2 |
Старожил
Регистрация: 15.02.2010
Сообщений: 15,830
|
![]()
Я бы даже сказал, что в большинстве случаев данный код выкинется. Т.к. старое значение не используется и сразу перезатирается.
|
![]() |
![]() |
![]() |
#3 |
Регистрация: 15.03.2015
Сообщений: 5
|
![]()
Хм, операция new может сгенерировать исключение. В этом случае переменная pVal не будет перезатёрта, а значит, если компилятор выкинет инициализацию нулём, то pVal будет содержать случайное значение. Следовательно попытка вызова delete в блоке catch может закончиться очень плохо ((
Таким образом, возможна ситуация, когда старое значение не перезатирается и используется. Компилятор это не учтёт и всё равно выкинет обнуление переменной?? |
![]() |
![]() |
![]() |
#4 |
Старожил
Регистрация: 15.02.2010
Сообщений: 15,830
|
![]()
Вы в катч попадаете, если у нью все плохо. Зачем там делит делать?
|
![]() |
![]() |
![]() |
#5 |
Регистрация: 15.03.2015
Сообщений: 5
|
![]()
Да, Вы правы, в данном конкретном случае delete внутри catch не нужен. Я написал его там просто для примера. Дело не в delete, дело в том, что старое значение переменной, которое, якобы не используется и будет выкинуто компилятором, на самом деле использоваться может.
Если компилятор не выбросит инициализацию указателя нулём, то вызов delete в блоке catch будет безопасен, а если выбросит, то delete будет применяться к неинициализированному указателю. Неужели компилятор это не учитывает? |
![]() |
![]() |
![]() |
#6 |
Участник клуба
Регистрация: 23.12.2010
Сообщений: 1,129
|
![]()
Компилятор может оптимизировать как угодно до тех пор, пока не меняется наблюдаемое поведение программы (as-if rule). У этого правила есть только пара исключений - компилятор может убирать некоторые вызовы конструктора копирования (copy elision), и некоторые выделения памяти (начиная с С++14).
В приведенном примере кода оптимизация очевидно влияет на наблюдаемое поведение: внутри обработчика catch мы можем увидеть неинициализированное значение, хотя в коде оно инициализируется. Следовательно, компилятор может убрать присваивание тогда и только тогда, когда он на 100% гарантирует, что вызов new не бросит эксепшн. Тобишь в реальной жизни практически никогда. |
![]() |
![]() |
![]() |
#7 |
Вредный кошак
Участник клуба
Регистрация: 14.10.2012
Сообщений: 1,159
|
![]() |
![]() |
![]() |
![]() |
#8 | |
Старожил
Регистрация: 15.02.2010
Сообщений: 15,830
|
![]() Цитата:
|
|
![]() |
![]() |
![]() |
#9 | |
Вредный кошак
Участник клуба
Регистрация: 14.10.2012
Сообщений: 1,159
|
![]() Цитата:
Например, если я перегружу operator new так, чтобы он выбрасывал не bad_alloc, то компилятор не сможет переместить присваивание в секцию catch, также, как и не сможет удалить его. Хотя он способен инициализировать нулем переменную сразу, потому как, между объявлением и присваиванием больше ничего не делается с данной переменной. |
|
![]() |
![]() |
![]() |
#10 |
Регистрация: 15.03.2015
Сообщений: 5
|
![]()
Ясно, всем спасибо за помощь.
|
![]() |
![]() |
![]() |
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Не обнуляется таймер почему-то... | FleXik | Общие вопросы Delphi | 5 | 13.04.2014 17:54 |
Обнуляется переменная | Leonid183 | Visual C++ | 0 | 27.10.2011 16:06 |
Обнуляется переменная | Hippie | Помощь студентам | 1 | 09.01.2010 20:22 |
Socket обнуляется переменнaя | KoBRaAndrey | Работа с сетью в Delphi | 4 | 06.01.2010 21:30 |
Всегда позади и всегда впереди в одном приложении | Legat | Win Api | 4 | 27.10.2007 15:48 |