简体   繁体   English

无警告地将“ void *”转换为int

[英]Convert “void*” to int without warning

I need to convert "void*" to int, but compiler keeps giving me warning. 我需要将“ void *”转换为int,但是编译器会不断警告我。 Wonder if there is a way to change the code so that compiler will not complain. 想知道是否有一种方法可以更改代码,以使编译器不会抱怨。 This occurs a lot in the code base, especially when passing an argument to starting a new thread. 这在代码库中经常发生,尤其是在传递参数以启动新线程时。

$ 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;
               ^

Here is the simple code "te1.cc": 这是简单的代码“ 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 UDPATE1

I understand that I will lose precision. 我知道我会失去精度。 It's intended sometimes. 有时是故意的。 What I need is to have a way to remove the warning in places I know for sure it's safe. 我需要的是有一种方法可以消除在我确定可以安全的地方发出的警告。 Sorry for not making it clear earlier. 对不起,您未及早说明。

UDPATE2 UDPATE2

Updated the code snippet to be a little less non-trivial to illustrate the point. 更新了代码片段,使它变得不那么平凡,以说明这一点。 The parameter needs to pass different type of values. 该参数需要传递不同类型的值。 I need a way to cast without generating warning. 我需要一种在不产生警告的情况下进行投射的方法。

I need to convert "void*" to int 我需要将“ void *”转换为int

no you don't. 不,你不会。

I really do... 我真的是

no, you need to represent a pointer as some kind of integer type which is guaranteed not to lose information. 不,您需要将指针表示为某种整数类型,以确保不会丢失信息。

#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;
}

ok, what I really want to do is work with 32-bit values in a standards-compliant way. 好的,我真正想做的是以符合标准的方式使用32位值。

This is what std::uint32_t is for: 这就是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 - guaranteed to be unsigned 32 bits std::uint32_t保证为无符号32位

std::int32_t - guaranteed to be signed 32 bits std::int32_t保证被签名32位

You are probably looking for something along the lines of 您可能正在寻找一些类似的东西

int x = static_cast<int>(reinterpret_cast<std::uintptr_t>(p));

This is not strictly guaranteed to work: perhaps surprisingly, the standard guarantees that a pointer converted to a large enough integer and back to a pointer results in the same value; 不能严格保证这是可行的:也许令人惊讶的是,该标准保证了将指针转换为足够大的整数并返回到指针会得到相同的值。 but doesn't provide a similar guarantee for when an integer is converted to a pointer and back to the integer. 但是对于将整数转换为指针然后返回整数时,并不能提供类似的保证。 All it says about the latter case is 关于后一种情况的所有说明是

[expr.reinterpret.cast]/4 A pointer can be explicitly converted to any integral type large enough to hold it. [expr.reinterpret.cast] / 4指针可以显式转换为足够大的整数类型以容纳它。 The mapping function is implementation-defined. 映射功能是实现定义的。 [ Note: It is intended to be unsurprising to those who know the addressing structure of the underlying machine. [ 注意:对于那些了解底层机器的寻址结构的人来说,这并不奇怪。 —end note ] —尾注 ]

Hopefully, you know the addressing structure of your machine, and won't be surprised. 希望您知道机器的寻址结构,并且不会感到惊讶。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 警告(过时):将void(*)(int)分配给外部“ C” void(*)(int) - Warning (Anachronism): Assigning void(*)(int) to extern “C” void(*)(int) 如何在使用pedantic标志进行编译时,在没有得到任何警告的情况下,在C ++中从(void *)重新键入int? - How to retype from (void *) to int in C++ without getting any warning when compiling with pedantic flag? 将void *十六进制转换为十进制整数 - convert void* hex to decimal int 在constexpr中将`void *`转换为`unsigned int` - convert `void*` to `unsigned int` in constexpr 无法从“ void”转换为“ int” - cannot convert from “void” to “int” 无法从void转换为int - Cannot convert from void to int 无法将参数 '2' 的 'int (Scheduler::*)(int, void*)' 转换为 'int (*)(int, void*)' 到 'bool irq_InstallISR(int, int (*)(int, void *), 空白*)' - cannot convert 'int (Scheduler::*)(int, void*)' to 'int (*)(int, void*)' for argument '2' to 'bool irq_InstallISR(int, int (*)(int, void*), void*)' 警告传递“double”以转换“void moveto(int, int)”的 2 - Warning passing `double' for converting 2 of `void moveto(int, int)' 如何将const void *转换为unsigned int? - How to convert const void* to unsigned int? 错误:无法将&#39;print&#39;从&#39;void(*)(int)&#39;转换为&#39;std :: function <void()> “ - error: could not convert ‘print’ from ‘void (*)(int)’ to ‘std::function<void()>’
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM