cast to 'void *'

M

Mark

Hello

is it proper use of explicit cast?

#include <stdio.h>

int main(void)
{
void *p;
int *x;

p = x;
x = p;

printf("p=%p, x=%p\n", p, (void *)x);
return 0;
}

When else is implicit conversion to 'void *' done, except assignment like
above written?

Thanks.

-- Mark
 
R

Rolf Magnus

Mark said:
Hello

is it proper use of explicit cast?

Casts are always explicit. But yes, it is.
#include <stdio.h>

int main(void)
{
void *p;
int *x;

p = x;
x = p;

printf("p=%p, x=%p\n", p, (void *)x);
return 0;
}

When else is implicit conversion to 'void *' done, except assignment like
above written?

Basically everywhere except variable argument lists.
 
H

Harald van Dijk

Rolf said:
Mark wrote: [...]
void *p;
int *x;

p = x;
x = p;

printf("p=%p, x=%p\n", p, (void *)x);
return 0;
}

When else is implicit conversion to 'void *' done, except assignment
like above written?

Basically everywhere except variable argument lists.

void* to/from function pointer is also not implicit.

Implementations commonly provide both implicit and explicit conversions
between void * and function pointers as extensions, and neither is
available in standard C.
 
M

Martin Ambuhl

blargg said:
void* to/from function pointer is also not implicit.

Nor is it standard C.
While pointers to objects are guaranteed to be (bidirectionally)
converted to pointers to void, function pointers are _not_ pointers to
objects.
The most you are assured of with conversion of function pointers is
1) That you can explicitly convert a pointer to function ot a
pointer to a function of a different type, but void* is not
a pointer to a function.
2) A null pointer constant can be converted to a function pointer,
so an initialization like
int (*foo)(void) = NULL;
is possible.
This is the one case where a pointer-to-void can be legally converte
to a function pointer:
int (*foo)() - (void *)0; /* a possible definition of NULL */
 
K

Keith Thompson

Martin Ambuhl said:
Nor is it standard C.

Well, sort of.
While pointers to objects are guaranteed to be (bidirectionally)
converted to pointers to void, function pointers are _not_ pointers to
objects.
The most you are assured of with conversion of function pointers is
1) That you can explicitly convert a pointer to function ot a
pointer to a function of a different type, but void* is not
a pointer to a function.
2) A null pointer constant can be converted to a function pointer,
so an initialization like
int (*foo)(void) = NULL;
is possible.
This is the one case where a pointer-to-void can be legally converte
to a function pointer:
int (*foo)() - (void *)0; /* a possible definition of NULL */

I think you mean

int (*foo)() = (void *)0;

But conversion between void* and a pointer-to-function type via a cast
operator is not a constraint violation, it's merely undefined behavior
(since C99 6.3.2.3 doesn't define the behavior of the conversion).
 
K

Keith Thompson

Harald said:
Rolf Magnus wrote:
Mark wrote:
[...]
void *p;
int *x;

p = x;
x = p;

printf("p=%p, x=%p\n", p, (void *)x);
return 0;
}

When else is implicit conversion to 'void *' done, except assignment
like above written?

Basically everywhere except variable argument lists.

void* to/from function pointer is also not implicit.

Implementations commonly provide both implicit and explicit conversions
between void * and function pointers as extensions, and neither is
available in standard C.

Argh! My statement above was about as relevant as

void* to/from struct tm is also not implicit.

Apologies.

Except that conversion between void* and struct tm is a constraint
violation. There is no implicit conversion, so such a conversion
would have to done via a cast operator. C99 6.5.4p2-3 says:

Constraints

2 Unless the type name specifies a void type, the type name shall
specify qualified or unqualified scalar type and the operand shall
have scalar type.

3 Conversions that involve pointers, other than where permitted by
the constraints of 6.5.16.1, shall be specified by means of an
explicit cast.

Conversion between void* and a function pointer, as I just wrote
elsethread, violates no constraint, but its behavior is undefined (but
of course an implementation is free to define it).

Incidentally, it seems to me that paragraph 3 is superfluous; any case
where it would apply is already covered by other constraints.
 
N

nicolas.sitbon

[email protected] (blargg) said:
Harald said:
Mark wrote:
[...]
    void *p;
    int *x;
    p = x;
    x = p;
    printf("p=%p, x=%p\n", p, (void *)x);
    return 0;
}
When else is implicit conversion to 'void *' done, except assignment
like above written?
Basically everywhere except variable argument lists.
void* to/from function pointer is also not implicit.
Implementations commonly provide both implicit and explicit conversions
between void * and function pointers as extensions, and neither is
available in standard C.
Argh! My statement above was about as relevant as
    void* to/from struct tm is also not implicit.
Apologies.

Except that conversion between void* and struct tm is a constraint
violation.  There is no implicit conversion, so such a conversion
would have to done via a cast operator.  C99 6.5.4p2-3 says:

    Constraints

  2 Unless the type name specifies a void type, the type name shall
    specify qualified or unqualified scalar type and the operand shall
    have scalar type.

  3 Conversions that involve pointers, other than where permitted by
    the constraints of 6.5.16.1, shall be specified by means of an
    explicit cast.

Conversion between void* and a function pointer, as I just wrote
elsethread, violates no constraint, but its behavior is undefined (but
of course an implementation is free to define it).

Incidentally, it seems to me that paragraph 3 is superfluous; any case
where it would apply is already covered by other constraints.

--
Keith Thompson (The_Other_Keith) (e-mail address removed)  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

I agree with you, nevertheless, new POSIX standard (issue 7) says:
" 2.12.3 Pointer Types
18881
All function pointer types shall have the same
representation as the type pointer to void.
18882
Conversion of a function pointer to void * shall not
alter the representation. A void * value
18883
resulting from such a conversion can be converted back to
the original function pointer type,
18884
using an explicit cast, without loss of information.
18885
The ISO C standard does not require this, but
it is required for POSIX conformance.
Note:
18886
"
Therefore, if you program a POSIX compliant application, the
conversion with an explicit cast is permitted.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,430
Messages
2,571,676
Members
48,796
Latest member
Greg L.

Latest Threads

Top