cast from int** to int*

J

James Kuyper

Rod said:
6.3.2.3 sub 7 ISO C99 (applies for explicit pointer casting conversions)

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

Ok, they're convertible and he is converting back... Yes? So, there is no
need for them to have compatible representation, since they are convertible
and the conversion is "round-trip". As long as he doesn't have an alignment
failure, he only has to worry about the legalities of casting an "lvalue".

You've mentioned the possibility of misalignment, cited the part of the
standard that says that the behavior of the program is undefined if that
possibility comes up; yet you write as though that possibility isn't
very important. Why?
 
W

Willem

James Kuyper wrote:
) You've mentioned the possibility of misalignment, cited the part of the
) standard that says that the behavior of the program is undefined if that
) possibility comes up; yet you write as though that possibility isn't
) very important. Why?

Probably because the pointer is allocated with malloc().


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
M

Morris Keesan

James Kuyper wrote:
) You've mentioned the possibility of misalignment, cited the part of the
) standard that says that the behavior of the program is undefined if
that
) possibility comes up; yet you write as though that possibility isn't
) very important. Why?

Probably because the pointer is allocated with malloc().

No, it's not. The pointer we're concerned with is the pointer which is
passed as an argument to fun(), then dereferenced to have malloc()'s
return value stored where it's pointing.
 
J

James Kuyper

Willem said:
James Kuyper wrote:
) You've mentioned the possibility of misalignment, cited the part of the
) standard that says that the behavior of the program is undefined if that
) possibility comes up; yet you write as though that possibility isn't
) very important. Why?

Probably because the pointer is allocated with malloc().

That fact wasn't mentioned in the message I was responding to. I could
have traced backward through the thread, but it didn't seem to be
necessary. It would have been clearer if Ron had mentioned that as the
reason he wasn't worrying about misalignment.

If, as Praveen says, the prototype for fun() is externally imposed, then
I strongly suspect that the package it is imposed by will try to
dereference it, as a pointer to int. Therefore, this strikes me as a
very risky way of doing things.
 
M

Morris Keesan

6.3.2.3 sub 7 ISO C99 (applies for explicit pointer casting conversions)

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

Ok, they're convertible and he is converting back... Yes? So, there is
no
need for them to have compatible representation, since they are
convertible
and the conversion is "round-trip". As long as he doesn't have an
alignment
failure, he only has to worry about the legalities of casting an
"lvalue".

But I didn't say anything here about the representation. I was just using
the term "compatible" (which I don't believe has any definition in the
language standard) to suggest that (int *) and (int **) might not be
convertible one-to-the-other in a defined way, which you acknowledge here -
"As long as he doesn't have an alignment failure"

....
I mean, if a void * is a pointer to a byte, and all objects must be
represented as bytes, then how can you convert one type to a void *, but
not
technically be able to convert that void * to another type especially if
that other type can also be converted to a void * ?

"As long as [you don't] have an alignment failure."

Consider a machine on which integers MUST be aligned on an even byte
boundary.
Consider, on that machine, a (char *) pointing to bye 148793.
Convert that (char *) to a (void *) -- no problem. Convert that (void *)
to
an (int *). On some implementations, even the attempt to store that value
in
an (int *) will cause program failure. On others, the failure won't occur
until
you try to dereference the misaligned pointer. On still others, the
conversion
could change the value of the pointer, making it point to a different
address.
It's undefined, hence non-portable.
 
J

James Kuyper

Morris said:
But I didn't say anything here about the representation. I was just using
the term "compatible" (which I don't believe has any definition in the
language standard)

See section 6.2.7: "Compatible type and composite type". Representation
is quite relevant.
... to suggest that (int *) and (int **) might not be
convertible one-to-the-other in a defined way, which you acknowledge here -
"As long as he doesn't have an alignment failure"

The conversion is defined, but only to the extent that it is reversible,
unless there's an alignment problem. I was wrong to accept Willem's
assertion that the relevant pointer had been the result of the a call to
malloc(), in which case alignment would not be an issue. The relevant
pointer is &p, which is not necessarily correctly aligned for conversion
into an int*.
 
L

lawrence.jones

Morris Keesan said:
But I didn't say anything here about the representation. I was just using
the term "compatible" (which I don't believe has any definition in the
language standard)

Your belief is incorrect -- "compatible type" is a well-defined, and
very important, technical term defined in 6.2.7.
 
R

Rod Pemberton

James Kuyper said:
You've mentioned the possibility of misalignment, cited the part of the
standard that says that the behavior of the program is undefined if that
possibility comes up; yet you write as though that possibility isn't
very important. Why?

He is converting from int ** to int * and then back to int **. Yes?

The original int** pointer is required to be aligned to a byte for all
objects. It's also correctly aligned for the object's type. The cast to
int * is required to be aligned to the same byte. Although byte aligned, it
may or may not be properly aligned for the resulting object type. Use of
int * is undefined, but only for platforms with alignment issues. It's
defined for platforms without alignment issues. But, in his revision above,
he doesn't use the intermediate pointer int *. He converts the int *
pointer back to an int** pointer. It's required that this conversion be
equivalent. It must be aligned to a byte, be correctly aligned to the
original type, and be equal to the original pointer. There can't be any
pointer lossage or conversion error due to misalignment. Effectively, this
is a "do nothing" or "round trip" or lossless pointer conversion.


Rod Pemberton
 
R

Rod Pemberton

Morris Keesan said:
I mean, if a void * is a pointer to a byte, and all objects must be
represented as bytes, then how can you convert one type to a void *, but
not
technically be able to convert that void * to another type especially if
that other type can also be converted to a void * ?

"As long as [you don't] have an alignment failure."

This doesn't affect the pointer conversion. It affects pointer usage.

All (non-bitfield) objects are required to be byte aligned (6.2.6.1 sub 2
ISO C99). Therefore, all pointers must be byte aligned to be compliant,
even if the spec. doesn't require all pointers to have the same
representation (6.2.5 sub 26 ISO C99). Ugh... Historically, most systems
have standardized on an 8-bit data type due to Bob Bemer's ASCII and EBCDIC
work. But, even if a system is "word" (16-bit) aligned, as long as a C byte
is defined as a "word", C will work on the system. Alignment issues occur
when you introduce a type to the C system that isn't or can't always be
aligned to a C byte, or isn't accessable due to alignment from every C byte.
Consider a machine on which integers MUST be aligned on an even byte
boundary.

.... "word" aligned or addressable ... PDP-11, Cray ... FYI, you could've
picked a PDP-10 (36-bit word, 7-bit char, 18-bit addresses) or IBM 705 or
other early 36-bit scientific computers... ;-) If C requires 8-bit
characters, what do you do with a 7-bit char PDP-10? It pre-dates C
development (PDP-11, 16-bit word, 8-bit byte addressable ... for ASCII)...
Consider, on that machine, a (char *) pointing to bye 148793.
Convert that (char *) to a (void *) -- no problem.

No problem.
Convert that (void *) to an (int *).

No problem.
On some implementations, even the attempt to store that value
in an (int *) will cause program failure.

First, they could've defined a C byte as having a alignment of two host
bytes thereby likely eliminating the issue.

Second, you used it while knowing it has an alignment issue for that
platform...!
It's undefined, hence non-portable.

As the spec. says, usage is undefined on that platform. ... "for the
pointed-to-type" ... usage, i.e., "behavior", is undefined.

Does failure on one (ancient or obscure) system imply the code is
non-portable? I'd say no.

There were quite a few systems that implemented C, but aren't fully spec.
compliant because they predated the spec. It's still portable C. It'll
work on modern systems and most microprocessors and cpu's back to the mid
'70's. The C spec. doesn't define many things which have been standardized
and are required for "portability", like the time epoch (AT&T Sys V, and
later POSIX), or character sets (esp. ASCII, also EBCDIC), or an 8-bit byte
addressable unaligned architecture, which are needed to implement C fully
and completely.

When was the last time anyone saw a system that didn't use
binary, one's and two's complement? They were working on trinary systems
some years ago, using tri-level voltages... If someone implement's C on
such a system, is all the C code of the past four decades non-portable,
since the spec. doesn't specify trinary arithmetic? (No.)

Just because a non-compatible system or a non-compliant system doesn't mean
the code is non-portable. It just means it's non-functioning on that
system. It's upto the programmer's for that host to fix the issues, or
recode their compiler. We're looking at the issue four decades after the
problems were solved with
a C specification that failed to record the solutions in the name of
portability. They know what the world standardized on: 8-bit (unaligned)
byte addressable memory with ASCII.


Rod Pemberton
 
K

Keith Thompson

Rod Pemberton said:
Morris Keesan said:
I mean, if a void * is a pointer to a byte, and all objects must be
represented as bytes, then how can you convert one type to a void *, but
not
technically be able to convert that void * to another type especially if
that other type can also be converted to a void * ?

"As long as [you don't] have an alignment failure."

This doesn't affect the pointer conversion. It affects pointer usage.

No, it affects the conversion.

C99 6.3.2.3p7:

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.

Note that this isn't about the alignment of a pointer object
(conversions yield values, not objects), it's about the alignment of
the address to which the pointer value points.

[...]
 
J

James Kuyper

Rod said:
He is converting from int ** to int * and then back to int **. Yes?

The original int** pointer is required to be aligned to a byte for all
objects.

Well, yes; all objects in C except bit-fields are required to be byte
aligned. Since it's a constraint violation to attempt to take the
address of a bit-field, pointers to object types must point to byte
aligned locations. That fact doesn't really have anything to do with
this issue.

The alignment requirement that is referred to by 6.3.2.3p7 is not the
implicit requirement in 6.2.6.1p2 that non-bitfield objects be aligned
on byte boundaries, which is defined by the standard. It is referring to
alignment in the more general sense defined in 3.2p1: "requirement that
objects of a particular type be located on storage boundaries with
addresses that are particular multiples of a byte address". The only
types for which you can derive the fact that the alignment requirement
must 1 byte are the character types. The alignment requirements for any
other types (such as 'int' and 'int*') are unspecified by the standard,
and can be greater than 1 byte.

An implementation must arrange for 'p' to be correctly aligned to hold
an object of type int*. However, there's no requirement that the
location of p be correctly aligned for an object of type 'int'.
Therefore, conversion of &p to (int*) may have undefined behavior. It
doesn't matter that the resulting pointer is never dereferenced;
6.3.2.3p7 says that the conversion itself that has undefined behavior.
 
N

Nick Keighley

Does failure on one (ancient or obscure) system imply the code is
non-portable?  I'd say no.

There were quite a few systems that implemented C, but aren't fully spec.
compliant because they predated the spec.  It's still portable C.
what?

 It'll
work on  modern systems and most microprocessors and cpu's back to the mid
'70's.  The C spec. doesn't define many things which have been standardized
and are required for "portability", like the time epoch (AT&T Sys V, and
later POSIX), or character sets (esp. ASCII, also EBCDIC), or an 8-bit byte
addressable unaligned architecture, which are needed to implement C fully
and completely.

When was the last time anyone saw a system that didn't use
binary, one's and two's complement?  They were working on trinary systems
some years ago, using tri-level voltages...  If someone implement's C on
such a system, is all the C code of the past four decades non-portable,
since the spec. doesn't specify trinary arithmetic?  (No.)

Just because a non-compatible system or a non-compliant system doesn't mean
the code is non-portable.  It just means it's non-functioning on that
system.

I don't see the difference between "non-functional [on a particular
system]" and "non-portable"
 It's upto the programmer[]s for that host to fix the issues, or
recode their compiler.  We're looking at the issue four decades after the
problems were solved with
a C specification that failed to record the solutions in the name of
portability.  They know what the world standardized on: 8-bit (unaligned)
byte addressable memory with ASCII.

there are no current system that require alignment on non-byte
boundaries?
I thought the trend with RISC stuff was to become *more* fussy about
alignment. Don't even pentiums have alignment issues?
 
N

Nick Keighley

Nick Keighley said:





There are no current systems that use character sets other than
ASCII?

Nick, you might want to check out RP's posting history before
wasting too much more time.

ah, he's an all-the-worlds-a-vax person is he?

[for "VAX" read whatever is this weeks favorite model]
 
M

mecej4

This is not valid C. The main problem is that you can't have a cast
expression as the target of an assignment.




It is not a good idea to reply on things like this. Why would you
want to do that? You seem to want this program:

#include <stdlib.h>
#include <stdio.h>

void fun(int **p)
{
*p = malloc(sizeof **p);
}

int main(void)
{
int *p;
fun(&p);
*p = 10;
printf("%d\n", *p);
free(p);
return 0;
}

which is well-defined and portable. Is that what you wanted to do?

|I know this is portable but this was to illustrate the problem..
|i dont want this..

Based on your responses to the well-meant attempts of others to help you, I
have to ask:

Are you trying to get some programming done, or are you training to become a
language lawyer?

In either case, you need to make your intentions clear.

HTH -- mecej4
 
R

Rod Pemberton

James Kuyper said:
Well, yes; all objects in C except bit-fields are required to be byte
aligned.

Okay, we're on the same page here.
Since it's a constraint violation to attempt to take the
address of a bit-field,

Other than just saying "it's a constraint violation", do you understand why
you _can't_ do this? If a byte is the minimum addressable unit of storage,
and all non-bitfield objects are aligned on byte boundaries, how do you
construct a pointer to point in-between bytes? to some un-addressable bit?
pointers to object types must point to byte
aligned locations.
Yes.

That fact doesn't really have anything to do with
this issue.

That's exactly what we've been discussing. 6.3.2.3p7 says the pointer
conversion from a type resulting in the same type is loss-less and it's
usage, if misaligned, is undefined.
The alignment requirement that is referred to by 6.3.2.3p7 is not the
implicit requirement in 6.2.6.1p2 that non-bitfield objects be aligned
on byte boundaries, which is defined by the standard.

It's not? How does a pointer point to an object then... If it's not, then
no pointer can point to any object. Is that what you're claiming? Really?
It [6.3.2.3p7] is referring to
alignment in the more general sense defined in 3.2p1: "requirement that
objects of a particular type be located on storage boundaries with
addresses that are particular multiples of a byte address".

Except for the fact that one specifies bit-fields as excluded for obvious
reasons and the other fails to do so, there is no difference between
6.3.2.3p7 and 3.2p1.
The only
types for which you can derive the fact that the alignment requirement
must 1 byte are the character types.

True. But, all types, except bitfields, must be byte aligned. They are
aligned to a byte boundary. If an int has a size of 4 and is aligned, it's
byte aligned to a byte boundary, every fourth byte...
The alignment requirements for any
other types (such as 'int' and 'int*') are unspecified by the standard,
and can be greater than 1 byte.

.... but are still aligned on a byte boundary. A byte is the minimum
addresable unit. You can't point a pointer in-between a byte.
An implementation must arrange for 'p' to be correctly aligned to hold
an object of type int*.
True.

However, there's no requirement that the
location of p be correctly aligned for an object of type 'int'.

True. But, this has nothing to do with the issue.
Therefore, conversion of &p to (int*) may have undefined behavior.

That's not what 6.3.2.3p7 says. It says the pointer behavior for the
pointed-to type is undefined. It says nothing about the pointer conversion
being undefined.
It
doesn't matter that the resulting pointer is never dereferenced;
6.3.2.3p7 says that the conversion itself that has undefined behavior.

No.


RP
 
R

Rod Pemberton

Richard Heathfield said:
Nick, you might want to check out RP's posting history before
wasting too much more time.

I'm not sure to what you're referring to. You constantly post incorrect
statements. I've corrected you numerous times. I've shown your posted code
to be wrong numerous times. I don't read and post here regularly, but I can
only recall one time that you posted correct code. And, I stated so. Keith
Thompson, who I don't care for either and who gets many things wrong too,
has had long periods where he has corrected you almost incessantly too. So,
the fact that you keep insulting me, by telling others _I'm_ the problem is
really annoying and is extremely childish.
There are no current systems that use character sets other than
ASCII?

I didn't say that. I said the world standardized on ASCII. HUGE
difference, but you never notice things like this, do you? And, the world
has, until recently been stuck with ASCII and EBCDIC. So, feel free to name
one non-IBM system that is current, i.e., within the last year and a half,
which can represent Germanic languages, and that doesn't use ASCII. If you
want to mention a system that uses an Oriental language, because you can't
find a Germanic one, go ahead. And then, feel free to post the quantities
of systems used from 1974 to 2007 broken down by ASCII and EBCDIC. The
numbers will confirm the world standardized on ASCII.


RP
 
R

Rod Pemberton


What what? C was standardized after many existing implementations. It's
been around since 1974 but was standardized in 1989. So, what what? What
do you mean by "what?" ?
Just because a non-compatible system or a non-compliant system doesn't mean
the code is non-portable. It just means it's non-functioning on that
system.

I don't see the difference between "non-functional [on a particular
system]" and "non-portable"

Look up portable and then look up functional. What you're saying is that
code that compiles on 99.999% of all machines, but doesn't compile on
00.001% is non-portable. If it compiles on 99.999% of all machines, it's
portable. It's non-functional on 00.001%. So, where is the boundary
between being portable and functional. If say 90%, 80%, 75%, maybe even
60%, then it's still portable. Today, I think we're much closer to 100%
than we were in 1974. I'd say 98%.
It's upto the programmer[]s for that host to fix the issues, or
recode their compiler. We're looking at the issue four decades after the
problems were solved with
a C specification that failed to record the solutions in the name of
portability. They know what the world standardized on: 8-bit (unaligned)
byte addressable memory with ASCII.

there are no current system that require alignment on non-byte
boundaries?

Not that I'm aware of, but I wouldn't doubt it some still obscure and custom
systems, say Crays, aren't.

What would they align on? A nybble? three-bits? nine-bits? A byte is the
minimum addressable unit in C, you can't point to something in-between. A
pointer must point to a byte boundary. Alignment is still on a byte
boundary even if an object is two byte or four byte aligned.
I thought the trend with RISC stuff was to become *more* fussy about
alignment. Don't even pentiums have alignment issues?

Wouldn't doubt it.


RP
 
R

Rod Pemberton

Keith Thompson said:
Rod Pemberton said:
Morris Keesan said:
On Sun, 05 Jul 2009 04:08:05 -0400, Rod Pemberton

I mean, if a void * is a pointer to a byte, and all objects must be
represented as bytes, then how can you convert one type to a void *, but
not
technically be able to convert that void * to another type especially if
that other type can also be converted to a void * ?

"As long as [you don't] have an alignment failure."

This doesn't affect the pointer conversion. It affects pointer usage.

No, it affects the conversion.

I've been over this, look back six messages... Or, look down some...
C99 6.3.2.3p7:

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.

Why do you always come in late, in the wrong part of the thread, then
requote, say "that's wrong", when this was already discussed elsewhere in
this same thread?
Note that this isn't about the alignment of a pointer object
(conversions yield values, not objects), it's about the alignment of
the address to which the pointer value points.

As I said, all pointers in C must point to a byte boundary, because all
objects, except bitfields, in C have byte alignment. Depending on the
object, the pointer may point to every byte boundary, every other byte
boundary, every fourth byte boundary, etc, but it still points to a byte
boundary. A byte is the minimum addressable unit in C, you can't point to
something in-between.


RP
 
K

Keith Thompson

Rod Pemberton said:
Keith Thompson said:
Rod Pemberton said:
On Sun, 05 Jul 2009 04:08:05 -0400, Rod Pemberton

I mean, if a void * is a pointer to a byte, and all objects
must be represented as bytes, then how can you convert one
type to a void *, but not technically be able to convert that
void * to another type especially if that other type can also
be converted to a void * ?

"As long as [you don't] have an alignment failure."

This doesn't affect the pointer conversion. It affects pointer usage.

No, it affects the conversion.

I've been over this, look back six messages... Or, look down some...
C99 6.3.2.3p7:

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.

Why do you always come in late, in the wrong part of the thread, then
requote, say "that's wrong", when this was already discussed elsewhere in
this same thread?

You claimed that an alignment failure doesn't affect the pointer
conversion. You were wrong. I replied immediately to the message in
which you made that incorrect claim.

[snip]
 
J

jameskuyper

Rod said:
Okay, we're on the same page here.


Other than just saying "it's a constraint violation", do you understand why
you _can't_ do this? ...

No. I understand why an implemention could in fact do this. However,
in most cases it's horribly inefficient, and the standard was
therefore explicitly written to not mandate such inefficiency.
... If a byte is the minimum addressable unit of storage,

The C byte is the minimum unit of storage that can be addressed by C
code. It need not be the same as the hardware addressable unit, and
there are many implementations where it is much smaller.
and all non-bitfield objects are aligned on byte boundaries, how do you
construct a pointer to point in-between bytes? to some un-addressable bit?

By creating a pointer that consists of a byte address and a bit
offset. Much the same approach must already be used to emulate char*
pointers on machines where the addressable storage unit was deemed, by
the implementor, to be too large for use as a C byte. The issue isn't
whether it's feasible for an implementation to provide bit-pointers;
it certainly is feasible. The issue is whether the C standard mandates
them; and it very specifically excludes the possibility.
That's exactly what we've been discussing. 6.3.2.3p7 says the pointer
conversion from a type resulting in the same type is loss-less and it's
usage, if misaligned, is undefined.

If byte-alignment were the only thing it was talking to, how could the
pointer ever get misaligned? Misaligned C pointers is a meaningful
concept only in the context of alignment requirements larger than 1
byte.
It's not? How does a pointer point to an object then...

By identifying the location that the object starts at. This location
might be a word boundary, with (for example) 4 bytes to a word.
Pointers of that type might be incapable of pointing at positions
withing a word. This is all allowed by the C standard. char* and void*
can't have this characteristic, but long* and double* might, and
there's real machines on which they do.
... If it's not, then
no pointer can point to any object.

No such conclusion can be validly drawn from my assertion.
... Is that what you're claiming?

Not at all.
... Really?

Really - not at all.
It [6.3.2.3p7] is referring to
alignment in the more general sense defined in 3.2p1: "requirement that
objects of a particular type be located on storage boundaries with
addresses that are particular multiples of a byte address".

Except for the fact that one specifies bit-fields as excluded for obvious
reasons and the other fails to do so, there is no difference between
6.3.2.3p7 and 3.2p1.

Yes there is. 3.2p1 defines what alignment means. 6.3.2.3p7 says,
among other things, that the behavior is undefined if you attempt to
convert a misaligned pointer. I see that as a rather huge difference,
my self.
True. But, all types, except bitfields, must be byte aligned.

Certainly, and irrelevant to 6.3.2.3p7.
They are
aligned to a byte boundary. If an int has a size of 4 and is aligned, it's
byte aligned to a byte boundary, every fourth byte...

Elsewhere, you seem to be implying that the only relevant alignment
requirement is 1 byte. However, in the above sentence it seems as
though you might be thinking that the alignment requirement has to
match the size. Is that what you're saying? if so, that's not the
case. A 4-byte int could have an alignment requirement of 2. What can
be proven by combining C's rules for pointer arithmetic, arrays, and
sizeof, is that the size of a data type must be an integer multiple of
the alignment requirement. The ratio of the size to the alignment
requirement could be 1, but is not required to be.
... but are still aligned on a byte boundary. A byte is the minimum
addresable unit. You can't point a pointer in-between a byte.

True, but the question is not whether you can point a pointer between
bytes. Let's consider an implementation where int is 4 bytes and has
an alignment requirement of 2. What 6.3.2.3p7 is saying is that the
following code:

int array[4];
int *pi = (int*)(1+(char*)array);

has undefined behavior, because the pointer value 1+(char*)array
points at an address which is incorrectly aligned to hold an int.
True. But, this has nothing to do with the issue.


That's not what 6.3.2.3p7 says. It says the pointer behavior for the
pointed-to type is undefined. It says nothing about the pointer conversion
being undefined.

"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 the
pointed-to type, the behavior is undefined."

In the above sentence "the behavior is undefined" can only refer to
the behavior when such a pointer is "converted to a pointer to a
different type or incomplete type". Not the behavior after the
conversion, but the behavior of the conversion itself.

This is not just a pedantic debate about what the standard means; in
the real world there are systems where pointers to different types are
handled in different fashions. For instance, there may be
implementations with CHAR_BIT==8 on systems where the hardward
addressable unit (word) is 32 bits. On such systems, pointers to some
types that have a size which is a multiple of the word size may
identify only which word the object starts in, and be physically
incapable of representing positions that are not at the beginning of
word. 6.3.2.3p7 was written for the explicit purpose of allowing such
implementations to qualify as conforming to the standard.
 

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,774
Messages
2,569,598
Members
45,151
Latest member
JaclynMarl
Top