Все олимпиадники делятся на два лагеря: те, кто отлаживает в отладчике, и те, кто отлаживает отладочным выводом. Можно бесконечно спорить о том, какой метод удобнее, но факт остается фактом -- и таких, и таких людей полным-полно. Я отношусь ко второму лагерю: во многих ситуациях применение отладчика невозможно, поэтому хочется быть от него независимым. Более того, лично для меня отладочный вывод удобнее (я использую отладчик только для того, чтобы понять, где именно программа упала).
Так о чем же этот пост? Большинство минусов отладочного вывода на C++ происходит из того, что, к примеру, чтобы вывести вектор, нужно написать довольно много байтов кода. Это не слишком удобно. Чтобы бороться с подобными проблемами, я написал маленькую библиотеку, которая лежит здесь. Если вы напишете такой код: http://pastebin.com/9t87jmdp, то в результате в stderr выведется следующее:
file "test.cpp" line 14: a = {(0, {1, 2}), (1, {})}
file "test.cpp" line 18: aa = {'a', 'b'}
file "test.cpp" line 19: 2 * 2 = 4
Если же вы хотите убрать отладочный вывод, то нужно закомментировать строку #define DEBUG_OUTPUT в test.cpp. В первой версии выводятся следующие переменные:
- которые можно вывести с помощью оператора <<;
- у которых есть .begin() и .end() (коллекции, например);
- std::pair.
Код в debug_output.h использует забавный хак C++, который называется SFINAE.
P.S. Код использует C++11 (поддержка которого есть, к примеру, в g++ 4.6 и Visual Studio 2010). Но, отключив отладочный вывод, можно компилировать код и более старыми компиляторами.
UPD В новой версии C++11 больше не нужен, также поправлен баг, который заметил Петросян.
Ну, это теоретически можно использовать для всяких топкодеров, CF и прочих локальных контестов. К тому же, это можно использовать и для отладки промышленного кода.
При отключенном дебаге твоя библиотечка сломает код такого плана:
if (что_то_случилось) DEBUG(a);
else ...
Лучше взять в круглые скобки
# define DEBUG(a) ({})
ничего не сломает.
я помню макрос
#define for if (0) ; else
для подавления идиотизма компилятора MS VS 6.0
если пару раз подрят написать циклы (не вложенные):
for (int i = 0; ...)
for (int i = 0; ... )
то во второй строке будет ошибка о том, что i уже объявлена.
for (int i=0;i<2;i++)
а потом не вложенно
int i = 0;
assert(i == 0);
будет assertion failed. Ну, или что-то с чем-то местами поменять.
ну да, ты прав. просто я не мог предположить что при отключенном дебаге там такая лажа.
вот это
#define DEBUG(x)
int main()
{
if (0) DEBUG(34); else ;
return 0;
}
спокойно компилится
Илье следует заменить
#else
#define DEBUG(x) {}
#endif
на
#else
#define DEBUG(x)
#endif
{...}
в дефайнах писать
do {...} while(0)
Ужас, ужас... %)
Как раз для случая
if (что_то_случилось) DEBUG(a);
else
Иначе приходится помнить, что точку с запятой ставить не надо.
Студия не поддерживает новый for, поэтому этой библиотекой смогут пользоваться только программирующие на g++.
Хотя исправить for не проблема :)
Вообще-то нет - такой for она не поддерживает. Более того, поддержка нового стандарта в целом студией (даже 2011 developer preview) оставляет желать лучшего. Пруф.