2017-01-25 35 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