Search code examples
cpointerspass-by-valuec89

pass by value in C


Is the following code portable?

I just pass the pointer by value and I can change it in the caller!

void foo(void *p)
{
    void **pp = (void**)p;
    *pp = "hahaha";
}

int main(int argc,char **argv)
{
    void *p = NULL;
    p = &p;
    printf("%p\n",p);
    foo(p);
    printf("%s\n",(char *)p);     // hahaha
    printf("%p\n",p);

    return 0;
}

Solution

  • You're always passing a pointer to a pointer by value making it seem a single pointer when you assign it to itself and when you pass it to the function; it works only because you made that pointer point to itself.

    What you're doing is basically this:

    void foo(void **p)
    {
        *p = "hahaha";
    }
    
    int main(int argc,char **argv)
    {
        void *p = NULL;
        printf("%p\n", &p);
        foo(&p);
        printf("%s\n",(char *)p);     // hahaha
        printf("%p\n", p);
        return 0;
    }
    

    with some casts and tricks added. "Card tricks in the dark", I'd say, and definitely not a good idea to put in a real program.

    To actually reply to the question: yes, it should be portable, because the standard guarantees that every data pointer can be casted to and from a void * without problems (which is what you do in your code all the time):

    A pointer to void may be converted to or from a pointer to any incomplete or object type. A pointer to any incomplete or object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

    (C99, §6.3.2.3.1)