Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > help on type compatibility?

Reply
Thread Tools

help on type compatibility?

 
 
Ark
Guest
Posts: n/a
 
      02-24-2006
Hello NG,

My Lint and my compiler disagree on whether this is valid code:

typedef int test_t(char *);
typedef int contest_t(const char *);
extern contest_t somefunction;
test_t *mypointer = somefunction;

I think the assignment is clean in what it does, but who cares? - What's
the verdict of the standard? (Both C90 and C99 resolutions are greatly
appreciated.)

Thank you,
- Ark
 
Reply With Quote
 
 
 
 
aegis
Guest
Posts: n/a
 
      02-24-2006

Ark wrote:
> Hello NG,
>
> My Lint and my compiler disagree on whether this is valid code:
>
> typedef int test_t(char *);
> typedef int contest_t(const char *);
> extern contest_t somefunction;
> test_t *mypointer = somefunction;
>
> I think the assignment is clean in what it does, but who cares? - What's
> the verdict of the standard? (Both C90 and C99 resolutions are greatly
> appreciated.)


Part of one of the clauses of 3.5.4.3 states:
[1] "For two function types to be compatible, both
shall specify compatible return types. Moreover,
the parameter type lists, if both are present, shall
agree in the number of parameters and in use of
the ellipsis terminator; corresponding parameters
shall have compatible types."

So we need to ascertain whether or not their parameters
have compatible type:

'Is char * compatible with const char *?'

3.5.4.1 from one of its clauses, states:

"For two pointer types to be compatible, both
shall be identically qualified and both shall
be pointers to compatible types."

So their compatibility is predicated upon
whether or not they
1) point to compatible types
2) share the same qualifications

2 does not hold here, and therefore the
types are not compatible. The implication
is then that [1] does not hold.

--
aegis

 
Reply With Quote
 
 
 
 
Ark
Guest
Posts: n/a
 
      02-24-2006
aegis wrote:
> Ark wrote:
>
>>Hello NG,
>>
>>My Lint and my compiler disagree on whether this is valid code:
>>
>>typedef int test_t(char *);
>>typedef int contest_t(const char *);
>>extern contest_t somefunction;
>>test_t *mypointer = somefunction;
>>
>>I think the assignment is clean in what it does, but who cares? - What's
>>the verdict of the standard? (Both C90 and C99 resolutions are greatly
>>appreciated.)

>
>
> Part of one of the clauses of 3.5.4.3 states:
> [1] "For two function types to be compatible, both
> shall specify compatible return types. Moreover,
> the parameter type lists, if both are present, shall
> agree in the number of parameters and in use of
> the ellipsis terminator; corresponding parameters
> shall have compatible types."
>
> So we need to ascertain whether or not their parameters
> have compatible type:
>
> 'Is char * compatible with const char *?'
>
> 3.5.4.1 from one of its clauses, states:
>
> "For two pointer types to be compatible, both
> shall be identically qualified and both shall
> be pointers to compatible types."
>
> So their compatibility is predicated upon
> whether or not they
> 1) point to compatible types
> 2) share the same qualifications
>
> 2 does not hold here, and therefore the
> types are not compatible. The implication
> is then that [1] does not hold.
>
> --
> aegis
>

Thank you, aegis.
But...
Is it indeed that char * is not compatible with const char * ?
char * is unqualified pointer to char; const char * is unqualified
pointer to const char. So the question reduces to whether char is
compatible with const char, and I think it is... After all, we routinely
write
char c;
const char cc;
char *p;
const char *cp;
..............
c = cc;
cp = p;
I beg for further clarification...
Thank you,
Ark
 
Reply With Quote
 
Robin Haigh
Guest
Posts: n/a
 
      02-24-2006

"Ark" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hello NG,
>
> My Lint and my compiler disagree on whether this is valid code:
>
> typedef int test_t(char *);
> typedef int contest_t(const char *);
> extern contest_t somefunction;
> test_t *mypointer = somefunction;
>
> I think the assignment is clean in what it does, but who cares? - What's
> the verdict of the standard? (Both C90 and C99 resolutions are greatly
> appreciated.)


The assignment is legal because it's portable to convert a function pointer
to a different function pointer type and back again. (This can avoid the
need to use unions of function pointer types, which would be pointlessly
clumsy.)

But it's well worth a warning at this point, because no warning can be given
later if you then call the function through the pointer of the wrong type,
and that would produce undefined behaviour.

The problem is that the caller and the callee must agree implicitly on all
the details of how the function call is actually set up. The compiler makes
its own rules about that, and it's allowed to refer to the types of the
arguments, including qualifiers, if there's a prototype. So calling through
the wrong prototype can produce a mismatch in the calling sequence.

In this case it's likely that the undefined behaviour produced is to do the
right thing on all implementations, unless somebody knows different...

--
RSH



 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      02-24-2006
Ark wrote:

> char * is unqualified pointer to char; const char * is unqualified
> pointer to const char.


No.

N869
6.2.5 Types
[#26]
Each
unqualified type has several qualified versions of its
type, corresponding to the combinations of one, two, or
all three of the const, volatile, and restrict qualifiers.

--
pete
 
Reply With Quote
 
mark
Guest
Posts: n/a
 
      02-24-2006
pete wrote:
> Ark wrote:
>
> > char * is unqualified pointer to char; const char * is unqualified
> > pointer to const char.

>
> No.


Yes.

 
Reply With Quote
 
Chris Torek
Guest
Posts: n/a
 
      02-24-2006
In article <(E-Mail Removed)>
Ark <(E-Mail Removed)> wrote:
>Is it indeed that char * is not compatible with const char *?


Yes, it is indeed not compatible.

>[yet] we routinely write
>char *p;
>const char *cp;
>.............
>cp = p;
>I beg for further clarification...


There is a special rule for assignment (including the implied
assignment from prototyped function calls) that relaxes the
constraints, so that you can do "cp = p", but not "p = cp".

This special rule does *not* apply to other cases, so:

char **pp;
...
pp = &cp;

requires a diagnostic.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
 
Reply With Quote
 
Chris Torek
Guest
Posts: n/a
 
      02-24-2006
>"Ark" <(E-Mail Removed)> wrote in message
>news:(E-Mail Removed)...
>> My Lint and my compiler disagree on whether this is valid code:
>>
>> typedef int test_t(char *);
>> typedef int contest_t(const char *);
>> extern contest_t somefunction;
>> test_t *mypointer = somefunction;


In article <dtmhjq$1fs$(E-Mail Removed)>
Robin Haigh <(E-Mail Removed)> wrote:
>The assignment is legal because ...


The assignment requires a diagnostic. GCC (some versions anyway)
just gets this wrong.

I think you are thinking of the version with casts:

test_t *mypointer = (test_t *)somefunction;

which does not require a diagnostic.

>The problem is that the caller and the callee must agree implicitly on all
>the details of how the function call is actually set up.


This, however, is correct.

The Standard has some wording that implies (or perhaps even "requires"
if you believe the footnotes, but the footnotes are "non-normative",
meaning an Evil Implementor can violate them without breaking the
rules) ... er, where was I? Oh yes: qualified and unqualified
variants of types are *supposed* to have the same underlying
representations, so one might simply assume that test_t and contest_t
are effectively interchangeable, and get away with it. It is quite
unlikely to break. Still, it is best not to skate on the thin ice.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      02-24-2006
mark wrote:
>
> pete wrote:
> > Ark wrote:
> >
> > > char * is unqualified pointer to char; const char * is unqualified
> > > pointer to const char.

> >
> > No.

>
> Yes.


Idiot.

> > N869
> > 6.2.5 Types
> > [#26]
> > Each
> > unqualified type has several qualified versions of its
> > type, corresponding to the combinations of one, two, or
> > all three of the const, volatile, and restrict qualifiers.


--
pete
 
Reply With Quote
 
Jordan Abel
Guest
Posts: n/a
 
      02-24-2006
On 2006-02-24, Chris Torek <(E-Mail Removed)> wrote:
>>"Ark" <(E-Mail Removed)> wrote in message
>>news:(E-Mail Removed)...
>>> My Lint and my compiler disagree on whether this is valid code:
>>>
>>> typedef int test_t(char *);
>>> typedef int contest_t(const char *);
>>> extern contest_t somefunction;
>>> test_t *mypointer = somefunction;

>
> In article <dtmhjq$1fs$(E-Mail Removed)>
> Robin Haigh <(E-Mail Removed)> wrote:
>>The assignment is legal because ...

>
> The assignment requires a diagnostic. GCC (some versions anyway)
> just gets this wrong.
>
> I think you are thinking of the version with casts:
>
> test_t *mypointer = (test_t *)somefunction;
>
> which does not require a diagnostic.
>
>>The problem is that the caller and the callee must agree implicitly on all
>>the details of how the function call is actually set up.

>
> This, however, is correct.
>
> The Standard has some wording that implies (or perhaps even "requires"
> if you believe the footnotes, but the footnotes are "non-normative",
> meaning an Evil Implementor can violate them without breaking the
> rules)


Even if the footnote is prescribing an interpretation of normative text,
rather than providing new rules?

> ... er, where was I? Oh yes: qualified and unqualified variants of
> types are *supposed* to have the same underlying representations, so
> one might simply assume that test_t and contest_t are effectively
> interchangeable, and get away with it. It is quite unlikely to break.
> Still, it is best not to skate on the thin ice.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
type(d) != type(d.copy()) when type(d).issubclass(dict) kj Python 5 12-26-2010 06:48 PM
#define ALLOCIT(Type) ((Type*) malloc (sizeof (Type))) Yevgen Muntyan C Programming 10 02-13-2007 02:52 AM
Help: Unable to cast object of type 'System.Int32' to type 'System.String'. keithb ASP .Net 3 05-07-2006 08:06 AM
Re: Type casting- a larger type to a smaller type pete C Programming 4 04-02-2004 05:19 PM
Re: Type casting- a larger type to a smaller type heyo C Programming 3 04-01-2004 06:35 PM



Advertisments