Как установить точку останова на пустой оператор в С++?

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

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);
}

Ответ 1

Фактическая инструкция no-op:

__asm nop

Ответ 2

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

#define BREAKPOINT __asm { int 3; }

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

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

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

Ответ 3

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

Ответ 4

С++ 03:

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

int main () {
    NO_OP;
}

С++ 11:

#define NO_OP [](){}()

int main () {
    NO_OP;
}

Ответ 5

В msvc x64 для этого есть неотъемлемая часть:

__nop;

Ответ 6

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