我需要将"void*"转换为int,但编译器会一直给我警告.不知道是否有办法改变代码,以便编译器不会抱怨.这在代码库中发生了很多,特别是在传递参数以启动新线程时.
$ g++ -fpermissive te1.cc
te1.cc: In function ‘void dummy(void*)’:
te1.cc:4:15: warning: cast from ‘void*’ to ‘int’ loses precision [-fpermissive]
int x = (int)p;
^
Run Code Online (Sandbox Code Playgroud)
这是简单的代码"te1.cc":
#include <stdio.h>
extern void someFunc(int);
void dummy(int type, void *p) {
if (type == 0) {
int x = (int)p;
someFunc(x);
} else if (type == 1) {
printf("%s\n", (char*)p);
}
}
int main(int argc, char *argv[]) {
void *p = (void*)5;
dummy(p);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
UDPATE1
我明白我会失去精确度.它有时是有意的.我需要的是有办法在我知道的地方删除警告,确保它是安全的.很抱歉没有在之前说清楚.
UDPATE2
更新了代码片段,以便说明这一点不那么重要.该参数需要传递不同类型的值.我需要一种方法来施放而不产生警告.
我需要将"void*"转换为int
不,你没有.
我真的...
不,你需要将指针表示为某种整数类型,保证不会丢失信息.
#include <cstdio>
#include <cstdint>
#include <iostream>
#include <cstring>
#include <utility>
#include <cinttypes>
void dummy(void *p) {
std::intptr_t x = reinterpret_cast<std::intptr_t>(p);
printf("x = %" PRIiPTR "\n", x);
// ^^ see here: http://en.cppreference.com/w/cpp/types/integer
}
int main(int argc, char *argv[]) {
void *p = (void*)5;
dummy(p);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
好吧,我真正想做的是以符合标准的方式使用32位值.
这std::uint32_t是为了什么:
#include <cstdint>
#include <iostream>
void dummy(std::uint32_t x) {
std::cout << x << '\n';
}
int main(int argc, char *argv[]) {
auto x = std::uint32_t(5);
dummy(x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
std::uint32_t - 保证是无符号32位
std::int32_t - 保证签名为32位
您可能正在寻找一些类似的东西
int x = static_cast<int>(reinterpret_cast<std::uintptr_t>(p));
Run Code Online (Sandbox Code Playgroud)
不能严格保证这是可行的:也许令人惊讶的是,该标准保证了将指针转换为足够大的整数并返回指针的结果相同。但是对于将整数转换为指针然后返回整数时,并不能提供类似的保证。关于后一种情况的所有说明是
[expr.reinterpret.cast] / 4指针可以显式转换为足以容纳它的任何整数类型。映射功能是实现定义的。[ 注意:对于那些了解底层机器的寻址结构的人来说,这并不奇怪。—尾注 ]
希望您知道机器的寻址结构,并且不会感到惊讶。