[英]How can I set a breakpoint on an empty statement in C++?
具體來說,我想寫一個宏
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; // when desired, set breakpoint here to monitor ignored tokens
}
else
{
// process token
DoThis(token);
DoThat(token);
}
一個實際的無操作指令:
__asm nop
也許你可以這樣做:
#define BREAKPOINT __asm { int 3; }
這將調用中斷 3,即斷點中斷。 這將在您的代碼中設置一個斷點,該斷點被編譯為您的代碼的一部分。
現在,如果您只想要一些可以設置斷點的操作,除了允許您在該行上中斷之外,它基本上什么都不做。 我認為你必須在不優化的情況下編譯你的代碼,因為你實現的 NO_OP 很可能會被優化編譯器從代碼中優化出來,優化打開。
另一點是,這似乎是一件非常奇怪的事情。 據我所知,人們通常會在想要查看的一行代碼上設置斷點。 查看變量狀態是什么,一次執行一行,等等。我真的不知道如何在一行代碼上設置斷點而在您的程序中基本上沒有意義,這將有助於您調試任何東西。
在 msvc x64 上有一個內在的:
__nop;
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;
}
__asm int 3
怎么樣? 另外,是否啟用了優化? 這可能是其他人失敗的原因(實際上從未試圖打破他們)。
在myassert.h
定義並包含應用程序中的任何地方(強制包含在 Visual Studio 中?)。
// Works cross-platform. No overhead in release builds
#ifdef DEBUG
// This function may need to be implemented in a cxx module if
// your compiler optimizes this away in debug builds
inline bool my_assert_func(const bool b)
{
// can set true/false breakpoints as needed
if (b) {
return true;
}
else {
return false;
}
}
#define myassert(b) assert(my_assert_func(b))
#else // RELEASE
// In release builds this is a NOP
#define myassert(b) ((void)0)
#endif
#define DEBUG_BREAKPOINT myassert(true)
現在你可以:
string token = GetNextToken();
if (Ignore(token))
DEBUG_BREAKPOINT;
}
else {
// process token
DoThis(token);
DoThat(token);
}
您可以定義一個全局unsigned int debug_counter
,那么您的“無操作”宏可以是debug_counter++
。 很確定編譯器不會刪除它,但絕對肯定的是,在某處放置一些代碼來打印計數器的值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.