错误:从“Foo*”强制转换到“无符号整数”失去精确度

发布于 2024-09-26 18:58:30 字数 909 浏览 5 评论 0原文

我正在尝试将指针强制转换为 int (或无符号 int),无论我尝试什么,它都不起作用。

我尝试过 static_cast(obj)reinterpret_cast(obj) 以及 C 风格转换的各种组合 intptr_t 's、unsigned int's,并且我包括 stdint.h。根据我读到的内容,我尝试过的众多方法之一应该有效。什么给?

我没有费心包含代码,因为它正是我所描述的,但既然你问了,我已经尝试了所有这些加上其他组合:

void myfunc(Foo* obj)
{
    // ...
    uintptr_t temp = reinterpret_cast<uintptr_t>(obj);
    uintptr_t temp = static_cast<uintptr_t>(obj);
    uintptr_t temp = (uintptr_t)obj;
    intptr_t temp = reinterpret_cast<intptr_t>(obj);
    intptr_t temp = static_cast<intptr_t>(obj);
    intptr_t temp = (intptr_t)obj;
    unsigned int temp = reinterpret_cast<unsigned int>(obj);
    unsigned int temp = static_cast<unsigned int>(obj);
    unsigned int temp = (unsigned int)obj;
    // ...
}

它们都给出了完全相同的错误。

I'm trying to cast a pointer to an int (or unsigned int) and no matter what I try it doesn't want to work.

I've tried static_cast<intptr_t>(obj), reinterpret_cast<intptr_t>(obj), and various combinations of C style casts, intptr_t's, unsigned int's, and I'm including stdint.h. From what I've read, one of the many things I've tried should work. What gives?

I didn't bother including the code because it's exactly what I described, but since you asked, I've tried all of these plus other combinations:

void myfunc(Foo* obj)
{
    // ...
    uintptr_t temp = reinterpret_cast<uintptr_t>(obj);
    uintptr_t temp = static_cast<uintptr_t>(obj);
    uintptr_t temp = (uintptr_t)obj;
    intptr_t temp = reinterpret_cast<intptr_t>(obj);
    intptr_t temp = static_cast<intptr_t>(obj);
    intptr_t temp = (intptr_t)obj;
    unsigned int temp = reinterpret_cast<unsigned int>(obj);
    unsigned int temp = static_cast<unsigned int>(obj);
    unsigned int temp = (unsigned int)obj;
    // ...
}

They all give the exact same error.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

丑丑阿 2024-10-03 18:58:31

您所在的平台要么 sizeof (Foo*) > sizeof (unsigned),或者您的编译器设置为警告不可移植代码。请注意,大多数 64 位编译器(LP64 和 LLP64)都属于这一类。

不要求指针必须位于 int 中。这就是 intptr_t 的全部意义。

如果您使用的第三方库在 callbacl 期间仅为用户上下文提供 int,则可以将索引传递到查找表中,以便指针本身存储在查找表中。这样做的额外好处是类型安全并且不会破坏别名假设。

编辑:对我有用。 (Comeau“tryitout” 非常方便)

#include <stdint.h>

void myfunc(class Foo* obj)
{
    uintptr_t temp = reinterpret_cast<uintptr_t>(obj);
}

Comeau C/C++ 4.3.10.1(2008 年 10 月 6 日)
11:28:09) ONLINE_EVALUATION_BETA2
版权所有 1988-2008 ComeauComputing。
版权所有。模式:严格
错误 C++ C++0x_extensions

“ComeauTest.c”,第 5 行:警告:
变量“temp”已声明但从未声明过
引用的
uintptr_t temp = reinterpret_cast(obj);reinterpret_cast(obj);

在严格模式下,使用-tused,编译成功(但请记住,Comeau在线编译器不会链接)。
编译时启用了 C++0x 扩展。

在 C89 模式下它也可以工作:

#include <stdint.h>

void myfunc(struct Foo* obj)
{
    uintptr_t temp = (uintptr_t)obj;
}

Comeau C/C++ 4.3.10.1(2008 年 10 月 6 日)
11:28:09) ONLINE_EVALUATION_BETA2
版权所有 1988-2008 ComeauComputing。
版权所有。模式:严格
错误 C90

“ComeauTest.c”,第 3 行:警告:
声明在外部不可见
函数 void myfunc(struct Foo*
对象)
^

“ComeauTest.c”,第 5 行:警告:
变量“temp”已声明但从未声明过
引用的
uintptr_t temp = (uintptr_t)obj;
^

在严格模式下,使用-tused,编译
成功了(但请记住,科莫
在线编译器不链接)。

You're either on a platform where sizeof (Foo*) > sizeof (unsigned), or your compiler is set to warn about non-portable code. Note that most 64-bit compilers, both LP64 and LLP64, fall into this category.

There's no requirement that a pointer fit in an int. That's the whole point of intptr_t.

If you're using a third-party library that provides only a int for user-context during callbacls, you could pass an index into a lookup table, so the pointer itself is stored in the lookup table. This has the additional benefit of being type-safe and not breaking aliasing assumptions.

EDIT: Works for me. (Comeau "tryitout" is very handy)

#include <stdint.h>

void myfunc(class Foo* obj)
{
    uintptr_t temp = reinterpret_cast<uintptr_t>(obj);
}

Comeau C/C++ 4.3.10.1 (Oct 6 2008
11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.
All rights reserved. MODE:strict
errors C++ C++0x_extensions

"ComeauTest.c", line 5: warning:
variable "temp" was declared but never
referenced
uintptr_t temp = reinterpret_cast(obj);reinterpret_cast(obj);

In strict mode, with -tused, Compile succeeded (but remember, the Comeau online compiler does not link).
Compiled with C++0x extensions enabled.

In C89 mode it also works:

#include <stdint.h>

void myfunc(struct Foo* obj)
{
    uintptr_t temp = (uintptr_t)obj;
}

Comeau C/C++ 4.3.10.1 (Oct 6 2008
11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing.
All rights reserved. MODE:strict
errors C90

"ComeauTest.c", line 3: warning:
declaration is not visible outside of
function void myfunc(struct Foo*
obj)
^

"ComeauTest.c", line 5: warning:
variable "temp" was declared but never
referenced
uintptr_t temp = (uintptr_t)obj;
^

In strict mode, with -tused, Compile
succeeded (but remember, the Comeau
online compiler does not link).

哑剧 2024-10-03 18:58:31

当然,最好掌握显式强制转换的类型转换。而且前面的回答已经说得很好了。

但我有一个绕过编译器的建议。有一个选项可以让编译器接受当前的精度损失:

gcc -fpermissive

Of course, it is better to master the type conversion by explicit cast. And the previous answers say it well.

But I have a suggestion to bypass the compiler. There is an option to let the compiler accept the current loss of precision:

gcc -fpermissive
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文