Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   incompatible pointer assignment (http://www.velocityreviews.com/forums/t955309-incompatible-pointer-assignment.html)

Prathamesh Kulkarni 12-10-2012 11:16 AM

incompatible pointer assignment
 
#include <stdio.h>

int
main(void)
{
char *p;
float a = 1.2;

p = &a;
printf("%p\n", p);
return 0;
}

when I compile this code with
gcc -std=c11, I get
warning: assignment from incompatible
pointer type [enabled by default]

I am not able to understand why.
From n1570 6.3.2.3 7th point (page 74):
When a pointer to an object is converted
to a pointer to a character type,the result
points to the lowest addressed byte of the
object.Successive increments of the result,
up to the size of the object, yield pointers
to the remaining bytes of the object

So I guess, that conversion of float * to char *
is defined in n1570 or am I interpreting the
standard incorrectly ?

I know that the above code is incorrect
in C99. From c99 rationale v5.10 6.3.2.3 (page 49):
It is invalid to convert a pointer to
an object of any type to a pointer
to an object of a different type without an
explicit cast.
So it would be invalid to assign &a to p without
casting &a to char *.

Ben Bacarisse 12-10-2012 12:40 PM

Re: incompatible pointer assignment
 
Prathamesh Kulkarni <bilbotheelffriend@gmail.com> writes:

> #include <stdio.h>
>
> int
> main(void)
> {
> char *p;
> float a = 1.2;
>
> p = &a;
> printf("%p\n", p);
> return 0;
> }
>
> when I compile this code with
> gcc -std=c11, I get
> warning: assignment from incompatible
> pointer type [enabled by default]
>
> I am not able to understand why.
> From n1570 6.3.2.3 7th point (page 74):
> When a pointer to an object is converted
> to a pointer to a character type,the result
> points to the lowest addressed byte of the
> object.Successive increments of the result,
> up to the size of the object, yield pointers
> to the remaining bytes of the object
>
> So I guess, that conversion of float * to char *
> is defined in n1570 or am I interpreting the
> standard incorrectly ?


Not quote. The part you quote defines the conversion but not how it
happens. The rules for assignment will tell you that the pointer types
must be (almost) compatible (you can have some differing qualifiers) so
a compiler must issue a diagnostic. As you say below, the conversion
*is* defined, but you must ask for it:

p = (char *)&a;

> I know that the above code is incorrect
> in C99. From c99 rationale v5.10 6.3.2.3 (page 49):
> It is invalid to convert a pointer to
> an object of any type to a pointer
> to an object of a different type without an
> explicit cast.
> So it would be invalid to assign &a to p without
> casting &a to char *.


Exactly. The conversion is defined but it does not happen
automatically.

--
Ben.

Bart van Ingen Schenau 12-10-2012 12:53 PM

Re: incompatible pointer assignment
 
On Mon, 10 Dec 2012 03:16:05 -0800, Prathamesh Kulkarni wrote:

> #include <stdio.h>
>
> int
> main(void)
> {
> char *p;
> float a = 1.2;
>
> p = &a;
> printf("%p\n", p);
> return 0;
> }
>
> when I compile this code with
> gcc -std=c11, I get
> warning: assignment from incompatible pointer type [enabled by default]
>
> I am not able to understand why.
> From n1570 6.3.2.3 7th point (page 74): When a pointer to an object is
> converted to a pointer to a character type,the result points to the
> lowest addressed byte of the object.Successive increments of the result,
> up to the size of the object, yield pointers to the remaining bytes of
> the object
>
> So I guess, that conversion of float * to char * is defined in n1570 or
> am I interpreting the standard incorrectly ?


You are interpreting the standard incorrectly (or rather, incompletely).
Clause 6.3 governs the results of both implicit and explicit conversions
(the latter are better known as type-casts), but it does not state which
of the conversions can be performed implicitly and which must be done
explicitly.

If you look in clause 6.5.4 (Cast operators), you will find the following
under the header 'constraints':
<quote>
3 Conversions that involve pointers, other than where permitted by the
constraints of 6.5.16.1, shall be specified by means of an explicit cast.
</quote>
Section 6.5.16.1 does not list the conversion to char* as being permitted
without a cast, so your program needs a cast to perform the conversion.

>
> I know that the above code is incorrect in C99. From c99 rationale v5.10
> 6.3.2.3 (page 49): It is invalid to convert a pointer to an object of
> any type to a pointer
> to an object of a different type without an explicit cast.
> So it would be invalid to assign &a to p without casting &a to char *.


Actually, there are no significant changes between C99 and C11 in this
area. At most some cleaning up of terminology.

Bart v Ingen Schenau

Prathamesh Kulkarni 12-10-2012 01:24 PM

Re: incompatible pointer assignment
 
consider,
char *p; float a;
p = (char *) &a;

So n1570 6.3.2.3 7th point
states what address p would point to
after the assignment p = (char *) &a ?
I am sorry for asking dumb questions,
have never looked through the standard
before.


Eric Sosman 12-10-2012 02:02 PM

Re: incompatible pointer assignment
 
On 12/10/2012 8:24 AM, Prathamesh Kulkarni wrote:
> consider,
> char *p; float a;
> p = (char *) &a;
>
> So n1570 6.3.2.3 7th point
> states what address p would point to
> after the assignment p = (char *) &a ?


Yes: `p' will point at "the lowest addressed byte" of `a'.
The bytes that make up the representation of `a' are `p[0]',
`p[1]',...,`p[sizeof(float)-1]'.

Deciding what each of those bytes means is trickier. Each
implementation defines its own representations for the various
C data types, and they don't all use the same encoding. If you
set `a = 3.14f;' and then print `*p' on different machines, you
may well get different outputs.

> I am sorry for asking dumb questions,
> have never looked through the standard
> before.


A question isn't dumb until it's asked twice. :-)

--
Eric Sosman
esosman@comcast-dot-net.invalid

James Kuyper 12-10-2012 02:04 PM

Re: incompatible pointer assignment
 
On 12/10/2012 08:24 AM, Prathamesh Kulkarni wrote:
> consider,
> char *p; float a;
> p = (char *) &a;
>
> So n1570 6.3.2.3 7th point
> states what address p would point to
> after the assignment p = (char *) &a ?


Yes.

> I am sorry for asking dumb questions,
> have never looked through the standard
> before.


There's an old saying "there's no such thing as a dumb question", but
I've seen counterexamples in this very newsgroup. Your question isn't
one of those counterexamples.

One of the most common kinds of dumb questions posted here is the kind
that says "what's wrong with my program?" without containing any of the
code from the program. I can understand people giving us an irrelevant
piece of code, if they're sufficiently confused about what would be
relevant. What I don't understand is how the people who provide no code
at all expect us to diagnose the problem (it can be done, in rare cases,
but expecting it to be possible isn't reasonable).
--
James Kuyper

Keith Thompson 12-10-2012 03:36 PM

Re: incompatible pointer assignment
 
Bart van Ingen Schenau <bart@ingen.ddns.info.invalid> writes:
[...]
> You are interpreting the standard incorrectly (or rather, incompletely).
> Clause 6.3 governs the results of both implicit and explicit conversions
> (the latter are better known as type-casts), but it does not state which
> of the conversions can be performed implicitly and which must be done
> explicitly.

[...]

And "type-casts" are better known as "casts".

--
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"

Keith Thompson 12-10-2012 03:38 PM

Re: incompatible pointer assignment
 
Eric Sosman <esosman@comcast-dot-net.invalid> writes:
> On 12/10/2012 8:24 AM, Prathamesh Kulkarni wrote:
>> consider,
>> char *p; float a;
>> p = (char *) &a;
>>
>> So n1570 6.3.2.3 7th point
>> states what address p would point to
>> after the assignment p = (char *) &a ?

>
> Yes: `p' will point at "the lowest addressed byte" of `a'.
> The bytes that make up the representation of `a' are `p[0]',
> `p[1]',...,`p[sizeof(float)-1]'.
>
> Deciding what each of those bytes means is trickier. Each
> implementation defines its own representations for the various
> C data types, and they don't all use the same encoding. If you
> set `a = 3.14f;' and then print `*p' on different machines, you
> may well get different outputs.


And if you want to examine the bytes that make up the representation of
some object, it's better to use unsigned char rather than plain char.
(Plain char may be either signed or unsigned, depending on the
implementation.)

[...]

--
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"


All times are GMT. The time now is 12:49 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.