Jos*_*oyd 59 c++ casting void-pointers
我有一个原型函数,void* myFcn(void* arg)
用作pthread的起点.我需要将参数转换为int以供以后使用:
int x = (int)arg;
Run Code Online (Sandbox Code Playgroud)
编译器(GCC版本4.2.4)返回错误:
file.cpp:233: error: cast from 'void*' to 'int' loses precision
Run Code Online (Sandbox Code Playgroud)
投这个的正确方法是什么?
Fer*_*cio 62
您可以将其强制转换为intptr_t
类型.它是一种int
保证足够大以包含指针的类型.使用#include <cstdint>
来定义它.
onl*_*ker 29
同样,上面的所有答案都严重错过了这一点.OP想要将指针值转换为int值,相反,大多数答案,无论是哪种方式,都试图将arg点的内容错误地转换为int值.并且,其中大多数甚至不适用于gcc4.
正确答案是,如果不介意丢失数据精度,
int x = *((int*)(&arg));
Run Code Online (Sandbox Code Playgroud)
这适用于GCC4.
最好的方法是,如果一个人可以,不做这样的转换,相反,如果必须为指针和int共享相同的内存地址(例如,为了保存RAM),使用union,并确保,如果mem地址被处理只有当你知道它最后被设置为int时才作为int.
AnT*_*AnT 11
int
在一般情况下,没有适当的方法来演绎这一点.C99标准库提供intptr_t
和uintptr_t
类型定义,它应该每当执行这样的铸造需要来将要使用的.如果您的标准库(即使它不是C99)恰好提供这些类型 - 请使用它们.如果没有,请检查平台上的指针大小,自己定义这些typedef并使用它们.
代替:
int x = (int)arg;
Run Code Online (Sandbox Code Playgroud)
使用:
int x = (long)arg;
Run Code Online (Sandbox Code Playgroud)
在大多数平台上,指针和长整数的大小相同,但是在64位平台上,整数和指针的大小通常不同.如果你将convert(void*
)转换为(long
)没有精度丢失,那么通过将(long
)分配给(int
),它会正确地截断数字以适应.
将指针转换为void*并返回是有效使用reinterpret_cast <>.所以你可以这样做:
pthread_create(&thread, NULL, myFcn, new int(5)); // implicit cast to void* from int*
Run Code Online (Sandbox Code Playgroud)
然后在myFcn中:
void* myFcn(void* arg)
{
int* data = reinterpret_cast<int*>(arg);
int x = *data;
delete data;
Run Code Online (Sandbox Code Playgroud)
注意:正如sbi所指出的,这需要在OP调用上进行更改以创建线程.
我试图强调的是,当你从一个平台移动到另一个平台时,从int转换到指针再返回可能会出现问题.但是,将指针转换为void*并再次返回可以得到很好的支持(无处不在).
因此,结果可能不太容易错误地生成指针并且使用它.记住在使用后删除指针,以便我们不泄漏.
我也遇到这个问题。
ids[i] = (int) arg; // error occur here => I change this to below.
ids[i] = (uintptr_t) arg;
Run Code Online (Sandbox Code Playgroud)
然后我可以继续编译。也许你也可以试试这个。
正确的方法是将其投射到另一个pointer type
. 将 a 转换void*
为 anint
是不可移植的方式,可能有效也可能无效!如果需要保留返回的地址,则保留为void*
。
归档时间: |
|
查看次数: |
129736 次 |
最近记录: |