Search code examples
c++castingreinterpret-cast

error: cast from 'char*' to 'int' loses precision [-fpermissive] on using reinterpret_cast (C++)


I was trying out the different casting operators in C++. In my understanding of reinterpret_cast, it converts don't type into a fundamentally different type. But the following piece of code throws this error "cast from 'char*' to 'int' loses precision [-fpermissive]".

#include <iostream>
#include <typeinfo>
using namespace std;

int main()
{
    int i;
    char *p = "This is a string";
    i = reinterpret_cast<int>(p);
    cout << i;
    return 0;
}

What does the error mean?


Solution

  • What does the error mean?

    Most importantly, the message means that the program is ill-formed. A conversion from the type char * into the type int is not defined in the language (in this case).

    The message also contains extra detail "loses precision". From that we can deduce that there can be more memory addresses representable by the pointer type than there are numbers representable by the integer type (in this particular implementation of the C++ language). This detail is the reason why the conversion isn't allowed. Reinterpret cast from pointer to integer is defined only in the case where the integer can represent all of the possible values of the pointer type. In language implementations where such integer type exists, there is a type alias for the type in the standard library: std::uintptr_t

    char *p = "This is a string"
    

    This implicit conversion is also ill-formed. A string literal, which is an array of const char is not implicitly convertible to char* in C++ (since C++11; prior to that such conversion was allowed but deprecated).


    Can you please provide a snippet of code where reinterpret_cast is used correctly?

    Correct uses of reinterpret_cast are extremely rare. There are many rules restrictions on its use, and in order to be able to write a correct program, you must understand all of the relevant rules and their subtleties.

    I can show an example, but you must understand that making any change, no matter how subtle, has very high chance of producing an incorrect program. Here is the example, as promised:

    struct standard_layout_struct {
        int first_member;
    };
    
    int main() {
        standard_layout_struct  instance { .first_member=42 };
        standard_layout_struct* pointer_to_instance = &instance;
        int* pointer_to_member = reinterpret_cast<int*>(pointer_to_instance);
        std::cout << *pointer_to_member;
    }