Hello
typedef signed int s_int32_t;
typedef void (*del_cb_t) (void *val);
typedef s_int32_t (*cmp_cb_t) (void *val1, void *val2);
int obj_create (cmp_cb_t cmp, del_cb_t del);
int obj_create (cmp_cb_t cmp, del_cb_t del)
{
/* do the stuff */
}
...
int my_cmp (void * data1, void * data2)
{
}
ret = obj_create ((cmp_cb_t)my_cmp, (del_cb_t)NULL);
Does it have any useful effect to typecast 'my_cmp' given that return value
is different with what defines typedef ?
No, because `int' and `s_int32_t' are *not* different types.
A typedef declaration does not create a new type; it just creates
an additional name for an existing type. Also, `signed int' and
`int' are not different types, but just two different ways to
name the same type. All of `s_int32_t', `signed int', and `int'
are different ways of naming one type, and all three aliases can
be used interchangeably.[*],[**]
If my_cmp() were in fact different -- if it returned a `float',
say, or an `unsigned long' -- then the cast would be both necessary
an *in*sufficient. "Necessary" in the sense that the compiler would
be required to issue a diagnostic if the cast were absent, but
"insufficient" in that even if it quieted the diagnostic the program
would still be wrong, with a wrongness that might not be detected
until run-time.
The other cast is also unnecessary. Because obj_create() is
declared with a prototype, the compiler "knows" the types of its
parameters and will convert the `NULL' argument to the proper
type.[***]
[*] Although `int' and `signed int' name the same type, note
that `char' and `signed char' do not. For historical reasons,
`char' is somewhat special, and is distinct from both `signed char'
and `unsigned char' even though it behaves just like one or the
other of them.
[**] In a bit-field declaration (like `int x : 4;' in a struct
or union), `int' and `signed int' may mean different things. Again
for historical reasons, a plain `int' bit-field may be either signed
or unsigned at the compiler's discretion, while `signed int x : 4;'
is definitely signed. It's helpful to adopt the viewpoint that
although `int' and `signed int' are the same, `int:N' and
`signed int:N' are distinct.
[***] Note that the compiler has no information about the types
of variadic parameters, those that match the `...' portion of a
variable-argument prototype. Casts are sometimes needed when
passing arguments to match those parameters; a cast is *always*
needed when passing `NULL' arguments to such parameters.