incubator-stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Sebor <mse...@gmail.com>
Subject Re: tellp()
Date Wed, 13 May 2009 00:28:27 GMT
[CC'ing dev@stdcxx.apache.org]

Steve Clamage wrote:
> I have a bug report where the customer expects to open a file for 
> appending, and have tellp() pointing to EOF before doing anything else. 
> Sample program:
> 
> mytest.cc
> ---------
> #include <iostream>
> #include <fstream>
> using namespace std;
> 
> int main(int argc, char** argv)
> {
>     if(argc != 2)
>     {
>         printf("Wrong nums of arguments\n");
>         return 1;
>     }
>     ofstream ofs;
>     ofs.open(argv[1], ios::out|ios::app);
>     cout << "tellp(): " << ofs.tellp() << '\n';
> }
> 
> % ls -l zout
>  -rw-rw-r--    1 clamage  staff         347 May 12 07:49 zout
> % CC mystest.cc
> % a.out zout
> tellp():0
> 
> The customer expects 347 in this example. Is that a correct expectation?
> libCstd, STLport, and stdcxx all print 0, but g++ prints 347.

I'm not sure the standard is 100% clear on this. Here's why:

     tellp() calls rdbuf()->pubseekoff(0, ios::cur, ios::out), which
     calls seekoff() with the same arguments.

     filebuf::seekoff(0, ios::cur, ios::out) calls fseek(file, 0,
     SEEK_CUR).

So far so good. The problem is the Returns clause for seekoff():

     Returns: a newly constructed pos_type object that stores the
     resultant stream position, if possible. If the positioning
     operation fails, or if the object cannot represent the resultant
     stream position, returns pos_type(off_type(-1)).

This doesn't say where the resultant position comes from:

  *  Is it the value obtained by calling ftell(file)? If so,
     ftell() returns the position of the end of the file.
  *  Is the value obtained using some other mechanism, such as
     "as if" by calling lseek(fileno(file), 0, SEEK_CUR)? If so,
     lseek() returns 0.
  *  Is the value calculated using some other algorithm? If so,
     which one?

I enhanced the program to show the behavior of C stdio and UNIX I/O.
See below. I think we should open an new issue to clarify what the
spec means.

Btw., calling lseek(fileno(file), 0, SEEK_CUR) on the underlying
FILE itself does actually return the same value as tellp(). It's
when filebuf is implemented in terms of POSIX streams as opposed
to stdio that we get this different behavior.

Martin

#include <cstdio>
#include <iostream>
#include <fstream>

#include <fcntl.h>
#include <unistd.h>

using namespace std;

int main(int argc, char** argv)
{
     if(argc != 2)
     {
         printf("Wrong nums of arguments\n");
         return 1;
     }
     ofstream ofs;
     ofs.open(argv[1], ios::out|ios::app);
     cout << "tellp(): " << ofs.tellp() << '\n';

     FILE *fp = fopen (argv [1], "a");
     cout << "ftell(): " << (fp ? ftell (fp) : -1) << '\n';

     int fd = open (argv [1], O_WRONLY | O_APPEND);
     cout << "lseek(): " << lseek (fd, 0, SEEK_CUR) << '\n';
}

The output with stdcxx is:

tellp(): 0
ftell(): 567
lseek(): 0

> 
> 
> ---
> Steve Clamage, stephen.clamage@sun.com


Mime
View raw message