pointer assignment

S

somenath

Hi All,
I have couple of question regarding pointer assignment. I am trying to
understand pointer assignment from signed type to unsigned vice versa.
For that I wrote the bellow mentioned code.

Code 1)

#include <stdio.h>
int main(void)
{
unsigned int test = 5;
unsigned int *uintP=&test;
signed int *sintP =NULL;
sintP = uintP;

return 0;


}
While I was compiling my compiler throws the bellow mentioned warning

src\hello.c", line 7: warning #513-D: a value of type "unsigned int *"
cannot
be assigned to an entity of type "signed int *"
sintP = uintP;
^

"src\hello.c", line 6: warning #550-D: variable "sintP" was set but
never used
signed int *sintP =NULL;

When I change the code as mentioned bellow I get the same type of
warning

Code 2)
#include <stdio.h>
int main(void)
{
unsigned int test = 5;
unsigned int *uintP=&test;
signed int *sintP =NULL;
uintP = sintP;

return 0;


}

"src\hello.c", line 7: warning #513-D: a value of type "signed int *"
cannot
be assigned to an entity of type "unsigned int *"
uintP = sintP;
^

"src\hello.c", line 5: warning #550-D: variable "uintP" was set but
never used
unsigned int *uintP=&test;
^

And if I use cast then compiler does not throw warning for the
pointer assignment
Code 3)

#include <stdio.h>
int main(void)
{
unsigned int test = 5;
unsigned int *uintP=&test;
signed int *sintP =NULL;
sintP = (signed int *)uintP;

return 0;


}

Building C:\Documents and Settings\somanath\My Documents\My Projects
\Project6\default.gpj
Compiling hello.c because hello.o does not exist

"src\hello.c", line 6: warning #550-D: variable "sintP" was set but
never used
signed int *sintP =NULL;
^

My questions are
1) Is not legal to assign pointer to unsigned type to pointer to
signed type? As the pointer size is same.
2) If I use cast for the above example will it work properly always?

Regards,
Somenath
 
R

Richard Heathfield

somenath said:

My questions are
1) Is not legal to assign pointer to unsigned type to pointer to
signed type? As the pointer size is same.

The C Standard offers no guarantee that the size of a pointer to a
signed type has the same size as a pointer to an unsigned type
(although in practice it's unlikely to differ, as I'm sure you
realise). And no, it's not legal, since the pointer types are not
compatible.
2) If I use cast for the above example will it work properly always?

No, the cast doesn't mean "work like I want you to" - its meaning is far
closer to "I know what I'm doing, compiler, so stop nagging me"
(although it does actually have a genuine use on occasion). Since it is
evident that you don't know what you're doing[1], the cast is a
mistake.

Casts are almost always mistakes. They hide bugs without removing them.


[1] Forgive me - I'm not trying to be unpleasant here, merely accurate.
In this case, it is obvious that you don't know what you're doing
*****in this specific situation***** or you wouldn't be asking the
question!
 
K

karthikbalaguru

Hi All,
I have couple of question regarding pointer assignment. I am trying to
understand pointer assignment from signed type to unsigned vice versa.
For that I wrote the bellow mentioned code.

Code 1)

#include <stdio.h>
int main(void)
{
unsigned int test = 5;
unsigned int *uintP=&test;
signed int *sintP =NULL;
sintP = uintP;

return 0;

}

While I was compiling my compiler throws the bellow mentioned warning

src\hello.c", line 7: warning #513-D: a value of type "unsigned int *"
cannot
be assigned to an entity of type "signed int *"
sintP = uintP;
^

"src\hello.c", line 6: warning #550-D: variable "sintP" was set but
never used
signed int *sintP =NULL;

When I change the code as mentioned bellow I get the same type of
warning

Code 2)
#include <stdio.h>
int main(void)
{
unsigned int test = 5;
unsigned int *uintP=&test;
signed int *sintP =NULL;
uintP = sintP;

return 0;

}

"src\hello.c", line 7: warning #513-D: a value of type "signed int *"
cannot
be assigned to an entity of type "unsigned int *"
uintP = sintP;
^

"src\hello.c", line 5: warning #550-D: variable "uintP" was set but
never used
unsigned int *uintP=&test;
^

And if I use cast then compiler does not throw warning for the
pointer assignment
Code 3)

#include <stdio.h>
int main(void)
{
unsigned int test = 5;
unsigned int *uintP=&test;
signed int *sintP =NULL;
sintP = (signed int *)uintP;

return 0;

}

Building C:\Documents and Settings\somanath\My Documents\My Projects
\Project6\default.gpj
Compiling hello.c because hello.o does not exist

"src\hello.c", line 6: warning #550-D: variable "sintP" was set but
never used
signed int *sintP =NULL;
^

My questions are
1) Is not legal to assign pointer to unsigned type to pointer to
signed type? As the pointer size is same.
2) If I use cast for the above example will it work properly always?

Regards,
Somenath

No, it can not be done. :):)
Casting is a kind of hack. Be careful, it can break when mixing
unsigned and signed.

Thx,
Karthik Balaguru
 
S

somenath

somenath said:

My questions are
1) Is not legal to assign pointer to unsigned type to pointer to
signed type? As the pointer size is same.

The C Standard offers no guarantee that the size of a pointer to a
signed type has the same size as a pointer to an unsigned type
(although in practice it's unlikely to differ, as I'm sure you
realise). And no, it's not legal, since the pointer types are not
compatible.
2) If I use cast for the above example will it work properly always?

No, the cast doesn't mean "work like I want you to" - its meaning is far
closer to "I know what I'm doing, compiler, so stop nagging me"
(although it does actually have a genuine use on occasion). Since it is
evident that you don't know what you're doing[1], the cast is a
mistake.

Casts are almost always mistakes. They hide bugs without removing them.

[1] Forgive me - I'm not trying to be unpleasant here, merely accurate.
In this case, it is obvious that you don't know what you're doing
*****in this specific situation***** or you wouldn't be asking the
question!

Many thanks for your answer.
I really don't have any problem if you answer my question in any
manner. At the end ,I am learning from you. It is blessing from me.
I regret some time that why I have not come to know about such a
wonderful group before.


Regards,
Somenath
 
A

Army1987

On Thu, 06 Sep 2007 22:15:39 -0700, somenath wrote:
[snip]
My questions are
1) Is not legal to assign pointer to unsigned type to pointer to
signed type? As the pointer size is same.
2) If I use cast for the above example will it work properly always?

I think it is legal, but you shouldn't do that unless you know
what you're doing. By adding a cast you essentially tell the
compiler "Yes, I *did* intend to do that.".
 
O

Old Wolf

The C Standard offers no guarantee that the size of a pointer to a
signed type has the same size as a pointer to an unsigned type

It guarantees that positive values of a signed
integer have the same representation as the
corresponding unsigned integer, right?

Given that, it's hard to see how the two types
could have different sizes.
 
K

Keith Thompson

Old Wolf said:
It guarantees that positive values of a signed
integer have the same representation as the
corresponding unsigned integer, right?

Given that, it's hard to see how the two types
could have different sizes.

Remember that we're talking about pointer sizes, not integer sizes,
i.e., whether sizeof(int*) == sizeof(unsigned*).

I can't think of any good reason why the pointer sizes should differ,
but the standard doesn't require them to be the same, or even imply
that they should be. And there's rarely any good reason to write code
that assume that they're the same.
 
O

Old Wolf

Remember that we're talking about pointer sizes, not integer sizes,
i.e., whether sizeof(int*) == sizeof(unsigned*).

Well, how is it relevant to the original question if
those pointers have different sizes? The code requests
that a pointer to int be converted to a pointer to unsigned
int. There's no problem converting a double to a float,
even though they have different sizes.

If the code were something like:

*(int **)&p_unsigned_int

then I would see your point, but it isn't.
 
K

Keith Thompson

Old Wolf said:
Well, how is it relevant to the original question if
those pointers have different sizes? The code requests
that a pointer to int be converted to a pointer to unsigned
int. There's no problem converting a double to a float,
even though they have different sizes.

If the code were something like:

*(int **)&p_unsigned_int

then I would see your point, but it isn't.

I lost track of the original question and just addressed the narrow
point.

Quoting the original article:
| #include <stdio.h>
| int main(void)
| {
| unsigned int test = 5;
| unsigned int *uintP=&test;
| signed int *sintP =NULL;
| sintP = (signed int *)uintP;
|
| return 0;
|
|
| }
[...]
| My questions are
| 1) Is not legal to assign pointer to unsigned type to pointer to
| signed type? As the pointer size is same.
| 2) If I use cast for the above example will it work properly always?

(An earlier version didn't have the cast.)

The pointer types int* and unsigned* are very likely (but not
required) to be the same size, but that's irrelevant to the question
of whether an unsigned* can be assigned directly to an int* (it
can't).

The OP's real question, though, is whether the pointer conversion
(which requires a cast) gives a meaningful result. Since int and
unsigned int are required to have the same size and alignment, and
since values (such as 5) that can be represented in either type must
have the same representation, it's very likely that it will work as
expected. But the standard, as far as I can tell, doesn't say enough
about pointer-to-pointer conversions to *guarantee* that it will work:

A pointer to an object or incomplete type may be converted to a
pointer to a different object or incomplete type. If the resulting
pointer is not correctly aligned for the pointed-to type, the
behavior is undefined. Otherwise, when converted back again,
the result shall compare equal to the original pointer. 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.

Here's a simpler version of the program:

#include <stdio.h>
int main(void)
{
unsigned int obj = 5;
int *ptr = (int*)&obj;
printf("%d\n", *ptr);
return 0;
}

Off the top of my head, I can't think of a plausible way that it could
do anything other than printing "5" under a conforming implementation.
On the other hand, I can't construct an argument based on the standard
that it must do so.
 
C

Charlie Gordon

Keith Thompson said:
Old Wolf said:
Well, how is it relevant to the original question if
those pointers have different sizes? The code requests
that a pointer to int be converted to a pointer to unsigned
int. There's no problem converting a double to a float,
even though they have different sizes.

If the code were something like:

*(int **)&p_unsigned_int

then I would see your point, but it isn't.

I lost track of the original question and just addressed the narrow
point.

Quoting the original article:
| #include <stdio.h>
| int main(void)
| {
| unsigned int test = 5;
| unsigned int *uintP=&test;
| signed int *sintP =NULL;
| sintP = (signed int *)uintP;
|
| return 0;
|
|
| }
[...]
| My questions are
| 1) Is not legal to assign pointer to unsigned type to pointer to
| signed type? As the pointer size is same.
| 2) If I use cast for the above example will it work properly
always?

(An earlier version didn't have the cast.)

The pointer types int* and unsigned* are very likely (but not
required) to be the same size, but that's irrelevant to the question
of whether an unsigned* can be assigned directly to an int* (it
can't).

The OP's real question, though, is whether the pointer conversion
(which requires a cast) gives a meaningful result. Since int and
unsigned int are required to have the same size and alignment, and
since values (such as 5) that can be represented in either type must
have the same representation, it's very likely that it will work as
expected. But the standard, as far as I can tell, doesn't say enough
about pointer-to-pointer conversions to *guarantee* that it will work:

I couldn't find where in the Standard int and unsigned int are required to
have the same size and alignment.
While the value bits of int must the same representation as those of the
corresponding unsigned type for the same value, the unsigned type has more
value bits than the int. Take for instance a representation with 32 value
bits for unsigned int, and 30 value bits + 1 sign bit + 1 padding bit for
int. Now this padding bit could be required to have value 1 for all ints
except 0. C99 6.2.6.2p2 only guarantees that the representation of the
value bits of int be the same as those of unsigned int, it says nothing
about the meaning of the extra value bits of the unsigned type were it to be
interpreted the corresponding signed type.
A pointer to an object or incomplete type may be converted to a
pointer to a different object or incomplete type. If the resulting
pointer is not correctly aligned for the pointed-to type, the
behavior is undefined. Otherwise, when converted back again,
the result shall compare equal to the original pointer. 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.

Here's a simpler version of the program:

#include <stdio.h>
int main(void)
{
unsigned int obj = 5;
int *ptr = (int*)&obj;
printf("%d\n", *ptr);
return 0;
}

Off the top of my head, I can't think of a plausible way that it could
do anything other than printing "5" under a conforming implementation.
On the other hand, I can't construct an argument based on the standard
that it must do so.

Note that the obj may legally be accessed by an expression differing only in
signedness (6.5p7).

But on the architecture described above, readily available on some DS9K, the
representation of the unsigned int for number 5 is indeed a trap value for a
signed int, dereferencing ptr causes the keyboard to heat up.

Am I correct ?
 
K

Keith Thompson

Charlie Gordon said:
"Keith Thompson" <[email protected]> a écrit dans le message de news: [...]
I couldn't find where in the Standard int and unsigned int are required to
have the same size and alignment.

C99 6.2.5p6:

For each of the signed integer types, there is a corresponding
(but different) unsigned integer type (designated with the keyword
unsigned) that uses the same amount of storage (including sign
information) and has the same alignment requirements.

[...]
Note that the obj may legally be accessed by an expression differing
only in signedness (6.5p7).

But on the architecture described above, readily available on some
DS9K, the representation of the unsigned int for number 5 is indeed
a trap value for a signed int, dereferencing ptr causes the keyboard
to heat up.

Am I correct ?

I'm afraid you might very well be.
 
O

Old Wolf

C99 6.2.5p6:

For each of the signed integer types, there is a corresponding
(but different) unsigned integer type (designated with the keyword
unsigned) that uses the same amount of storage (including sign
information) and has the same alignment requirements.

That text doesn't actually say that the corresponding
type to 'signed int' is 'unsigned int'; it could be that
'uint32_t' is the corresponding type, and unsigned int
has different size and alignment requirements?
 
C

Charlie Gordon

Old Wolf said:
That text doesn't actually say that the corresponding
type to 'signed int' is 'unsigned int'; it could be that
'uint32_t' is the corresponding type, and unsigned int
has different size and alignment requirements?

The spirit says the corresponding unsigned type for 'int' is 'unsigned int'.
Alas lhe words also say the corresponding unsigned type to 'signed int' is
'unsigned signed int' :-(
It might also imply that int8_t have a corresponding unsigned int8_t ...
This paragraph could use a better wording.
 
K

Keith Thompson

Old Wolf said:
That text doesn't actually say that the corresponding
type to 'signed int' is 'unsigned int'; it could be that
'uint32_t' is the corresponding type, and unsigned int
has different size and alignment requirements?

uint32_t isn't "designated with the keyword unsigned".

But uint32_t could very well be the corresponding type to signed int,
if it happens to be typedef'ed as 'unsigned int' (since a typedef
merely creates an alias, not a new type).
 
Joined
Jun 19, 2011
Messages
1
Reaction score
0
Hi All,
I have couple of question regarding pointer assignment. I am trying to
understand pointer assignment from signed type to unsigned vice versa.
For that I wrote the bellow mentioned code.

Code 1)

#include <stdio.h>
int main(void)
{
unsigned int test = 5;
unsigned int *uintP=&test;
signed int *sintP =NULL;
sintP = uintP;

return 0;


}
While I was compiling my compiler throws the bellow mentioned warning

src\hello.c", line 7: warning #513-D: a value of type "unsigned int *"
cannot
be assigned to an entity of type "signed int *"
sintP = uintP;
^

"src\hello.c", line 6: warning #550-D: variable "sintP" was set but
never used
signed int *sintP =NULL;

When I change the code as mentioned bellow I get the same type of
warning

Code 2)
#include <stdio.h>
int main(void)
{
unsigned int test = 5;
unsigned int *uintP=&test;
signed int *sintP =NULL;
uintP = sintP;

return 0;


}

"src\hello.c", line 7: warning #513-D: a value of type "signed int *"
cannot
be assigned to an entity of type "unsigned int *"
uintP = sintP;
^

"src\hello.c", line 5: warning #550-D: variable "uintP" was set but
never used
unsigned int *uintP=&test;
^

And if I use cast then compiler does not throw warning for the
pointer assignment
Code 3)

#include <stdio.h>
int main(void)
{
unsigned int test = 5;
unsigned int *uintP=&test;
signed int *sintP =NULL;
sintP = (signed int *)uintP;

return 0;


}

Building C:\Documents and Settings\somanath\My Documents\My Projects
\Project6\default.gpj
Compiling hello.c because hello.o does not exist

"src\hello.c", line 6: warning #550-D: variable "sintP" was set but
never used
signed int *sintP =NULL;
^

My questions are
1) Is not legal to assign pointer to unsigned type to pointer to
signed type? As the pointer size is same.
2) If I use cast for the above example will it work properly always?

Regards,
Somenath
Hello, friend.
I suggest you to follow the following code for two pointers.

#include <conio.h>
#include <stdio.h>

int main(void)
{
unsigned int test=5;
unsigned int *uintP=&test;
signed int **sintP;

(unsigned int **) sintP=&uintP;
printf("%d", **sintP);

return 0;
}
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top