438 / 96 / 41
Регистрация: 04.10.2011
Сообщений: 343
1

Delete внутри тела цикла while(0)

14.02.2017, 23:20. Показов 1365. Ответов 5

Author24 — интернет-сервис помощи студентам
Всем привет. Нашел в недрах cocos2dx такую конструкцию:
C++
1
#define CC_SAFE_DELETE(p)   do { delete (p); (p) = nullptr; } while(0)
кто подскажет зачем помещать delete внутрь тела цикла? Почему нельзя просто сделать:
C++
1
2
delete p; 
p = nullptr;
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.02.2017, 23:20
Ответы с готовыми решениями:

Ошибка: Нельзя изменять значение переменной цикла внутри этого цикла
при запуске в цикле while в строке x:=x div 10; выдает ошибку "Нельзя изменять значение переменной...

Ошибка: Нельзя изменять значение переменной цикла внутри этого цикла
при запуске в строке If i=k Then i:=i+1; выдает ошибку "Нельзя изменять значение переменной цикла...

Почему не срабатывает изменение границы цикла, принятое внутри цикла?
Работает цикл for-Next V_Rod = UBound(Rod, 2) For j = 1 To V_Rod For k = 1 To...

Применение цикла if для определения простых чисел. If внутри цикла for
Доброго времени суток, подскажите пожалуйста, в чем тут дело. С кодом все хорошо, все работает,...

5
Вездепух
Эксперт CЭксперт С++
11688 / 6367 / 1723
Регистрация: 18.10.2014
Сообщений: 16,050
15.02.2017, 01:14 2
Лучший ответ Сообщение было отмечено moskitos80 как решение

Решение

Цитата Сообщение от moskitos80 Посмотреть сообщение
зачем помещать delete внутрь тела цикла
"Просто сделать" нельзя потому, что если вы потом напишете

C++
1
2
if (условие)
  CC_SAFE_DELETE(ptr);
то под if окажется только delete p;. Что является полной белибердой.

Наивное решение проблемы будет таким

C++
1
#define CC_SAFE_DELETE(p)   { delete (p); (p) = nullptr; }
Однако такой вариант не будет работать вот в таком случае

C++
1
2
3
4
if (условие)
  CC_SAFE_DELETE(ptr);
else
  что-то еще;
ибо ; после CC_SAFE_DELETE(ptr) насильно завершит этот if, в результате чего else окажется "оторванным" от if и код компилироваться не будет. Чтобы это работало, надо постоянно помнить, что после CC_SAFE_DELETE(ptr) нельзя ставить ;. Это неудобно. Хотелось бы, чтобы CC_SAFE_DELETE(ptr) вело себя как обычный вызов функции с точки зрения общего синтаксиса.

Однако можно поступить более остроумно - надо внутри макро использовать какой-то способ группирования инструкций, который, согласно грамматике, всегда явно завершается ;. Таким способом группирования является, например, цикл do/while. Это единственный цикл в С/С++, который включает в себя завершающую ;.

Поэтому и делают

C++
1
#define CC_SAFE_DELETE(p)  do { delete (p); (p) = nullptr; } while(0)
Понятно, что из-за условия while(0) никакого итерирования тут происходить не будет.

В таком варианте вы может спокойно писать

C++
1
2
3
4
if (условие)
  CC_SAFE_DELETE(ptr);
else
  что-то еще;
и никаких неожиданностей не будет.

Альтернативным вариантом достижения того же эффекта может быть

C++
1
#define CC_SAFE_DELETE(p)  if (1) { delete (p); (p) = nullptr; } else
но он более опасен в плане неожиданностей из-за болтающегося на хвосте else.
6
438 / 96 / 41
Регистрация: 04.10.2011
Сообщений: 343
15.02.2017, 01:31  [ТС] 3
Т.е. это все только для того что бы упростить правильное использование макроса?
0
Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
15.02.2017, 02:00 4
moskitos80, Чтобы макрос работал как положено. Безошибочно.
1
Вездепух
Эксперт CЭксперт С++
11688 / 6367 / 1723
Регистрация: 18.10.2014
Сообщений: 16,050
15.02.2017, 02:37 5
Цитата Сообщение от moskitos80 Посмотреть сообщение
Т.е. это все только для того что бы упростить правильное использование макроса?
Ну да. Чтобы его использовать фактически как функцию, не задумываясь о том, что это макрос.
3
Вездепух
Эксперт CЭксперт С++
11688 / 6367 / 1723
Регистрация: 18.10.2014
Сообщений: 16,050
12.04.2024, 20:20 6
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Альтернативным вариантом достижения того же эффекта может быть
Также стоит добавить, что эти трюки с do/while нужны именно в том случае, когда ваш макрос состоит из нескольких statements. То есть если вам внутри макроса нужно делать какие-то последовательные действия, включающие, например, объявления переменных, циклы for и т.п., то без statements в общем случае не обойтись. И когда их становится несколько, тогда и становятся полезными "скобки" из do/while.

Однако во многих случаях можно выразить требуемую функциональность не прибегая к множественным statements, вместо этого запихнув все требуемые действия в одно выражение (expression). В одном выражении можно объединить несколько последовательных действий при помощи оператора , и, при необходимости, выполнить ветвление при помощи оператора ?:.

В данном случае можно (и даже лучше) было бы пойти именно по этому пути. Как вы, наверное, помните delete в С++ - это оператор, а оператор можно применять в выражениях. То есть можно было сделать так

C++
1
#define CC_SAFE_DELETE(p) (delete (p), (p) = nullptr)
и все. Это решило бы все проблемы.

Такой вариант, если он реализует требуемую вам функциональность, лучше варианта с do/while.
1
12.04.2024, 20:20
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.04.2024, 20:20
Помогаю со студенческими работами здесь

Нельзя изменять значение переменной цикла внутри этого цикла
function factorial(x:integer):integer; begin var i,var1:integer; for i:=1 to x do begin...

Изменение начального положения цикла внутри этого цикла
есть два маппинга в одном 180000 строк в другом 85000 нужно один прогнать по другому на...

Цикл For. Вывод цикла внутри цикла
Всем привет, есть проблемка. Код рабочий но при вводе среднего бала допустим выше несуществующего...

Паскаль выдает Ошибку "Нельзя изменять значение переменной цикла внутри этого цикла"
Здравствуйте, мне задали задание в колледже написать программу 3 разными способами While do,Repeat...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru