Tuesday, September 26, 2006

Is it a 'char' or 'unsigned char' or 'signed char'?

I inherited a overly-loaded code something like this...

void func(boost::int8_t p)
{
std::cout << "boost::int8_t" << std::endl;
}
void func(boost::uint8_t p)
{
std::cout << "boost::uint8_t" << std::endl;
}
void f1(boost::int16_t s)
{
std::cout << "boost::int16_t" << std::endl;
}
void f1(boost::uint16_t s)
{
std::cout << "boost::uint16_t" << std::endl;
}
main()
{
short sh;
char c;
f1(sh);
func(c);
}


I tried to compile the above code but the compiler is refusing to proceed balking at "func(c)", while it is completely happy with f1(sh). For the uninitiated boost types are typedef-ed to the appropriate platform types like int8_t -> signed char uint8_t -> unsigned char.

It turned out that the language does not specify whether variables of type char are signed or unsigned quantities. So the compiler complains about the func(c) call because it is ambiguous. Whereas f1(sh) succeeds.

Changind the "char c" to "unsigned char" or "signed char" resolves the ambiguity and calms down the compiler. Curiously even forcing the compiler with -funsigned-char didn't help in this case.

Well my philosophy of solving any problem by an extra level of indirection also didn't work. I tried something like this...


template
void func_char_resolver(T c);

template<>
void func_char_resolver(boost::int8_t c) { /// dealing with singed char....
}

template<>
void func_char_resolver(boost::uint8_t c) { /// dealing with unsinged char....
}
void func(char c)
{
func_char_resolver(c);
}


I don't know may be because `char' is a distinct type (of undefined sign) hence none of the specializations matched. Oh well!

No comments: