在没有警告的情况下将"void*"转换为int

pac*_*tie 1 c++

我需要将"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

更新了代码片段,以便说明这一点不那么重要.该参数需要传递不同类型的值.我需要一种方法来施放而不产生警告.

Ric*_*ges 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;
}
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位


Igo*_*nik 5

您可能正在寻找一些类似的东西

int x = static_cast<int>(reinterpret_cast<std::uintptr_t>(p));
Run Code Online (Sandbox Code Playgroud)

不能严格保证这是可行的:也许令人惊讶的是,该标准保证了将指针转换为足够大的整数并返回指针的结果相同。但是对于将整数转换为指针然后返回整数时,并不能提供类似的保证。关于后一种情况的所有说明是

[expr.reinterpret.cast] / 4指针可以显式转换为足以容纳它的任何整数类型。映射功能是实现定义的。[ 注意:对于那些了解底层机器的寻址结构的人来说,这并不奇怪。—尾注 ]

希望您知道机器的寻址结构,并且不会感到惊讶。