Search code examples
c++g++auto

Why does a compiler allow a user to change the type of an 'auto' variable?


I expected the auto keyword to deduce the type of a variable from an intializer once and keep that type throughout the code. To my surprise, my compiler (g++ 9.3.0) allows me to change it's type and it still works. This is sort of acceptable to me when I first use the variable as an int and then as a float. But when I use the auto keyword to declare a string and then assign a float value to that variable, the compiler doesn't throw an error but also doesn't print the value after the float assignment. Can someone explain why it allows assigning a float value to a string variable in the first place? Does the compiler just accept the new assignment each time? Or does it throw some kind of exception that I am not able to catch? Code below -

#include <iostream>

int main()
{
 auto x = '2';
 
 std::cout << x << std::endl;
 
 x = 3.0; // Why is this allowed?
 
 std::cout << x << std::endl; // This won't print
 
 return 0;
}

Solution

  • To show you what's going on I extended the example with some compile time type checks:

    #include <type_traits>
    #include <iostream>
    
    int main()
    {
        auto x = '2';
    
        // decltype(x) is the type for variable x
        // compare it at compile time with char type
        static_assert(std::is_same_v<decltype(x), char>);
    
        std::cout << x << std::endl;
    
        x = 3.0; // Why is this allowed? because it does a narrowing conversion from double to char
        // my compiler even gives this warning :
        // main.cpp(11,6): warning C4244: '=': conversion from 'double' to 'char', possible loss of data
        
        // type of x is still the same and it is still a char
        static_assert(std::is_same_v<decltype(x), char>);
    
        std::cout << static_cast<int>(x) << std::endl; // the cast is here to be able to print the actual value of the char
    
        return 0;
    }