簡體   English   中英

C ++:使用宏比較指針時發生編譯器錯誤

[英]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 = &target;
    int* ptr2 = &target;

    //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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM