Ответ 1
Фактическая инструкция no-op:
__asm nop
В частности, я хочу написать макрос, который
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);
}
Фактическая инструкция no-op:
__asm nop
Возможно, вы можете сделать это:
#define BREAKPOINT __asm { int 3; }
Это вызовет прерывание 3, которое является прерыванием прерывания. Это установит точку останова в вашем коде, которая будет скомпилирована как часть вашего кода.
Теперь, если вы хотите только некоторую операцию, на которую вы можете установить точку останова, что по сути ничего не делает, кроме того, что вы можете разбить эту строку. Я думаю, что вам нужно скомпилировать свой код без оптимизации, поскольку NO_OP, как вы уже реализовали, скорее всего, будет оптимизирован из кода оптимизирующим компилятором, при этом оптимизация будет включена.
Другой момент заключается в том, что это кажется очень странным делом. Насколько мне известно, обычно устанавливается точка останова на строке кода, на которую нужно смотреть. Посмотрите, какое состояние переменной, шаг за одной строкой за раз и т.д. Я действительно не вижу, как настройка точки останова на строке кода, которая практически не имеет значения в вашей программе, поможет вам отлаживать что-либо.
Как насчет __asm int 3
? Кроме того, включены ли оптимизации? Это может быть причиной того, что другие не смогли (фактически никогда не пытались сломать их).
С++ 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;
}
В msvc x64 для этого есть неотъемлемая часть:
__nop;
Вы можете определить глобальный unsigned int debug_counter
, тогда ваш макрос "no-op" может быть debug_counter++
. Довольно уверен, что компилятор не удалит это, но, чтобы быть абсолютно уверенным, поместите некоторый код где-нибудь, чтобы напечатать значение счетчика.