Search code examples
cunsigned-integertypecast-operator

Typecast warning of Conversion of one type to another C


I am running into a warning in the gcc compiler that is shown below:

thread_primes.c(295): warning #810: conversion from "unsigned int *" to "unsigned int" may lose significant bits
        unsigned int i = (unsigned int*) vp;
                     ^

The function that it is happening in are:

void *elim_composites(void *vp)
{
    //*((unsigned int*) vp)
    unsigned int i = (unsigned int*) vp;
    unsigned int min = i * (max_prime / num_threads) + 1;
    /* If we're on the last thread, set the max equal to the max_prime */
    unsigned int max =
        (i ==
         num_threads - 1) ? max_prime : min +
        (max_prime / num_threads) - 1;
    unsigned int j;
    unsigned long k;    //This is much faster as long as opposed to unsigned int
    j = 1;
    while ((j = next_seed(j)) != 0) 
    {
        for (k = (min / j < 3) ? 3 : (min / j); (j * k) <= max;
             k++) 
        {
            set_not_prime(j * k);
        }
    }
    pthread_exit(EXIT_SUCCESS);
}

I have tried ((unsigned int*) vp) to try to fix the warning and it did get rid of the warning but has caused a segmentation fault. I would post the rest of my code but there is a lot of it and hopefully this is enough for someone to give some input.

I know I am assigning a unsigned int pointer to an unsigned int which thinking about it is not the same size but I am not sure where to go from here.

Any help would be appreciated.

Thank you.


Solution

  • You are attempting to cast a pointer to an integer. C allows this, but it doesn't often do what you want, and in this case the target type is not as wide as the starting type, so the conversion may result in a loss of significant digits. That's what the compiler is warning you about.

    If the function argument vp is a pointer to the unsigned int value you want, then you're looking for

    unsigned int i = *(unsigned int *)vp;
    

    That is, you cast pointer-to-void to pointer-to-unsigned int as you already did, then dereference the result to get the value it points to.

    On the other hand, if you're doing something dumb, such as passing the wanted unsigned int value itself as if it were a pointer value, then you can simply ignore the warning. Your code probably will work as-is in that case, and the warning is the price you pay for being sloppy.