Comments 107
Ужас какой. Для этих целей нужно заводить константы, которые описывают, зачем такое нужно, а еще лучше — специальные properties в файлах настройки программы.
+13
Пятнично :)
А ведь есть вероятность того, что конструкции в if (false) {… } будут игнорироваться компилятором так же как и обычные комментарии?
А ведь есть вероятность того, что конструкции в if (false) {… } будут игнорироваться компилятором так же как и обычные комментарии?
+2
Скорее всего эта проверка использовалась для того что бы включить/выключить debug mode, но зачем? Есть ведь директивы препроцессора для этих целей.
+1
Есть. Но представьте, что действия нужно выполнять не всегда в дебаг режиме, а только иногда. Вот шли вы в пошаговой отладке — и вдруг захотелось дампануть весь объект на диск (пусть операция занимает много времени). Останавливаться, править код и перезапускать? Долго. Дампить в дебаге всегда? Долго.
+1
Есть же блок #if DEBUG или Watcher тот же.
+5
Не во всех языках он есть.
0
Пример на С# написан, вот и привел такой пример.
Где нет #if DEBUG, наверняка, есть другие человеческие приемы, в отличии от примера ОП-поста
А Watcher почти везде есть.
Где нет #if DEBUG, наверняка, есть другие человеческие приемы, в отличии от примера ОП-поста
А Watcher почти везде есть.
0
В исходник на практически любом языке можно вставить #define/#if и т.д. Просто перед компиляцией нужно пропустить его через препроцессор cpp, что легко делается добавлением одной строчки в Makefile.
0
А мысль, что это просто говнокод, не посещала?
+36
тогда гугл говнокодит, видел такое условие в demos для андроид, могу дать ссылку если интересно
+2
А Вы читали статью дальше первого абзаца?
+3
Сам такого никогда не писал, но видел, как заказчик после себя в коде оставлял такие блоки с кодом, где вызывались некоторые фичи для «потестировать, а потом когда-нибудь включим»
+4
Есть ещё вариация на тему. Знаю людей, которые так хранят куски кода, которые редко, но надо вызывать при специальном режиме работы вспомогательной программы (утилиты). При этом совет удалить такой код (он всё равно есть в системе контроля версий) они отказываются.
0
А я знаю людей, которые так хранят куски кода, чтобы копипастить их в другие места. Удобный темплейт — всегда под рукой. Тоже удалять отказываются…
0
Чтобы достать его из системы контроля, надо помнить, когда он есть, а потом вытащить из старой версии файла и вставить в нужное место новой (код вокруг этого куска давно изменился)? Нет уж, пусть лучше на месте полежит. Я его, правда, окружаю #if false, а не if(false), но идея насчет контроля кода компилятором мне понравилась. Жаль только, что он будет давать ворнинги.
+1
Пока ваш код лежит в #if false, он точно также не анализируется компилятором на предмет ошибок, так что это не аргумент. Сказанное справедливо для C#, как дела обстоят в C++, я не знаю. А про вытащить старую версию файла тоже надуманно. Просмотр истории файла делается в два клика, если ваша IDE интегрирована с клиентом системы контроля версий.
Но я признаю, что это всё на любителя. У каждого свои привычки и т.д. «Кто как хочет...», как говорится.
Но я признаю, что это всё на любителя. У каждого свои привычки и т.д. «Кто как хочет...», как говорится.
0
В процессе автоматического рефакторинга могут происходить такие казусы.
+2
false переопределен? Как вариант.
+4
Ну просто понадобилось зачем-то быстро выключить часть кода (видимо с целью потом его также быстро включить), не заморачиваясь с комментариями или директивами препроцессора.
Кстати, в ранних версиях LabVIEW до введения Disable структуры подобный метод был практически единственным.
Такое вполне может встретиться в процессе отладки, однако из продакшн кода такие конструкции надо выкидывать при code review, либо пользоваться макросами, объясняющими суть происходящего, иначе они запросто могут вводить в ступор следующих программистов.
Кстати, в ранних версиях LabVIEW до введения Disable структуры подобный метод был практически единственным.
Такое вполне может встретиться в процессе отладки, однако из продакшн кода такие конструкции надо выкидывать при code review, либо пользоваться макросами, объясняющими суть происходящего, иначе они запросто могут вводить в ступор следующих программистов.
+3
Все ж это бессмысленно.
Хоть я и не С программист, но можно назначить константы (В PHP у них глобальная область видимости)
И в них писать Boolean, который как раз и отвечает за дебаг.
А вот этот if(false) нужно будет найти в куче файлов и заменить на if(true).
Не логично и не лаконично.
Хоть я и не С программист, но можно назначить константы (В PHP у них глобальная область видимости)
И в них писать Boolean, который как раз и отвечает за дебаг.
А вот этот if(false) нужно будет найти в куче файлов и заменить на if(true).
Не логично и не лаконично.
+1
UFO just landed and posted this here
#define false true
:D
:D
-1
Ещё адекватный, имхо, вариант — true/false в условии имеет функцию ключа компиляции или параметра конфига. Грубо говоря, true — использовать gd, false — использовать imagemagik. Но по каким-то причинам использовать, например, константы для придания семантики булеву значению, не стали.
0
Ну, если хочется что-то отладить, можно использовать такую конструкцию в качестве комментария, чтобы потом в процессе пробовать запускать программу то с false то с true, это быстрее, чем то писать /* */, то стирать это. Хотя я бы скорее вынес переменную true/false в #define:)
0
Такой код есть в шаблоне корзины в Битриксе :)
+3
UFO just landed and posted this here
Непонятно, за что пост начали минусовать. Мне он показался интересным, забавным и таким, где можно подумать. Я смог назвать все варианты кроме «выполнение иногда нужных операций в режиме отладки». Интересный примем, который где-то может вполне пригодиться.
Могу добавить в копилку ещё некоторые варианты. Взято из разных проектов.
Могу добавить в копилку ещё некоторые варианты. Взято из разных проектов.
1) Обходные маневры
// Old versions of MSVC (6.0 and previous) don't
// support C99 for loop scoping rules. This fixes them.
# if (_MSC_VER <= 1200)
// This trick will generate a warning; disable the warning
# pragma warning (disable : 4127)
# define for if (false) {} else for
# endif
2) Что-то типа static_assert
// Ensures that To is a sub-type of From *. This test is here only
// for compile-time type checking, and has no overhead in an
// optimized build at run-time, as it will be optimized away
// completely.
if (false) {
const To to = NULL;
::testing::internal::ImplicitCast_<From*>(to);
}
3) Недописанный ещё до конца код
if (0)
{
// TODO: Prefix with date
код которые компилируется, но ещё не работает
}
4) Удаление нестандартных расширений
//__try and __except dont work in gcc, so heres some defines to take em out
#define __try
#define __except(x) if(false)
+10
> # pragma warning (disable: 4127)
> # define for if (false) {} else for
Главное потом не забыть это убрать. Я б предупреждение таки не стал отключать.
А как, кстати, PVS на все эти трюки реагирует?
> # define for if (false) {} else for
Главное потом не забыть это убрать. Я б предупреждение таки не стал отключать.
А как, кстати, PVS на все эти трюки реагирует?
0
о, а это, кстати, чуть ли не единственные разумные причины. 3) это правда просто временное закомментирование кода, а все остальное — вполне жизненно. И 1,2,4 — пожалуй единственные убедительные причины появления такого if-а в коммитах.
а, вру. у меня еще вот такой был:
читаемость выше чем с #ifdef'ами и компилируются всегда обе ветки (то есть некоторые ошибки big-endian кода компилятор поймает уже на low-endian).
а, вру. у меня еще вот такой был:
if (LITTLE_ENDIAN && some_condition)
{
...
}
else
{
...
}
читаемость выше чем с #ifdef'ами и компилируются всегда обе ветки (то есть некоторые ошибки big-endian кода компилятор поймает уже на low-endian).
+1
Не раз видел такое в raw php темплейтах, чтобы закомментировать ненужный в данный момент большой кусок html кода.
<?php if(false): ?>
большой кусок кода
<?php endif ?>
0
UFO just landed and posted this here
Есть ещё одно применение для ActionScript 3.0 — не вызывать конструктор предка. Если программист этого не делает руками, то компилятор подставляет этот вызов в начало конструктора, а если компилятор найдёт его даже под if(false), то сам ничего делать не будет. В итоге получаем объект, для которого не вызван конструктор предка. Костыль конечно, но иногда можно использовать.
0
неа, неправда.
Флексовый компилятор достаточно умён чтобы выбросить if(false), и тогда, после выбрасывания этого куска конструктор будет вписан. И даже if (2!=2) он, по-моему, палит, точно не помню. А вот if((2+2)!=4) вот это не палит. Связано это видимо с тем что он не производит вычисления при компиляции, т.к. в байткоде будет сложение и потом сравнение.
Флексовый компилятор достаточно умён чтобы выбросить if(false), и тогда, после выбрасывания этого куска конструктор будет вписан. И даже if (2!=2) он, по-моему, палит, точно не помню. А вот if((2+2)!=4) вот это не палит. Связано это видимо с тем что он не производит вычисления при компиляции, т.к. в байткоде будет сложение и потом сравнение.
0
Во время отладки Set next statement внутрь if (false)?
Я правда в таких случаях пишу как-то так:
Мне как-то проще переменную отладчиком поменять, чем c Set next statement играться.
Я правда в таких случаях пишу как-то так:
static bool debug = false;
if (debug)
{
Мне как-то проще переменную отладчиком поменять, чем c Set next statement играться.
+1
Посмотрел на это, и пришла в голову садистская мысль:
#define false true
Пятница наверное, домой пора.
#define false true
Пятница наверное, домой пора.
-1
Я иногда использую строку в условии:
if ("Send report to owner") {
// здесь куча строчек кода / вычислений, которые можно отнести к какой-то маленькой фиче,
// прошитой только в этом файле. Отключать эту фичу никому в голову не придет (поэтому и не дефайн),
// но не хочется размазывать все ее переменные/действия по файлу (скажем это не мой, макаронный код).
// Да, можно сделать функцию c говорящим названием (даже если она не реюзается).
// Но фраза на английском наиболее говорящая.
}
if ("Dumb block to refactor") {
// тут и так все понятно. Это вместо того чтобы писать два комментария:
# TODO refactor this block
...
# end of block to refactor
}
+1
UFO just landed and posted this here
Для подсказки в Zend Studio часто пишу так:
if(0) $a = new MyClass()
Ну и забываю иногда удалить :)
if(0) $a = new MyClass()
Ну и забываю иногда удалить :)
0
а phpDoc в ZS не рулит?
ну там /** @var $a MyClass */ или типа того?
ну там /** @var $a MyClass */ или типа того?
0
Нет, @var действует только на поля класса.
Иногда помогает @return MyClass
Но часто функция может возвращать объекты разных типов (фабрика, например, ну или просто объявленная в родительском классе функция — Zend Studio всегда будет думать, что она возвращает родительский класс), и чтобы ZS подсказывала функции нужного класса, приходится делать такое фиктивное присваивание.
Иногда помогает @return MyClass
Но часто функция может возвращать объекты разных типов (фабрика, например, ну или просто объявленная в родительском классе функция — Zend Studio всегда будет думать, что она возвращает родительский класс), и чтобы ZS подсказывала функции нужного класса, приходится делать такое фиктивное присваивание.
0
Вот спасибо. Если когда-нибудь я встречу в коде нечто подобное, буду знать, где корень зла.
Шутки-шутками, а ведь немало тех, кто возьмет это в оборот.
Шутки-шутками, а ведь немало тех, кто возьмет это в оборот.
+1
Что значит, возьмёт? Нормальная практика. Ну может в продакш коде опасно такое оставлять, но для внутреннего использования или ресёча — вполне себе нормальный код.
0
В большинстве случаев, я уверен, из дев версии такой код перейдет и в продакшн. Это во-первых, а во-вторых, выше уже заметили, что лучше использовать константу с адекватным именем, например DEBUG_MODE. Даже постороннему человеку сразу будет понятно, что это за условный блок.
+1
Ещё отмечу, что для быстрого включения/отключения кода писать не if(false), а if(0), который превращается в true одним символом: if(1).
Ну и ещё из этого разряда:
А теперь отключаем блок:
Ессно, тут надо быть осторожным, учитывать блоки else и всё такое, но всяко быстрее, чем «выделить и закомментировать».
Ну и ещё из этого разряда:
// было
if(some_condition && some_another_condition) { /* do */ }
А теперь отключаем блок:
if(false && some_condition && some_another_condition) { /* do */ }
Ессно, тут надо быть осторожным, учитывать блоки else и всё такое, но всяко быстрее, чем «выделить и закомментировать».
0
Я как-то раз из-за
отключил биллинг на продакшне :) спас только звонок клиента через день — «эм… собственно, а почему деньги списываются, а товар не продаётся?» (слава богу, начальник так и не узнал об этом) =)
if (false && $this->billing->makePayment()....)
отключил биллинг на продакшне :) спас только звонок клиента через день — «эм… собственно, а почему деньги списываются, а товар не продаётся?» (слава богу, начальник так и не узнал об этом) =)
0
В пхп нет lazy evaluation? Врёте же, небось написали что-то вроде такого:
if ($this->billing->makePayment() && false)
0
Не совсем понял, а в чем разница? От переменых мест слагаемых сумма разве не меняется?
0
Меняется, Билли, меняется.
В обоих случаях блок внутри if'а не сработает. Но в Вашем случае
Почему? Потому что парсер «ленивый».
В Вашем примере:
он смотрит на первую часть условия, находит там false, а за ним — логическое «и». Значит на второй операнд можно и не смотреть.
В моем:
проводит успешную оплату. Потом применяет «и» на false и внутрь блока уже не заходит.
Судя по жалобе клиента я предположил, что Вы использовали именной мой вариант.
В общем, добро пожаловать в программирование.
В обоих случаях блок внутри if'а не сработает. Но в Вашем случае
$this->billing->makePayment()
выполнится, а в моем — нет.Почему? Потому что парсер «ленивый».
В Вашем примере:
он смотрит на первую часть условия, находит там false, а за ним — логическое «и». Значит на второй операнд можно и не смотреть.
В моем:
проводит успешную оплату. Потом применяет «и» на false и внутрь блока уже не заходит.
Судя по жалобе клиента я предположил, что Вы использовали именной мой вариант.
В общем, добро пожаловать в программирование.
0
Я так тестировал свой механизм проверки покрытия кода тестами (проценты).
Второй вариант — когда то писал я шаблонизатор, где однажды выполненный фрагмент кода можно было повторять.
Например, сверху и снизу страницы постраничная навигация.
И если сверху он бывает не нужен, то отключается. Был даже тег который пребразовывался в <?php if(false) {
Второй вариант — когда то писал я шаблонизатор, где однажды выполненный фрагмент кода можно было повторять.
Например, сверху и снизу страницы постраничная навигация.
<fragment paginator>
//тут постраничная навигация
</fragment>
// тут контент
<include fragment="paginator">
И если сверху он бывает не нужен, то отключается. Был даже тег который пребразовывался в <?php if(false) {
0
Парсер съел тег <hidden>, который пребразовывался в <?php if(false) {
0
Дисклеймер для тех, кто прочитает эти строки не в январе 2012, а допустим, в июне 2013. Это не фрагмент кода, по которому учатся. Если подобные вещи выносить во внешние файлы, то затраченное время будет меньше на много порядков (примерно в 1000-2000 раз по моим подсчётам и моим примерам).
Более того, гораздо лучше подготовить заранее переменную и выводить её в шаблон хоть тыщу раз.
Более того, гораздо лучше подготовить заранее переменную и выводить её в шаблон хоть тыщу раз.
0
Как насчёт такого: внутри if(false) {...} содержится упоминание статического класса. И хотя в этот блок исполнение никогда не зайдёт, статический класс будет проинициализирован, а его статический конструктор будет вызван. Я прав?
Хотя, с таким нужно быть очень осторожным, так как компилятор может оптимизировать код и просто удалить блок, в который исполнение никогда не зайдёт.
Хотя, с таким нужно быть очень осторожным, так как компилятор может оптимизировать код и просто удалить блок, в который исполнение никогда не зайдёт.
0
Внутри может быть банальный набор #define, которые нужны, а исполняемый код рядом не нужен.
0
Нет, конструктор вызван не будет пока выполнение не дойдёт до точки, где определена переменная. И да, компилятор скорее всего удалит этот блок при включённой оптимизации.
0
Какая переменная?
0
Хотя, что бы вы ни имели в виду, вы правы :) По крайней мере, для C#, статический конструктор не вызывается, пока не встречается хоть какое-то использование класса. Я когда-то читал, что вызов статического конструктора — это вообще недетерменированная штука, и не стоит рассчитывать, что он вызовется в какой-то определенный момент.
Так что, моё изначальное предположение не подтвердилось.
Так что, моё изначальное предположение не подтвердилось.
0
UFO just landed and posted this here
А еще так можно хранить примеры и это удобнее чем в комментариях, т.к. работает подсветка и навигация по коду. при компиляции оно все-равно поскипается оптимизатором. Да и дебажить бывает очень даже удобно таким способом.
+2
Я пишу на Lua, и использую такую конструкцию для включения дебаг режима исключительно в начале main файла, впринципе, можно было бы создать глобальную переменную DEBUG = true, и менять ее, а не условие, но за чем лишний раз засорять глобальное пространство.
0
Не могу поставить плюс, поэтому спасибо. Не задумывался о таком применении.
0
В 1С — единственный вариант type hinting для значений, тип которых неизвестен (например передаваемый в функцию параметр), например:
(не плюйтесь про код на родном языке, в США так все пишут ;))
Процедура ПриветХабр(Параметр)
Если Ложь Тогда
Параметр = Новый СписокЗначений;
КонецЕсли;
...
(не плюйтесь про код на родном языке, в США так все пишут ;))
+1
нужно было назвать статью «Как оправдать свой говнокод»
-1
Я пишу if (1==2), такая конструкция при просмотре кода сильнее бросается в глаза
0
Only those users with full accounts are able to leave comments. Log in, please.
В чём смысл?