2010-07-23 48 views
21

我在the assert() reference page考慮看看,我卡住了,而我讀給定的例子:我誤解了assert()的用法嗎?

/* assert example */ 
#include <stdio.h> 
#include <assert.h> 

int main() 
{ 
    FILE * datafile; 
    datafile=fopen ("file.dat","r"); 
    assert (datafile); 

    fclose (datafile); 

    return 0; 
} 

在這個例子中,使用assert如果數據文件進行比較等於0中止程序執行,這恰好當前打電話給fopen是不成功的。

我完全同意,如果fopen()失敗,assert()將中止執行。不過,我很擔心這個例子的正確性:

在我看來assert()有檢測案件不能正常發生(如傳遞NULL指針,其文檔指出,禁止一個函數)。

在這個例子中,未能打開文件不是通常不會發生的事。事實上,我可以看到幾十個原因爲什麼會失敗。該文件不能存在,程序可能沒有必要的權限運行,等等。

我寧願做了一樣的東西:

/* not longer an assert example */ 
#include <stdio.h> 
#include <assert.h> 

int main() 
{ 
    FILE * datafile; 
    datafile=fopen ("file.dat","r"); 

    if (datafile != NULL) 
    { 
    // Do something, whatever. 
    fclose (datafile); 
    } else 
    { 
    // Report the error somehow. 
    } 

    return 0; 
} 

是我如何assert()應該用理解不正確的?


編輯和好消息!

看起來被推薦的網站是由嚴謹的人統治的。這裏是我從一個網站維護者收到的郵件:

嗨朱利安,我不得不同意, 示例代碼是選擇不好。它現在已經被 更改爲 更合適。

非常感謝 指出這一點,併爲此感到抱歉 這可能導致 你。

最好的問候,

和更新的例子:

/* assert example */ 
#include <stdio.h> 
#include <assert.h> 

void print_number(int* myInt) { 
    assert (myInt!=NULL); 
    printf ("%d\n",*myInt); 
} 

int main() 
{ 
    int a=10; 
    int * b = NULL; 
    int * c = NULL; 

    b=&a; 

    print_number (b); 
    print_number (c); 

    return 0; 
} 

高興地看到,有些人做他們的工作以及在互聯網上! ;)

+8

+1認識到這是一個不好的例子。 +2然後郵寄網站聯繫人。 – 2010-07-23 09:52:50

+4

你的理解是現貨。 'assert'用於編程錯誤,而不是用戶錯誤。 – GManNickG 2010-07-23 09:56:32

+0

我刪除了C++標籤,因爲帖子中沒有C++代碼。 – Puppy 2010-07-23 10:29:42

回答

13

你是完全正確的先生。這是assert的糟糕用法。

+0

確實,斷言應該是最後的手段又名世界崩潰 – RvdK 2010-07-23 09:34:51

+2

感謝您的反饋。我寫信給聯繫頁面以通知他們有關問題。我想知道他們是否會更新它。 – ereOn 2010-07-23 09:37:26

+0

+1這可能是潛在的答案;-) – KedarX 2010-07-23 13:09:56

1

次要通知:這將是,如果你寫越好..

FILE * datafile = NULL; 

此外,斷言只能在調試模式......所以你的方法比較好。

+0

嗯,這不是我的代碼。雖然我通常初始化我的局部變量,這裏'datafile'是在聲明後分配的,所以它並不重要;) 關於調試模式的好處,我甚至都沒有想到。 – ereOn 2010-07-23 09:31:10

+0

是什麼讓你說它只能在調試模式下工作? – 2010-07-23 09:47:49

+1

@Praveen:assert是一個宏,只有當'NDEBUG'沒有被定義時纔會執行某些操作。所以通常在調試模式下。 – ereOn 2010-07-23 09:55:27

2

你說得對。正如其他人已經指出的那樣,assert()將更有可能在發佈版本中編譯出來(我發現人們強迫這些斷言留在發佈版本中)。

我只是想補充有關這個問題,我已經看到了一個代碼庫一個恐怖故事:

assert(do_something() == NO_ERR); 

有些人不應該被允許使用的鍵盤。

+1

是的。儘管它取決於do_something()所做的事情。如果do_something()實際上是do_complex_validation_that_system_state_is_valid(),那麼它可能是合理的,如果它沒有副作用 – jcoder 2010-07-25 18:30:24