Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

istream.get(unsigned char&)

146 views
Skip to first unread message

Torsten Bronger

unread,
Jun 23, 2002, 1:56:01 PM6/23/02
to
Halloechen!

I have in my C++ program the lines

unsigned char c2;
in.get(c2);

Everything worked fine, but then I switched to the newest GNU compiler
(ver 3.1) and it said

no matching function for call to `std::basic_istream<char,std::char_traits<char> >::get(unsigned char&)'
c:/djgpp/lang/cxx-v31/bits/istream.cc:513: candidates are: [...]
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::get(_CharT&) [with _CharT = char, _Traits = std::char_traits<char>]

So it works with normal 'char', but not with 'unsigned char'. It's a
template, so why can't the compiler generate the code for 'unsigned
char'? (Which it did, in the older version.)


Tschoe,
Torsten.

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]

Carl Barron

unread,
Jun 24, 2002, 6:42:18 AM6/24/02
to
Torsten Bronger <bro...@physik.rwth-aachen.de> wrote:

> Halloechen!
>
> I have in my C++ program the lines
>
> unsigned char c2;
> in.get(c2);
>
> Everything worked fine, but then I switched to the newest GNU compiler
> (ver 3.1) and it said

> [snip]
Well if you don't need signed chars in your program and there is a
compiler switch [argument to compiler] that tells the compiler to use
unsigned chars for chars, then this may be the easiest solution. {beware
such an option may require some recompilation of the standard library
library file].
If the standard library contains a generic std::char_traits template,
see the header <string>,
then using basic_ifstream<unsigned char> and basic_istream<unsigned
char> should do the trick.
If there is only template <class charT> class char_traits; then you
need to write an std::char_traits<unsigned char> not extremely difficult
but time consuming...
Not really sure about gcc 3's implimentation of the standard C++
library.

Yannick Loitiere

unread,
Jun 24, 2002, 6:57:07 AM6/24/02
to
The _Char template parameter of the get member function is the same as
the _Char template parameter of the stream class. You stream class is
specialised on 'char', therefore, so is get.

> It's a template, so why can't the compiler generate the code for
> 'unsigned char'? (Which it did, in the older version.)

--
- Yannick Loitiere -
Hi! I'm a .signature virus! Copy me into your ~/.signature to help me
spread!

Bence Kodaj

unread,
Jun 24, 2002, 11:36:18 AM6/24/02
to
> no matching function for call to `std::basic_istream<char,std::char_traits<char> >::get(unsigned char&)'
> c:/djgpp/lang/cxx-v31/bits/istream.cc:513: candidates are: [...]
> std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
> _Traits>::get(_CharT&) [with _CharT = char, _Traits = std::char_traits<char>]
>
> So it works with normal 'char', but not with 'unsigned char'. It's a
> template, so why can't the compiler generate the code for 'unsigned
> char'? (Which it did, in the older version.)

Because get() is a member function of a class template, but it's not a
template member function.
Look at the error message again. The parameter type of get() is
'_CharT &', where _CharT is the first type parameter of the
basic_istream class template. The message shows that you instantiated
basic_istream with 'char' as the first type argument (your 'in' object
is probably of a predefined stream type like ifstream or
istringstream); therefore, get() expects a 'char &'.

Bence Kodaj

James Kanze

unread,
Jun 25, 2002, 9:10:44 AM6/25/02
to
cbar...@ix.netcom.com (Carl Barron) wrote in message
news:<1fe95su.1ab6cti1y8btz4N%cbar...@ix.netcom.com>...
> Torsten Bronger <bro...@physik.rwth-aachen.de> wrote:

> > I have in my C++ program the lines

> > unsigned char c2;
> > in.get(c2);

> > Everything worked fine, but then I switched to the newest GNU
> > compiler (ver 3.1) and it said
> > [snip]

> Well if you don't need signed chars in your program and there is
> a compiler switch [argument to compiler] that tells the compiler to
> use unsigned chars for chars, then this may be the easiest
> solution. {beware such an option may require some recompilation of
> the standard library library file].

That doesn't change anything. The type char is still a different type
than unsigned char (just as it is a different type than signed char
otherwise).

Logically, I can't imagine anyone having the option for plain char to
be unsigned not using it, systematically. It is a lot less subject to
error.

> If the standard library contains a generic std::char_traits
> template, see the header <string>, then using
> basic_ifstream<unsigned char> and basic_istream<unsigned char>
> should do the trick.

That sort of depends on what the generic class contains. I have heard
of people having problems with it -- if I remember correctly, both g++
and VC++ (Dinkumware) have a generic version, but the two have
different behavior. (Since the standard is sigularly silent about
this, both are "right".) And you cannot provide your own
specialization.

With a modern library, of course, you will probably also run into
problems with codecvt -- there may not be a generic version of that,
either.

In practice, the result of all of these constraints is that you cannot
instantiate the iostream templates except for char, wchar_t and user
defined POD types.

> If there is only template <class charT> class char_traits; then you
> need to write an std::char_traits<unsigned char> not extremely difficult
> but time consuming...

And illegal. (Although I'll admit that it is what I recommended in
the case above.)

--
James Kanze mailto:jka...@caicheuvreux.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)69 63198627

matthew.towler

unread,
Jun 28, 2002, 9:49:28 PM6/28/02
to
> > Well if you don't need signed chars in your program and there is
> > a compiler switch [argument to compiler] that tells the compiler to
> > use unsigned chars for chars, then this may be the easiest
> > solution. {beware such an option may require some recompilation of
> > the standard library library file].
>
> That doesn't change anything. The type char is still a different type
> than unsigned char (just as it is a different type than signed char
> otherwise).
>
> Logically, I can't imagine anyone having the option for plain char to
> be unsigned not using it, systematically. It is a lot less subject to
> error.

Recently I came across a problem where I had two compilers one which had
plain char signed and the other unsigned. It then had the typedefs

typedef UINT8 unsigned char;
typedef CHAR char;
typedef INT8 char;

so in one compiler INT8 was not actually signed leading to various obscure
looping bugs. Initially I tried to fix this by changing the typedef for
INT8 to a signed char. This broke a lot of code which assumed that INT8 and
plain char were equivalent (this is the default in microsoft C++ so is often
considered a de facto standard).

What I then found is that strictly there are 3 char types. It does not
matter what way you have defined plain char to be in your compiler, it is
still not equivalent to either signed or unsigned. This really matters when
dealing with pointers in C++.

However most compilers are not quite this choosy. Personally I like to use
plain char for real strings of characters, UINT8 for hardware access where
it is needed, and INT8 very rarely.

My solution for your case is to use a reinterpret_cast. I really wish there
was an alternative for the 3 char pointer types (as I believe they are
guaranteed to be the same size).

Matthew

0 new messages