Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert "void*" to int without warning

Tags:

c++

I need to convert "void*" to int, but compiler keeps giving me warning. 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":

#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

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

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.

like image 806
packetie Avatar asked Dec 10 '22 15:12

packetie


1 Answers

I need to convert "void*" to 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.

This is what std::uint32_t is for:

#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::int32_t - guaranteed to be signed 32 bits

like image 167
Richard Hodges Avatar answered Dec 13 '22 03:12

Richard Hodges