使用fstream关闭文件

时间:2016-03-20 18:41:59

标签: c++ fstream

如果您打开文件然后将其关闭。如果您尝试关闭已经关闭的文件,为什么程序会编译?

例如

ifstream inFile;
inFile.open("filename");
inFile.close();
inFile.close();

为什么编译器不能识别您已经关闭了文件?

3 个答案:

答案 0 :(得分:3)

  

为什么编译器不能识别您已经关闭了文件?

这些语句在语法上是正确的,因此编译器不会抱怨。

理论上第二个close()调用可能在运行时失败,但由于它是一个幂等操作,它不会。

正如您从reference documentation

中看到的那样
  
    

注释

         

当流对象超出范围并且通常不直接调用时,basic_fstream的析构函数调用此函数。

  

甚至必须以同等方式实施。

答案 1 :(得分:2)

标准清楚地明确指出如果你在未打开的fstreambuf上调用close()会发生什么(没有效果,即它什么也不做),所以在运行时它不是错误,所以编译器拒绝编译这样的代码是完全错误的。

在任何情况下,编译器都不会检查C ++中的内容。让我们想象一下C ++的工作方式就像你期望的那样。如果你有这样的功能:

void close(std::ifstream& f);

实际上(在某些其他文件中)实现了:

void close(std::ifstream& f) { f.close(); }

您将代码更改为:

ifstream inFile;
inFile.open("filename");
close(inFile);
inFile.close();

然后它会编译好,因为编译器无法“看到”第一个调用关闭文件。但是如果close(std::fstream&)函数是内联的,那么编译器现在是否会拒绝它?或者直接在单个函数中调用它只是一个错误?您想象的世界难以使用且难以指定。它会使代码非常脆弱且对上下文敏感,并使重构变得困难。

C ++不能像那样工作,这是件好事。

您想象的世界还需要编译器“理解”inFile.close() 的含义。就编译器而言,它只是执行一系列操作,最终导致一些调用,如fclose(fp)close(fd),但这将嵌套在几个级别的函数调用中,可能不是内联的。即使它们都是内联的,编译器也不会“理解”每个操作的含义和效果,它只是编译你编写的内容并调用你告诉它调用的函数。您如何期望它“知道”所有代码实际上意味着

在编译器 理解每个操作的含义时非常简单:

int i = 1;
int* p = &i;
int j = *p;
p = nullptr;
int k = *p;

即使第二个*p具有未定义的行为,编译器也不会拒绝这一点。你的工作就是不写代码,而不是编译器的工作来抓住代码。

答案 2 :(得分:1)

此类代码可能产生的错误类型是运行时异常。编译器不关心这些事情。相反,它会将您的代码解析为目标文件,以便进行后续链接。要生成这些目标文件,您的代码只需要在语法上正确并且与您选择的语言格式正确。

因此,只有在将目标文件链接到库或可执行文件然后执行之后,才会发生运行时异常。

也许答案是:编译器不知道或不关心代码的运行时行为,而你提到的错误类型是运行时错误。