Search code examples
c++linuxmacosstreamfstream

Is this seemingly odd behaviour concerning seekp correct?


EDIT, apologies, this question is clearly a duplicate of failbit not being set when seekg seeks past end of file (C++,Linux)


To get to where I'm at, firstly touch a file in the terminal to create an empty file (linux or mac):

touch test.file

And then compile and execute this code

#include <fstream>
#include <iostream>

int main()
{
    std::fstream stream("test.file", std::ios::in | std::ios::out | std::ios::binary);
    stream.seekp(54765476543); // arbitrarily large number
    std::cout<<"stream.tellp() "<<stream.tellp()<<std::endl;
    std::cout<<"stream.bad()? "<<stream.bad()<<std::endl;
    std::cout<<"stream.fail()? "<<stream.fail()<<std::endl;
    stream << "test";
    stream.flush();
    stream.close();
    return 0;
}

with your favourite c++ compiler (I tried Apple LLVM version 4.2 (clang-425.0.28) for clang++ and i686-apple-darwin11-llvm-g++-4.2 for g++ and g++ (Debian 4.7.2-5) on linux)

E.g.

clang++ testStream.cpp -o ts

When I run 'ts' I get the output:

stream.tellp() 54765476543
stream.bad()? 0
stream.fail()? 0

This is where my confusion arrises: I thought tellp() would give '-1' (since I'm trying to seek past the end) and that stream.fail() would at least equate to true. Is such behaviour undefined or am I missing something?

Even more curiously is that when I then do

ls -lh test.file

I get

-rw-r--r--  1 bjones  users    51G Aug 13 04:32 test.file

Now clearly the file isn't 54G in size. Finally when I do

cat test.file

to see if anything was actually written, the output just hangs.

Is the above behaviour correct?

Thanks,

Ben.


Solution

  • There is nothing wrong in doing a seekp() past the end of file (and possibly then write to it)

    You really are writing this file by moving the cursor forward.

    Whether the file really is that big (and if it is a sparse file) entirely depend on your OS/file system : as far as C++ is concerned, this is valid.