Как я могу установить точку останова на пустой оператор в C ++? - PullRequest
16 голосов
/ 27 января 2012

В частности, я хочу написать макрос, который

1) позволяет мне установить точку останова
2) больше ничего не делает
3) не вызывает предупреждений компилятора

#define NO_OP   ((void)0)

void main()
{
    bool b = true;
    if (b)
        NO_OP;  // I try to set a breakpoint here, but

}               // it jumps to here (in Visual Studio 2010)

Я также пытался

#define NO_OP   (assert(1))             // doesn't work
#define NO_OP   (sizeof(int))           // doesn't work
#define NO_OP   __asm{}                 // doesn't work
#define NO_OP   do {(void)0;} while(0)  // warning: conditional is constant

Единственная вещь, которая работает до сих пор, - это достойная пощады

#define NO_OP   { int x = 0; x = x; }

Должен быть лучший путь.

РЕДАКТИРОВАТЬ
Спасибо Blorgbeard , __asm ​​{nop} действительно работает.Но я только что понял, что что-либо с фигурными скобками не идеально (проблематично?), Потому что после него остается бесполезная точка с запятой.(Позже) Я не знаю приседания о ассемблере, но я попытался снять скобки, и вуаля!Вот ответ: __asm ​​nop Спасибо!

ДЛЯ КУРЬЕРНЫХ
Вот немного менее абсурдный пример:

string token = GetNextToken();
if (!Ignore(token))
{
    // process token
    DoThis(token);
    DoThat(token);
}

Этот код завершен - покатак как программа работает правильно, мне все равно, что нужно знать о игнорируемых токенах.Но в любой момент времени (и без изменения кода) я хочу убедиться, что я не отказываюсь от хороших токенов

string token = GetNextToken();
if (Ignore(token))
{
    NO_OP; // set breakpoint here to monitor ignored tokens
}
else
{
    // process token
    DoThis(token);
    DoThat(token);
}

Ответы [ 6 ]

7 голосов
/ 27 января 2012

Фактическая неоперационная инструкция:

__asm nop
5 голосов
/ 27 января 2012

Возможно, вы можете сделать это:

#define BREAKPOINT __asm { int 3; }

Это вызовет прерывание 3, которое является прерыванием точки останова. Это установит точку останова в вашем коде, который скомпилирован как часть вашего кода.

Теперь, если вам нужна просто какая-то операция, для которой вы можете установить точку останова, которая по сути ничего не делает, кроме того, что позволяет вам прерывать эту строку. Я думаю, что вы должны скомпилировать свой код без оптимизации с одной стороны, поскольку NO_OP, который вы реализовали, вероятно, будет оптимизирован из кода оптимизирующим компилятором с включенными оптимизациями.

Другое дело, что это кажется очень странной вещью. Насколько я знаю, обычно устанавливают точку останова в строке кода, которую нужно просмотреть. Посмотрите, что такое состояние переменных, шаг за шагом по одной строке и т. Д. Я действительно не вижу, как установка точки останова для строки кода, по сути не имеющей значения в вашей программе, поможет вам что-либо отладить.

1 голос
/ 12 октября 2017

На MSVC x64 есть встроенная функция для этого:

__nop;
1 голос
/ 27 января 2012

C ++ 03:

inline void __dummy_function_for_NO_OP () {}
#define NO_OP __dummy_function_for_NO_OP ()

int main () {
    NO_OP;
}

C ++ 11:

#define NO_OP [](){}()

int main () {
    NO_OP;
}
1 голос
/ 27 января 2012

Как насчет __asm int 3?Кроме того, включены ли оптимизации?Это может быть причиной неудачи других (на самом деле никогда не пытался их сломать).

0 голосов
/ 27 января 2012

Вы можете определить глобальный unsigned int debug_counter, тогда ваш макрос "no-op" может быть debug_counter++. Я уверен, что компилятор не удалит это, но чтобы быть абсолютно уверенным, поместите код где-нибудь, чтобы вывести значение счетчика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...