1

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?

  • 1
    casting should be avoided when possible. – Jarod42 Sep 14 '21 at 10:48
  • 2
    `char *p = "This is a string";` -> `const char *p = "This is a string";` – Jarod42 Sep 14 '21 at 10:48
  • 1
    `std::/*u*/intptr_t` seems more appropriate than `int`. – Jarod42 Sep 14 '21 at 10:49
  • 1
    std::string str{"This is a string"}; – Pepijn Kramer Sep 14 '21 at 10:52
  • The size of a pointer is larger then the size of an int (in memory). So casting it to an int would mean having to throw away bytes, which is loss of precission – Pepijn Kramer Sep 14 '21 at 10:55
  • if you think `reinterpret_cast` can cast anything to anything then your understanding is wrong. Thats not what it does – 463035818_is_not_an_ai Sep 14 '21 at 10:58
  • Thank you @PKramer. Yes, I was trying to convert the string to int. – Arpitha Prakash Sep 14 '21 at 10:58
  • @ArpithaPrakash You are trying to convert a string that does not contain any number to `int`? What result do you expect? – Daniel Langr Sep 14 '21 at 11:00
  • Can you run a program containing this line, and then [edit] your post to include its output? `std::cout << "sizeof(int) = " << sizeof(int) << ", sizeof(char*) = " << sizeof(char*) << "\n";` – Fabio says Reinstate Monica Sep 14 '21 at 11:03
  • 2
    This question is not a duplicate of "How can I convert a std::string to int?". There's no mention of std::string here, but most importantly, the OP isn't trying to convert a string to an int; rather, they are trying to understand how reinterpret_cast works. – Fabio says Reinstate Monica Sep 14 '21 at 11:48
  • @FabiosaysReinstateMonica Have you read the OP's comment above, which says: _"I was trying to convert the string to int."_? It really doesn't seem that this question is about how `reinterpret_cast` works. BTW, the accepted answer in the linked questions also mentions how to convert a "C" string into `int`. – Daniel Langr Sep 14 '21 at 11:58
  • 1
    @DanielLangr Converting a string to int is the *specific* way in which the OP was trying to achieve the *general* goal of understanding casts. Even in the comment to the accepted answer they asked about the purpose of reinterpret_cast, and an example of its correct usage. The reason why they tried to cast a string to an int is simply that, to try casts, you must cast *something* to *something else*. Here, this happens to be a string and an int. But the string isn't even a number! It's "This is a string"! – Fabio says Reinstate Monica Sep 14 '21 at 12:15

2 Answers2

3

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;
}
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • But isn't the purpose of reinterpret_cast to convert from one type to another radically different type? Can you please provide a snippet of code where reinterpret_cast is used correctly? – Arpitha Prakash Sep 14 '21 at 11:01
  • 1
    No reinterpret_cast is telling you know better then the compiler. And should only be used sparingly and with caution, sometimes its the only way to connect to legacy code. Or for example to overlay structure information on top of a byte array (e.g a stream of data from the internet) – Pepijn Kramer Sep 14 '21 at 11:02
  • 1
    @ArpithaPrakash `reinterpret_cast` is legal only in specific cases. They are, for instance, enumerated here: https://en.cppreference.com/w/cpp/language/reinterpret_cast. – Daniel Langr Sep 14 '21 at 11:04
  • 1
    In other words reinterpret cast it is not something that does magical conversions for you. Quite the opposite, you have to know what a piece of memory looks like and then you tell the compiler, treat that bit of memory as if it was this type. – Pepijn Kramer Sep 14 '21 at 11:05
  • 1
    @ArpithaPrakash I added an example. – eerorika Sep 14 '21 at 11:10
2

To convert strings to values, a typecast wont work. The input string needs to be parsed, the standard library can do this for you like this:

#include <iostream>
#include <string>

int main()
{
    std::string str{ "42" };
    auto value = std::stoi(str);
    std::cout << value;
    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19