Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #25810 > unrolled thread

Do not cast pointers to functions to pointers to primitive types

Started byajaybgr <ajay.bgr@gmail.com>
First post2012-09-03 01:50 -0700
Last post2012-09-06 21:34 -0700
Articles 20 on this page of 21 — 13 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#25810 — Do not cast pointers to functions to pointers to primitive types

Fromajaybgr <ajay.bgr@gmail.com>
Date2012-09-03 01:50 -0700
SubjectDo 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]


#25811

FromIan Collins <ian-news@hotmail.com>
Date2012-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]


#25813

FromNick Keighley <nick_keighley_nospam@hotmail.com>
Date2012-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]


#25817

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-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]


#25831

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-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]


#25855

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#25856

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-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]


#25861

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#25866

Frompacman@kosh.dhis.org (Alan Curry)
Date2012-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]


#25878

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#25885

Frompacman@kosh.dhis.org (Alan Curry)
Date2012-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]


#25886

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#25910

Frompacman@kosh.dhis.org (Alan Curry)
Date2012-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]


#25913

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-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]


#25915

FromBarry Schwarz <schwarzb@dqel.com>
Date2012-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]


#25887

Frompete <pfiland@mindspring.com>
Date2012-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]


#25867

FromVincenzo Mercuri <vincenzo.mercuri@yahoo.it>
Date2012-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]


#25881

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#25880

FromKaz Kylheku <kaz@kylheku.com>
Date2012-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]


#25896

From"Scott Fluhrer" <sfluhrer@ix.netcom.com>
Date2012-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