Здравствуйте, enji, Вы писали:
E>Собственно вопрос — чем такой код лучше goto?
На правах ИМХО.
goto по своей природе слишком "мощный". Если я вижу break, я точно знаю, что переход произойдёт в конец текущего блока-цикла. Если я вижу goto, то знаю, что перейти он может куда угодно, и восприятие кода сразу усложняется. Кроме того, с goto легче допустить какой-нибудь ляпсус, воткнув пару операций между концом блока и меткой, или просто опечатавшись каким-нибудь CYCLE1_END вместо CYCLE2_END, а потом удивляться, чего это поток управления скачет по всей функции взад-вперёд.
Здравствуйте, CaptainFlint, Вы писали:
CF>Да ради Бога, назовём END_OF_BLOCK. Слово "цикл" я использовал исключительно из-за использования "цикловых" синтаксический конструкций языка. На суть моего поста это не влияет ни в малейшей степени, чего придираться по мелочам?
Это не мелочи. Тут все называют эту штуку "циклом"! Это говорит о том, что она воспринимается НЕ ТАК, КАК НАДО, для понимания кода!!!
Кроме того, метка END_OF_BLOCK тоже плоха.
1) Похожа на макрос
2) Ничего не говорит о коде. Ты же не называешь переменные variable, почему же считаешь хорошим именем метки "END_OF_BLOCK"?..
CF>Вот я написал код. Метки понятные, расположены где надо, переменные названы вразумительно, — короче, поддерживай да радуйся. НО! Тот человек, который по каким-то причинам получил мой код для разбора и поддержки, — он-то не знает, что я располагал всё правильно, называл всё грамотно. Он видит goto на какую-то метку. Пусть даже эта метка названа так, что совершенно очевидно, что она располагается в конце текущего блока. Но очевидное название — это не гарантия. Она может располагаться и в другом месте. И тот человек, не будучи уверенным в качестве моего кода, вынужден сам, своими ручками искать метку и убеждаться, что да, она поставлена ровно там, где должна быть поставлена.
Ну тогда можно сомневаться и в том, что типы названы верно и переменные и всё остальное...
Кроме того, серебрянной пули, конечно нет, но правило "не писать функции, определение которых не помещается на ОДИН экран" на серебрянную дробину таки тянет!
CF>Оператор break лишён этого недостатка. Даже если я пишу невероятно криво (ну, не считая #define break, конечно), любой человек, читающий код, будет точно и с абсолютной гарантией знать: да, break выходит из текущего цикла. Таким образом, если я использую goto, я добавляю потенциальному "поддерживателю" моего кода неуверенностей и необходимости лишних действий для проверки неких предпосылок. Если же я использую break, поведение регулируется уже не мной, а самим языком, значит, "поддерживатель" меньше зависит от моих выкрутасов, следовательно, ему не придётся гадать, грамотно я писал или нет.
Ну, эта проблема, IMHO, сильно не самая важная. В С++ есть намного более эффективнные способы по запутыванию кода, чем goto за конец блока.
Кроме того, для понимания конструкции do{ } while( 0 ); всё равно надо искать конец блока, кроме того, внутри блока ничто не предупреждлает тебя о том, что это надо делать...
Я ещё раз намекаю тебе, что в первом обсуждении этого антипаттерна участвовали коллеги, которые при беглом взгляде поняли этот код НЕВЕРНО!!!
А код с goto неверно понять НАМНОГО СЛОЖНЕЕ!
goto сразу говорит нам, что вот ребята, авторы кода немного облажались и не смогли написать всё красиво и процедурно. Так что будьте бдительны!
А цикл планомерно вводит нас в заблуждение, причём совсем без предупреждений!
В выборе между goto и этим вот недоциклом я пользуюсь всего двумя простыми и широкоизвестными принципами
1) Принцип наименьшего удивления. Тут goto удивления мало вызывает, IMНO, а вот do{}while(false) -- много
2) Код который нелегко понять хуже кода, который легко понять НЕВЕРНО и НЕ ЗАМЕТИТЬ этого!
Интересно, какой из них ты не разделяешь?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, qqqqq, Вы писали:
Q>Я даже не могу понять, как еще можно было написать алгоритм, который читает и обрабатывает какие-то там данные будь то из сокета или из файла, если не известно сколько их там и надо обрабатывать ошибки. Можно, конечно, вместо тех break-ов поставить условия в операторы циклов или поменять условия наоборот вместо continue, но иногда это не делают по разным причинам. По мне, так особенно большой связи с гото не наблюдается, за исключением того, что все нетривиальные нелинеиные программы в конечном счете набор операций и jump-ов из одного места в другое, как и гото.
Эт ясно. У вас есть цикл, в нем вам нужны break\continue; они есть в языке, пользуйтесь. Но когда у вас нет цикла и вам нужен goto, то зачем изобретать do { ... if () break; .... } while(false) или аналог на switch(0)case 0: ? Почему не признаться — да, мне нужен goto?
Чем
do
{
func1();
if (func2()) break;
func3();
if (func4()) break;
func5();
} while (false);
лучше
{
func1();
if (func2()) goto end_job;
func3();
if (func4()) goto end_job;
func5();
end_job:
}
Здравствуйте, CaptainFlint, Вы писали:
CF>...Да, её можно назвать END_OF_CYCLE,
Боже мой!!! Какой такой цикл? В этом коде НЕТ НИКАКОГО ЦИКЛА!!!
CF>да, её можно расположить в конце цикла. Но можно ведь и не располагать, вот в чём проблема. И читатель кода, пока явным образом не полезет и не найдёт точное расположение метки, не может быть уверенным, что программист воткнул эту метку куда надо было, а не куда захотелось его левой пятке.
А ещё можно все функции и переменные в программе назвать НЕПРАВИЛЬНО!
Нет бы вот назвать метку ПОНЯТНО, и расположить где надо. Получится простой С++, практически простой С-код. СРАЗУ ЖЕ ПОНЯТНЫЙ при поддержке.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Sni4ok, Вы писали:
A>>Кстати, можно вынести внутренности цикла в отдельный метод с говорящим названием и вместо break использовать return.
Для этого нужны вложенные фунцкии, как в паскале. Для одептов GCC и Delphi, для виндоморонов и C++ -- никак нельзя.
S>а из двойного цикла вы как предлагаете выходить, кучу флажков с проверкой вставлять?
Профессиональные программисты используют longjmp()! goto -- для ламиров!
Здравствуйте, CaptainFlint, Вы писали:
CF>Здравствуйте, Erop, Вы писали:
E>>Здравствуйте, CaptainFlint, Вы писали:
CF>>>Кроме того, если не нравится цикл, можно его замаскировать под блок какими-нибудь дефайнами типа BLOCK_BEGIN (do), BLOCK_END (while(0)), BLOCK_EXIT (break). Это скорее вопрос привычки и личного восприятия.
E>>Это ЕЩЁ ХУЖЕ для поддержки. Так тебе надо въехать в то, что цикл -- это на самом деле не цикл. А так сначала надо будет найти и понять эти макросы, а потом въехать, что цикл -- это не цикл
CF>Гм… Возможно, у нас разные способы чтения кода, но если я увижу код CF>
CF>BLOCK_BEGIN
CF>{
CF> if (smth)
CF> BLOCK_EXIT;
CF> if (smth_else)
CF> BLOCK_EXIT;
CF> do_smth_useful();
CF>}
CF>BLOCK_END
CF>
CF>то я в первую очередь восприму в нём семантику (блок кода и выход из него при выполнении определённых условий). И уже потом, если будет время и желание, начну разбираться, а как это программист умудрился сделать конструкцию, которой изначально в языке нет, полезу в определения макросов, и т.д.
Да, и ни капли не сомневаюсь напишу похожий код:
BLOCK_BEGIN
{
while (condition)
if (smth)
BLOCK_EXIT;
while (another_condition)
if (smth_else)
BLOCK_EXIT;
}
BLOCK_END
Здравствуйте, enji, Вы писали: E>Собственно вопрос — чем такой код лучше goto?
Лучше структурированностью кода. В случаи брейк ты точно знаешь, что это переход к концу текущего блока. Приэтом при покидании блока корректно освободятся локальные переменные блока.
В случаи гоуту это посыл програмиста неизвестно куда. Чтоб найти куда послали — нодо сначало "погуглить" по коду эту метку. Приэтом логика кода будет сильней запутана, если начнут встречаться переходы из внутренностей одного блока в другой. E>Я в курсе, что goto стоит избегать и согласен с этим, но зачем его маскировать циклами или switch? Все же goto встроен в С/С++, а идиома "цикл, который выполняется 1 раз" — какая-то искусственная...
Он здесь не маскируется. Это принципиально другой подход, который лучше чем использование гоуту. Брейк — это досрочное прерывание текущей последовательности действий. Гоуту — это некоторый посыл фигзнает куда.
Здравствуйте, Erop, Вы писали:
CF>>goto по своей природе слишком "мощный". Если я вижу break, я точно знаю, что переход произойдёт в конец текущего блока-цикла. Если я вижу goto, то знаю, что перейти он может куда угодно, и восприятие кода сразу усложняется. Кроме того, с goto легче допустить какой-нибудь ляпсус, воткнув пару операций между концом блока и меткой, или просто опечатавшись каким-нибудь CYCLE1_END вместо CYCLE2_END, а потом удивляться, чего это поток управления скачет по всей функции взад-вперёд.
E>стоп-стоп-стоп! E>Откуда таки у тебя вдруг возникло много меток? Возможность перейти не туда и т. д? E>У нас в оригинальном коде была одна точка для выхода из блока? Вот и у goto будет ОДНА метка...
Точка одна, но блоков-то таких может быть несколько. И у каждого будет своя метка выхода. Опечатался — попал в точку выхода не того блока, и здравствуй, отладка.
Кроме того, проблема не только во множественности меток, но и в отсутствии каких-либо гарантий относительно их местоположении (чуть подробнее описал здесь
Здравствуйте, Erop, Вы писали:
E>Тут есть два всего варианта. (редкий)...(частый)
Только у меня, к примеру, как-то все ровно наоборот -- в этом году уже три случая, когда нужно было оживлять сторонний (говно)код, писаный в подобном стиле: atapi-драйвер и драйвер серийного порта в Windows CE, а про третий не скажу (пусть сами догадаются и им будет стыдно) .
AL>>... Может, поговорим об этом? E>Но Мересьев, вернее его прототип, бил фашистских гадов и сражался за Родину. Да и ноги у него, сначала всё-таки были. За что страдаешь ты, коллега?
Это было шутка юмора, ага Хотя совет про IDE приму с премногими благодарностями.
N_>Полностью согласен Но реали таковы что приходится поддерживать код, который написан неидеально и встречаются длинные функции. Я предпочту встретить внем брейк, вместо гоуту неизвестно куда.
Вообще-то ровно наоборот. Найти, куда ведет готу — одно нажатие на шоткат поиска. Найти, где конец этого цикла — задача гораздо менее тривиальная.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, CaptainFlint, Вы писали:
CF>>...Да, её можно назвать END_OF_CYCLE, E>Боже мой!!! Какой такой цикл? В этом коде НЕТ НИКАКОГО ЦИКЛА!!!
Да ради Бога, назовём END_OF_BLOCK. Слово "цикл" я использовал исключительно из-за использования "цикловых" синтаксический конструкций языка. На суть моего поста это не влияет ни в малейшей степени, чего придираться по мелочам?
CF>>да, её можно расположить в конце цикла. Но можно ведь и не располагать, вот в чём проблема. И читатель кода, пока явным образом не полезет и не найдёт точное расположение метки, не может быть уверенным, что программист воткнул эту метку куда надо было, а не куда захотелось его левой пятке.
E>А ещё можно все функции и переменные в программе назвать НЕПРАВИЛЬНО!
E>Нет бы вот назвать метку ПОНЯТНО, и расположить где надо. Получится простой С++, практически простой С-код. СРАЗУ ЖЕ ПОНЯТНЫЙ при поддержке.
Так, меня всё-таки не поняли. Попробую зайти с другой стороны.
Вот я написал код. Метки понятные, расположены где надо, переменные названы вразумительно, — короче, поддерживай да радуйся. НО! Тот человек, который по каким-то причинам получил мой код для разбора и поддержки, — он-то не знает, что я располагал всё правильно, называл всё грамотно. Он видит goto на какую-то метку. Пусть даже эта метка названа так, что совершенно очевидно, что она располагается в конце текущего блока. Но очевидное название — это не гарантия. Она может располагаться и в другом месте. И тот человек, не будучи уверенным в качестве моего кода, вынужден сам, своими ручками искать метку и убеждаться, что да, она поставлена ровно там, где должна быть поставлена.
Оператор break лишён этого недостатка. Даже если я пишу невероятно криво (ну, не считая #define break, конечно), любой человек, читающий код, будет точно и с абсолютной гарантией знать: да, break выходит из текущего цикла. Таким образом, если я использую goto, я добавляю потенциальному "поддерживателю" моего кода неуверенностей и необходимости лишних действий для проверки неких предпосылок. Если же я использую break, поведение регулируется уже не мной, а самим языком, значит, "поддерживатель" меньше зависит от моих выкрутасов, следовательно, ему не придётся гадать, грамотно я писал или нет.
do
{
if () break;
if () break;
} while(false);
switch(0)
{ case 0:
if () break;
}
тут недавно пробегала тема с
for(;;)
{
if () break;
if () continue;
break;
}
и там же мелькал if_break
Собственно вопрос — чем такой код лучше goto?
Я в курсе, что goto стоит избегать и согласен с этим, но зачем его маскировать циклами или switch? Все же goto встроен в С/С++, а идиома "цикл, который выполняется 1 раз" — какая-то искусственная...
10.09.10 12:19: Перенесено модератором из 'C/C++' — Кодт
Здравствуйте, enji, Вы писали:
E>В последнее время часто встречаю что-то вроде E>
E>do
E>{
E> if () break;
E> if () break;
E>} while(false);
E>
E>Собственно вопрос — чем такой код лучше goto?
Он более структурный и предсказуемый (для goto придётся ещё метки ставить — громоздко и можно ошибиться).
Кстати, можно вынести внутренности цикла в отдельный метод с говорящим названием и вместо break использовать return.
Здравствуйте, andy1618, Вы писали: A>Он более структурный и предсказуемый
Насколько я понимаю, "нехороши" все нарушения потока выполнения — break, continue, много return-ов...
Правда goto — самый нехороший
A>(для goto придётся ещё метки ставить — громоздко и можно ошибиться).
Ну а так приходится писать do {} while(false) — еще более громоздко...
A>Кстати, можно вынести внутренности цикла в отдельный метод с говорящим названием и вместо break использовать return.
Понятно, что можно переписать код без goto; часто он при этом улучшается (а иногда — ухудшается ), вопрос в другом — зачем "маскировать" goto?
Здравствуйте, CaptainFlint, Вы писали:
CF>На правах ИМХО. CF>goto по своей природе слишком "мощный". Если я вижу break, я точно знаю, что переход произойдёт в конец текущего блока-цикла. Если я вижу goto, то знаю, что перейти он может куда угодно, и восприятие кода сразу усложняется. Кроме того, с goto легче допустить какой-нибудь ляпсус, воткнув пару операций между концом блока и меткой, или просто опечатавшись каким-нибудь CYCLE1_END вместо CYCLE2_END, а потом удивляться, чего это поток управления скачет по всей функции взад-вперёд.
Это да, но ведь и сам цикл — довольно "сложная" конструкция, затрудняющая понимание программы. Я вижу goto — это именно переход; я вижу цикл — зачем он? Сколько раз мы по нему пройдем, когда выйдем? А если while(false) — далеко внизу и не бросается в глаза...
Я не спорю с тем, что код с большим кол-вом goto сложен для чтения и понимания; скорее всего его стоит переписать. Но маскировать goto циклами — какое-то странное решение, ИМХО
Капитан на вопрос ответил полностью. О себя хочу добавить, что ничего нового или необычного в тех конструкциях нет. Я даже не могу понять, как еще можно было написать алгоритм, который читает и обрабатывает какие-то там данные будь то из сокета или из файла, если не известно сколько их там и надо обрабатывать ошибки. Можно, конечно, вместо тех break-ов поставить условия в операторы циклов или поменять условия наоборот вместо continue, но иногда это не делают по разным причинам. По мне, так особенно большой связи с гото не наблюдается, за исключением того, что все нетривиальные нелинеиные программы в конечном счете набор операций и jump-ов из одного места в другое, как и гото.
Здравствуйте, enji, Вы писали:
E>Собственно вопрос — чем такой код лучше goto?
Если пишем на голом Си, то при помощи такой конструкции можно легко реализовать откат, скажем, многоступенчатой инициализации, инкрементируя номер каждой успешной стадии. После while(0), в случае неудачи где-нибудь посреди do{}while(0), стадии легко откручиваются обратно при помощи switch по номеру стадии без break-ов внутри.
Здравствуйте, A.Lokotkov, Вы писали:
AL>С goto можно, конечно, но не так красиво, кмк,
А тебе какой-то из обсуждаемых тут вариантов (что этот цикл-не цикл, что блок с досрочным выходом по goto, что switch, который не switch) кажется красивым?
AL>ибо появляется лишняя именованная сущность (метка).
В альтернативном варианте получается лишний цикл...
Метке-то хотя бы имя понятное можно дать
AL>По моему опыту, если нескольким разработчикам разрешено использовать goto для реализации подобных конструкций, рано или поздно кто-нибудь рожает фрагмент с абсолютно нечитабельным control flow.
По моему опыту, чем менее стандартные и прямые конструкции разрешишь юзать таким разработчикам, тем дольше потом разгребать
Что касается конкретно использования goto, макросов и прочих спорных конструкций, то мой опыт говорит мне, что хорошо работает такое правило, что их использование нужно согласовать с начальником. Обычно этого достаточно, чтобы природная лень подвигала людей на поиск нормальных решений...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>А тебе какой-то из обсуждаемых тут вариантов (что этот цикл-не цикл, что блок с досрочным выходом по goto, что switch, который не switch) кажется красивым?
Сам по себе -- ни один из, только в сравнении. Просто когда в чужом коде встречаю goto somewhere, а somewhere не находится в пределах экрана, это кажется еще менее красивым, мягко говоря. Да еще и вперемешку с десятком return-ов из функции на 5-6 экранов.
Кстати, расстановку фигурных скобок в стиле Кернигана-Ритчи тоже не переношу -- бывает, хрен поймешь, где начало, а где кончало . Может, поговорим об этом?
Здравствуйте, A.Lokotkov, Вы писали:
AL>Здравствуйте, Erop, Вы писали:
AL>Ну, скажем, до разгребания (говно)кода, превращения его в do {} while(0) и разбиения на мелкие подфункции, при инициализации ide-канала драйвер категорически отказывался находить secondary master-а,
Ну таки не по делу значит говнокод-то был?
Всё понимаю, но при чём тут do{ } while( 0 ); -- не понимаю
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Это не мелочи. Тут все называют эту штуку "циклом"! Это говорит о том, что она воспринимается НЕ ТАК, КАК НАДО, для понимания кода!!! E>Кроме того, метка END_OF_BLOCK тоже плоха. E>1) Похожа на макрос E>2) Ничего не говорит о коде. Ты же не называешь переменные variable, почему же считаешь хорошим именем метки "END_OF_BLOCK"?..
Хорошо, назови, как твоей душе угодно. Или вообще замени всю фразу "Да, её можно назвать END_OF_CYCLE" на что-нибудь вроде "Да, её можно назвать интуитивно понятным именем". Суть поста-то от этого совершенно не меняется. Нафига демагогию разводить на пустом месте?
CF>>Вот я написал код. Метки понятные, расположены где надо, переменные названы вразумительно, — короче, поддерживай да радуйся. НО! Тот человек, который по каким-то причинам получил мой код для разбора и поддержки, — он-то не знает, что я располагал всё правильно, называл всё грамотно. Он видит goto на какую-то метку. Пусть даже эта метка названа так, что совершенно очевидно, что она располагается в конце текущего блока. Но очевидное название — это не гарантия. Она может располагаться и в другом месте. И тот человек, не будучи уверенным в качестве моего кода, вынужден сам, своими ручками искать метку и убеждаться, что да, она поставлена ровно там, где должна быть поставлена.
E>Ну тогда можно сомневаться и в том, что типы названы верно и переменные и всё остальное... E>Кроме того, серебрянной пули, конечно нет, но правило "не писать функции, определение которых не помещается на ОДИН экран" на серебрянную дробину таки тянет!
Во-первых, на нетбуке и на 26" мониторе понятия "один экран" чуточку разнятся. Во-вторых, даже если весь код уместился на один экран, всё, что я говорил об очевидности поведения кода, здесь тоже применимо с тем лишь отличием, что придётся не текст прокручивать, а глазами по коду прыгать. Согласен, это не та проблема, чтобы бить в барабаны, но всё же, согласись, найти текстовый идентификатор и проверить его идентичность метке в goto занимает больше времени и усилий, чем просто найти конец текущего блока.
Я нигде не утверждал, что сабжевая конструкция — это серебряная пуля. Изначально был задан вопрос: в чём преимущества этого подхода перед goto? Я описал те преимущества, которые усмотрел в таком подходе. Я нигде не утверждал, что недостатки отсутствуют, что это идеальный код, что его обязательно надо использовать везде, что можно забыть про coding conventions, и так далее. Просто есть определённые приятности, которых другими средствами достичь невозможно. Насколько велики эти приятности, окупят ли они присущие данному подходу недостатки, — это всё решается индивидуально, в зависимости от потребностей текущего проекта и коллектива разработчиков.
CF>>Оператор break лишён этого недостатка. Даже если я пишу невероятно криво (ну, не считая #define break, конечно), любой человек, читающий код, будет точно и с абсолютной гарантией знать: да, break выходит из текущего цикла. Таким образом, если я использую goto, я добавляю потенциальному "поддерживателю" моего кода неуверенностей и необходимости лишних действий для проверки неких предпосылок. Если же я использую break, поведение регулируется уже не мной, а самим языком, значит, "поддерживатель" меньше зависит от моих выкрутасов, следовательно, ему не придётся гадать, грамотно я писал или нет.
E>Ну, эта проблема, IMHO, сильно не самая важная. В С++ есть намного более эффективнные способы по запутыванию кода, чем goto за конец блока.
Речь не о том, как запутать код, а о том, как объяснить читателю, что код не запутан.
E>Кроме того, для понимания конструкции do{ } while( 0 ); всё равно надо искать конец блока, кроме того, внутри блока ничто не предупреждлает тебя о том, что это надо делать...
Согласен, есть такой аспект. Но я ведь с самого начала сказал об этом: да, информация, которую мы получаем, видя break, неполна.
E>Я ещё раз намекаю тебе, что в первом обсуждении этого антипаттерна участвовали коллеги, которые при беглом взгляде поняли этот код НЕВЕРНО!!! E>А код с goto неверно понять НАМНОГО СЛОЖНЕЕ!
Во-первых, это субъективно. Во-вторых, ты как-то слишком легко судишь о том, кто чего и как понял. Вот взять меня: я тоже называл эту конструкцию циклом. Значит ли это, что я не понял, что это не цикл а однопроходовый блок? Да нифига! Прекрасно я всё понял (тем более, что уже прочитал до этого тему Не такой уж и WTF
и знал, о чём идёт речь). Я использовал слово "цикл" просто потому что привык называть for и do/while циклами, а также потому, что для подобной конструкции банально нет устоявшегося термина (ну или мне он неизвестен), только и всего.
E>goto сразу говорит нам, что вот ребята, авторы кода немного облажались и не смогли написать всё красиво и процедурно. Так что будьте бдительны!
E>А цикл планомерно вводит нас в заблуждение, причём совсем без предупреждений!
Да, неочевидность кода — это один из недостатков данного подхода, совершенно верно.
E>В выборе между goto и этим вот недоциклом я пользуюсь всего двумя простыми и широкоизвестными принципами E>1) Принцип наименьшего удивления. Тут goto удивления мало вызывает, IMНO, а вот do{}while(false) -- много E>2) Код который нелегко понять хуже кода, который легко понять НЕВЕРНО и НЕ ЗАМЕТИТЬ этого!
E>Интересно, какой из них ты не разделяешь?
Оба пункта, которые ты привёл, опять-таки, субъективны. Тебя некий код удивит, а кого-нибудь другого — нет. А другой код — наоборот. И какой из них считать "наименее удивляющим"?
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Nik_1, Вы писали:
N_>>Приэтом логика кода будет сильней запутана, если начнут встречаться переходы из внутренностей одного блока в другой.
E>А вот и не надо использовать goto из внутренностей одного блока ВО ВНУТРЕННОСТИ другого. И goto назада не надо. E>Надо goto наружу блока, непосредственно за его конец!
А зачем? Чтоб сделать гоуту за блок в языке введен оператор брейк, и не надо никаких меток плодить в коде, придумывать им имена и заботиться об их уникальности. Гоуту — это очень низкоуровневый инструмент, как и асемблерные вставки. Он был введен в язык для использования в крайней необходимости — когда высокоуровневыми средствами нельзя достич требуемого результата. Так где можно обойтись высокоуровневым средством нет смысла прибигать к низкоуровневым. E>>>Я в курсе, что goto стоит избегать и согласен с этим, но зачем его маскировать циклами или switch? Все же goto встроен в С/С++, а идиома "цикл, который выполняется 1 раз" — какая-то искусственная...
Яж написал, что это не маскировка. Наоборот, гоуту — это будет маскировка брейка( здесь суть действия — досрочное прерывание блока из последовательности операторов, спецально для этого в языке есть ключивые слова брейк и континью).
N_>>Он здесь не маскируется. Это принципиально другой подход, который лучше чем использование гоуту. Брейк — это досрочное прерывание текущей последовательности действий. Гоуту — это некоторый посыл фигзнает куда.
E>Вот объясни мне, почему тебе конструкция
Как говориться, дьвол кроится в деталях, а в данном случаи за этим многоточием. На практике код там обычно бывает длянным и куда нас послали придется искать через поиск.
E>При ответе учти, пожалуйста, что конструкция с goto стандартная, а стандартная конструкция с циклом выглядит так:
Это лишь изза того, что в языке не ввели возможность создния блоков без цикла. Поэтому это обходят через вайл(фолс). E>При этом нестандартное использование цикла происходит без объявления войны. E>Вот мы читаем код какой-то функции, видим цикл, и пока до while не дочитаем, про то, что это нифига не цикл так и не узнаем
Аналогично, в случаи брейка зато мы точно знаем куда идет посыл — в конец текущего блока. А в случаи с гоуту пока не дочитаем до метки, не поймем что имелось ввиду под этим посылом.
Здравствуйте, Erop, Вы писали: E>>>В ЭТОЙ ПРОГРАММЕ НЕТ НИКАКОГО ЦИКЛА!!! MC>>Если ты про break, я имел в виду, еснно if() break; или if() continue; break. E>Я про то, что эта ваша "конструкция" вводит всех в заблуждение, показывая тут цикл, хотя цикла никакого как раз и нет...
Это уже издержки того что в языке нет конструкции на этот случай. Но тут уже предлагали использать дефайны которые решают эту проблему, и все сразу становится наглядно
Здравствуйте, Erop, Вы писали: E>Что касается конкретно использования goto, макросов и прочих спорных конструкций, то мой опыт говорит мне, что хорошо работает такое правило, что их использование нужно согласовать с начальником. Обычно этого достаточно, чтобы природная лень подвигала людей на поиск нормальных решений...
Хосподи, а макросы то тебе чем не угодили?
Здравствуйте, Erop, Вы писали: E>Ну, как по мне, так такой нормальный и есть.
Он не нанормален тем, что внем тяжело искать начало и конец блоков. Когда открывающая скобка стоит в конце строки, то ее найти ооочень тяжело(т.е. на несколько порядков больше тратится усилий, чем когда она вначали строки). Но это уже тема для отдельного холивара E>Но MSVC, например, умеет форматировать под тот стандарт оформления, что в него вбит. Он вроде настраивается.
Ну так всетаки, как мне включить в студии чтоб все брекиты отображались правильно(=как мне надо)?
Здравствуйте, Erop, Вы писали:
CF>>Рассматривай это как паттерн. Есть определённые ситуации, в которых требуется конструкция вида "однопроходный блок с выходом из него по условиям". Роль такой конструкции может играть try/catch, может функция с return'ами, может обычный блок с goto, а может и псевдо-цикл do/while(0). Есть люди, которым последний подход показался интересным и достаточно вразумительным. Тебе он таковым не показался — что ж, это твоё личное мнение. Но это не означает, что этот подход никому в мире не должен казаться понятным и полезным.
E>Ужос! try-то с catch'ем-то за что? Я верно понял, что речь идёт о конструкции вида:
Это уж совсем ни в какие ворота не того. Чего толкьо люди из-за религиозного страха перед goto не делают!!!
Э-э… Боюсь показаться необразованным дураком, но что не так в этом коде? Неоднократно встречал, да и сам использовал…
/нервно оглядываюсь, ища куда бы заныкаться от неотвратимого гнева гуру/
Здравствуйте, Erop, Вы писали:
CF>>Просто потому что до прочтения той темы мне эта конструкция в Сях нигде не попадалась.
E>Ну это и обозначает её полную необщепринятость
Эм… Ну, скажем, я не настолько высокого о себе мнения, чтобы полагать, что знаю абсолютно все общепринятые конструкции и паттерны.
E>А вообще вопрос неважный. Но лично я бы с очень большим подозрением относился к коду коллеги, кому такой приём нравится. E>Ну просто я это воспринимаю, так, что если есть дубовое решение и есть трюк, то человек выбирает трюк. А я предпочёл бы дубовое, конечно. Так как оно стандартное.
E>Ну в целом, я думаю, можно уже расслабиться на тему...
Ну, я как-то особо и не напрягался.
Хоть во мнениях и не сошлись, но всё же лично мне было интересно и полезно узнать альтернативную точку зрения (да и вообще о слабых сторонах разных подходов). Надеюсь, взаимно.
Здравствуйте, andy1618, Вы писали:
A>Кстати, можно вынести внутренности цикла в отдельный метод с говорящим названием и вместо break использовать return.
а из двойного цикла вы как предлагаете выходить, кучу флажков с проверкой вставлять?
Здравствуйте, enji, Вы писали:
E>Я не спорю с тем, что код с большим кол-вом goto сложен для чтения и понимания; скорее всего его стоит переписать. Но маскировать goto циклами — какое-то странное решение, ИМХО
Это не более, чем плохонькая замена вложенным и анонимным функциям. В нормальных языках оно искаропки есть.
Здравствуйте, dilmah, Вы писали:
fk0>> Для этого нужны вложенные фунцкии, как в паскале. Для одептов GCC и Delphi, для виндоморонов и C++ -- никак нельзя.
D>но в С++ есть локальные структуры.
локальные структуры в отличие от вложенных функций (в дельфи\gcc) не могут использовать локальные переменные...
Здравствуйте, enji, Вы писали:
E>локальные структуры в отличие от вложенных функций (в дельфи\gcc) не могут использовать локальные переменные...
Но могут иметь члены-данные, разделённые между всеми вложенными методами. Не самый удобный вариант на многих сценариях, лямбды из C++0x были бы предпочтительнее.
Здравствуйте, enji, Вы писали:
E>Это да, но ведь и сам цикл — довольно "сложная" конструкция, затрудняющая понимание программы. Я вижу goto — это именно переход; я вижу цикл — зачем он? Сколько раз мы по нему пройдем, когда выйдем? А если while(false) — далеко внизу и не бросается в глаза...
Да, есть такая проблема. Но таковы ограничения языка, что у него нет нормальных способов работы с выделенными блоками кода. Поэтому сама идея использования цикла для однократного прохода поначалу выглядит несколько невнятно и может сбивать с толку. Однако после понимания сути происходящего удобство использования подобной конструкции может превысить неудобства синтаксиса.
Кроме того, если не нравится цикл, можно его замаскировать под блок какими-нибудь дефайнами типа BLOCK_BEGIN (do), BLOCK_END (while(0)), BLOCK_EXIT (break). Это скорее вопрос привычки и личного восприятия.
E>Я не спорю с тем, что код с большим кол-вом goto сложен для чтения и понимания; скорее всего его стоит переписать. Но маскировать goto циклами — какое-то странное решение, ИМХО
Про вермишелевый код с кучей goto я сейчас не говорю, это тема отдельного разбирательства. Тут всё-таки речь идёт не о goto как таковых, а о конкретном сравнении двух подходов: а) обычный блок кода с выходом из него по goto (блок тут не в смысле языковой конструкции, а просто с точки зрения логики кода), б) псевдо-цикл с однократным проходом и выходом по break, исполняющему роль того же goto. Так вот, ключевое слово break позволяет читателю кода сразу же понять, куда пойдёт программа в случае выполнения соответствующего условия. А именно, break однозначно утверждает, что точка перехода находится ниже по коду программы и совпадает с точкой окончания текущего цикла. Конечно, это не исчерпывающая информация — до конца цикла тоже ещё дойти надо. Но если вместо break стоит goto, то у нас даже этой неполной информации нет, т.к. метка может располагаться где угодно. Да, её можно назвать END_OF_CYCLE, да, её можно расположить в конце цикла. Но можно ведь и не располагать, вот в чём проблема. И читатель кода, пока явным образом не полезет и не найдёт точное расположение метки, не может быть уверенным, что программист воткнул эту метку куда надо было, а не куда захотелось его левой пятке.
Здравствуйте, CaptainFlint, Вы писали:
CF>goto по своей природе слишком "мощный". Если я вижу break, я точно знаю, что переход произойдёт в конец текущего блока-цикла. Если я вижу goto, то знаю, что перейти он может куда угодно, и восприятие кода сразу усложняется. Кроме того, с goto легче допустить какой-нибудь ляпсус, воткнув пару операций между концом блока и меткой, или просто опечатавшись каким-нибудь CYCLE1_END вместо CYCLE2_END, а потом удивляться, чего это поток управления скачет по всей функции взад-вперёд.
стоп-стоп-стоп!
Откуда таки у тебя вдруг возникло много меток? Возможность перейти не туда и т. д?
У нас в оригинальном коде была одна точка для выхода из блока? Вот и у goto будет ОДНА метка...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, enji, Вы писали: E>Собственно вопрос — чем такой код лучше goto?
for(;) { break } — это примитив структурного программирования (безусловный цикл). Тем и лучше.
Здравствуйте, CaptainFlint, Вы писали:
CF>Кроме того, если не нравится цикл, можно его замаскировать под блок какими-нибудь дефайнами типа BLOCK_BEGIN (do), BLOCK_END (while(0)), BLOCK_EXIT (break). Это скорее вопрос привычки и личного восприятия.
Это ЕЩЁ ХУЖЕ для поддержки. Так тебе надо въехать в то, что цикл -- это на самом деле не цикл. А так сначала надо будет найти и понять эти макросы, а потом въехать, что цикл -- это не цикл
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, CaptainFlint, Вы писали:
CF>Точка одна, но блоков-то таких может быть несколько. И у каждого будет своя метка выхода. Опечатался — попал в точку выхода не того блока, и здравствуй, отладка.
Проще надо писать функции. ПРОЩЕ! Короче, понятнее...
И идентификаторы выбирать осмысленные, а не var1, var2, var3...
Лучше всего, чтобы одна функция делала ОДНО дело. То есть код
void foo()
{
MyObj* theObj = 0;
{ // Search objectif( cond1_1 ) {
theObj = ...;
goto endOfSearchObj;
}
if( cond1_2 ) {
theObj = ...;
goto endOfSearchObj;
}
if( cond1_3 ) {
theObj = ...;
goto endOfSearchObj;
}
}
endOfSearchObj: ;
// тут какой-то хитрый эпилог поиска, из-за которого goto вообще понадобился
assert( theObj != 0 );
{ // process theObjif( cond2_1 ) {
// process theObj...goto endOfProcessObj;
}
if( cond2_2 ) {
// process theObj...goto endOfProcessObj;
}
if( cond2_3 ) {
// process theObj...goto endOfProcessObj;
}
}
endOfProcessObj: ;
// тут какой-то хитрый эпилог обработки, из-за которого goto вообще понадобился
}
лучше всего оформить как-то так:
MyObj* findObj()
{
MyObj* theObj = 0;
{ // Search objectif( cond1_1 ) {
theObj = ...;
goto endOfSearchObj;
}
if( cond1_2 ) {
theObj = ...;
goto endOfSearchObj;
}
if( cond1_3 ) {
theObj = ...;
goto endOfSearchObj;
}
}
endOfSearchObj: ;
// тут какой-то хитрый эпилог поиска, из-за которого goto вообще понадобился
assert( theObj != 0 );
return theObj;
}
MyObj* processObj( MyObj* theObj )
{
{ // process theObjif( cond2_1 ) {
// process theObj...goto endOfProcessObj;
}
if( cond2_2 ) {
// process theObj...goto endOfProcessObj;
}
if( cond2_3 ) {
// process theObj...goto endOfProcessObj;
}
}
endOfProcessObj: ;
// тут какой-то хитрый эпилог обработки, из-за которого goto вообще понадобился
}
void foo()
{
processObj( findObj() );
}
а ещёлучше в виде объекта-механизма...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Mr.Cat, Вы писали:
MC>for(;) { break } — это примитив структурного программирования (безусловный цикл). Тем и лучше.
Чего?
В ЭТОЙ ПРОГРАММЕ НЕТ НИКАКОГО ЦИКЛА!!!
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, A.Lokotkov, Вы писали:
AL>Если пишем на голом Си, то при помощи такой конструкции можно легко реализовать откат, скажем, многоступенчатой инициализации, инкрементируя номер каждой успешной стадии. После while(0), в случае неудачи где-нибудь посреди do{}while(0), стадии легко откручиваются обратно при помощи switch по номеру стадии без break-ов внутри.
Ну и с goto можно точно так же...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Ну и с goto можно точно так же...
С goto можно, конечно, но не так красиво, кмк, ибо появляется лишняя именованная сущность (метка). По моему опыту, если нескольким разработчикам разрешено использовать goto для реализации подобных конструкций, рано или поздно кто-нибудь рожает фрагмент с абсолютно нечитабельным control flow.
Здравствуйте, Erop, Вы писали: MC>>for(;) { break } — это примитив структурного программирования (безусловный цикл). Тем и лучше. E>Чего? E>В ЭТОЙ ПРОГРАММЕ НЕТ НИКАКОГО ЦИКЛА!!!
Если ты про break, я имел в виду, еснно if() break; или if() continue; break.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, CaptainFlint, Вы писали:
CF>>Кроме того, если не нравится цикл, можно его замаскировать под блок какими-нибудь дефайнами типа BLOCK_BEGIN (do), BLOCK_END (while(0)), BLOCK_EXIT (break). Это скорее вопрос привычки и личного восприятия.
E>Это ЕЩЁ ХУЖЕ для поддержки. Так тебе надо въехать в то, что цикл -- это на самом деле не цикл. А так сначала надо будет найти и понять эти макросы, а потом въехать, что цикл -- это не цикл
Гм… Возможно, у нас разные способы чтения кода, но если я увижу код
BLOCK_BEGIN
{
if (smth)
BLOCK_EXIT;
if (smth_else)
BLOCK_EXIT;
do_smth_useful();
}
BLOCK_END
то я в первую очередь восприму в нём семантику (блок кода и выход из него при выполнении определённых условий). И уже потом, если будет время и желание, начну разбираться, а как это программист умудрился сделать конструкцию, которой изначально в языке нет, полезу в определения макросов, и т.д.
Или ты никогда сторонними библиотеками не пользовался? В MFC ты первым делом бросаешься разгребать, во что задефайнены все эти жуткие DECLARE_DYNAMIC, BEGIN_MESSAGE_MAP, END_MESSAGE_MAP, и как они работают? А в Qt не станешь изучать программу, пока досконально не разберёшься, какой промежуточный C++-код генерируется из отсутствующих в синтаксисе языка сигналов и слотов?
Здравствуйте, Mr.Cat, Вы писали:
MC>>>for( ; ; ) { break } — это примитив структурного программирования (безусловный цикл). Тем и лучше. E>>Чего? E>>В ЭТОЙ ПРОГРАММЕ НЕТ НИКАКОГО ЦИКЛА!!! MC>Если ты про break, я имел в виду, еснно if() break; или if() continue; break.
Я про то, что эта ваша "конструкция" вводит всех в заблуждение, показывая тут цикл, хотя цикла никакого как раз и нет...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Nik_1, Вы писали:
N_>Приэтом логика кода будет сильней запутана, если начнут встречаться переходы из внутренностей одного блока в другой.
А вот и не надо использовать goto из внутренностей одного блока ВО ВНУТРЕННОСТИ другого. И goto назада не надо.
Надо goto наружу блока, непосредственно за его конец!
E>>Я в курсе, что goto стоит избегать и согласен с этим, но зачем его маскировать циклами или switch? Все же goto встроен в С/С++, а идиома "цикл, который выполняется 1 раз" — какая-то искусственная... N_>Он здесь не маскируется. Это принципиально другой подход, который лучше чем использование гоуту. Брейк — это досрочное прерывание текущей последовательности действий. Гоуту — это некоторый посыл фигзнает куда.
Вот объясни мне, почему тебе конструкция
do { // Обработка команд сервераif( обычный_случай ) {
// ...break;
}
} while( 0 );
При ответе учти, пожалуйста, что конструкция с goto стандартная, а стандартная конструкция с циклом выглядит так:
do { // Обработка команд сервераif( необычный_случай ) {
// ...break;
}
} while( условие_продолжения );
При этом нестандартное использование цикла происходит без объявления войны. Вот мы читаем код какой-то функции, видим цикл, и пока до while не дочитаем, про то, что это нифига не цикл так и не узнаем
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
CF>BLOCK_BEGIN
CF>{
CF> if (smth)
CF> BLOCK_EXIT;
CF> if (smth_else)
CF> BLOCK_EXIT;
CF> do_smth_useful();
CF>}
CF>BLOCK_END
CF>
CF>то я в первую очередь восприму в нём семантику (блок кода и выход из него при выполнении определённых условий). И уже потом, если будет время и желание, начну разбираться, а как это программист умудрился сделать конструкцию, которой изначально в языке нет, полезу в определения макросов, и т.д.
1) Я подумаю, что эти все макросы -- какой-то замут на тему об обработке ОШИБОК...
Соответсвенно, буду ожидать, что условия if'ов -- это какие-то исключительные ситуации...
CF>Или ты никогда сторонними библиотеками не пользовался? В MFC ты первым делом бросаешься разгребать, во что задефайнены все эти жуткие DECLARE_DYNAMIC, BEGIN_MESSAGE_MAP, END_MESSAGE_MAP, и как они работают? А в Qt не станешь изучать программу, пока досконально не разберёшься, какой промежуточный C++-код генерируется из отсутствующих в синтаксисе языка сигналов и слотов?
Ну я конечно понимаю, что я старомоден, но перед использованием библиотек я обычно заглядываю сначала в мануал...
Кстати, как ты планируешь понимать конструкцию BEGIN_MESSAGE_MAP или DECLARE_DYNAMIC без мануала?
Вот видтшь ты BEGIN_MESSAGE_MAP( MyWindow, CWnd )
ON_COMMAND( XXX, onXXX )
END_MESSAGE_MAP;
И как ты понимаешь что это? Хотя бы код это или данные (можно ли там бряки ставить, например)?
Про то, что какой именно код получит управление при обработке сообщения ты без мануала вообще не поймёшь, так как там обычно больше одного мэпа в процессе участвует, я вообще скромно умалчиваю пока.
При этом, обрати внимание, мы как бы про поддержку говорим да?
То есть есть два варианта.
1) Меня на самом деле вообще не интересует вся этам фигня с выбором обработчика сообщения. Ну так тогда мне вообще этот код читать не надо. Вполне достаточно глянуть на него и приянть к сведению. что он есть. при этом очень хорошо бы, чтобы первое беглое впечатление не вводило меня в заблуждение.
Например, наличие в карте сообщений сообщения, которое никогда через эту конкретную карту не роутится, например, потому, что оно обрабатывается в другом объекте, скажем во вьюшке, -- это очень, очень плохо. Так как я запомню, что обработчик лежит там-то, а он, на самом деле, совсем и в другом месте!
2) Меня волнуте именно то, что сообщение обрабатывается как-то не там и этот код мне читать НУЖНО. Как во втором случае читать без мануала (не зная что такое карта сообщений) я
При этом мне не нравится, когда библиотека не заставляет меня меня читать мануал из-за всякой ерунды.
Карта сообщений делает вполне сложную и нужную функциональность. А вот все эти пляски с do while(0) вокруг goto никакого функционала, IMHO, не добавляют, то есть вредят.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, A.Lokotkov, Вы писали:
AL>Сам по себе -- ни один из, только в сравнении. Просто когда в чужом коде встречаю goto somewhere, а somewhere не находится в пределах экрана, это кажется еще менее красивым, мягко говоря. Да еще и вперемешку с десятком return-ов из функции на 5-6 экранов.
Тут есть два всего варианта.
2) (редкий) Эти все навороты строго по делу. Например это результат нереальной оптимизации в сочетании с редкой убогостью компилятора. Так бывает, но очень редко. И в таком коде, обычно, есть вообще много особеностей всяких, кроме goto. Соответсвенно, при поддержке, надо всё это понять досконально, зачем тут так, а там сяк извернулись и всё это ЗАДОКУМЕНТИРОВАТЬ, если ещё не. Лучше всего прямо в комментах к коду. Ну и править аккуратно очень. Но это редкий, да и всё равно тяжкий для поддержки случай. Хорошо всё-таки, что редкий!
1) (частый, обычный, встречающийся на практике, в отличии от (2), повсеместно)
Это просто говонокод, написанный говнокодерами. Его надо срочно отрефакторить, а того, кто допустил коммит этого г. депримировать!
Скорее всего там и goto не нужен и недоцикл не нужен и вообшще всё можно написать НОРМАЛЬНО!!!
Не согласен? AL>Кстати, расстановку фигурных скобок в стиле Кернигана-Ритчи тоже не переношу -- бывает, хрен поймешь, где начало, а где кончало . Может, поговорим об этом?
1) Прости, но программировать на С/С++, и при этом не мочь приспособиться к одной из общеприянтых схем расстановки скобок -- это подвиг. Примерно на уровне полётов Мересьва...
Но Мересьев, вернее его прототип, бил фашистских гадов и сражался за Родину. Да и ноги у него, сначала всё-таки были. За что страдаешь ты, коллега?
2) Могу посоветовать разориться на нормальную IDE, которая умеет автоматом форматировать код так, как тебе удобно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, A.Lokotkov, Вы писали:
E>>Тут есть два всего варианта. (редкий)...(частый) AL>Только у меня, к примеру, как-то все ровно наоборот -- в этом году уже три случая, когда нужно было оживлять сторонний (говно)код, писаный в подобном стиле: atapi-драйвер и драйвер серийного порта в Windows CE, а про третий не скажу (пусть сами догадаются и им будет стыдно) .
Ну так если так всё по делу, то куда деваться? И вряд ли трбк с циклом может что-то улучшить в такой ситуации E>>Но Мересьев, вернее его прототип, бил фашистских гадов и сражался за Родину. Да и ноги у него, сначала всё-таки были. За что страдаешь ты, коллега?
AL>Это было шутка юмора, ага
Ну про Мересьева тоже
Ну а про IDE не шутка. AL>Хотя совет про IDE приму с премногими благодарностями.
Пожалуйста!
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Ну так если так всё по делу, то куда деваться? И вряд ли трбк с циклом может что-то улучшить в такой ситуации
Ну, скажем, до разгребания (говно)кода, превращения его в do {} while(0) и разбиения на мелкие подфункции, при инициализации ide-канала драйвер категорически отказывался находить secondary master-а, являющегося единственным диском в системе. Ибо в многостадийной инициализации в случае облома на фоне return-ов и goto легко забыть что-нибудь убрать за собой, освободить какой-нибудь ресурс и пр., что и произошло в данном случае. MS-овцы этот баг, кстати, скопипастили в следующую версию Win CE.
Здравствуйте, RomikT, Вы писали:
RT>Да, и ни капли не сомневаюсь напишу похожий код: RT>
RT>BLOCK_BEGIN
RT>{
RT> while (condition)
RT> if (smth)
RT> BLOCK_EXIT;
RT> while (another_condition)
RT> if (smth_else)
RT> BLOCK_EXIT;
RT>}
RT>BLOCK_END
RT>
RT>Который, естественно, работать не будет.
Можно, кстати, доработать напильником:
BLOCK_BEGIN(BlockName)
{
while (condition)
if (smth)
BLOCK_EXIT(BlockName);
while (another_condition)
if (smth_else)
BLOCK_EXIT(BlockName);
}
BLOCK_END(BlockName)
только с явными вызовами goto лично мне всё равно понятнее
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>1) Я подумаю, что эти все макросы -- какой-то замут на тему об обработке ОШИБОК... E>Соответсвенно, буду ожидать, что условия if'ов -- это какие-то исключительные ситуации...
Во, так я именно такую ситуацию и имел в виду, когда писал пример кода. Значит, код-то понятный получился.
CF>>Или ты никогда сторонними библиотеками не пользовался? В MFC ты первым делом бросаешься разгребать, во что задефайнены все эти жуткие DECLARE_DYNAMIC, BEGIN_MESSAGE_MAP, END_MESSAGE_MAP, и как они работают? А в Qt не станешь изучать программу, пока досконально не разберёшься, какой промежуточный C++-код генерируется из отсутствующих в синтаксисе языка сигналов и слотов?
E>Ну я конечно понимаю, что я старомоден, но перед использованием библиотек я обычно заглядываю сначала в мануал...
В мануал и я заглядываю. Но мануал описывает высокоуровневое поведение. Если провести аналогию с приведёнными мной макросами, то в мануале напишут, что BLOCK_BEGIN и BLOCK_END ограничивают однопроходный блок, а BLOCK_EXIT позволяет выйти в конец блока. А что эти макросы разворачиваются конкретно в do/while/break там описываться не должно, это уже низкоуровневые детали реализации.
E>Кстати, как ты планируешь понимать конструкцию BEGIN_MESSAGE_MAP или DECLARE_DYNAMIC без мануала? E>Вот видтшь ты BEGIN_MESSAGE_MAP( MyWindow, CWnd ) E> ON_COMMAND( XXX, onXXX ) E>END_MESSAGE_MAP; E>И как ты понимаешь что это? Хотя бы код это или данные (можно ли там бряки ставить, например)?
Я это понимаю как некую абстракцию, как эдакое расширение синтаксиса языка. Изначально вопрос о том, что кроется внутри этих макросов просто не возникает. Бряки там ставить не требуется, т.к. логика кода сидит не в объявлениях обработчиков событий, а в самих обработчиках. Это фреймворк, я просто принимаю его таким, какой он есть.
И только если вдруг что-то не работает, или если я подозреваю баги в MFC, или просто делать нечего, а любопытство гложет, я начинаю смотреть, а что же такое на самом деле прячется под этими макросами, как они выполняют привязку, каким синтаксическим языковым конструкциям соответствуют, ну и так далее.
E>Про то, что какой именно код получит управление при обработке сообщения ты без мануала вообще не поймёшь, так как там обычно больше одного мэпа в процессе участвует, я вообще скромно умалчиваю пока.
Про мануал я и не говорю ничего, он необходим. Но ты-то говорил совсем о другом. Ещё раз процитирую твоё сообщение: E>А так сначала надо будет найти и понять эти макросы
Так вот, моё утверждение заключается в том, что для понимания сути происходящего совершенно необязательно находить определения макросов. Достаточно общего понимания того, что эти макросы делают. Я читаю в мануале: BEGIN_MESSAGE_MAP используется для начала такого-то блока, имеет такие-то параметры. Всё. И меня совершенно не колебёт, что на самом деле этот BEGIN_MESSAGE_MAP разворачивается в жутковатую хренотень вида
Даже более того, если бы мне мануал вместо человеческого описания начал предлагать вот такие вот конструкции — да я бы послал этот мануал в пешее эротическое путешествие. Вместе с самим фреймворком.
Соответственно, в моём примере достаточно лишь сказать, что макросы BLOCK_* выполняют такие-то и сякие-то действия. А что BEGIN — это именно do, а END — это именно while(0), — на данном этапе это совершенно ненужная, засоряющая информация. Вот если в дефайнах окажутся баги, тогда да, придётся лезть в них, разбираться, почему они именно такие.
E>При этом, обрати внимание, мы как бы про поддержку говорим да? E>То есть есть два варианта. E>1) Меня на самом деле вообще не интересует вся этам фигня с выбором обработчика сообщения. Ну так тогда мне вообще этот код читать не надо. Вполне достаточно глянуть на него и приянть к сведению. что он есть. при этом очень хорошо бы, чтобы первое беглое впечатление не вводило меня в заблуждение. E>Например, наличие в карте сообщений сообщения, которое никогда через эту конкретную карту не роутится, например, потому, что оно обрабатывается в другом объекте, скажем во вьюшке, -- это очень, очень плохо. Так как я запомню, что обработчик лежит там-то, а он, на самом деле, совсем и в другом месте! E>2) Меня волнуте именно то, что сообщение обрабатывается как-то не там и этот код мне читать НУЖНО. Как во втором случае читать без мануала (не зная что такое карта сообщений) я
E>При этом мне не нравится, когда библиотека не заставляет меня меня читать мануал из-за всякой ерунды.
Похоже, мы под мануалом понимаем разные вещи… Для меня мануал — это то, что описывает функциональность библиотеки и методику её использования, а не сугубо внутренние детали реализации.
E>Карта сообщений делает вполне сложную и нужную функциональность. А вот все эти пляски с do while(0) вокруг goto никакого функционала, IMHO, не добавляют, то есть вредят.
Рассматривай это как паттерн. Есть определённые ситуации, в которых требуется конструкция вида "однопроходный блок с выходом из него по условиям". Роль такой конструкции может играть try/catch, может функция с return'ами, может обычный блок с goto, а может и псевдо-цикл do/while(0). Есть люди, которым последний подход показался интересным и достаточно вразумительным. Тебе он таковым не показался — что ж, это твоё личное мнение. Но это не означает, что этот подход никому в мире не должен казаться понятным и полезным.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, CaptainFlint, Вы писали:
CF>Во-первых, на нетбуке и на 26" мониторе понятия "один экран" чуточку разнятся. Во-вторых, даже если весь код уместился на один экран, всё, что я говорил об очевидности поведения кода, здесь тоже применимо с тем лишь отличием, что придётся не текст прокручивать, а глазами по коду прыгать. Согласен, это не та проблема, чтобы бить в барабаны, но всё же, согласись, найти текстовый идентификатор и проверить его идентичность метке в goto занимает больше времени и усилий, чем просто найти конец текущего блока.
Дык он должен быть как раз в конце блока...
CF>Я нигде не утверждал, что сабжевая конструкция — это серебряная пуля.
Либо я тебя не понял, либо твои приятности становятся актуальны, когда меток в функции много, блоков много и вообще всего много. IMHO, такие сложные функции лучше не писать
CF>Речь не о том, как запутать код, а о том, как объяснить читателю, что код не запутан.
Ну вот мне в конструкции с псевдоциклом больше всего не нравится то, что код запутан, но это замаскировано.
CF>Согласен, есть такой аспект. Но я ведь с самого начала сказал об этом: да, информация, которую мы получаем, видя break, неполна.
Хуж! Она не та! пока не дойдём до конца, так и не узнаем к чему всё это было.
CF>Во-первых, это субъективно.
Что субъективно? Что такой "цикл" может и не насторожить или что goto не может не насторожить?
CF>Во-вторых, ты как-то слишком легко судишь о том, кто чего и как понял.
Да нет, не ты. Ты юы наверное понял бы, что ты не понял и изменил бы мнение о конструкции.
Но были посты типа "и что вам тут не нравится, обычный цикл получения данных"
CF>Да, неочевидность кода — это один из недостатков данного подхода, совершенно верно.
Ну да. IMHO, это очень боьлшой недостаток. Так как код с goto только гипотетически может оказаться неочевидным, и то, если автор допустит в нём ошибку, использовав не ту метку, или поставив метку не сразу после конца, а где-то ещё. А код с псевдоциклом СРАЗУ неочевидный...
CF> E>>В выборе между goto и этим вот недоциклом я пользуюсь всего двумя простыми и широкоизвестными принципами E>>1) Принцип наименьшего удивления. Тут goto удивления мало вызывает, IMНO, а вот do{}while(false) -- много E>>2) Код который нелегко понять хуже кода, который легко понять НЕВЕРНО и НЕ ЗАМЕТИТЬ этого!
E>>Интересно, какой из них ты не разделяешь?
CF>Оба пункта, которые ты привёл, опять-таки, субъективны. Тебя некий код удивит, а кого-нибудь другого — нет. А другой код — наоборот. И какой из них считать "наименее удивляющим"?
Прикольно! Ты не знаешь принципа наименьшего удивления? Это очень хороший и широкоупотребляемый принцип. Очень ценен при работе в команде. Правда я не готов сейчас углубляться в обсуждение самого принципа. Это тут офтоп несколько.
Так что вернусь к goto vs псевдоцикл. Оно конечно немного субъектитвно, но всё равно всё просто и понятно. Вот смотри, ты тут выше, когда писал про то, что я неверно сужу кто там что понял или не понял, писал, что тут-то ты всё понял, потому что читал перед этим тему про WTF? А вот про код с goto ты от чего-то таких разъяснений делать не стал. Не подскажешь почему?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, CaptainFlint, Вы писали:
E>>А так сначала надо будет найти и понять эти макросы CF>Так вот, моё утверждение заключается в том, что для понимания сути происходящего совершенно необязательно находить определения макросов. Достаточно общего понимания того, что эти макросы делают.
... CF>Соответственно, в моём примере достаточно лишь сказать, что макросы BLOCK_* выполняют такие-то и сякие-то действия. А что BEGIN — это именно do, а END — это именно while(0), — на данном этапе это совершенно ненужная, засоряющая информация. Вот если в дефайнах окажутся баги, тогда да, придётся лезть в них, разбираться, почему они именно такие.
Ну, да, но при поддержке надо будет держать в голове этот мануал. Зачем это?
IMHO, без макросов лучше чем с ними, при любом раскладе. Не в смысле вообще и всегда, а в данном конкретном случае.
CF>Рассматривай это как паттерн. Есть определённые ситуации, в которых требуется конструкция вида "однопроходный блок с выходом из него по условиям". Роль такой конструкции может играть try/catch, может функция с return'ами, может обычный блок с goto, а может и псевдо-цикл do/while(0). Есть люди, которым последний подход показался интересным и достаточно вразумительным. Тебе он таковым не показался — что ж, это твоё личное мнение. Но это не означает, что этот подход никому в мире не должен казаться понятным и полезным.
Ужос! try-то с catch'ем-то за что? Я верно понял, что речь идёт о конструкции вида:
try {
if( XXX ) {
throw 666;
}
} catch( int rootOfEvil ) {
// process XXX
}
Это уж совсем ни в какие ворота не того. Чего толкьо люди из-за религиозного страха перед goto не делают!!!
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Nik_1, Вы писали:
N_>Яж написал, что это не маскировка. Наоборот, гоуту — это будет маскировка брейка( здесь суть действия — досрочное прерывание блока из последовательности операторов, спецально для этого в языке есть ключивые слова брейк и континью).
интересно, что в данной конкретной конструкции будет делать слово континью, которое специально для этого есть в языке?
N_>Как говориться, дьвол кроится в деталях, а в данном случаи за этим многоточием. На практике код там обычно бывает длянным и куда нас послали придется искать через поиск.
Ну и что? Так хотя бы искать прийдётся, а иначе ты вообще можешь никогда не узнать, что цикл-то не цикл на самом деле...
N_>Это лишь изза того, что в языке не ввели возможность создния блоков без цикла. Поэтому это обходят через вайл(фолс).
Ну так и зачем небенально рожать конструкцию, которой нет, вместо того, чтобы использовать конструкцию, которая есть и которую все знают?
N_>Аналогично, в случаи брейка зато мы точно знаем куда идет посыл — в конец текущего блока. А в случаи с гоуту пока не дочитаем до метки, не поймем что имелось ввиду под этим посылом.
Ну так-то мы можем хотя бы поискать. Кроме того, меткам принято давать осмысленные имена, вообще-то.
А так мы вообще всё неверно поймём...
Да и вообще, если мы читаем последовательно, то goto наверх быть уже не межет, значит, а вниз тоже далеко не пошлёшь -- до первого объекта с конструктором... Так что свобода goto в С++ не так уж и велика, как тебе кажется.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Nik_1, Вы писали:
N_>Это уже издержки того что в языке нет конструкции на этот случай. Но тут уже предлагали использать дефайны которые решают эту проблему, и все сразу становится наглядно
1) C дефайнами это уже другая конструкция!!! IMHO излишняя, кстати.
2) Наглядно становится, если эти дефайны знать.
3) И дефайны точно нужно не через break определять, а то оконфузишься...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Nik_1, Вы писали:
E>>Надо goto наружу блока, непосредственно за его конец! N_>А зачем? Чтоб сделать гоуту за блок в языке введен оператор брейк
Точно? У K&R писали, что для преждевременного выхода из циклов и switch'ей...
И, кстати, почему break, а не continue?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Nik_1, Вы писали:
N_>Хосподи, а макросы то тебе чем не угодили?
Если коротко, то всем
Моим подчинённым, например, крайне редко удаётся протащить через меня какой-нибудь макрос...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Nik_1, Вы писали:
N_>Какая ИДЕ умеет отоброжать брекиты написанные в дуратском стиле: N_>
N_>do{
N_>};
N_>
N_>в нормальный стиль?
Ну, как по мне, так такой нормальный и есть. Но MSVC, например, умеет форматировать под тот стандарт оформления, что в него вбит. Он вроде настраивается.
Ещё много где можно писать макросы...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Nik_1, Вы писали:
N_>>Хосподи, а макросы то тебе чем не угодили? E>Если коротко, то всем
Тебя что в детстве макросы покусали чтоль Это незаменимый в целом ряде случаев инструмент, который можно и нужно использовать понеобходимости. E>Моим подчинённым, например, крайне редко удаётся протащить через меня какой-нибудь макрос...
Назовите название конторы, куда никогда не следует посылать резюме Этож вообще писец, если каждую строчку кода нужно бегать согласовывать с начальством. Как тока народ не разбежался еще из конторы.
Здравствуйте, Erop, Вы писали: N_>>Как говориться, дьвол кроится в деталях, а в данном случаи за этим многоточием. На практике код там обычно бывает длянным и куда нас послали придется искать через поиск. E>Ну и что? Так хотя бы искать прийдётся, а иначе ты вообще можешь никогда не узнать, что цикл-то не цикл на самом деле...
Ну а зачем чтото искать, когда можно и не искать
N_>>Это лишь изза того, что в языке не ввели возможность создния блоков без цикла. Поэтому это обходят через вайл(фолс). E>Ну так и зачем небенально рожать конструкцию, которой нет, вместо того, чтобы использовать конструкцию, которая есть и которую все знают?
Затем, что эта конструкция более правильная с точки зренеия структурированности кода, и позволяет писать более качественный код, чем с гоуту.
E>Да и вообще, если мы читаем последовательно, то goto наверх быть уже не межет, значит, а вниз тоже далеко не пошлёшь -- до первого объекта с конструктором... Так что свобода goto в С++ не так уж и велика, как тебе кажется.
Я не селен в стандарте с++ относительно оператора гоуту. Это закреплено внем что можно делать переход тока вниз, но не наверх?
Здравствуйте, Nik_1, Вы писали:
N_>Назовите название конторы, куда никогда не следует посылать резюме Этож вообще писец, если каждую строчку кода нужно бегать согласовывать с начальством. Как тока народ не разбежался еще из конторы.
А у тебя в каждой строчке макросы? Тогда действительно резюме твоё тут не надо...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Nik_1, Вы писали:
N_>Ну а зачем чтото искать, когда можно и не искать
У тебя большой опыт поддержки большого объёма кода? Ты когда по коду шаршься, по каждой конкретной нужде, то замечаешь что-то и запоминаешь что да как где видел. Когда код работает совсем не так, как выгядит на первый взгляд, получается довольно неприятно...
N_>Затем, что эта конструкция более правильная с точки зренеия структурированности кода, и позволяет писать более качественный код, чем с гоуту.
А что значит "более правильная"? IMHO, более правильная конструкция -- вынести всё в отдельную функцию или в объект-механизм!
А в тех, крайне редких случаях, когда так сделать от чего-то нельзя, использовать goto, а не хитро извращаться с недоциклами...
N_>Я не селен в стандарте с++ относительно оператора гоуту. Это закреплено внем что можно делать переход тока вниз, но не наверх?
Я тебе советую сначала изучить имеющиеся конструкции языка, а потом уже предлагать новые...
Что касается goto, то по нему нельзя обрулить создание объекта, доступного в точке, куда осуществляется переход...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали: E>А у тебя в каждой строчке макросы? Тогда действительно резюме твоё тут не надо...
Вот ненадо тока переиначивать. Ты говорил что вообще макросы не разрешаешь, причем тут в каждой строчке
Здравствуйте, Nik_1, Вы писали:
N_>Вот ненадо тока переиначивать. Ты говорил что вообще макросы не разрешаешь, причем тут в каждой строчке
Ну я на всякий случай повторю.
Есть список опасных и сомнительных конструкций, использование которых ОБЯЗАТЕЛЬНО нужно согласовать с начальником В КАЖДОМ СЛУЧАЕ ОТДЕЛЬНО.
Соответсвенно, если у тебя эти сомнительные конструкции не используются то и согласовывать ничего не надо
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Nik_1, Вы писали:
N_>Ну так всетаки, как мне включить в студии чтоб все брекиты отображались правильно(=как мне надо)?
Ну если она не умеет так широко настраивать свой коде-стиль (фиг тебя знает, как тебе надо?), то напиши макрос...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>А что значит "более правильная"? IMHO, более правильная конструкция -- вынести всё в отдельную функцию или в объект-механизм!
Полностью согласен Но реали таковы что приходится поддерживать код, который написан неидеально и встречаются длинные функции. Я предпочту встретить внем брейк, вместо гоуту неизвестно куда. E>А в тех, крайне редких случаях, когда так сделать от чего-то нельзя, использовать goto, а не хитро извращаться с недоциклами...
Гоуту не нужен
E>Я тебе советую сначала изучить имеющиеся конструкции языка, а потом уже предлагать новые...
Уменя на практике ниразу не возникало необходимости им воспользоваться, поэтому не вникал в особенности его работы, а лишь знаю что он есть и как примерно работает. Возниклаб необходимость внем — глянул бы в справку про ньюансы, но вот пока ниразу не понадобился
E>Что касается goto, то по нему нельзя обрулить создание объекта, доступного в точке, куда осуществляется переход...
Вот и говорю что не нужен , потому что слишком много всяких таких "но" и подводных камней в его использовании.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Nik_1, Вы писали:
N_>>Ну так всетаки, как мне включить в студии чтоб все брекиты отображались правильно(=как мне надо)?
E>Ну если она не умеет так широко настраивать свой коде-стиль (фиг тебя знает, как тебе надо?), то напиши макрос...
мне нужен обычный стиль, когда все на раздных строках:
while()
{
};
Скажи по пунктам куда тыкать и что нажимать, чтобы она отображала мне все исходники в таком стиле. ( студия 2008-я)
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Nik_1, Вы писали:
N_>>Вот ненадо тока переиначивать. Ты говорил что вообще макросы не разрешаешь, причем тут в каждой строчке
E>Ну я на всякий случай повторю. E>Есть список опасных и сомнительных конструкций, использование которых ОБЯЗАТЕЛЬНО нужно согласовать с начальником В КАЖДОМ СЛУЧАЕ ОТДЕЛЬНО.
Если они далеко не "в каждой строчке" будут использоваться, всеравно замаишься согласовывать. Я б такого начальника отдела с его заморочками послалбы куда подальше. E>Соответсвенно, если у тебя эти сомнительные конструкции не используются то и согласовывать ничего не надо
Ну так скажи что такого плохо в макросах?
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, CaptainFlint, Вы писали:
CF>>Во-первых, на нетбуке и на 26" мониторе понятия "один экран" чуточку разнятся. Во-вторых, даже если весь код уместился на один экран, всё, что я говорил об очевидности поведения кода, здесь тоже применимо с тем лишь отличием, что придётся не текст прокручивать, а глазами по коду прыгать. Согласен, это не та проблема, чтобы бить в барабаны, но всё же, согласись, найти текстовый идентификатор и проверить его идентичность метке в goto занимает больше времени и усилий, чем просто найти конец текущего блока.
E>Дык он должен быть как раз в конце блока...
Верно. Но его ещё надо сравнить с тем, который упомянут в goto: а та ли это метка, на которую мы переходим или всё-таки другая?
CF>>Я нигде не утверждал, что сабжевая конструкция — это серебряная пуля. E>Либо я тебя не понял, либо твои приятности становятся актуальны, когда меток в функции много, блоков много и вообще всего много. IMHO, такие сложные функции лучше не писать
Мои приятности приятны тем, что тебе не будет ни малейшей необходимости даже задумываться о том, много ли у тебя меток, блоков и вообще всего. Ты видишь break и сразу же точно знаешь, куда попадаешь. Всё.
CF>>Речь не о том, как запутать код, а о том, как объяснить читателю, что код не запутан. E>Ну вот мне в конструкции с псевдоциклом больше всего не нравится то, что код запутан, но это замаскировано.
CF>>Согласен, есть такой аспект. Но я ведь с самого начала сказал об этом: да, информация, которую мы получаем, видя break, неполна. E>Хуж! Она не та! пока не дойдём до конца, так и не узнаем к чему всё это было.
Если почитать эту тему, то видно, что так считают не все.
CF>>Во-первых, это субъективно. E>Что субъективно? Что такой "цикл" может и не насторожить или что goto не может не насторожить?
Твоя фраза E>А код с goto неверно понять НАМНОГО СЛОЖНЕЕ!
субъективна, потому что сложность понимания языковых конструкций у разных людей разная. Кому-то именно код с goto покажется не тем, чем он является на самом деле (например, решит, что это выход не из блока, а вообще переход в конец функции), зато do/while(0) этот человек опознает мгновенно и не будет понимать, как о нём можно подумать что-нибудь неправильное.
CF>>Во-вторых, ты как-то слишком легко судишь о том, кто чего и как понял. E>Да нет, не ты. Ты юы наверное понял бы, что ты не понял и изменил бы мнение о конструкции. E>Но были посты типа "и что вам тут не нравится, обычный цикл получения данных"
А, ну если ты про них, тогда ладно. Просто мне показалось, что ты говорил вообще про всех, кто хотя бы раз упомянул слово "цикл".
CF>>Да, неочевидность кода — это один из недостатков данного подхода, совершенно верно. E>Ну да. IMHO, это очень боьлшой недостаток. Так как код с goto только гипотетически может оказаться неочевидным, и то, если автор допустит в нём ошибку, использовав не ту метку, или поставив метку не сразу после конца, а где-то ещё. А код с псевдоциклом СРАЗУ неочевидный...
CF>>Оба пункта, которые ты привёл, опять-таки, субъективны. Тебя некий код удивит, а кого-нибудь другого — нет. А другой код — наоборот. И какой из них считать "наименее удивляющим"? E>Прикольно! Ты не знаешь принципа наименьшего удивления? Это очень хороший и широкоупотребляемый принцип. Очень ценен при работе в команде. Правда я не готов сейчас углубляться в обсуждение самого принципа. Это тут офтоп несколько.
Скажем так: я специально его не изучал, но полагал его означающим то, что он интуитивно должен означать. Глянул Википедию — там про него описано именно то, что я о нём предполагал. Так что мои слова остаются в силе: удивление пользователя — критерий неуниверсальный, потому что разные пользователи могут ожидать разного поведения программ и, соответственно, удивляться разным вещам. Если взять пример из той же Википедии с Ctrl+Q: один пользователь будет ожидать, что сочетание запишется, другой — что программа закроется, третий — что запись макроса прервётся. И какой вариант ни выберешь, остальные два пользователя будут удивлены выбранному поведению. Вопрос лишь в количестве пользователей каждой категории, но набирать объективную статистику такого рода — занятие неблагодарное.
E>Так что вернусь к goto vs псевдоцикл. Оно конечно немного субъектитвно, но всё равно всё просто и понятно. Вот смотри, ты тут выше, когда писал про то, что я неверно сужу кто там что понял или не понял, писал, что тут-то ты всё понял, потому что читал перед этим тему про WTF? А вот про код с goto ты от чего-то таких разъяснений делать не стал. Не подскажешь почему?
Просто потому что до прочтения той темы мне эта конструкция в Сях нигде не попадалась. Я точно так же мог сказать о любой ранее не знакомой мне конструкции, — хоть про goto, хоть про какой-нибудь синглтон, хоть про что-то ещё — если бы так получилось, что я о них раньше не слышал, а тут так совпало, что прочёл о них в соседней ветке буквально за пару дней до обсуждения.
Здравствуйте, Erop, Вы писали:
N_>>Хосподи, а макросы то тебе чем не угодили? E>Если коротко, то всем E>Моим подчинённым, например, крайне редко удаётся протащить через меня какой-нибудь макрос...
fk0>> Для этого нужны вложенные фунцкии, как в паскале. Для одептов GCC и Delphi, для виндоморонов и C++ -- никак нельзя. E>Да ладно уж прямо вот и никак
Здравствуйте, enji, Вы писали:
fk0>> Это не более, чем плохонькая замена вложенным и анонимным функциям. В нормальных языках оно искаропки есть. E>Насколько я помню опыт дельфей, функция с кучей вложенных функций тоже далека от идеала ясности и легкости сопровождения.
Заставь дурака богу молиться...
E>Как вам могут помочь анонимные функции, я не понял.
fk0>> Для этого нужны вложенные фунцкии, как в паскале. Для одептов GCC и Delphi, для виндоморонов и C++ -- никак нельзя. D>но в С++ есть локальные структуры.
fk0>>> Для этого нужны вложенные фунцкии, как в паскале. Для одептов GCC и Delphi, для виндоморонов и C++ -- никак нельзя. D>>но в С++ есть локальные структуры.
fk0> В голом C тоже есть.
Здравствуйте, Erop, Вы писали:
E>Всё понимаю, но при чём тут do{ } while( 0 ); -- не понимаю
Конструкция do { sequence } while( condition ); определяет последовательность действий, выполняемую, как минимум, один раз и прерываемую break-ом всюду внутри. По крайней мере, в нашей группе разработчиков это предельно ясно всем.
В предыдущем сообщении я говорил
, что "в многостадийной инициализации в случае облома на фоне return-ов и goto легко забыть что-нибудь убрать за собой, освободить какой-нибудь ресурс и пр., что и произошло в данном случае". И я систематически встречаюсь с подобной goto-induced багом в стороннем коде. Более мне добавить нечего.
Если goto тебе и твоим коллегам кажется более понятной конструкцией, используйте goto на здоровье.
C>Вот этот — точно нет. Потому что он даёт неправильный результат при вызове с указателем.
Увы, но отличить массив от указателя в С (не С++) нельзя никак.
Можно лишь ввести некоторую "защиту":
Здравствуйте, CaptainFlint, Вы писали:
CF>Здравствуйте, Erop, Вы писали:
... CF>Э-э… Боюсь показаться необразованным дураком, но что не так в этом коде? Неоднократно встречал, да и сам использовал… CF>/нервно оглядываюсь, ища куда бы заныкаться от неотвратимого гнева гуру/
По всей видимости речь идёт о:
1. накладных расходах при работе с ислючениями в С++.
2. неправильности использования исключений (в данном случае) для передачи управления. Например, в отладчике это исключение может ловится в то время, как никакой исключительной ситуации не наступило; обычная, заранее предусмотренная передача управления.
Сообщение заговорено потомственным колдуном, целителем и магом в девятом поколении!
Модерирование или минусование сообщения ведет к половому бессилию, венерическим заболеваниям, венцу безбрачия и диарее!
Здравствуйте, Кондраций, Вы писали:
CF>>Э-э… Боюсь показаться необразованным дураком, но что не так в этом коде? Неоднократно встречал, да и сам использовал… CF>>/нервно оглядываюсь, ища куда бы заныкаться от неотвратимого гнева гуру/ К>По всей видимости речь идёт о: К>1. накладных расходах при работе с ислючениями в С++. К>2. неправильности использования исключений (в данном случае) для передачи управления. Например, в отладчике это исключение может ловится в то время, как никакой исключительной ситуации не наступило; обычная, заранее предусмотренная передача управления.
1. ЕМНИП, если исключения не происходит, накладные расходы там мизерные. Во всяком случае, когда я в своей проге их замерял (для далеко не самых навороченных функций), разница в производительности оставалась в пределах погрешностей.
2. Ну, здесь как и с любым инструментом: если кто-то пихает его, где ни попадя, это значит, что плох программист, а не инструмент. Не знаю, я подобные try-catch применяю в таких случаях, как, например, проверка входных данных.
Здравствуйте, CaptainFlint, Вы писали:
CF>1. ЕМНИП, если исключения не происходит, накладные расходы там мизерные. Во всяком случае, когда я в своей проге их замерял (для далеко не самых навороченных функций), разница в производительности оставалась в пределах погрешностей.
Ветка под условием XXX наверняка не единственная; раз так — стоит ожидать более-менее единообразной обработки в разных if-ах. Сказать определённо нельзя, но в данном случае стоит ожидать, КМК, достаточно частого выброса исключений.
Еще одно — поддержка исключений в С++ требует линковки CRT.
CF>2. Ну, здесь как и с любым инструментом: если кто-то пихает его, где ни попадя, это значит, что плох программист, а не инструмент. Не знаю, я подобные try-catch применяю в таких случаях, как, например, проверка входных данных.
Ну тут много зависит, кроме желаний программиста, от:
1. возможностей библиотек, которые ты используешь (т.е. представляют ли они альтернативы исключениям);
2. прогнозируемой частоты неверных входных данных (если важна производительность).
... << RSDN@Home 1.2.0 alpha 4 rev. 1476>>
Сообщение заговорено потомственным колдуном, целителем и магом в девятом поколении!
Модерирование или минусование сообщения ведет к половому бессилию, венерическим заболеваниям, венцу безбрачия и диарее!
Здравствуйте, Vamp, Вы писали:
V>Вообще-то ровно наоборот. Найти, куда ведет готу — одно нажатие на шоткат поиска. Найти, где конец этого цикла — задача гораздо менее тривиальная.
Это если все писать в notepad-е. (Кстати, а где у него шорткат поиска?) Уже в notepad++ можно видеть границы блоков. А если еще и нормальную IDE взять, там блоки выделяются просто кликом в районе фигурной скобки.
P>Это если все писать в notepad-е. (Кстати, а где у него шорткат поиска?)
Ctrl-F с утра было. Но вообще-то должен заметить, что между notepad и IDE лежит чертова уйма редакторов. И далеко не всегда есть возможность пользоваться IDE.
P>А если еще и нормальную IDE взять, там блоки выделяются просто кликом в районе фигурной скобки.
Только надо еще начало блока найти для этого. А если блок не помещается на экран — это тоже не элементарно.
fk0>>>> Для этого нужны вложенные фунцкии, как в паскале. Для одептов GCC и Delphi, для виндоморонов и C++ -- никак нельзя. D>>>но в С++ есть локальные структуры. fk0>> В голом C тоже есть. D>но в голом С в этих структурах нет методов
Здравствуйте, Vamp, Вы писали:
V>Ctrl-F с утра было.
А, ну да. В пятницу вечером, да еще если не запускал его давненько, забыл.
V>Но вообще-то должен заметить, что между notepad и IDE лежит чертова уйма редакторов.
Т.е. относительно notepad++ возражений нет?
V>И далеко не всегда есть возможность пользоваться IDE.
А когда в нормальной работе нет возможности пользоваться IDE? Мне приходит в голову только древний Workbench от Microsoft на 80286. Правда, я не знаю положение дел на мэйнфреймах.
V>Только надо еще начало блока найти для этого. А если блок не помещается на экран — это тоже не элементарно.
Это достаточно просто. Нормальная IDE сама отмечает границы блоков.
fk0>>>>> Для этого нужны вложенные фунцкии, как в паскале. Для одептов GCC и Delphi, для виндоморонов и C++ -- никак нельзя. D>>>>но в С++ есть локальные структуры. fk0>>> В голом C тоже есть. D>>но в голом С в этих структурах нет методов
fk0> void (*TheMethodOfMyStructure)(void);
хех Ну как минимум здесь ты платишь цену косвенного вызова, то есть это виртуальный метод С++, а не обычный.
Во-вторых, непонятно почему без аргументов, а не void (*TheMethodOfMyStructure)(struct tag* self);
Но я не понимаю о чем спор вообще? В С++ есть красивый способ кодирования: допустим тебе нужно написать мощную функцию/метод (которая делает что-то нетривиальное). Тогда внутри этой функции ты определяешь локальную структуру, которая будет "движком" этой функции, локальные переменные этой функции ты обычно затягиваешь внутрь этой структуры, чтобы методы структуры могли с ней работать. Ну и заодно десторуктор этой струткуры занимается освобождением ресурсов. В С такого стиля нет.
P>Т.е. относительно notepad++ возражений нет?
Никогда не пользовался.
P>А когда в нормальной работе нет возможности пользоваться IDE? Мне приходит в голову только древний Workbench от Microsoft на 80286. Правда, я не знаю положение дел на мэйнфреймах.
Например, мне неизвестна НОРМАЛЬНАЯ (в твоем понимании) IDE под Солярис. Тебе известна?
P>Это достаточно просто. Нормальная IDE сама отмечает границы блоков.
Будь ласка, перечисли нормальные ИДЕ
Здравствуйте, Vamp, Вы писали:
P>>Т.е. относительно notepad++ возражений нет? V>Никогда не пользовался.
Попробуй.
V>Например, мне неизвестна НОРМАЛЬНАЯ (в твоем понимании) IDE под Солярис. Тебе известна?
NetBeans?
V>Будь ласка, перечисли нормальные ИДЕ
Какие у тебя критерии нормальности IDE? Как по мне, IDEA, Студия, тот же NetBeans, местами даже Eclipse... Во всяком случае средства, помогающие анализировать код, есть у всех.
Первый -- нет, static_assert ничем не хуже. Только у нас static_saaert без текстового сообщения.
Кроме того у тебя в макросе предполагается, что CHAR_BIT равно 8, что не обязательно.
Второй -- нет. Во-первых, есть такая стандартная функция. Во-вторых, он вводит в заблуждение. Если внутри цикла cont.end() поменяется, то всё гавкнется. Кроме того если вызвать что-то типа foreach( i, *++vectors ), то будет а-та-та...
Для третьего в нашей библиотеке уже есть похожий макрос, ну и вообще он обычно уже есть => не надо вводить свой, надо юзать стандартный.
Так что нет все три раза.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
?..
fk0> Костыли и подпорки! Попытка через ()() сделать то, что в других языках делается просто и непосредственно!
Через какое такое ()()? Просто метод Process зовёшь и радуешься!
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, CaptainFlint, Вы писали:
CF>/нервно оглядываюсь, ища куда бы заныкаться от неотвратимого гнева гуру/
Я не гуру, но этот код в упор непроцедурный и такой же неэффективный...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, CaptainFlint, Вы писали:
CF>Просто потому что до прочтения той темы мне эта конструкция в Сях нигде не попадалась.
Ну это и обозначает её полную необщепринятость
А вообще вопрос неважный. Но лично я бы с очень большим подозрением относился к коду коллеги, кому такой приём нравится.
Ну просто я это воспринимаю, так, что если есть дубовое решение и есть трюк, то человек выбирает трюк. А я предпочёл бы дубовое, конечно. Так как оно стандартное.
Ну в целом, я думаю, можно уже расслабиться на тему...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Nik_1, Вы писали:
N_>Если они далеко не "в каждой строчке" будут использоваться, всеравно замаишься согласовывать. Я б такого начальника отдела с его заморочками послалбы куда подальше.
Организуешь свой бизнес -- пошлёшь
Но я тебе советую ориентироваться не на такие вещи, а на производительность и качество работы в отделе твоих будущих начальниуов отделов в твоём будущем бизнесе
E>>Соответсвенно, если у тебя эти сомнительные конструкции не используются то и согласовывать ничего не надо N_>Ну так скажи что такого плохо в макросах?
Ну это скучно. Обилием тркднодетектируемых ошибок не угодили.
Есть куча примеров описанных в литературе...
#drfine MAX( A, B ) ((A) > (B) ? (A) : (B))
char* q = "12";
int mx = MAX( *q++. *q++ );
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Nik_1, Вы писали:
E>>Что касается goto, то по нему нельзя обрулить создание объекта, доступного в точке, куда осуществляется переход... N_>Вот и говорю что не нужен , потому что слишком много всяких таких "но" и подводных камней в его использовании.
Каких таких камней? Тебе компилятор не даст сделать так:
goto afterA;
std::string A;
afterA: ;
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Nik_1, Вы писали:
N_>Вот ненадо тока переиначивать. Ты говорил что вообще макросы не разрешаешь, причем тут в каждой строчке
Тут сообщения вроде как не исчезают никуда в основном. Перечитай внимательно что я там говорил, и подумай, как из того, что я говорил, следует необходимость согласования каждой строчки...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, dilmah, Вы писали:
D>Но я не понимаю о чем спор вообще? В С++ есть красивый способ кодирования: допустим тебе нужно написать мощную функцию/метод (которая делает что-то нетривиальное). Тогда внутри этой функции ты определяешь локальную структуру, которая будет "движком" этой функции, локальные переменные этой функции ты обычно затягиваешь внутрь этой структуры, чтобы методы структуры могли с ней работать. Ну и заодно десторуктор этой струткуры занимается освобождением ресурсов. В С такого стиля нет.
Говнокод. Костыли и подпорки. В GCC есть локальные функции.
CC>>пролезли бы?
E>Первый -- нет, static_assert ничем не хуже. Только у нас static_saaert без текстового сообщения.
Первый нужен чтоб быстро написать что то подобное:
E>Кроме того у тебя в макросе предполагается, что CHAR_BIT равно 8, что не обязательно.
Это мелочь. Можно заменить на константу.
Но блин покажите мне промышленную систему где это не так, и для которой С++ компилятор поддерживает static_assert.
E>Второй -- нет. Во-первых, есть такая стандартная функция.
Это которая std::for_each? Сие есть редкостное говно, ибо не позволяет писать в виде:
foreach (it, cont)
{
foo (*it);
}
E>Во-вторых, он вводит в заблуждение. Если внутри цикла cont.end() поменяется, то всё гавкнется.
Есть такой гипотетический минус, правда легко исправляемый:
#define foreach(it,cont) for (auto it = (cont).begin ();it != (cont).end ();++it)
Правда почему то за пяток лет активного использования на практике никто на это так и не напоролся.
Кстати std::for_each также подвержен этой "беде".
template<class _InIt, class _Fn1> inline _Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
{ // perform function for each element
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Func);
_CHECKED_BASE_TYPE(_InIt) _ChkFirst(_CHECKED_BASE(_First));
_CHECKED_BASE_TYPE(_InIt) _ChkLast(_CHECKED_BASE(_Last));
for (; _ChkFirst != _ChkLast; ++_ChkFirst)
_Func(*_ChkFirst);
return (_Func);
}
E> Кроме того если вызвать что-то типа foreach( i, *++vectors ), то будет а-та-та...
— Доктор, у меня болит когда я делаю вот так.
— Не делайте так (С)
E>Для третьего в нашей библиотеке уже есть похожий макрос, ну и вообще он обычно уже есть => не надо вводить свой, надо юзать стандартный.
Т.е. по сути это уже принято.
E>Так что нет все три раза.
Ясно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
А зачем это писать *быстро*? Да и вообще, зачем это писать?.. Особенно про WORD и DWORD...
E>>Кроме того у тебя в макросе предполагается, что CHAR_BIT равно 8, что не обязательно. CC>Это мелочь. Можно заменить на константу.
Это ошибка, а не мелочь...
CC>Но блин покажите мне промышленную систему где это не так, и для которой С++ компилятор поддерживает static_assert.
В чём проблема, написать свой переносимый аналог static_assert'а?.. E>>Для третьего в нашей библиотеке уже есть похожий макрос, ну и вообще он обычно уже есть очень во многих библиотеках => не надо вводить свой, надо юзать стандартный. CC>Т.е. по сути это уже принято.
Ну это много где принято. Но сами по себе программисты всё равно не должны писать свой макрос, но могут использовать библиотечный. E>>Второй -- нет. Во-первых, есть такая стандартная функция. CC>Это которая std::for_each? Сие есть редкостное говно, ибо не позволяет писать в виде:
Я от STL тоже сильно не в восторге. Но это не значит, что надо вводить макросы с именами очень похожими на стандартные функции...
E>>Во-вторых, он вводит в заблуждение. Если внутри цикла cont.end() поменяется, то всё гавкнется. CC>Правда почему то за пяток лет активного использования на практике никто на это так и не напоролся.
Ну, наверное, на практике, все знают, какие циклы так можно писать, а какие нет. То есть мысленно подставляют этот макрос в код и проверяют
CC>Кстати std::for_each также подвержен этой "беде".
Мы вроде как сошлись на том, что он ниже плинтуса? Или нет?
CC>- Не делайте так (С)
Дык это опять надо нигде не наколоться. То есть знать, что на самом деле этот макрос раскрывается в то-то... Например, так:
foreach( it, readVectorFromFile() );
тоже гавкнется...
В общем идея такая, что не так важна скорость набора кода, как скорость чтения/понимания/внесения правок.
Так что чем плодить макрос foreach берёшь да и пишешь всюду
for( auto it = cont.begin(), it != cont.end(); ++it ) {
}
А программист, который слишком медленно набирает тескт, берёт "соло" или другую такую же прогу и осваивает таки слепой десятипальцевый метод хотя бы на уровне 200 символов в минуту.
Ну а инвалид, который не может освоить 200 ударов в минуту, и мегамозг, из которого льётся С++ код с большей скоростью мне в подчинённые не нужны
Кстати, если бы внутри foreach сидела какая-то нетривиальная очень итерация и назывался бы он как-то forEachTreeNode, то можно было бы и посмотреть...
E>>Так что нет все три раза. CC>Ясно.
Ну и хорошо, что ясно.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, CreatorCray, Вы писали:
CC>Гм. У вас до сих пор работают люди, которые допускают такие детские ошибки?
Такие -- это какие?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
В общем лучше пользоваться библиотечным макросом...
C>Заодно не засоряем пространство имён.
Тогда надо без макроса как-то делать!
Как ты думаешь, читабелен ли такой синтаксис:
sizeof in_items( arr )
Мне лично, кажется извратом...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
CC>>Гм. У вас до сих пор работают люди, которые допускают такие детские ошибки? E>Такие -- это какие?
Непонимание как работают макросы
int mx = MAX( *q++. *q++ );
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, Erop, Вы писали:
E>А зачем это писать *быстро*? Да и вообще, зачем это писать?.. Особенно про WORD и DWORD...
Sanity check. Мало ли на какой экзотике это собирать вздумают.
CC>>Но блин покажите мне промышленную систему где это не так, и для которой С++ компилятор поддерживает static_assert. E>В чём проблема, написать свой переносимый аналог static_assert'а?..
А потом ещё и свой переносимый аналог С++0х? Чтоб остальное собралось.
E>>>Для третьего в нашей библиотеке уже есть похожий макрос, ну и вообще он обычно уже есть очень во многих библиотеках => не надо вводить свой, надо юзать стандартный. CC>>Т.е. по сути это уже принято. E>Ну это много где принято. Но сами по себе программисты всё равно не должны писать свой макрос, но могут использовать библиотечный.
В библиотеке оно само образовалось или всё таки сначала было написано программистом и потом включено в библиотеку?
Те же foreach и countof тоже сначала болтались в отдельных файла проекта, пока не стали настолько общеупотребляемыми что заняли своё место во фреймворке.
CC>>Кстати std::for_each также подвержен этой "беде". E>Мы вроде как сошлись на том, что он ниже плинтуса? Или нет?
Раз у стандартного та же "проблема", которую до сих пор так никто и не исправил, то значит это не очень то и проблема на самом деле. Не?
E>Дык это опять надо нигде не наколоться. То есть знать, что на самом деле этот макрос раскрывается в то-то...
Ну ведь знают же люди к примеру что стандартные макросы min и max во что то раскрываются. И что в целом в макросы подобные значения пихать не стоит тоже откуда то знают.
E>В общем идея такая, что не так важна скорость набора кода, как скорость чтения/понимания/внесения правок.
Дык цель любого макроса — заменить многабукаф на одно имя, в случаях когда запихивание этого кода в функцию менее эффективно. И foreach для читабельности и понимания несколько выгоднее чем for (многабукаф)
E>Так что чем плодить макрос foreach берёшь да и пишешь всюду [c]for( auto it = cont.begin(), it != cont.end(); ++it ) {
Писал, но крайне быстро задрало. Да и читать это потом не очень.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
CC>Непонимание как работают макросы CC>
CC>int mx = MAX( *q++. *q++ );
CC>
Не всегда легко понять кто именно тут макрос
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, dilmah, Вы писали:
CC>>Ну ведь знают же люди к примеру что стандартные макросы min и max во что то раскрываются. D>ээ.. std::min вроде сегодня утром шаблонной функцией был?
Дык я не про них
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
E>2) Код который нелегко понять хуже кода, который легко понять НЕВЕРНО и НЕ ЗАМЕТИТЬ этого!
В смысле, конечно, лучше
То есть лучше код, который трудно понять, чем код, который вводит в заблуждение.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском