2017-01-25 37 views
1

爲了讓測試具體功能更簡潔,我想對fclose函數執行測試。但是在嘗試寫入和重新讀取位圖圖像時遇到了問題。問題測試fclose返回值

assert(fclose(bmp_image) != EOF); 

雖然下面的代碼不會給出任何錯誤:

其實,我測試的時候fclose這種方式有一個bug發生的歷史

int closing_ok = fclose(bmp_image); 
assert(closing_ok != EOF); 

有了更多的測試,我看到這個差異僅在寫入模式下發生,但不在讀取模式下發生。這種差異是否正常?有人能解釋我這種差異嗎?

編輯: 我試圖讓錯誤與代碼含義:

if(fclose(output_file) != EOF) { 
    printf("ERROR: %s\n", strerror(errno)); 
} 

但也正是在這裏很好,沒有錯誤。

+0

問題是什麼是什麼呢?它沒有被調用嗎? – StoryTeller

+0

@StoryTeller我想是的。它可能無法正常關閉文件... 這不是一個大問題,我只是不明白這種行爲。 – baptiste

+0

你在if(fclose(output_file)!= EOF)中的測試應該是'if(fclose(output_file)== EOF)'來打印錯誤原因。 – Gerhardh

回答

3

assert是用NDEBUG編譯時被替換爲無操作的宏。粗略地說,如果您構建可執行文件的發佈版本,則從代碼中消除對fclose的整個調用。

這是文件未能正確關閉的可能原因。

+0

這是這裏的問題。在使用cmake的發佈模式下,根本沒有文件關閉... – baptiste

2

assert()必須與標量表達式一起使用。這意味着你不應該使用它的功能。

您得到此行爲是因爲fclose(bmp_image)被評估了兩次。所以它在第二次調用時返回EOF,因爲該文件已經關閉。

你可以用這個測試:

int my_fclose(FILE *file) { 
    int ret = fclose(file); 
    if (ret == EOF) { 
    printf("ERROR: %s\n", strerror(errno)); 
    } 
    else { 
    printf("no problem\n"); 
    } 
    fflush(stdout); 
    return ret; 
} 

int main(void) { 
    // bad 
    assert(my_fclose(bmp_image) != EOF); 
} 
+0

問題中的代碼有什麼區別?你也可以在assert中調用一個函數。如果定義了'NDEBUG',那麼'my_fclose'函數根本不會被調用。 – Gerhardh

+0

@Gerhardh它總是打印一些東西,所以OP可以看到函數調用了兩次。也許添加一個'fflush(stdout);'。爲了確定。 – Stargateur