incompatible pointer assignment

  • Thread starter Prathamesh Kulkarni
  • Start date
P

Prathamesh Kulkarni

#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 *.
 
B

Ben Bacarisse

Prathamesh Kulkarni said:
#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.
 
B

Bart van Ingen Schenau

#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
 
P

Prathamesh Kulkarni

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.
 
E

Eric Sosman

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. :)
 
J

James Kuyper

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).
 
K

Keith Thompson

Bart van Ingen Schenau said:
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".
 
K

Keith Thompson

Eric Sosman said:
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.)

[...]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top