4

Consider the following snippet:

void my_func(int a, void *b);
...

struct my_struct s = { };
my_func(10, (void *)&s);

Is it necessary to typecast to (void *) when passing &s to the function?

3
  • 6
    No, it is not necessary. Any object pointer can be silently converted back and forth to and from void*. Commented Jan 16, 2019 at 19:38
  • 1
    @EugeneSh. Perhaps not always silently. void my_func(int a, void *b); int main(void) { const char *x; my_func(1,x); } --> "warning: passing argument 2 of 'my_func' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]" Yet agree in this case, no cast needed. Commented Jan 16, 2019 at 19:57
  • Specially when gcc flag -pendantic is used . Compilation command: gcc -Wall -pendantic main.c -o main Commented Jan 16, 2019 at 21:30

3 Answers 3

5

A pointer to any type may be freely converted to or from a void * without a cast.

Section 6.3.2.3p1 of the C standard states:

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

The only time a cast is needed is if you pass a pointer to a variadic function like printf where an implicit conversion can't occur, since it won't know what the exact type being passed in is.

Note that, as with any pointer type, you can't "remove" a qualifier such as const when passing to a function without a cast. Sections 6.3.2.3p2 states:

For any qualifier q, a pointer to a non-q-qualified type may be converted to a pointer to the q-qualified version of the type; the values stored in the original and converted pointers shall compare equal.

Sign up to request clarification or add additional context in comments.

6 Comments

the is no conversion on any modern system (except the 8 bits systems with named address spaces or far pointers). The times of the
@P__J__ "Conversion" is not a system specific thing, but a term that the standard is using.
IMO it is wrong - the word cast should be used. Conversion and cast mean something different.
Casting is the operation which is performing conversion - Preceding an expression by a parenthesized type name converts the value of the expression to the named type. This construction is called a cast. - port70.net/~nsz/c/c11/n1570.html#6.5.4p5.
@P__J__ Referencing your answer, that has nothing to do with void * and everything to do with qualifiers. You'll get the same if you pass a const int * when a int * is expected.
|
2

you do not have to with some exceptions as you may get the warning if the object which reference you pass to the function is volatile or const - generally has different attribute.

void ee(void *q)
{
    pritntf("%p", q);
}

volatile int g;
const int f;

int main()
{

    ee(&g);
    ee(&f);
}

gives this warnings:

<source>: In function 'main':

<source>:17:8: warning: passing argument 1 of 'ee' discards 'volatile' qualifier from pointer target type [-Wdiscarded-qualifiers]

     ee(&g);

        ^~

<source>:6:15: note: expected 'void *' but argument is of type 'volatile int *'

 void ee(void *q)

         ~~~~~~^

<source>:18:8: warning: passing argument 1 of 'ee' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]

     ee(&f);

        ^~

<source>:6:15: note: expected 'void *' but argument is of type 'const int *'

 void ee(void *q)

         ~~~~~~^

Compiler returned: 0

Comments

1

No, it is not required, it just makes the code clearer on what exactly is being passed to the function.

1 Comment

No warnings should be ever produced without the cast.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.