Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #16352 > unrolled thread
| Started by | "Mark" <mark_cruzNOTFORSPAM@hotmail.com> |
|---|---|
| First post | 2012-01-28 08:15 -0500 |
| Last post | 2012-01-28 14:08 +0000 |
| Articles | 10 — 6 participants |
Back to article view | Back to comp.lang.c
typecast function pointer "Mark" <mark_cruzNOTFORSPAM@hotmail.com> - 2012-01-28 08:15 -0500
Re: typecast function pointer Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-01-28 08:52 -0500
Re: typecast function pointer "Mark" <mark_cruzNOTFORSPAM@hotmail.com> - 2012-01-29 16:47 -0500
Re: typecast function pointer Ian Collins <ian-news@hotmail.com> - 2012-01-30 10:56 +1300
Re: typecast function pointer Keith Thompson <kst-u@mib.org> - 2012-01-29 14:27 -0800
Re: typecast function pointer Ike Naar <ike@iceland.freeshell.org> - 2012-01-30 00:14 +0000
Re: typecast function pointer Keith Thompson <kst-u@mib.org> - 2012-01-29 21:05 -0800
Re: typecast function pointer Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-01-29 18:07 -0500
Re: typecast function pointer Keith Thompson <kst-u@mib.org> - 2012-01-29 21:06 -0800
Re: typecast function pointer Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-01-28 14:08 +0000
| From | "Mark" <mark_cruzNOTFORSPAM@hotmail.com> |
|---|---|
| Date | 2012-01-28 08:15 -0500 |
| Subject | typecast function pointer |
| Message-ID | <jg0sdr$b96$1@speranza.aioe.org> |
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 ?
Mark
[toc] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-01-28 08:52 -0500 |
| Message-ID | <jg0ui5$o9l$1@dont-email.me> |
| In reply to | #16352 |
On 1/28/2012 8:15 AM, Mark wrote:
> 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.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | "Mark" <mark_cruzNOTFORSPAM@hotmail.com> |
|---|---|
| Date | 2012-01-29 16:47 -0500 |
| Message-ID | <jg4epn$se9$1@speranza.aioe.org> |
| In reply to | #16353 |
"Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message news:jg0ui5$o9l$1@dont-email.me... > 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.[*],[**] Thanks for comprehensive answers! What can be the reason to declare a function returning 'signed int' instead of 'int' if those are all the same types? IMHO it only brings in confusion, as in my case. Mark.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-01-30 10:56 +1300 |
| Message-ID | <9oltjgFcosU1@mid.individual.net> |
| In reply to | #16409 |
On 01/30/12 10:47 AM, Mark wrote: > "Eric Sosman"<esosman@ieee-dot-org.invalid> wrote in message > news:jg0ui5$o9l$1@dont-email.me... >> 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.[*],[**] > > Thanks for comprehensive answers! > > What can be the reason to declare a function returning 'signed int' instead > of 'int' if those are all the same types? IMHO it only brings in confusion, > as in my case. There aren't any really. Maybe the original authour was trying to look smart? -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-01-29 14:27 -0800 |
| Message-ID | <lnk44aywia.fsf@nuthaus.mib.org> |
| In reply to | #16409 |
"Mark" <mark_cruzNOTFORSPAM@hotmail.com> writes:
> "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message
> news:jg0ui5$o9l$1@dont-email.me...
>> 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.[*],[**]
>
> Thanks for comprehensive answers!
>
> What can be the reason to declare a function returning 'signed int' instead
> of 'int' if those are all the same types? IMHO it only brings in confusion,
> as in my case.
The compiler doesn't care whether you write "int", or "signed int", or
"signed", or "int unsigned" for that matter.
You might write "signed int" for emphasis, to distinguish it from
"unsigned int":
unsigned int this_function(void);
signed int that_function(void);
(And "signed int" is not necessarily "int" when used to declare a bit
field, but the question was about function return types, so that doesn't
apply.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ike Naar <ike@iceland.freeshell.org> |
|---|---|
| Date | 2012-01-30 00:14 +0000 |
| Message-ID | <slrn3vfsjibo7m.42d.ike@iceland.freeshell.org> |
| In reply to | #16412 |
On 2012-01-29, Keith Thompson <kst-u@mib.org> wrote: > The compiler doesn't care whether you write "int", or "signed int", or > "signed", or "int unsigned" for that matter. That sentence (or else the compiler) needs to be fixed.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-01-29 21:05 -0800 |
| Message-ID | <lnfwexzsnn.fsf@nuthaus.mib.org> |
| In reply to | #16416 |
Ike Naar <ike@iceland.freeshell.org> writes:
> On 2012-01-29, Keith Thompson <kst-u@mib.org> wrote:
>> The compiler doesn't care whether you write "int", or "signed int", or
>> "signed", or "int unsigned" for that matter.
>
> That sentence (or else the compiler) needs to be fixed.
Oops, the last should be "int signed".
To summarize, the following are all equivalent names for the same type:
int
signed int
int signed
signed
The "int signed" form is rarely used, but the standard permits type
specifiers to appear in any order.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-01-29 18:07 -0500 |
| Message-ID | <jg4jfn$u4t$1@dont-email.me> |
| In reply to | #16409 |
On 1/29/2012 4:47 PM, Mark wrote:
> "Eric Sosman"<esosman@ieee-dot-org.invalid> wrote in message
> news:jg0ui5$o9l$1@dont-email.me...
>> 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.[*],[**]
>
> Thanks for comprehensive answers!
>
> What can be the reason to declare a function returning 'signed int' instead
> of 'int' if those are all the same types? IMHO it only brings in confusion,
> as in my case.
The `signed' keyword was absent from original prehistoric C,
and was added in the first ("C89", "ANSI") version of the Standard.
The intent was to allow the programmer to write `signed char' or
`unsigned char' when a tiny signed or unsigned integer was desired,
or to write plain `char' when the signedness was unimportant and
the choice could be left to the compiler.
When `signed char' became available, the committee decided that
`signed int' and `signed short' and `signed long' should also be
allowed, even though `signed' added no new meaning (these integer
flavors were and still are always signed). Perhaps the committee was
inspired by a desire for "regularity" in the language, or perhaps
they were thinking of declarations constructed by macro expansion.
Whatever their reason, `signed int' is now an alias for `int'.
To me, it seems pointless to write `signed int' instead of `int'.
Some might feel that `signed int' is more self-documenting in that
it emphasizes the fact that the type holds signed values, but it seems
to me that this is such a basic property of C that anyone who needs
the emphasis probably shouldn't be using the language. (I also find
`short int' similarly useless, and avoid `long int signed long' as
a threat to sanity.) Tastes vary, though, and a C programmer must be
prepared for the occasional "unusual" declaration.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-01-29 21:06 -0800 |
| Message-ID | <lnboplzsly.fsf@nuthaus.mib.org> |
| In reply to | #16415 |
Eric Sosman <esosman@ieee-dot-org.invalid> writes:
[...]
> To me, it seems pointless to write `signed int' instead of `int'.
[...]
Except for bit fields, of course.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-01-28 14:08 +0000 |
| Message-ID | <0.859530793c0f93752836.20120128140823GMT.87wr8b3oo8.fsf@bsb.me.uk> |
| In reply to | #16352 |
"Mark" <mark_cruzNOTFORSPAM@hotmail.com> writes:
> typedef signed int s_int32_t;
>
> typedef void (*del_cb_t) (void *val);
> typedef s_int32_t (*cmp_cb_t) (void *val1, void *val2);
It would be better is these could be const void * parameters.
> 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 ?
Not really. I suppose it just possible that it might suppress a
warning. No diagnostic is required, but I can maybe an overly "helpful"
compiler might warn about the code without the cast.
However, you are setting yourself up for a maintenance problem later on.
If, in some future port of the software, s_int32_t ends not being
compatible with int, the code will be undefined and the cast might mask
all warnings about that. Is not possible to define my_cmp as returning
an s_int32_t?
--
Ben.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web