Is casting to pointers to pointers to void always safe?

前端 未结 3 664
暗喜
暗喜 2021-01-20 14:31
#include 

void swap(void *v[], int i, int j)
{
    void *tmp;

    tmp = v[i];
    v[i] = v[j];
    v[j] = tmp;
}

int main(void)
{
    char *s[] = {         


        
相关标签:
3条回答
  • 2021-01-20 15:04

    To avoid the warning call the function as follows,

    swap((void *) s, 0, 1);
    

    It is always safe to cast any pointer as a void pointer.

    0 讨论(0)
  • 2021-01-20 15:07

    You need to typecast the pointer in swap call. Change it to swap ( ( void * )s, 0, 1 );

    0 讨论(0)
  • 2021-01-20 15:13

    No, it is not necessarily safe to pass a char** where a void** (which is what a void*[] function parameter actually is) is expected. The fact that the compiler makes you perform an explicit cast is a hint about that.

    In practice, it is likely to be fine. Strictly speaking, however, you usually have no guarantee that sizeof (T*) == sizeof (U*) for distinct types T and U. (For example, you could imagine a hypothetical system where sizeof (int*) < sizeof (char*) because pointers-to-int are aligned and therefore don't need to store the least significant bits.) Consequently, your swap function might index into the v array using the wrong offsets.

    Also see Q4.9 from the comp.lang.c FAQ: Can I give the formal parameter type void **, and do something like this?

    To call swap safely, you should do something like:

    void* temp[] = { &s[0], &s[1] };
    swap(temp, 0, 1);
    

    although that would swap the elements of temp, not of s.

    If you're authoring swap, in general you should make such a function take a void* argument (instead of a void** one) and a size_t argument that specifies the size of each element. Your function then could cast the void* to char* safely and swap individual bytes:

    void swap(void* p, size_t elementSize, size_t i, size_t j)
    {
        char* item1 = p;
        char* item2 = p;
    
        item1 += i * elementSize;
        item2 += j * elementSize;
    
        while (elementSize-- > 0) {
            char temp = *item1;
            *item1 = *item2;
            *item2 = temp;
            item1++;
            item2++;
        }
    }
    

    Edit: Also see this StackOverflow answer to a similar question.

    0 讨论(0)
提交回复
热议问题