newbie question on streambuf

A

Aarti

I was going through the streambuf class and found that the signature
of function sgetc is as follows

int sgetc ( );

Now if it returns a char why could we not have it as char sgetc( ) ?

Thanks in advance.
 
B

BobR

Aarti said:
I was going through the streambuf class and found that the signature
of function sgetc is as follows

int sgetc ( );

Now if it returns a char why could we not have it as char sgetc( ) ?
Thanks in advance.

Because it does not return a 'char'. It can be coerced to a 'char'.

cout<<" sizeof(wchar_t) ="<<sizeof(wchar_t)<<std::endl;
// out: sizeof(wchar_t) =2


In GCC(MinGW) (<streambuf>):
// .....
typedef _Traits traits_type;
typedef typename traits_type::int_type int_type;
// .....
int_type sgetc(){ /* .... */ }
 
O

osmium

Aarti said:
I was going through the streambuf class and found that the signature
of function sgetc is as follows

int sgetc ( );

Now if it returns a char why could we not have it as char sgetc( ) ?

Because sgetc() can return EOF and EOF is not a character; it is a
"condition" which can be and is encoded/indicated in an int but not in a
char..
 
J

James Kanze

I was going through the streambuf class and found that the signature
of function sgetc is as follows
int sgetc ( );
Now if it returns a char why could we not have it as char sgetc( ) ?

Because it has to return out of band information. The return
value is either in the range [0, UCHAR_MAX], or is EOF
(guaranteed to be negative, typically -1).

As an amusing sidelight, note that the results of assigning it
to a char (even when it is not EOF) is implementation defined,
and may even result in an implementation defined signal:).
(That's according to the standard. In practice, no
implementation would dare not make it work as expected.)
 
O

Old Wolf

int sgetc ( );
Now if it returns a char why could we not have it as char sgetc( ) ?

Because it has to return out of band information. The return
value is either in the range [0, UCHAR_MAX], or is EOF
(guaranteed to be negative, typically -1).

I posted about this in c.s.c++ a few days ago but
the post seems not to have shown up...

I couldn't find where in the standard it specifies
that sgetc() returns stuff in that range, the
standard only seemed to have circular references.

Secondly, that would mean that this code is wrong:
http://www.cplusplus.com/reference/iostream/ofstream/rdbuf.html
 
J

James Kanze

int sgetc ( );
Now if it returns a char why could we not have it as char sgetc( ) ?
Because it has to return out of band information. The return
value is either in the range [0, UCHAR_MAX], or is EOF
(guaranteed to be negative, typically -1).
I posted about this in c.s.c++ a few days ago but
the post seems not to have shown up...
I couldn't find where in the standard it specifies
that sgetc() returns stuff in that range, the
standard only seemed to have circular references.

Interesting. You could easily be right with regards to
streambuf itself; I can't remember having seen this explicit
constraint myself, either. What is required, however, is that
char_traits<char>::eof() return EOF (which is defined in the C
standard, and must be negative), and that eof() be
distinguishable from any valid char value converted to an int.

Without looking at it in detail: the semantics of filebuf are
defined in terms of the semantics of FILE*, as defined in the C
standard; the requirements that I mentionned are in fact those
of fgetc(), in the C standard. So I'd say that the intent, at
least is clear.

Note that it is difficult to say much, at a standards level,
because even in C, you have the difficulty that when assigning
the results of fgetc() to a char, "either the result is
implementation-defined or an implementation-defined signal is
raised." Any implementation which raises a signal here is going
to break 99.99% of all C code ever written.

The real solution is simple, of course: require plain char to be
unsigned. The problem is that plain char was signed on a PDP-11
(because making it unsigned resulted in a significant
performance hit), and a lot of early C was written supposing
that char was signed. Vendors of C compilers didn't want to
break this code (even if K&R said that it was already broken),
so even today, C and C++ allow plain char to be signed, and most
compilers make it signed by default. And would continue to do
so, even if the standard said that it had to be unsigned.

C++ could solve the problem, theoretically, by requiring
char_traits<char>::to_char_type to do the right thing, even if
the conversion int->char could raise a signal---in fact, I
rather suspect that that is the intent even today. But
practically, who uses char_traits<char>::to_char_type to convert
an int to a char, except maybe in a template, where you're
concerned about instantiations other than char?
Secondly, that would mean that this code is wrong:
http://www.cplusplus.com/reference/iostream/ofstream/rdbuf.html

That code is wrong on several counts, and fails on a lot of
common implementations. (VC++ under Windows, g++ under Linux on
a PC, g++ or Sun CC under Solaris, etc.) Just for the fun of it,
try compiling it with the option /J with VC++, or
-fno-signed-char with g++. (At least g++ gives a warning.) With
signed char, try it with a list of the towns in the Paris
suburbs. If you're using ISO 8869-1 (a frequent default),
you'll probably find that it stops in the middle of
L'Haÿ-les-Roses.

Of course, if the goal is to copy any file, it also fails
because it doesn't open the files in binary mode, so some byte
values (0x1A under Windows, for example), won't be readable, and
others might be translated in some funny ways (Windows will
insert a 0x0D in front of any 0x0A output, even if there wasn't
one in the input). There's also no error checking, of course.
The program returns a successful status even if the disk was
full, and the copy was incomplete.

These last two issues may have simply been ignored for
pedagogical reasons, however (although if this is the case, a
short sentence saying so would be appreciated). But the use of
out of band data here is fundamental to the C/C++ idiom of
character IO, and cannot be ignored.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,291
Messages
2,571,453
Members
48,137
Latest member
IndiraMcCo

Latest Threads

Top