Reputation: 439
in c++, is it okay to compare an int to a char because of implicit type casting? Or am I misunderstanding the concept?
For example, can I do
int x = 68;
char y;
std::cin >> y;
//Assuming that the user inputs 'Z';
if(x < y)
{
cout << "Your input is larger than x";
}
Or do we need to first convert it to an int?
so
if(x < static_cast<int>(y))
{
cout << "Your input is larger than x";
}
Upvotes: 4
Views: 36131
Reputation: 40625
The problem with both versions is that you cannot be sure about the value that results from negative/large values (the values that are negative if char
is indeed a signed char
). This is implementation defined, because the implementation defines whether char
means signed char
or unsigned char
.
The only way to fix this problem is to cast to the appropriate signed/unsigned char type first:
if(x < (signed char)y)
or
if(x < (unsigned char)y)
Omitting this cast will result in implementation defined behavior.
Personally, I generally prefer use of uint8_t
and int8_t
when using chars as numbers, precisely because of this issue.
This still assumes that the value of the (un)signed char
is within the range of possible int
values on your platform. This may not be the case if sizeof(char) == sizeof(int) == 1
(possible only if a char
is 16 bit!), and you are comparing signed and unsigned values.
To avoid this problem, ensure that you use either
signed x = ...;
if(x < (signed char)y)
or
unsigned x = ...;
if(x < (unsigned char)y)
Your compiler will hopefully complain with warning about mixed signed comparison if you fail to do so.
Upvotes: 6
Reputation: 45664
Your code will compile and work, for some definition of work.
Still you might get unexpected results, because y
is a char
, which means its signedness is implementation defined. That combined with unknown size of int will lead to much joy.
Also, please write the char literals you want, don't look at the ASCII table yourself. Any reader (you in 5 minutes) will be thankful.
Last point: Avoid gratuituous cast, they don't make anything better and may hide problems your compiler would normally warn about.
Upvotes: 3
Reputation: 1
Yes you can compare an int
to some char
, like you can compare an int
to some short
, but it might be considered bad style. I would code
if (x < (int)y)
or like you did
if (x < static_cast<int>(y))
which I find a bit too verbose for that case....
BTW, if you intend to use bytes not as char
consider also the int8_t
type (etc...) from <cstdint>
Don't forget that on some systems, char
are signed
by default, on others they are unsigned
(and you could explicit unsigned char
vs signed char
).
Upvotes: 2
Reputation: 70929
The code you suggest will compile, but I strongly recommend the static_cast
version. Using static_cast
you will help the reader understand what do you compare to an integer.
Upvotes: 1