使用 fstream 关闭文件
Closing files using fstream
如果您打开一个文件,然后关闭它。如果您尝试关闭已经关闭的文件,为什么程序会编译?
例如
ifstream inFile;
inFile.open("filename");
inFile.close();
inFile.close();
为什么编译器无法识别您已经关闭了文件?
为什么编译器无法识别您已经关闭了文件?
这些语句在语法上是正确的,因此编译器不会抱怨。
从理论上讲,第二个close()
调用可能会在运行时失败,但由于它是幂等操作,因此不会失败。
从参考文档中可以看出:
笔记
当流对象超出范围且通常不直接调用时,basic_fstream 的析构函数将调用此函数。
它甚至必须以幂等方式实现。
该标准明确规定了如果您在未打开的 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
具有未定义的行为。你的工作是不编写代码,而不是编译器的工作来捕获它。
此类代码可能产生的错误类型是运行时异常。编译器不关心这些事情。相反,它会将您的代码解析为对象文件以供后续链接。若要生成这些对象文件,代码只需在语法上正确且相对于所选语言的格式正确。
因此,只有在将目标文件链接到库或可执行文件中然后执行之后,才会发生运行时异常。
也许答案是:编译器不知道或不关心代码的运行时行为,并且您提到的错误类型是运行时错误。
- 使用fstream对txt文件中的数字进行循环
- 为什么 fstream 在打开带有格式的文件时会导致分段错误?
- 无法打开 fstream C++文件,即使它与 .cpp 位于同一位置
- 使 std::fstream 写入文件末尾,但从头开始读取
- 如何修复函数中的 fstream 文件输入以将正确的信息存储在结构数组中?
- 如何检查文件是否已存在于 fstream C++中
- 使用 fstream 库并在屏幕上打印的文件有问题?
- Windows std::fstream 修改文件后打开()?
- 如何删除文件中的数字,通过 c++ fstream 的
- 如何使用单个fstream创建、读取和写入文件
- 如何使用fstream从.txt文件C++中取出int值
- fstream库,试图创建一个变量名为(c++)的文件
- 变量 std::fstream 文件具有初始值设定项,但类型不完整 编译错误
- 如何在 c++ 中使用 fstream 读取.txt文件
- 为什么错误"permission denied","id returned 1 exit status"仅在 IM 使用 C++ 中的头文件 fstream 时才出现
- 创建.dat文件 (fstream) c++
- 如何读取特定文件fstream
- 在驱动器c:中按类打开文件fstream类
- 使用库更新文件<fstream>(仅覆盖特定部分)
- 读取和写入同一个文件fstream