2016-11-04 58 views
2

我試圖找出失敗的原因ofstream::close(),並遇到一些我不明白的行爲。C++ ofstream:評估關閉()錯誤

我使用std::ofstreamstd::copy()將數據寫入流中,然後使用close()寫入文件。如果我引發錯誤(例如文件系統已滿),則failbitclose()設置,但我希望得到更詳細的錯誤描述。

到目前爲止,我認爲如果系統調用失敗,總是會設置errno。但errnoSuccess如果我close()失敗後立即檢查。

我確定系統調用時使用close()流,因爲它會將文件寫入文件系統,但那麼errno怎麼可能不告訴任何有關該問題?所以:

  • 請問ofstream::close()不使用任何系統調用?

如果我明確地調用flush()std::copy()後,再errno正確

No space left on device 

集和failbit設置。隨後調用close()也設置故障位。令人驚訝的是errno重置爲success

errno手冊頁:

errno is never set to zero by any system call or library function 

,我沒有看到哪些其他功能將重新errno

  • ofstream::close()明確重置errno萬一它成功了嗎?

關於ofstream的文檔我找到並沒有說關於errno的約束。

測試Linux x86 g ++ 4.7.3。

回答

1

的確,ofstream :: close()會進行多個系統調用。即使系統調用和C庫函數沒有將errno設置爲零,C++庫也可能會這樣。至少一些ofstream :: close()的實現將errno設置爲0.請參閱下面的註釋。

我的建議是關注你使用的東西的文檔,不要做出假設。在這種情況下,正如你所指出的,ofstream :: close()的文檔沒有提及errno,所以在調用ofstream :: close()之後你不應該對errno做任何假設。另一方面,C函數,如close(fd)在文檔中特別提到了errno。所以如果你真的需要errno,請改用C函數。

+0

但根據手冊頁,系統調用不應將'errno'設置爲0(成功)。在這種情況下使用C函數可能是更好的選擇,但是我不得不放棄更通用的方法(C++流)的優勢。 – radix

+0

我的理解是,errno的manpage只說沒有系統調用,或者C庫會將errno設置爲0.但是它不會限制其他代碼(如用戶代碼或C++庫)將errno設置爲0.我研究了C++系統源代碼並找到ofstream :: close()調用basic_filebuf :: close(),調用__basic_file :: close(),根據至少一個實現,將errno設置爲0.請參閱https://opensource.apple.com/ source/libstdcxx/libstdcxx-52/src/basic_file.cc –

+0

我已經接受了,但實際上認爲......下面應該部分進入答案:_ofstream :: close()可以將errno設置爲0,並且至少在一些執行_ – radix