5

次のプログラムは、libc++ と libstdc++ (clang3.3 を使用) の間で std::getline の動作に矛盾があることを示しています。

プログラムはファイル testfile を開き、eof まで読み取り、次に ifstream::clear を使用してエラー ビットをクリアし、同じファイルハンドルから再度読み取りを試みて、新しいデータがファイルに追加されたかどうかを確認します。

#include <fstream>
#include <iostream>
#include <unistd.h>

using namespace std;

int main() {
    ifstream* file = new ifstream("testfile");
    if ( ! file->is_open() ) {
        cout << "testfile does not exist" << endl;
        return -1;
    }

    while ( 1 ) {
        file->clear(); // remove end of file evil bits
        string line;

        // workaround:
        // file->seekg(file->tellg());

        while ( getline(*file, line) )
            cout << "read line: " << line << endl;

        if ( file->eof() )
            cout << "File reports eof after getline\n";

        usleep(1000000);
    }
}

libstdc++ を使用して (コンパイラに関係なく)、プログラムの実行中にデータを testfile に追加すると、データは次のループ反復で getline 呼び出しによって読み取られます。

libc++ を使用する OS-X 上の clang 3.3 では、最初にファイルの終わりが検出された後、getline は常に失敗し、ファイルに追加されたデータを読み取ることなく、後続のすべての呼び出しで eof ビットを設定します。現在の位置をシークするだけの回避策のコメントを外すと、libstdc++ の動作が復元されます。clang++ -stdlib=libstdc++ を使用して libstdc++ に対してコンパイルすると、以前の動作に戻ります。

これが予想される変更であるかどうかは誰にもわかりますか? サポートされていない方法でこれを行おうとしていますか、それとも現在の libc++ バージョンの問題ですか?

私にとってこの動作をトリガーする clang バージョンは、XCode for Mavericks に同梱されている最新のものです。

Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix

リンクされている libc++ ライブラリには、次のバージョン情報があります。

/usr/lib/libc++.1.dylib:
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/usr/lib/libc++abi.dylib (compatibility version 1.0.0, current version 48.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
4

1 に答える 1