[英]C++: Compiler Error While Comparing Pointers using Macros
我定義了一個自定義的斷言宏。 這對於所有其他比較都可以正常工作。 但是,我得到了編譯器錯誤:
ISO C++ forbids comparison between pointer and integer
使用下面顯示的宏(DWASSERT)比較指針時,如下面的代碼所示。
#define DWASSERT(condition,printstatement) if(!condition){ printf(printstatement); assert(condition); }
#include <stdio.h>
int main()
{
int target = 0;
int* ptr1 = ⌖
int* ptr2 = ⌖
//Normal comparison works fine
if(ptr1 == ptr2)
printf("Equal");
//Comparison using Macro generates compiler
//error on the next line
DWASSERT(ptr1 == ptr2, "Pointers not equal!\n");
return 0;
}
盡管我可以避免在這種情況下使用DWASSERT,但是我很好奇為什么會生成此編譯器錯誤。
問題是DWASSERT(ptr1 == ptr2, ...
被擴展為
if(!ptr1 == ptr2){ printf(...
你知道發生了什么嗎? !ptr1 == ptr2
等效於(!ptr1) == (ptr2)
,並且由於!ptr1
是整數類型,而ptr2
是指針類型,因此會出現錯誤。
要解決此問題,您需要將宏定義更改為:
#define DWASSERT(condition,printstatement) if(!(condition)){ printf...
另外,請記住,以任意方式將printf
用作任意字符串是一種不好的主意 。 在某些時候,有人會給您一個包含%
的字符串,事情會破裂。 您應該使用puts(x)
或printf("%s", x)
。
更改
if(!condition)
至
if(! (condition) )
您的操作方式!
應用於比較中的第一個指針,而不是比較結果,它的優先級高於==
。
您應始終將宏參數括在括號中,以避免類似的問題。 有時,編譯器不會警告您,並且您會在晚上尋找問題的消息。
將括號放在條件中的if
宏中:
#define DWASSERT(condition,printstatement) if(!(condition)){ printf(printstatement); assert(condition); }
編譯器看到:
if (!ptr1 == ptr2) { ... }
解釋為:
if ((!ptr1) == ptr2) { ... }
這不是您想要的。 但是您確實應該為此使用適當的功能-該條件可能會通過宏兩次評估。 在某些情況下,第二個測試可能會產生與第一個不同的結果,這將帶來非常令人驚訝的結果。
int i = -1;
DWASSERT(++i, "will I assert?");
(如果確實需要使用宏,則應在其中創建一個匿名塊,並將條件的評估結果保存在臨時的bool
。這通常是通過do { ... } while(0)
構造完成的。)
嘗試
DWASSERT((ptr==ptr2), "Pointers not equal!\n");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.