Comparing char to Int in c++

29,018

Solution 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).

Solution 2

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.

Solution 3

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.

Solution 4

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.

Share:
29,018
user3029001
Author by

user3029001

Updated on November 02, 2020

Comments

  • user3029001
    user3029001 over 3 years

    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";
    }
    
  • Deduplicator
    Deduplicator about 10 years
    Never knew that to be bad style. Just that generally comparing different type values is error-prone.
  • Alan Stokes
    Alan Stokes about 10 years
    Gratuitous casts (especially C-style ones) are often considered bad style.
  • Deduplicator
    Deduplicator about 10 years
    @Alan: Hm, my comment was in line with you, while i posted. Later edits to the answer though changed that. Damn.
  • jfs
    jfs over 6 years
    it also assumes: PRECISION(UCHAR_MAX) < PRECISION(INT_MAX) (likely in practice)
  • cmaster - reinstate monica
    cmaster - reinstate monica over 6 years
    @jfs Right, forgot about that corner case. I've added a note on this to the answer now. Hope you like it.