I'm proposing a change to a library whose public API currently looks like this:
typedef size_t enh; /* handle */
int en_open(enh *handle)
{
struct internal *e = malloc(...);
*handle = (enh)e;
return 0;
}
int en_start(enh handle)
{
struct internal *e = (struct internal*)handle;
return do_something(e);
}
Does this usage, casting back and forth to size_t
break strict aliasing?
For the record, I'm proposing a typical opaque forward declaration of struct internal
in the public API, as shown on this Programmers.SE question about the same code.
size_t
guaranteed to be wide enough to hold a pointer? I don't think so.. – Chrysasize_t
may just truncate it. – Chrysasize_t
! The correct type would beuintptr_t
(You should know that, why else would you mention it?) – Poultryvoid *
be better for a generic/opaque pointer anyway? Or am I missing something obvious here? – Boscagevoid*
is not good, because it makes type checking impossible. Think of what happens when you have two different handle types in your interface. If either one isvoid*
, the compiler won't catch the error if the user mixes them up. With proper opaque pointers, the compiler will catch these errors. – Corronuintptr_t
help for type checking? I am lost. – Vicevoid*
is much better thanuintptr_t
or any other integer type. – Vicevoid*
, which is better thanuintptr_t
, which is better thansize_t
. Precisely in that order :-) – Corron