Surprising result when reading int_fast8_t from std::cin

I am trying to build a simple cpp code to check whether an input number is an even number bigger than 2 (trying to experimentally solve codeforce’s watermelon using cstdint). Problem is, when i use int_fast8_t as the data type for the input interger, the code somehow prints "yes" when i put in 2 as an input. This problem is nonexistent when I use basic int data type. Any ideas on why this happens?

the code is as below:

#include <cstdint>
#include <iostream>

int main(int argc, char* argv[]) {
    int_fast8_t input;
    std::cin >> input;

    if ((input % 2 == 0) && (input > 2)) {
        std::cout << "YES";
    } else {
        std::cout << "NO";
    } std::cout << "\n";

    return 0;
}
input: 2

expected output: NO
actual output  : YES

>Solution :

The problem is that int_fast8_t is defined as a type alias for signed char. This isn’t required by the C++ standard, but it’s what your standard library chose to do.

You could verify this by looking at the source code of your standard library, or with:

static_assert(std::is_same_v<std::int_fast8_t, signed char>>);

As a result, what you’re actually doing is:

signed char input;
std::cin >> input;

This calls operator>>(std::istream&, signed char&), which is a special overload that treats signed char like a character, instead of an integer.

When providing 2 as user input, this is actually the ASCII/UTF-8 character '2', which has the numeric value 50.

This passes the test input % 2 == 0 because 50 is divisible by 2, and also passes the test input > 2 because 50 is greater than 2.

Solution

To fix this, use int instead; at least for user input.

See Also

Leave a Reply