This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Question: is it a compiler bug or else...?
- From: Graziano Servizi <Graziano dot Servizi at bo dot infn dot it>
- To: libstdc++ at gcc dot gnu dot org
- Date: Fri, 22 Nov 2013 15:18:44 +0100
- Subject: Question: is it a compiler bug or else...?
- Authentication-results: sourceware.org; auth=none
Hi everybody,
My name is Graziano Servizi, Associate Professor in Mathematical Physics
at Bologna University, Italy.
I would ask a question about some trouble I have with a sample code
I would propose to students for teaching purposes.
I have read that the putback function of the basic_istream class would
set "badbit" on failure, is it right?
In the included code I called putback "on purpose" on a "readonly" input
stream (an instance of the ifstream class) in a "modifying putback" context.
This shouldn't be allowed, I guess...
And indeed, after this call, the input stream turns out to be
"corrupted" (it is put at eof), despite the fact that rdstate()
continues returning "goodbit", thus preventing any reasonable
check on it.
The code follows here, with embedded comments where I tried to explain
what kind of problems I met.
// code begins
# include <iostream>
# include <fstream>
# include <sstream>
# include <exception>
# include <system_error>
using namespace std;
int main( )
{
//istringstream is("abcdefghijklmnopqrstuvwxyz");
ifstream is("file"); // with the same content
cout << "begins: " << is . tellg( ) << '\n';
char c = is.get( );
cout << "after get " << is . tellg( ) << " with " << is . gcount( )
<< " and c is [" << c << "]\n";
is.seekg(2, ios::cur); // move ahead two bytes
cout << "after seekg " << is . tellg( ) << " with " << is . gcount( )
<< '\n';
cout << "STATE A " << is.rdstate() << '\n';
is . putback(c); // shouldn't set badbit ??
try
{
is . exceptions(is . badbit);
// moreover neither this exception is thrown
}
catch(ios_base :: failure & e)
{cout << "caught!\n";
cout << e.what() << '\n' /*<< e.code() << '\n'*/;
// and in addition ios_base::failure objects seem NOT to inherit
// the function code() from std :: system_error
// (that's why it is commented out): what happens?
}
cout << "STATE B " << is.rdstate() << '\n';
// it turns out that badbit is not set (same output [0] in STATE A as
in STATE B)
// however...the stream appears to be at eof...and accordingly c is
unaffected by get():
cout << "after putback " << is . tellg( ) << " with " << is . gcount(
) << " and next byte will be [";
cout << (c = is.get( )) << "]\n";
}
// code ends
Meanwhile I saw that it is known the lacking of inheritance of "failure"
from "system_error": is it planned to fix this?
Please note that NO PROBLEM OCCURS when the "istringstream" class is
used instead of "ifstream" (I mean: the badbit is set and the exception
is thrown and caught). I already knew this, but nevertheless why should
the "ifstream" class clearly put the stream at eof WITHOUT MAKING THE
PROGRAM AWARE of that in any way?
What is wrong in my code?
Thanks in advance. Hoping for an answer...or a fix of my code.
G. Servizi
P.S.:
I'm using gcc 4.7.2 on a Linux Fedora 18 x86_64 system and the
problem occurs both with or without the -std=c++11 compiling option.
The content of the file "file" is whatever you want, provided it is
long enough: I used the 26 lowercase letters...
Here follows the output I GOT, compiling without any particular options,
except the -std=c++11 which, in turn, proved to be irrelevant.
// OUTPUT BEGINS (relative to the "abcdefgh......." content)
begins: 0
after get 1 with 1 and c is [a]
after seekg 3 with 1
STATE A 0
STATE B 0
after putback 26 with 0 and next byte will be [a]
// OUTPUT ENDED