Отладка макросов
От: Аноним  
Дата: 06.02.10 17:04
Оценка:
Как сделать чтобы Visual Studio 2008 видя что вызывается #define макрос при отладке входила в тело макроса?

10.02.10 20:43: Перенесено из 'C/C++'
Re: Отладка макросов
От: nen777w  
Дата: 06.02.10 17:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как сделать чтобы Visual Studio 2008 видя что вызывается #define макрос при отладке входила в тело макроса?


Макрос не вызывается. Макрос это макрос это то что в результате становится кодом после обработки препроцессором.
В студии можно посмотреть то что получается после обработки препроцессора, для этого для конкретного модуля компиляции (файла c/cpp) надо включить выводить результат препроцессинга в файл (будет с расширением i)

Что бы отладить можно сперва создать такой файл, скопировать оттуда код, потом закоментарить макрос вставить полученный код отключить вывод препроцессора и отладить код.
Re[2]: Отладка макросов
От: asdasdasd2  
Дата: 06.02.10 17:54
Оценка: +1 :))
N>Макрос не вызывается. Макрос это макрос это то что в результате становится кодом после обработки препроцессором.
Я знаю что макрос добавляет код на стадии компиляции, но и предполагаю что студия с отладчиком это должны знать...
Неужели мелкомягкие не предусмотрели такую ситуацию?
Re[3]: Отладка макросов
От: servancho Россия https://dedis.ru
Дата: 06.02.10 18:49
Оценка:
Здравствуйте, asdasdasd2, Вы писали:

N>>Макрос не вызывается. Макрос это макрос это то что в результате становится кодом после обработки препроцессором.

A>Я знаю что макрос добавляет код на стадии компиляции, но и предполагаю что студия с отладчиком это должны знать...
A>Неужели мелкомягкие не предусмотрели такую ситуацию?

То что требует отладки обязано быть в виде функции.
Возьми за правило использовать макросы только для условной компиляции, а не для подстановок.
Если руки золотые, не важно из какого места они растут.
Re[3]: Отладка макросов
От: gear nuke  
Дата: 06.02.10 19:36
Оценка:
Здравствуйте, asdasdasd2, Вы писали:

A>Я знаю что макрос добавляет код на стадии компиляции


Полная чаша
Один профессор пришел к известному учителю дзен Нан-ину, что бы узнать о дзен. Нан-ин предложил ему выпить чаю и стал наполнять чашку. Чашка уже была полна, но мастер все лил и лил в неё чай. Профессор долго следил за ним и наконец не выдержал:
— Что вы делаете?! Чашка переполнена, в неё больше ничего не войдет!
— Так же как эта чашка, — ответил Нан – ин, – вы полны ваших собственных мнений и знаний. Как я смогу показать вам дзен, если вы не опустошите свою чашку?


В процессе трансляции, сначала проиходит обработка препроцессором, а потом компиляция.

A> но и предполагаю что студия с отладчиком это должны знать...


Они знают только то, что компилировалось.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: Отладка макросов
От: Sni4ok  
Дата: 06.02.10 19:45
Оценка: +1 :))
Здравствуйте, servancho, Вы писали:

S>Возьми за правило использовать макросы только для условной компиляции, а не для подстановок.


ага, а если нужно нагенерировать много разных классов, или функций?
Re[5]: Отладка макросов
От: servancho Россия https://dedis.ru
Дата: 06.02.10 19:51
Оценка: +1 :))
Здравствуйте, Sni4ok, Вы писали:

S>Здравствуйте, servancho, Вы писали:


S>>Возьми за правило использовать макросы только для условной компиляции, а не для подстановок.

S>ага, а если нужно нагенерировать много разных классов, или функций?

Лучше не надо!
Если руки золотые, не важно из какого места они растут.
Re: Какой язык имеется в виду?
От: Erop Россия  
Дата: 06.02.10 20:00
Оценка: +3
Здравствуйте, Аноним, Вы писали:

А>Как сделать чтобы Visual Studio 2008 видя что вызывается #define макрос при отладке входила в тело макроса?


Если С++, то срочно начинай думать в сторону шаблонов, а если чистый С, то в сторону того, чтобы перейти на "С с классами", вернее на "С с классами и простыми шаблонами" Хотя бы в той части твоей программы, которая нуждается в этих мега-макросах.

Если же перейти на "С с классами" тоже есть какие-то непреодолимые препятствия, то
1) Расскажи, что тебе надо на самом деле
2) Скорее всего ты можешь добавить в свой проект отдельный шаг "генерация таких-то функций", написать на С или С++ или взять готовую генерилку и генерить ей то, что тебе надо...

А от макросов, скорее всего, лучше отказаться. Их главный недостаток в том и состоит, что их ни отлаживать ни поддерживать по-человечески нефига не получается...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Отладка макросов
От: Кодт Россия  
Дата: 06.02.10 20:11
Оценка: 12 (1)
Здравствуйте, Аноним, Вы писали:

А>Как сделать чтобы Visual Studio 2008 видя что вызывается #define макрос при отладке входила в тело макроса?

Заплатить из своего кармана разработчикам Visual Studio 2012.

В настоящий же момент все известные мне компиляторы Си и С++ расставляют точки отладки на линии кода.
Если в одной линие окажется несколько стейтментов — дебаггер перепрыгнет их одним махом.
#line 1 // в отладочную информацию входит соответствие позиций в коде и позиций в исходниках
foo(); bar(); buz(); // невозможно поставить брекпоинт между foo и bar; только перед foo и затем по шагам прогуляться внутрь их всех

#line 2
foo();\
bar();\
buz(); // та же самая история - для компилятора это одна линия, см. бэкслеш

#line 3
#define BAR() bar1(); bar2(); bar3()

#line 4
foo(); BAR(); buz(); // внутри макроса нет меток #line - и быть не может; отладчик ничего не знает про line 3

// даже если определим
#line 5
#define BAR() \
  bar1(); \
  bar2(); \
  bar3(); // это всё равно одна строка, без обрамляющих меток #line


Это — результат тяжкого наследия из глубокой древности и ограничения языка
Хотелось бы вот такого:
#point("a.cpp",1,1)# foo(); #point("a.cpp",1,8)# bar(); #point("a.cpp",1,15)# buz();

#point("a.cpp",1,1)# foo(); #point("macro.h",1,15)# bar1(); #point("macro.h",1,24)# bar2(); #point("macro.h",1,33)# bar3(); #point("a.cpp",1,15)# buz();

Но макроязык Си такой фокус не просто не может поддержать, а и не имеет права.
Потому что макрос может быть развёрнут и в строку кода, и в строковый литерал. Такую проблему можно наблюдать, к примеру, с макросом __LINE__ в режиме edit-n-continue. Но это, что называется, меньшее зло.
А, допустим, мы напишем
#define PPSTR(s) PPSTR_(s)
#define PPSTR_(s) #s

BAR();
printf("%s", PPSTR(__LINE__)); // внезапно!
printf("%s", PPSTR(BAR()));

Спрашивается: ожидаем ли мы увидеть в выводе разметку для отладчика? навряд ли.
А может ли препроцессор отличить — когда макрос это часть кода, вынесенная куда-то вовне, а когда специальная синтаксическая каша, в принципе не являющаяся кодом (например, подлежащая стрингизации)? Хотя, наверно, может... просто возьмёт да и вырежет метки перед стрингизацией или там конкатенацией токенов.

Компиляторы языков, в которых макросы не столь дубовые или вообще отсутствуют — VB, C# и т.п. — не имеют таких проблем и могут расставлять точки внутри линий. Завидно, конечно... Но Microsoft, FreeSoftwareFoundation, Intel, Comeau и прочие авторы компиляторов С/С++ здесь не при чём.
Перекуём баги на фичи!
Re[2]: Отладка макросов
От: Кодт Россия  
Дата: 06.02.10 20:16
Оценка:
К>Компиляторы языков, в которых макросы не столь дубовые или вообще отсутствуют — VB, C# и т.п. — не имеют таких проблем и могут расставлять точки внутри линий. Завидно, конечно... Но Microsoft, FreeSoftwareFoundation, Intel, Comeau и прочие авторы компиляторов С/С++ здесь не при чём.

А там, где макросы не дубовые (Nemerle, Lisp, Template Haskell) — там они вообще сами генерируют код. Соответственно, отладчику просто некуда углубляться — в исходниках нет того места, на котором он сейчас стоит.
Как если бы мы сгенерировали исходный файл в %temp%, скомпилировали, а ненужный более исходник удалили.
Перекуём баги на фичи!
Re[2]: Отладка макросов
От: gear nuke  
Дата: 07.02.10 05:33
Оценка:
Здравствуйте, Кодт, Вы писали:

К>В настоящий же момент все известные мне компиляторы Си и С++ расставляют точки отладки на линии кода.


Отладчик в Студии может ставить брякпоинты на ассемблерных командах (Debug-->Windows-->Disassembly). У WinDbg можно еще в консоли написать что-то вроде:
bp fun+5

То есть при определённой сноровке можно ставить на каждом операторе. Самое главное в Студии в режиме edit&continue быть на чеку — можно поставить бряк в "старый дубликат" функции.

Впринципе, информация связывающая адрес машинной команды со строкой находится в PDB файле, и технически можно наверное разбить строку на несколько.

Но проще расставлять точки останова в исходнике:
extern "C" void __debugbreak();
#pragma intrinsic(__debugbreak)

__forceinline void bp()
{
#if 1
  __debugbreak();
#else
  __asm int 3
#endif
}
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[3]: Отладка макросов
От: Кодт Россия  
Дата: 07.02.10 08:59
Оценка:
Здравствуйте, gear nuke, Вы писали:

К>>В настоящий же момент все известные мне компиляторы Си и С++ расставляют точки отладки на линии кода.


GN>Отладчик в Студии может ставить брякпоинты на ассемблерных командах (Debug-->Windows-->Disassembly).

Естественно, что отладчик с исполнимым кодом может что угодно творить — дизассемблировать и ставить бряки на каждую инструкцию. (Интересно, а если сделать jmp в середину инструкции — поймёт?)
Но чтобы привести в соответствие машинные адреса и кусочки исходных текстов, ему нужна отладочная информация.
А отладочная информация гранулирована по строкам, увы.
Да ещё и довольно-таки издевательски расставлена — как я понимаю, многострочный стейтмент обретает свою приписку в строке, где он заканчивается. Поэтому — ставишь бряк на начало выражения, а отладчик резво скачет в конец.
(@)  int retcode =
       HelloWorldEx(
         "hello",
         "world",
         NULL,
         HWX_SINGLELINE|HWX_CONSOLE|HWX_INTERACTIVE
         // TODO ...
         // FIXME ...
       )
==>  ;
Перекуём баги на фичи!
Re[3]: Отладка макросов
От: nen777w  
Дата: 07.02.10 10:26
Оценка:
Здравствуйте, asdasdasd2, Вы писали:

N>>Макрос не вызывается. Макрос это макрос это то что в результате становится кодом после обработки препроцессором.

A>Я знаю что макрос добавляет код на стадии компиляции, но и предполагаю что студия с отладчиком это должны знать...
A>Неужели мелкомягкие не предусмотрели такую ситуацию?

Вы путаете компилятор с интерпретатором.
Re[4]: Отладка макросов
От: Кодт Россия  
Дата: 07.02.10 14:11
Оценка: 2 (1)
Здравствуйте, nen777w, Вы писали:

N>Вы путаете компилятор с интерпретатором.


Интерпретатор столкнётся с теми же проблемами, что и компилятор.
Исходный код, рассыпаный осколками по многим файлам и собранный из кусочков, границы которых не обязательно проходят по границам выражений и стейтментов.

#define FOO  printf("hello %"
#define BAR  "d!", 123);

int main() {
  FOO BAR
}

Хоть компилируй, хоть интерпретируй — некуда углубляться.

Максимум, что можно сделать — это разделить фазы препроцессора и компилятора, и отлаживаться в препроцессированном коде.

В студии, я думаю, это очень легко сделать: добавить в проект .i-файлы, генерируемые препроцессором из исходных .cpp, так, как добавляются в проект .h и .c-файлы, генерируемые MIDL-ом из .idl или другими тулзами.
Перекуём баги на фичи!
Re[4]: Отладка макросов
От: gear nuke  
Дата: 07.02.10 16:46
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Интересно, а если сделать jmp в середину инструкции — поймёт?


Когда ставим обычный брякпоинт, отладчик пишет в это место int3 (при хите восстанавливает оригинал). То есть при переходе в середину инструкции будет выполняться код (обычно мусор) после этого int3. Есть еще аппаратные точки останова (в Студии только на доступ к данным) но они тоже ограничены 1м байтом.

К>Но чтобы привести в соответствие машинные адреса и кусочки исходных текстов, ему нужна отладочная информация.

К>А отладочная информация гранулирована по строкам, увы.
К>Да ещё и довольно-таки издевательски расставлена — как я понимаю, многострочный стейтмент обретает свою приписку в строке, где он заканчивается.

Да, и это вроде логично — части могут вычисляться в неустановленном порядке.

Если же кто-то написал 5 стейтментов в строке — значит ему и так на них наплевать
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[5]: Отладка макросов
От: ononim  
Дата: 08.02.10 15:03
Оценка:
К>Максимум, что можно сделать — это разделить фазы препроцессора и компилятора, и отлаживаться в препроцессированном коде.
Все что _нужно_ сделать это сохранять в символьной информации (.pdb) то что такой то код относиться к строчкам кода которые попадают в макрос, а не в точку его указания в функции.
.pdb генерируются компилятором, и в принципе теоретически ничего принципиально сложного учитывать информацию препроцессора при генерации .pdb я не вижу. Другой вопрос будет ли это являться идеологически более "правильным". В этом отношении я на стороне МС, хотя бы потому что это дает однозначное двустороннее соответствие точки в бинарном коде <-> точки в исходнике, если конечно выключен оптимизатор.
Как много веселых ребят, и все делают велосипед...
Re[6]: Отладка макросов
От: Кодт Россия  
Дата: 08.02.10 16:26
Оценка:
Здравствуйте, ononim, Вы писали:

К>>Максимум, что можно сделать — это разделить фазы препроцессора и компилятора, и отлаживаться в препроцессированном коде.

O>Все что _нужно_ сделать это сохранять в символьной информации (.pdb) то что такой то код относиться к строчкам кода которые попадают в макрос, а не в точку его указания в функции.

Если отладочная информация сопоставляет позициям бинарного кода позиции букв в тексте, то очевидно, можно найти исходное положение (происхождение) ключевых букв стейтмента (или выражения, если мы захотим отлаживаться с точностью до подвыражений — как это делают VB или C#).
Например, ключевыми буквами будут первая и последняя непробельные буквы.

Подсвечивать кусок текста от начала до конца — идея несбыточная, я уже показал, как легко разодрать один стейтмент.
Значит, нам остаётся следить только за началом или только за концом.
Но и здесь нас ждёт заподло
#define FOO \  /* вообще-то, это всё одна строка... но мы позиционируемся с точностью до букв */
   f(); \            /* line2 */
   o(); \            /* line3 */
   o();              /* line4 */
#define WTF(j) \
   w() j \
   t() j \
   f() ;             /* line9 */
#define COMMA ,
#define SEMICOLON ;  /* line11 */

int main()
{
  FOO            // попрыгаем по line2, line3, line4 - желаемое поведение
  WTF(COMMA)     // прыгнем на line9 - ну, в принципе, да...
  WTF(SEMICOLON) // внезапно, line11, line11, и только потом line9 - что за чёрт?
}


Либо надо в отладчике, на глазах у изумлённой публики, в отдельном окошке раскрывать макрос до мелочей. Там уже можно будет и по подстрокам гулять.
Перекуём баги на фичи!
Re[7]: Отладка макросов
От: Тот кто сидит в пруду Россия  
Дата: 08.02.10 16:37
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Либо надо в отладчике, на глазах у изумлённой публики, в отдельном окошке раскрывать макрос до мелочей. Там уже можно будет и по подстрокам гулять.


Ну дизассемблер же показывают. Не поленились бы — и макросы бы так же раскрывали. Но, это действительно сначала отладчик надо не построчный, а пооператорный сделать.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[8]: Отладка макросов
От: Кодт Россия  
Дата: 08.02.10 18:04
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

К>>Либо надо в отладчике, на глазах у изумлённой публики, в отдельном окошке раскрывать макрос до мелочей. Там уже можно будет и по подстрокам гулять.


ТКС>Ну дизассемблер же показывают. Не поленились бы — и макросы бы так же раскрывали. Но, это действительно сначала отладчик надо не построчный, а пооператорный сделать.


Интеллисенс показывает разворот макросов.
Но чтобы сделать полноценный отладчик, там нужно над UI поплясать. Хотя, что там плясать: просто ещё одно окошко типа watch, где показывалась бы текущая строка в развёрнутом виде.

Ещё бы макросы были многострочными (а не псевдомногострочными с бэкслешем) — так вообще щасте бы наступило.
Перекуём баги на фичи!
Re[8]: Отладка макросов
От: asdasdasd2  
Дата: 08.02.10 20:48
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Здравствуйте, Кодт, Вы писали:


К>>Либо надо в отладчике, на глазах у изумлённой публики, в отдельном окошке раскрывать макрос до мелочей. Там уже можно будет и по подстрокам гулять.


ТКС>Ну дизассемблер же показывают. Не поленились бы — и макросы бы так же раскрывали. Но, это действительно сначала отладчик надо не построчный, а пооператорный сделать.



вот я думал что такое уже реализовано (я топикстартер)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.