簡體   English   中英

無警告地將“ void *”轉換為int

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

我需要將“ 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

更新了代碼片段,使它變得不那么平凡,以說明這一點。 該參數需要傳遞不同類型的值。 我需要一種在不產生警告的情況下進行投射的方法。

我需要將“ 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位

您可能正在尋找一些類似的東西

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

不能嚴格保證這是可行的:也許令人驚訝的是,該標准保證了將指針轉換為足夠大的整數並返回到指針會得到相同的值。 但是對於將整數轉換為指針然后返回整數時,並不能提供類似的保證。 關於后一種情況的所有說明是

[expr.reinterpret.cast] / 4指針可以顯式轉換為足夠大的整數類型以容納它。 映射功能是實現定義的。 [ 注意:對於那些了解底層機器的尋址結構的人來說,這並不奇怪。 —尾注 ]

希望您知道機器的尋址結構,並且不會感到驚訝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM