【问题标题】:Converting from unsigned Char* to unsigned int从 unsigned Char* 转换为 unsigned int
【发布时间】:2012-04-28 22:29:10
【问题描述】:

当我执行以下操作时,我收到此错误:

../src/Sample.cpp:19: 错误:从 \u2018UINT8*\u2019 转换为 \u2018UINT8\u2019 失去精度

#include <iostream>
using namespace std;

typedef unsigned char UINT8;
typedef unsigned int UINT32;

#define UNUSED(X) X=X

int main() {
    UINT8 * a = new UINT8[34];
    UINT32 b = reinterpret_cast<UINT8>(a);

    UNUSED(b);

    return 0;
}

我将如何解决这个问题。请记住,我不是试图将字符串转换为无符号长整数,而是将 char*(地址值)转换为 int。

谢谢

解决方案:

原来这个问题与指针大小有关。在 32 位机器上,指针大小是 32 位,而对于 64 位机器,当然是 64。以上在 64 位机器上不起作用,但在 32 位机器上可以。这将适用于 64 位机器。

#include <iostream>
#include <stdint.h>

using namespace std;

typedef  uint8_t UINT8;
typedef int64_t UINT32;

#define UNUSED(X) X=X

int main() {
    UINT8 * a = new UINT8[34];
    UINT32 b = reinterpret_cast<UINT32>(a);
    UNUSED(b);

    return 0;
}

【问题讨论】:

  • 您是否正在为 32 位架构进行编译?
  • 请记住,您正在尝试将 34 个字节的数据存储到 4 个字节中。错误说明了一切。
  • @Rowland Shaw,不,它是 64 位的,是的,刚刚意识到感谢代码导致了问题,因为它最初使用的是 32 位编译器。
  • @Anonymous:如果您的编译器支持它,您应该使用来自&lt;cstdint&gt;&lt;stdint.h&gt; 的标准整数类型。特别是,std::uintptr_t 保证足够大以存储指针值。即使在 32 位平台上,也无法转换为 &lt;UINT8&gt;
  • @Mike Seymour 我同意,我切换到 32 位编译。这就是我一直认为的编译方式。

标签: c++ types compiler-errors


【解决方案1】:

假设 sizeof(int) == sizeof(void*) 您可以使用此代码进行转换:

int b = *reinterpret_cast<int*>(&a);

或其变体。我认为 static_cast 也可以。

当然 a 必须是左值(可以分配给)才能获得它的地址。对于非 l 值,您需要使用一个函数,旧的联合技巧将起作用:

int Pointer2Int (void* p)
{
    union { void* p; int i; } converter;
    converter.p = p;
    return converter.i;
}

【讨论】:

  • 转换的好主意,但问题是使用 32 位程序,并尝试使用 64 位编译器进行编译。上面的代码不起作用,因为int是32,指针是64。但是+1联合的想法。
  • 谢谢,这就是为什么我说假设 sizeof(int) == sizeof(void*)。因此,您的代码需要使用 long long、_int64 或只是 long,具体取决于您的编译器。 C/C++ 类型系统真的不是最好的。
  • 我将编译切换到 32 位,现在它可以工作了。谢谢。
  • 我很确定在这里使用 reinterpret_cast 是未定义的行为。将unsigned char* 读取为unsigned int 会破坏严格的别名。
  • @Timo 不,只要您确定指针大小与无符号整数相同,它就可以工作
【解决方案2】:

这不是一个好主意,但该行应该是:

UINT32 b = reinterpret_cast<UINT32>(a);

reinterpret_cast 将目标类型的类型作为模板参数。

使用正确的类型,g++ 会告诉你这不是一个好主意:

error: invalid cast from type ‘char’ to type ‘int’

请参阅 Cthutu 的答案以获得更正确的方法。

【讨论】:

  • 实际上正如我在问题中提到的,这不是问题。编译器抱怨精度损失的问题。我刚刚发现我正在尝试为 64 位系统进行编译。这意味着指针大小是 64 位,而不是 32 位。除非我使用 64 位整数,否则这将不起作用。
  • 这就是为什么我说假设 sizeof(int) == sizeof(void*)。但是当然如果 sizeof(int)
【解决方案3】:

一个选项是:

int *a; 字符 b[64]; 诠释 c;

a = (int*) malloc (sizeof(int));

sprintf(b, "%d", a);

c = atoi(b);

【讨论】:

  • @Skippy 谢谢,但正如我在问题中提到的那样,“请记住,我不是试图将字符串转换为无符号长整数,而是将 char*(地址值)转换为 int。”跨度>
  • 那么我的意思是 %x 而不是 %d。对不起。
猜你喜欢
  • 2014-12-27
  • 2013-05-16
  • 1970-01-01
  • 2014-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
相关资源
最近更新 更多