【问题标题】:error: cast from 'char*' to 'int' loses precision [-fpermissive] on using reinterpret_cast (C++) [duplicate]错误:在使用 reinterpret_cast (C++) 时,从 'char*' 转换为 'int' 会失去精度 [-fpermissive] [重复]
【发布时间】:2021-11-09 13:14:51
【问题描述】:

我正在尝试 C++ 中的不同类型转换运算符。 在我对 reinterpret_cast 的理解中,它将不类型转换为根本不同的类型。 但是下面的代码会抛出这个错误“从 'char*' 转换为 'int' 失去精度 [-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;
}

错误是什么意思?

【问题讨论】:

  • 尽可能避免强制转换。
  • char *p = "This is a string"; -> const char *p = "This is a string";
  • std::/*u*/intptr_t 似乎比int 更合适。
  • std::string str{"这是一个字符串"};
  • 这个问题不是“如何将 std::string 转换为 int?”的重复问题。这里没有提到 std::string ,但最重要的是,OP 并没有尝试将字符串转换为 int ;相反,他们试图了解 reinterpret_cast 的工作原理。

标签: c++ casting reinterpret-cast


【解决方案1】:

错误是什么意思?

最重要的是,该消息意味着程序格式错误。语言中没有定义从 char * 类型到 int 类型的转换(在这种情况下)。

该消息还包含“失去精确度”的额外细节。由此我们可以推断,指针类型可表示的内存地址比整数类型可表示的数字多(在 C++ 语言的这个特定实现中)。这个细节是不允许转换的原因。仅在整数可以表示指针类型的所有可能值的情况下才定义从指针到整数的重新解释转换。在存在这种整数类型的语言实现中,标准库中的类型有一个类型别名:std::uintptr_t

char *p = "This is a string"

这种隐式转换也是格式错误的。字符串文字,它是 const char 的数组,在 C++ 中不能隐式转换为 char*(从 C++11 开始;在此之前,这种转换是允许的,但已弃用)。


您能否提供一个正确使用 reinterpret_cast 的代码的 sn-p 代码?

reinterpret_cast 的正确使用极为罕见。它的使用有很多规则限制,为了能够编写出正确的程序,你必须了解所有相关规则及其微妙之处。

我可以举个例子,但你必须明白,做出任何改变,无论多么微妙,都有很大的机会产生错误的程序。这是一个例子,正如承诺的那样:

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;
}

【讨论】:

  • 但是 reinterpret_cast 的目的不就是从一种类型转换为另一种完全不同的类型吗?你能提供一个正确使用 reinterpret_cast 的代码的 sn-p 吗?
  • 没有 reinterpret_cast 告诉你比编译器更清楚。并且只能谨慎使用,有时它是连接遗留代码的唯一方法。或者例如在字节数组之上覆盖结构信息(例如来自互联网的数据流)
  • @ArpithaPrakash reinterpret_cast 仅在特定情况下是合法的。例如,它们在此处列举:en.cppreference.com/w/cpp/language/reinterpret_cast
  • 换句话说,重新解释演员表并不会为您带来神奇的转换。恰恰相反,你必须知道一块内存是什么样子,然后告诉编译器,把那块内存当作这种类型来对待。
  • @ArpithaPrakash 我添加了一个示例。
【解决方案2】:

要将字符串转换为值,类型转换不起作用。 输入字符串需要解析,标准库可以这样为你做:

#include <iostream>
#include <string>

int main()
{
    std::string str{ "42" };
    auto value = std::stoi(str);
    std::cout << value;
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-19
    • 2022-12-31
    • 2014-10-18
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 2019-10-23
    相关资源
    最近更新 更多