我需要转换" 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;
^
这是简单的代码" 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;
}
UDPATE1
我明白我会失去精确度。它有时是有意的。我需要的是有一种方法可以在我知道的地方删除警告,确保它是安全的。很抱歉没有在之前说清楚。
UDPATE2
更新了代码段,以便说明重点。该参数需要传递不同类型的值。我需要一种方法来施放而不产生警告。
答案 0 :(得分:7)
我需要将“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;
}
好吧,我真正想做的是以符合标准的方式使用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;
}
std::uint32_t
- 保证是无符号32位
std::int32_t
- 保证签名为32位
答案 1 :(得分:5)
您可能正在寻找符合
的内容int x = static_cast<int>(reinterpret_cast<std::uintptr_t>(p));
这并不能严格保证工作:也许令人惊讶的是,标准保证指针转换为足够大的整数并返回指针会产生相同的值;但是,当整数转换为指针并返回整数时,并没有提供类似的保证。所有关于后一种情况的说法都是
[expr.reinterpret.cast] / 4 指针可以显式转换为足以容纳它的任何整数类型。映射函数是实现定义的。 [注意:对于那些了解底层机器的寻址结构的人来说,这并不奇怪。 -end note ]
希望您知道机器的寻址结构,并且不会感到惊讶。