Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #25810 > unrolled thread
| Started by | ajaybgr <ajay.bgr@gmail.com> |
|---|---|
| First post | 2012-09-03 01:50 -0700 |
| Last post | 2012-09-06 21:34 -0700 |
| Articles | 20 on this page of 21 — 13 participants |
Back to article view | Back to comp.lang.c
Do not cast pointers to functions to pointers to primitive types ajaybgr <ajay.bgr@gmail.com> - 2012-09-03 01:50 -0700
Re: Do not cast pointers to functions to pointers to primitive types Ian Collins <ian-news@hotmail.com> - 2012-09-03 20:59 +1200
Re: Do not cast pointers to functions to pointers to primitive types Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-09-03 02:13 -0700
Re: Do not cast pointers to functions to pointers to primitive types Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-09-03 11:24 +0100
Re: Do not cast pointers to functions to pointers to primitive types James Kuyper <jameskuyper@verizon.net> - 2012-09-03 08:31 -0400
Re: Do not cast pointers to functions to pointers to primitive types Keith Thompson <kst-u@mib.org> - 2012-09-03 13:21 -0700
Re: Do not cast pointers to functions to pointers to primitive types James Kuyper <jameskuyper@verizon.net> - 2012-09-03 16:57 -0400
Re: Do not cast pointers to functions to pointers to primitive types Keith Thompson <kst-u@mib.org> - 2012-09-03 14:48 -0700
Re: Do not cast pointers to functions to pointers to primitive types pacman@kosh.dhis.org (Alan Curry) - 2012-09-03 21:57 +0000
Re: Do not cast pointers to functions to pointers to primitive types Keith Thompson <kst-u@mib.org> - 2012-09-03 18:11 -0700
Re: Do not cast pointers to functions to pointers to primitive types pacman@kosh.dhis.org (Alan Curry) - 2012-09-04 02:03 +0000
Re: Do not cast pointers to functions to pointers to primitive types Keith Thompson <kst-u@mib.org> - 2012-09-03 19:20 -0700
Re: Do not cast pointers to functions to pointers to primitive types pacman@kosh.dhis.org (Alan Curry) - 2012-09-04 20:27 +0000
Re: Do not cast pointers to functions to pointers to primitive types James Kuyper <jameskuyper@verizon.net> - 2012-09-04 17:10 -0400
Re: Do not cast pointers to functions to pointers to primitive types Barry Schwarz <schwarzb@dqel.com> - 2012-09-04 14:14 -0700
Re: Do not cast pointers to functions to pointers to primitive types pete <pfiland@mindspring.com> - 2012-09-03 22:51 -0400
Re: Do not cast pointers to functions to pointers to primitive types Vincenzo Mercuri <vincenzo.mercuri@yahoo.it> - 2012-09-04 00:02 +0200
Re: Do not cast pointers to functions to pointers to primitive types Keith Thompson <kst-u@mib.org> - 2012-09-03 18:19 -0700
Re: Do not cast pointers to functions to pointers to primitive types Kaz Kylheku <kaz@kylheku.com> - 2012-09-04 01:18 +0000
Re: Do not cast pointers to functions to pointers to primitive types "Scott Fluhrer" <sfluhrer@ix.netcom.com> - 2012-09-04 11:59 -0400
Re: Do not cast pointers to functions to pointers to primitive types Philip Lantz <prl@canterey.us> - 2012-09-06 21:34 -0700
Page 1 of 2 [1] 2 Next page →
| From | ajaybgr <ajay.bgr@gmail.com> |
|---|---|
| Date | 2012-09-03 01:50 -0700 |
| Subject | Do not cast pointers to functions to pointers to primitive types |
| Message-ID | <fce4988c-58d7-4847-84fe-edb1ed3b722c@googlegroups.com> |
Not sure if this is the right place or OT.
One of the Parasoft coding guidelines (which I am using for current project) is
"Do not cast pointers to functions to pointers to primitive types [CODSTA-09-3]"
EXAMPLE(from parasoft document):
void Foo(char *ptrC)
{
*ptrC = 0;
return;
}
void f()
{
void *ptrV = 0;
void (*funPtr) (char*) = 0;
funPtr = &Foo;
ptrV = (void*)funPtr; // Violation of the rule and raise error
return;
}
I can see why it is a bad idea not to write code this way.
But can any one explain where this kind of code is useful?
(imo, to be a guideline it must have been used/misused a lot)
Where casting a function pointer to primitive type makes sense?
Sorry if this is too silly, my mind seems to have hit a wall today.
Regards
Ajay
[toc] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2012-09-03 20:59 +1200 |
| Message-ID | <aaj9saF3lnU5@mid.individual.net> |
| In reply to | #25810 |
On 09/ 3/12 08:50 PM, ajaybgr wrote:
> Not sure if this is the right place or OT.
> One of the Parasoft coding guidelines (which I am using for current project) is
> "Do not cast pointers to functions to pointers to primitive types [CODSTA-09-3]"
>
> EXAMPLE(from parasoft document):
> void Foo(char *ptrC)
> {
> *ptrC = 0;
> return;
> }
>
> void f()
> {
> void *ptrV = 0;
> void (*funPtr) (char*) = 0;
> funPtr =&Foo;
> ptrV = (void*)funPtr; // Violation of the rule and raise error
> return;
> }
>
> I can see why it is a bad idea not to write code this way.
> But can any one explain where this kind of code is useful?
In a bad dream...
> (imo, to be a guideline it must have been used/misused a lot)
> Where casting a function pointer to primitive type makes sense?
An awful lot of bad C code has been has been hacked together in the past
30+ years!
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Nick Keighley <nick_keighley_nospam@hotmail.com> |
|---|---|
| Date | 2012-09-03 02:13 -0700 |
| Message-ID | <b8297166-a992-4838-8fbf-2b109b7b9da3@13g2000vbf.googlegroups.com> |
| In reply to | #25810 |
On Sep 3, 9:50 am, ajaybgr <ajay....@gmail.com> wrote:
> Not sure if this is the right place or OT.
> One of the Parasoft coding guidelines (which I am using for current project) is
> "Do not cast pointers to functions to pointers to primitive types [CODSTA-09-3]"
>
> EXAMPLE(from parasoft document):
> void Foo(char *ptrC)
> {
> *ptrC = 0;
> return;
>
> }
>
> void f()
> {
> void *ptrV = 0;
> void (*funPtr) (char*) = 0;
> funPtr = &Foo;
> ptrV = (void*)funPtr; // Violation of the rule and raise error
> return;
>
> }
>
> I can see why it is a bad idea not to write code this way.
> But can any one explain where this kind of code is useful?
> (imo, to be a guideline it must have been used/misused a lot)
> Where casting a function pointer to primitive type makes sense?
> Sorry if this is too silly, my mind seems to have hit a wall today.
it probably arises from the misconception that "void* is a pointer to
anything" since on most architectures object pointers and functions
pointers are "just addreses" you can get away with it a lot of the
time. Yes it is a bad idea.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-09-03 11:24 +0100 |
| Message-ID | <0.e245be652ae4afd8e5ce.20120903112453BST.87txvf4d56.fsf@bsb.me.uk> |
| In reply to | #25810 |
ajaybgr <ajay.bgr@gmail.com> writes:
> Not sure if this is the right place or OT. One of the Parasoft coding
> guidelines (which I am using for current project) is "Do not cast
> pointers to functions to pointers to primitive types [CODSTA-09-3]"
>
> EXAMPLE(from parasoft document):
> void Foo(char *ptrC)
> {
> *ptrC = 0;
> return;
> }
>
> void f()
> {
> void *ptrV = 0;
> void (*funPtr) (char*) = 0;
> funPtr = &Foo;
> ptrV = (void*)funPtr; // Violation of the rule and raise error
> return;
> }
>
> I can see why it is a bad idea not to write code this way.
> But can any one explain where this kind of code is useful?
> (imo, to be a guideline it must have been used/misused a lot)
> Where casting a function pointer to primitive type makes sense?
Like others, I can't really answer your question except to add that
these sorts of conversion are undefined according to the definition of
C. It's possible, then, that the rule is in your coding guidelines, not
because it's so tempting, but simply because it's a no-so-well-known
rule of the language.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-09-03 08:31 -0400 |
| Message-ID | <k227u5$i0a$1@dont-email.me> |
| In reply to | #25810 |
On 09/03/2012 04:50 AM, ajaybgr wrote:
> Not sure if this is the right place or OT.
> One of the Parasoft coding guidelines (which I am using for current project) is
> "Do not cast pointers to functions to pointers to primitive types [CODSTA-09-3]"
>
> EXAMPLE(from parasoft document):
> void Foo(char *ptrC)
> {
> *ptrC = 0;
> return;
> }
>
> void f()
> {
> void *ptrV = 0;
> void (*funPtr) (char*) = 0;
> funPtr = &Foo;
> ptrV = (void*)funPtr; // Violation of the rule and raise error
> return;
> }
>
> I can see why it is a bad idea not to write code this way.
> But can any one explain where this kind of code is useful?
> (imo, to be a guideline it must have been used/misused a lot)
> Where casting a function pointer to primitive type makes sense?
> Sorry if this is too silly, my mind seems to have hit a wall today.
There are real platforms, in common use, where the behavior of such
code, while not defined by the C standard, is defined by some other
standard, and there's a fair amount of code written for those platforms
which actually relies upon that assumption. This produces the
unjustified but understandable belief that the technique will work
everywhere.
Example: the dlsym() function is specified by the X-open standard to
take a void* argument which can be either a pointer to an object or a
pointer to a function. The Rationale for that function notes;
> ... the ISO C standard does not require that an object of type void * can hold a pointer to a function. Implementations supporting the XSI extension, however, do require that an object of type void * can hold a pointer to a function. The result of converting a pointer to a function into a pointer to another data type (except void *) is still undefined, however. Note that compilers conforming to the ISO C standard are required to generate a warning if a conversion from a void * pointer to a function pointer is attempted ...
> Due to the problem noted here, a future version may either add a new function to return function pointers, or the current interface may be deprecated in favor of two new functions: one that returns data pointers and the other that returns function pointers.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-09-03 13:21 -0700 |
| Message-ID | <lnzk56vov4.fsf@nuthaus.mib.org> |
| In reply to | #25831 |
James Kuyper <jameskuyper@verizon.net> writes:
[...]
> Example: the dlsym() function is specified by the X-open standard to
> take a void* argument which can be either a pointer to an object or a
> pointer to a function. The Rationale for that function notes;
>
[...]
>> Note that compilers conforming to the ISO C standard are required to
>> generate a warning if a conversion from a void * pointer to a
>> function pointer is attempted.
[...]
I don't believe that's correct. The behavior of converting a void*
pointer to a function pointer is not defined, but as far as I can tell
it doesn't violate any constraint.
A concrete example:
int obj;
void *vp = &obj;
void (*fp)(void) = (void (*)(void))vp;
The constraints on a cast operator are described in N1570 6.5.4.
The cast in the above code doesn't violate any of them. (Perhaps
there *should* be such a constraint.)
Or am I missing something?
--
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 | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-09-03 16:57 -0400 |
| Message-ID | <k235j8$q9j$1@dont-email.me> |
| In reply to | #25855 |
On 09/03/2012 04:21 PM, Keith Thompson wrote: > James Kuyper <jameskuyper@verizon.net> writes: > [...] >> Example: the dlsym() function is specified by the X-open standard to >> take a void* argument which can be either a pointer to an object or a >> pointer to a function. The Rationale for that function notes; >> > [...] >>> Note that compilers conforming to the ISO C standard are required to >>> generate a warning if a conversion from a void * pointer to a >>> function pointer is attempted. > [...] > > I don't believe that's correct. The behavior of converting a void* > pointer to a function pointer is not defined, but as far as I can tell > it doesn't violate any constraint. > > A concrete example: > > int obj; > void *vp = &obj; > void (*fp)(void) = (void (*)(void))vp; > > The constraints on a cast operator are described in N1570 6.5.4. > The cast in the above code doesn't violate any of them. (Perhaps > there *should* be such a constraint.) > > Or am I missing something? It's possible that they're referring to implicit conversion, rather than one using a cast. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-09-03 14:48 -0700 |
| Message-ID | <lnpq62vkuk.fsf@nuthaus.mib.org> |
| In reply to | #25856 |
James Kuyper <jameskuyper@verizon.net> writes:
> On 09/03/2012 04:21 PM, Keith Thompson wrote:
>> James Kuyper <jameskuyper@verizon.net> writes:
>> [...]
>>> Example: the dlsym() function is specified by the X-open standard to
>>> take a void* argument which can be either a pointer to an object or a
>>> pointer to a function. The Rationale for that function notes;
>>>
>> [...]
>>>> Note that compilers conforming to the ISO C standard are required to
>>>> generate a warning if a conversion from a void * pointer to a
>>>> function pointer is attempted.
>> [...]
>>
>> I don't believe that's correct. The behavior of converting a void*
>> pointer to a function pointer is not defined, but as far as I can tell
>> it doesn't violate any constraint.
[...]
>
> It's possible that they're referring to implicit conversion, rather than
> one using a cast.
It's possible, but if so they phrased it poorly.
Note that gcc also appears to get this wrong (assuming my interpretation
is correct). With "-std=c11 -pedantic", gcc 4.7 complains:
warning: ISO C forbids conversion of object pointer to function pointer type [-pedantic]
--
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 | pacman@kosh.dhis.org (Alan Curry) |
|---|---|
| Date | 2012-09-03 21:57 +0000 |
| Message-ID | <k2393k$go1$1@speranza.aioe.org> |
| In reply to | #25861 |
In article <lnpq62vkuk.fsf@nuthaus.mib.org>, Keith Thompson <kst-u@mib.org> wrote: >James Kuyper <jameskuyper@verizon.net> writes: >> On 09/03/2012 04:21 PM, Keith Thompson wrote: >>> James Kuyper <jameskuyper@verizon.net> writes: >>> [...] >>>> Example: the dlsym() function is specified by the X-open standard to >>>> take a void* argument which can be either a pointer to an object or a >>>> pointer to a function. The Rationale for that function notes; >>>> >>> [...] >>>>> Note that compilers conforming to the ISO C standard are required to >>>>> generate a warning if a conversion from a void * pointer to a >>>>> function pointer is attempted. >>> [...] >>> >>> I don't believe that's correct. The behavior of converting a void* >>> pointer to a function pointer is not defined, but as far as I can tell >>> it doesn't violate any constraint. >[...] >> >> It's possible that they're referring to implicit conversion, rather than >> one using a cast. > >It's possible, but if so they phrased it poorly. Any idiot should be able to read that and know without being told that using a cast will get rid of the warning. Casts do that. It's obvious. -- Alan Curry
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-09-03 18:11 -0700 |
| Message-ID | <lnharevbgq.fsf@nuthaus.mib.org> |
| In reply to | #25866 |
pacman@kosh.dhis.org (Alan Curry) writes:
> In article <lnpq62vkuk.fsf@nuthaus.mib.org>,
> Keith Thompson <kst-u@mib.org> wrote:
>>James Kuyper <jameskuyper@verizon.net> writes:
>>> On 09/03/2012 04:21 PM, Keith Thompson wrote:
>>>> James Kuyper <jameskuyper@verizon.net> writes:
>>>> [...]
>>>>> Example: the dlsym() function is specified by the X-open standard to
>>>>> take a void* argument which can be either a pointer to an object or a
>>>>> pointer to a function. The Rationale for that function notes;
>>>>>
>>>> [...]
>>>>>> Note that compilers conforming to the ISO C standard are required to
>>>>>> generate a warning if a conversion from a void * pointer to a
>>>>>> function pointer is attempted.
>>>> [...]
>>>>
>>>> I don't believe that's correct. The behavior of converting a void*
>>>> pointer to a function pointer is not defined, but as far as I can tell
>>>> it doesn't violate any constraint.
>>[...]
>>>
>>> It's possible that they're referring to implicit conversion, rather than
>>> one using a cast.
>>
>>It's possible, but if so they phrased it poorly.
>
> Any idiot should be able to read that and know without being told that using
> a cast will get rid of the warning. Casts do that. It's obvious.
Were you aware that we're talking about conversion from void* to
a function pointer, a conversion whose behavior is not defined by
the standard, whether it's done by a cast or not? This is quite
distinct from other pointer-to-pointer conversions, which in most
cases merely yield an implementation-defined result.
I posted a code snippet upthread. Here's a small complete program:
int main(void) {
int obj;
void *vp = &obj;
void (*fp)(void) = (void (*)(void))vp; /* line 4 */
return 0;
}
When I compile this with gcc 4.7, with "-pedantic" and any of
"-std={c90,c99,c11}", I get the following warning:
c.c:4:24: warning: ISO C forbids conversion of object pointer to function pointer type [-pedantic]
I get the same warning with or without the (void (*)(void)) cast.
(Without the cast, it's definitely a constraint violation.)
You might want to reconsider your "Any idiot" statement.
--
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 | pacman@kosh.dhis.org (Alan Curry) |
|---|---|
| Date | 2012-09-04 02:03 +0000 |
| Message-ID | <k23ni1$hmn$1@speranza.aioe.org> |
| In reply to | #25878 |
In article <lnharevbgq.fsf@nuthaus.mib.org>,
Keith Thompson <kst-u@mib.org> wrote:
>pacman@kosh.dhis.org (Alan Curry) writes:
>>
>> Any idiot should be able to read that and know without being told that using
>> a cast will get rid of the warning. Casts do that. It's obvious.
>
[...]
>
>I posted a code snippet upthread. Here's a small complete program:
>
> int main(void) {
> int obj;
> void *vp = &obj;
> void (*fp)(void) = (void (*)(void))vp; /* line 4 */
> return 0;
> }
>
>When I compile this with gcc 4.7, with "-pedantic" and any of
>"-std={c90,c99,c11}", I get the following warning:
>
> c.c:4:24: warning: ISO C forbids conversion of object pointer to
>function pointer type [-pedantic]
>
>I get the same warning with or without the (void (*)(void)) cast.
>(Without the cast, it's definitely a constraint violation.)
>
>You might want to reconsider your "Any idiot" statement.
I reassert "idiot" in the direction of gcc then. Casts should be silent.
--
Alan Curry
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-09-03 19:20 -0700 |
| Message-ID | <lntxvettoe.fsf@nuthaus.mib.org> |
| In reply to | #25885 |
pacman@kosh.dhis.org (Alan Curry) writes:
> In article <lnharevbgq.fsf@nuthaus.mib.org>,
> Keith Thompson <kst-u@mib.org> wrote:
>>pacman@kosh.dhis.org (Alan Curry) writes:
>>>
>>> Any idiot should be able to read that and know without being told that using
>>> a cast will get rid of the warning. Casts do that. It's obvious.
>>
> [...]
>>
>>I posted a code snippet upthread. Here's a small complete program:
>>
>> int main(void) {
>> int obj;
>> void *vp = &obj;
>> void (*fp)(void) = (void (*)(void))vp; /* line 4 */
>> return 0;
>> }
>>
>>When I compile this with gcc 4.7, with "-pedantic" and any of
>>"-std={c90,c99,c11}", I get the following warning:
>>
>> c.c:4:24: warning: ISO C forbids conversion of object pointer to
>>function pointer type [-pedantic]
>>
>>I get the same warning with or without the (void (*)(void)) cast.
>>(Without the cast, it's definitely a constraint violation.)
>>
>>You might want to reconsider your "Any idiot" statement.
>
> I reassert "idiot" in the direction of gcc then. Casts should be silent.
So you don't want to distinguish between casts whose behavior
is well defined, those whose behavior is implementation-defined,
and those whose behavior is completely undefined?
I can understand that opinion, but it hardly seems reasonable to
call those who disagrees with it idiots.
Casts are commonly interpreted to mean "Shut up, compiler, I know
what I'm doing"-- but the standard doesn't say or imply that.
How do you feel about casts applied to struct types, which are a
constraint violation?
--
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 | pacman@kosh.dhis.org (Alan Curry) |
|---|---|
| Date | 2012-09-04 20:27 +0000 |
| Message-ID | <k25o72$imk$1@speranza.aioe.org> |
| In reply to | #25886 |
In article <lntxvettoe.fsf@nuthaus.mib.org>, Keith Thompson <kst-u@mib.org> wrote: > >So you don't want to distinguish between casts whose behavior >is well defined, those whose behavior is implementation-defined, >and those whose behavior is completely undefined? > >I can understand that opinion, but it hardly seems reasonable to >call those who disagrees with it idiots. > >Casts are commonly interpreted to mean "Shut up, compiler, I know >what I'm doing"-- but the standard doesn't say or imply that. > >How do you feel about casts applied to struct types, which are a >constraint violation? Those are errors, not warnings. You can't cast away an error. Failure to distinguish errors and warnings is a problem that only The Standard has. In the real world everybody knows they're different. -- Alan Curry
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-09-04 17:10 -0400 |
| Message-ID | <50466E3A.2000303@verizon.net> |
| In reply to | #25910 |
On 09/04/2012 04:27 PM, Alan Curry wrote: > In article <lntxvettoe.fsf@nuthaus.mib.org>, > Keith Thompson <kst-u@mib.org> wrote: >> >> So you don't want to distinguish between casts whose behavior >> is well defined, those whose behavior is implementation-defined, >> and those whose behavior is completely undefined? >> >> I can understand that opinion, but it hardly seems reasonable to >> call those who disagrees with it idiots. >> >> Casts are commonly interpreted to mean "Shut up, compiler, I know >> what I'm doing"-- but the standard doesn't say or imply that. >> >> How do you feel about casts applied to struct types, which are a >> constraint violation? > > Those are errors, not warnings. You can't cast away an error. > > Failure to distinguish errors and warnings is a problem that only The > Standard has. In the real world everybody knows they're different. The standard cannot distinguish between error messages and warning messages, because whether or not something constitutes an error is highly dependent on factors outside the scope of the standard. The code in question has undefined behavior, the worst thing that the standard can say about any code construct. However, the X/Open standard does define the behavior (a fact which is outside the scope of the C standard). A programmer who decides to write code which relies upon that definition, believing that it will only ever need to be run on systems that conform to the X/Open standard (something else that is also outside the scope of the C standard) is NOT making an error (unless that belief is incorrect). The standard leaves the distinction between errors and warnings up to the implementations. Were you rewriting the C standard to remove that freedom, how would you make that distinction in such a way as to apply to cases like this? It seems to me that a mind-reading compiler with the capacity to make better judgements than the developer about the reasonability of such beliefs is needed, in order to make that distinction.
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2012-09-04 14:14 -0700 |
| Message-ID | <ehrc48p96lkbsreqd39j2q357ru4bss6jc@4ax.com> |
| In reply to | #25910 |
On Tue, 4 Sep 2012 20:27:14 +0000 (UTC), pacman@kosh.dhis.org (Alan
Curry) wrote:
>In article <lntxvettoe.fsf@nuthaus.mib.org>,
>Keith Thompson <kst-u@mib.org> wrote:
>>
>>So you don't want to distinguish between casts whose behavior
>>is well defined, those whose behavior is implementation-defined,
>>and those whose behavior is completely undefined?
>>
>>I can understand that opinion, but it hardly seems reasonable to
>>call those who disagrees with it idiots.
>>
>>Casts are commonly interpreted to mean "Shut up, compiler, I know
>>what I'm doing"-- but the standard doesn't say or imply that.
>>
>>How do you feel about casts applied to struct types, which are a
>>constraint violation?
>
>Those are errors, not warnings. You can't cast away an error.
Of course you can. Consider
int * x = NULL;
float *y = x;
This is an error. Adding the appropriate cast to the last expression
eliminates the error.
>
>Failure to distinguish errors and warnings is a problem that only The
>Standard has. In the real world everybody knows they're different.
Yes, but not everyone agrees on which side of the line a particular
situation falls, or even if the situation always falls on the same
side of the line.
--
Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | pete <pfiland@mindspring.com> |
|---|---|
| Date | 2012-09-03 22:51 -0400 |
| Message-ID | <50456CC9.2150@mindspring.com> |
| In reply to | #25861 |
Keith Thompson wrote:
>
> James Kuyper <jameskuyper@verizon.net> writes:
> > On 09/03/2012 04:21 PM, Keith Thompson wrote:
> >> James Kuyper <jameskuyper@verizon.net> writes:
> >> [...]
> >>> Example: the dlsym() function is specified by the X-open standard to
> >>> take a void* argument which can be either a pointer to an object or a
> >>> pointer to a function. The Rationale for that function notes;
> >>>
> >> [...]
> >>>> Note that compilers conforming to the ISO C standard are required to
> >>>> generate a warning if a conversion from a void * pointer to a
> >>>> function pointer is attempted.
> >> [...]
> >>
> >> I don't believe that's correct. The behavior of converting a void*
> >> pointer to a function pointer is not defined, but as far as I can tell
> >> it doesn't violate any constraint.
> [...]
> >
> > It's possible that they're referring to implicit conversion, rather than
> > one using a cast.
>
> It's possible, but if so they phrased it poorly.
>
> Note that gcc also appears to get this wrong (assuming my interpretation
> is correct). With "-std=c11 -pedantic", gcc 4.7 complains:
>
> warning: ISO C forbids conversion of object pointer to function pointer type [-pedantic]
This expression is defined,
if it occurs where main is in scope:
((void *)0 != main)
N1570
6.3.2.3 Pointers
3
If a null pointer constant
is converted to a pointer type,
the resulting pointer, called a null pointer,
is guaranteed to compare unequal
to a pointer to any object or function.
6.5.9 Equality operators
Semantics
5
If one operand is a pointer
and the other is a null pointer constant,
the null pointer constant
is converted to the type of the pointer.
--
pete
[toc] | [prev] | [next] | [standalone]
| From | Vincenzo Mercuri <vincenzo.mercuri@yahoo.it> |
|---|---|
| Date | 2012-09-04 00:02 +0200 |
| Message-ID | <%N91s.204532$GZ3.83537@tornado.fastwebnet.it> |
| In reply to | #25855 |
On 03/09/2012 22:21, Keith Thompson wrote: [..] > A concrete example: > > int obj; > void *vp = &obj; > void (*fp)(void) = (void (*)(void))vp; > > The constraints on a cast operator are described in N1570 6.5.4. > The cast in the above code doesn't violate any of them. (Perhaps > there*should* be such a constraint.) > > Or am I missing something? My understanding is that there is not such a constraint to allow such casts as a "common extension", N1570 J.5.7: A pointer to an object or to void may be cast to a pointer to a function, allowing data to be invoked as a function (6.5.4). A pointer to a function may be cast to a pointer to an object or to void, allowing a function to be inspected or modified (for example, by a debugger) (6.5.4). If that cast violated a constraint any implementation with such extension would be nonconforming. I only see a warning with gcc however when `-pedantic' is enabled. -- Vincenzo Mercuri
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-09-03 18:19 -0700 |
| Message-ID | <lnd322vb2p.fsf@nuthaus.mib.org> |
| In reply to | #25867 |
Vincenzo Mercuri <vincenzo.mercuri@yahoo.it> writes:
> On 03/09/2012 22:21, Keith Thompson wrote:
> [..]
>> A concrete example:
>>
>> int obj;
>> void *vp = &obj;
>> void (*fp)(void) = (void (*)(void))vp;
>>
>> The constraints on a cast operator are described in N1570 6.5.4.
>> The cast in the above code doesn't violate any of them. (Perhaps
>> there*should* be such a constraint.)
>>
>> Or am I missing something?
>
> My understanding is that there is not such a constraint to allow
> such casts as a "common extension", N1570 J.5.7:
>
> A pointer to an object or to void may be cast to a pointer
> to a function, allowing data to be invoked as a function (6.5.4).
>
> A pointer to a function may be cast to a pointer to an object or to
> void, allowing a function to be inspected or modified (for example,
> by a debugger) (6.5.4).
>
> If that cast violated a constraint any implementation with such
> extension would be nonconforming. I only see a warning with gcc
> however when `-pedantic' is enabled.
It's not necessary to omit a constraint to allow an extension like
this. Many extensions give meaning to code that would otherwise
violate a constraint or syntax rule. The compiler has to issue
a diagnostic (which can be a non-fatal warning) if it's invoked
in conforming mode; once it's issued the warning, it's free to do
whatever the extension specifies. And/or the compiler can have a
non-conforming mode that implements the extension without complaint.
An example: gcc permits arithmetic on void* pointers as an extension.
Any such arithmetic is a constraint violation.
Looking through the list of common extensions in J.5, some of
them can break strictly conforming programs, which violates 4p6.
Predefined macro names not starting with an underscore are one
example.
--
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 | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2012-09-04 01:18 +0000 |
| Message-ID | <20120903180738.297@kylheku.com> |
| In reply to | #25810 |
On 2012-09-03, ajaybgr <ajay.bgr@gmail.com> wrote: > Not sure if this is the right place or OT. > One of the Parasoft coding guidelines (which I am using for current project) is > "Do not cast pointers to functions to pointers to primitive types [CODSTA-09-3]" [ snip ] > I can see why it is a bad idea not to write code this way. > But can any one explain where this kind of code is useful? Such code is found in the implementation of shared libraries. For instance, the dlsym function on POSIX returns void *, and this function is used whether you're looking up a function or some other kind of symbol. There is nothing wrong with doing this, except that it's not "maximally portable". For instance, here is one potential problem: what if function pointers are 48 bits wide and object pointers 32 bits wide. If you're sure that portability isn't an issue, then it may be the best way to solve the kind of problem that it solves, because doing it portably (e.g. with unions to store two kinds of pointers in the same space) may add some clutter to the program. > (imo, to be a guideline it must have been used/misused a lot) > Where casting a function pointer to primitive type makes sense? Where you're going to cast it back to a function pointer type later. Say you have a linked list which stores "void *" items and you want to put function pointers in it.
[toc] | [prev] | [next] | [standalone]
| From | "Scott Fluhrer" <sfluhrer@ix.netcom.com> |
|---|---|
| Date | 2012-09-04 11:59 -0400 |
| Message-ID | <1346774432.563437@rcdn-nntpcache-3> |
| In reply to | #25880 |
"Kaz Kylheku" <kaz@kylheku.com> wrote in message
news:20120903180738.297@kylheku.com...
> On 2012-09-03, ajaybgr <ajay.bgr@gmail.com> wrote:
>> Not sure if this is the right place or OT.
>> One of the Parasoft coding guidelines (which I am using for current
>> project) is
>> "Do not cast pointers to functions to pointers to primitive types
>> [CODSTA-09-3]"
>
> [ snip ]
>
>> I can see why it is a bad idea not to write code this way.
>> But can any one explain where this kind of code is useful?
>
> Such code is found in the implementation of shared libraries.
>
> For instance, the dlsym function on POSIX returns void *,
> and this function is used whether you're looking up a function or some
> other
> kind of symbol.
>
> There is nothing wrong with doing this, except that it's not "maximally
> portable".
>
> For instance, here is one potential problem: what if function pointers are
> 48
> bits wide and object pointers 32 bits wide.
>
> If you're sure that portability isn't an issue, then it may be the best
> way to
> solve the kind of problem that it solves, because doing it portably (e.g.
> with
> unions to store two kinds of pointers in the same space) may add some
> clutter
> to the program.
>
>> (imo, to be a guideline it must have been used/misused a lot)
>> Where casting a function pointer to primitive type makes sense?
>
> Where you're going to cast it back to a function pointer type later.
>
> Say you have a linked list which stores "void *" items and you want to
> put function pointers in it.
Actually, if you are in such a circumstance (where you need to store a
function pointer, and some infrastructure only gives you a void * to store
it in), there is a totally portable way to handle it. Instead of attempting
to store the function pointer into the void * type, store a pointer to a
pointer to the function instead, For example:
typedef void (*function)(int, double, char *);
void my_function(int a, double b, char *c);
function *p_my_function = &my_function; /* p_my_function is a pointer to a
'primitive type', specifically, a function pointer type */
struct linked_list {
void *data;
}
/* Functions which uses the linked_list type */
struct linked_list *p;
p->data = p_my_function; /* Completely portable, because we can assign a
data pointer to a void * type */
...
function *func = p->data; /* Again, completely portable; the pointer func
is a data pointer */
(*func)( 7, 3.14159, "Hi ma!" );
--
poncho
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web