By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,110 Members | 1,010 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,110 IT Pros & Developers. It's quick & easy.

pointer conversion

P: n/a
guys,

I have a question regarding pointer conversion. Please look at the
following code snippet.

char *cptr;
int *iptr;

/* Some code here that initializes "iptr" */

cptr = (char *)iptr; /* Line 1
*/
cptr = cptr + sizeof(int); /* Line 2 */
iptr = (int *)cptr; /* Line 3 */

Now as per the pointer conversion rule:
Page 47: n1124.pdf

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 aligned57) for thepointed-to type, the
behavior is undefined. Otherwise, when converted back again, the
result shall compare equal to the original pointer.

According to above conversion rule, "Line 1" should be perfectly fine.
But, I want to know if the conversion done at "Line 3" is allowed or
not.
I have this doubt because the "cptr" has been changed.
But, it is properly aligned to point to an integer object.

Aug 31 '07 #1
Share this Question
Share on Google+
13 Replies


P: n/a

<ju**********@yahoo.co.inwrote in message
news:11**********************@i38g2000prf.googlegr oups.com...
guys,

I have a question regarding pointer conversion. Please look at the
following code snippet.

char *cptr;
int *iptr;

/* Some code here that initializes "iptr" */

cptr = (char *)iptr; /* Line 1
*/
cptr = cptr + sizeof(int); /* Line 2 */
iptr = (int *)cptr; /* Line 3 */

Now as per the pointer conversion rule:
Page 47: n1124.pdf

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 aligned57) for thepointed-to type, the
behavior is undefined. Otherwise, when converted back again, the
result shall compare equal to the original pointer.

According to above conversion rule, "Line 1" should be perfectly fine.
But, I want to know if the conversion done at "Line 3" is allowed or
not.
I have this doubt because the "cptr" has been changed.
But, it is properly aligned to point to an integer object.
You will be OK.
char is always 1 byte. So casting an arbitrary pointer to a char *, adding
an exact multiple of the size of the original type, and casting back is
guaranteed to preserve alignment.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Aug 31 '07 #2

P: n/a
>>>>"M" == Malcolm McLean <re*******@btinternet.comwrites:

MYou will be OK. char is always 1 byte. So casting an arbitrary
Mpointer to a char *, adding an exact multiple of the size of
Mthe original type, and casting back is guaranteed to preserve
Malignment.

I am not so sure about that; would you care to cite C&V, please, if
you claim that it's guaranteed by the standard?

Charlton
--
Charlton Wilbur
cw*****@chromatico.net
Aug 31 '07 #3

P: n/a

"Charlton Wilbur" <cw*****@chromatico.netwrote in message
news:87************@mithril.chromatico.net...
>>>>>"M" == Malcolm McLean <re*******@btinternet.comwrites:

MYou will be OK. char is always 1 byte. So casting an arbitrary
Mpointer to a char *, adding an exact multiple of the size of
Mthe original type, and casting back is guaranteed to preserve
Malignment.

I am not so sure about that; would you care to cite C&V, please, if
you claim that it's guaranteed by the standard?
Arrays have to be contiguous in memory. No padding bytes may be inserted
between items.
The rest follows from that.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Aug 31 '07 #4

P: n/a
Charlton Wilbur wrote:
>>>>>"M" == Malcolm McLean <re*******@btinternet.comwrites:

MYou will be OK. char is always 1 byte. So casting an arbitrary
Mpointer to a char *, adding an exact multiple of the size of
Mthe original type, and casting back is guaranteed to preserve
Malignment.

I am not so sure about that; would you care to cite C&V, please, if
you claim that it's guaranteed by the standard?
He's wrong: it's not guaranteed. Simple example:

int target = 42;
int *ptr = &target + 1; /* "an arbitrary pointer" */
ptr = (int*)((char*)ptr + sizeof *ptr); /* U.B. */

If the original pointer points at an actual object of its
type (so it's not "arbitrary"), the conversion is safe.

--
Eric Sosman
es*****@ieee-dot-org.invalid
Aug 31 '07 #5

P: n/a
In article <_e******************************@comcast.com>,
Eric Sosman <es*****@ieee-dot-org.invalidwrote:
> MYou will be OK. char is always 1 byte. So casting an arbitrary
Mpointer to a char *, adding an exact multiple of the size of
Mthe original type, and casting back is guaranteed to preserve
Malignment.
>I am not so sure about that; would you care to cite C&V, please, if
you claim that it's guaranteed by the standard?
He's wrong: it's not guaranteed. Simple example:

int target = 42;
int *ptr = &target + 1; /* "an arbitrary pointer" */
ptr = (int*)((char*)ptr + sizeof *ptr); /* U.B. */

If the original pointer points at an actual object of its
type (so it's not "arbitrary"), the conversion is safe.
That seems to be excessive pedantry. He said it "preserves
alignment", not that it's legal. Presumably you would deny that
adding 2 to an int preserves it odd/even parity, because you might
choose INT_MAX.

-- Richard

--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Aug 31 '07 #6

P: n/a

"Richard Tobin" <ri*****@cogsci.ed.ac.ukwrote in message
news:fb***********@pc-news.cogsci.ed.ac.uk...
In article <_e******************************@comcast.com>,
Eric Sosman <es*****@ieee-dot-org.invalidwrote:
>> MYou will be OK. char is always 1 byte. So casting an arbitrary
Mpointer to a char *, adding an exact multiple of the size of
Mthe original type, and casting back is guaranteed to preserve
Malignment.
>>I am not so sure about that; would you care to cite C&V, please, if
you claim that it's guaranteed by the standard?
> He's wrong: it's not guaranteed. Simple example:

int target = 42;
int *ptr = &target + 1; /* "an arbitrary pointer" */
ptr = (int*)((char*)ptr + sizeof *ptr); /* U.B. */

If the original pointer points at an actual object of its
type (so it's not "arbitrary"), the conversion is safe.

That seems to be excessive pedantry. He said it "preserves
alignment", not that it's legal. Presumably you would deny that
adding 2 to an int preserves it odd/even parity, because you might
choose INT_MAX.
Yes, to be a successful pedant you've got to be absolutely, precisely
accurate.

Clearly if the pointer is misaligned, adding sizeof(*ptr) will preserve the
(mis) alignment.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
Aug 31 '07 #7

P: n/a
Richard Tobin wrote:
In article <_e******************************@comcast.com>,
Eric Sosman <es*****@ieee-dot-org.invalidwrote:
>> MYou will be OK. char is always 1 byte. So casting an arbitrary
Mpointer to a char *, adding an exact multiple of the size of
Mthe original type, and casting back is guaranteed to preserve
Malignment.
>>I am not so sure about that; would you care to cite C&V, please, if
you claim that it's guaranteed by the standard?
> He's wrong: it's not guaranteed. Simple example:

int target = 42;
int *ptr = &target + 1; /* "an arbitrary pointer" */
ptr = (int*)((char*)ptr + sizeof *ptr); /* U.B. */

If the original pointer points at an actual object of its
type (so it's not "arbitrary"), the conversion is safe.

That seems to be excessive pedantry. He said it "preserves
alignment", not that it's legal. Presumably you would deny that
adding 2 to an int preserves it odd/even parity, because you might
choose INT_MAX.
Adding two to an "arbitrary" integer need not preserve
parity, although adding two to most integers does. For the
two problematic integers you get undefined behavior, after
which assertions about what is and isn't preserved -- or
pickled -- just evaporate.

Adding sizeof *ptr to an "arbitrary" value of ptr need
not preserve alignment, although adding it to a restricted
class of values certainly does. But once U.B. occurs, the
Standard abdicates and no longer supports arguments that
formerly relied on it. It is wrong to claim that alignment
preservation is "guaranteed" in light of U.B.; "guaranteed"
by whom or by what?

BTW, "excessive pedantry" is unnecessarily redundant. ;-)

--
Eric Sosman
es*****@ieee-dot-org.invalid
Aug 31 '07 #8

P: n/a
In article <K6******************************@bt.com>,
Malcolm McLean <re*******@btinternet.comwrote:
>Yes, to be a successful pedant you've got to be absolutely, precisely
accurate.

Clearly if the pointer is misaligned, adding sizeof(*ptr) will preserve the
(mis) alignment.
No. If you're a real pedant, you will observe that the undefined
behaviour of creating the misaligned pointer could be that the addition
produces an aligned one.

But the example wasn't a misaligned pointer - it was that the addition
produced a pointer outside of the object.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Aug 31 '07 #9

P: n/a
In article <D5******************************@comcast.com>,
Eric Sosman <es*****@ieee-dot-org.invalidwrote:
BTW, "excessive pedantry" is unnecessarily redundant. ;-)
I thought the comp.lang.c view was that it's an oxymoron.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Aug 31 '07 #10

P: n/a

"Richard Tobin" <ri*****@cogsci.ed.ac.ukwrote in message
news:fb***********@pc-news.cogsci.ed.ac.uk...
In article <K6******************************@bt.com>,
Malcolm McLean <re*******@btinternet.comwrote:
>>Yes, to be a successful pedant you've got to be absolutely, precisely
accurate.

Clearly if the pointer is misaligned, adding sizeof(*ptr) will preserve
the
(mis) alignment.

No. If you're a real pedant, you will observe that the undefined
behaviour of creating the misaligned pointer could be that the addition
produces an aligned one.
I surrender. Yes, the misaligned pointer can only be assigned to a pointer
of that type with UB, after which any futher operations are allowed to
produce any results whatsoever.
>
But the example wasn't a misaligned pointer - it was that the addition
produced a pointer outside of the object.
That's an example of useful pedantry. I should have specified that the
operation is not safe, if the new pointer cannot be contained in the old
object.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm
Aug 31 '07 #11

P: n/a
Eric Sosman wrote:
>
.... snip ...
>
Adding two to an "arbitrary" integer need not preserve parity,
although adding two to most integers does. For the two problematic
integers you get undefined behavior, after which assertions about
what is and isn't preserved -- or pickled -- just evaporate.
Oh? When I was in primary school:

4 had 1 bit
4 + 2 is 6, with 2 bits
6 + 2 is 8, with 1 bit

which doesn't seem to preserve parity.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Aug 31 '07 #12

P: n/a
In article <46**************@yahoo.com>,
CBFalconer <cb********@maineline.netwrote:
>Oh? When I was in primary school:

4 had 1 bit
4 + 2 is 6, with 2 bits
6 + 2 is 8, with 1 bit

which doesn't seem to preserve parity.
Oops. I was using the term "parity" in the mathematical sense of
whether a number is odd or even; not in the computer sense of whether
it has an odd or even number of bits set. I used the phrase "odd/even
parity" to emphasize the kind of parity I meant, but of course it does
nothing of the kind.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Aug 31 '07 #13

P: n/a
On 31 Aug 2007 12:24:43 -0400, Charlton Wilbur
<cw*****@chromatico.netwrote:
>>>>>"M" == Malcolm McLean <re*******@btinternet.comwrites:

MYou will be OK. char is always 1 byte. So casting an arbitrary
Mpointer to a char *, adding an exact multiple of the size of
Mthe original type, and casting back is guaranteed to preserve
Malignment.

I am not so sure about that; would you care to cite C&V, please, if
you claim that it's guaranteed by the standard?
It follows directly from paragraph 2 in section 6.5.2.1 and the first
few sentences of paragraph 8 in section 6.5.6 of n1124.

While the arithmetic is guaranteed to preserve alignment, it can still
invoke undefined behavior. If the resulting address is not within (or
just 1 past the end of) the original object, the next to last sentence
of paragraph 8 of section 6.5.6 applies.
Remove del for email
Sep 1 '07 #14

This discussion thread is closed

Replies have been disabled for this discussion.