6.3.2.3#1 of N1362 says:
1 A pointer to void may be converted to or from a pointer to any
incomplete or object type. A pointer to any incomplete or object
type may be converted to a pointer to void and back again; the
result shall compare equal to the original pointer.
but isn't that already covered by 6.3.2.3#7, which is more accurate
(see the restriction on the alignment, for which #1 says nothing)?
7 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 aligned59) for the pointed-to type, the
behavior is undefined. Otherwise, when converted back again, the
result shall compare equal to the original pointer. [...]
--
Vincent Lef�vre <vin...@vinc17.net> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / Ar�naire project (LIP, ENS-Lyon)
void is not an object or incomplete type.
DES
--
Dag-Erling Smørgrav - d...@des.no
6.2.5:
19 The void type comprises an empty set of values; it is an
incomplete type that cannot be completed.
--
Ben.
> Hi,
>
> 6.3.2.3#1 of N1362 says:
>
> 1 A pointer to void may be converted to or from a pointer to any
> incomplete or object type. A pointer to any incomplete or object
> type may be converted to a pointer to void and back again; the
> result shall compare equal to the original pointer.
>
> but isn't that already covered by 6.3.2.3#7, which is more accurate
> (see the restriction on the alignment, for which #1 says nothing)?
>
> 7 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. [...]
>
Just an educated guess: When is something correctly aligned for "void"?
Alignment is a "requirement that objects of a particular type be located on
storage boundaries with addresses that are particular multiples of a byte
address".
The additional paragraph about void will make it clear.
> Vincent Lefevre wrote:
I don't understand what you mean here. Only paragraph 7 makes alignment
clear for pointers to void (something missing from paragraph 1). So,
what does paragraph 1 make clear?
Note that paragraph 7 is important, e.g. when considering (incorrect)
code like:
short *p;
(long *) (void *) p;
i.e. you can't do anything you want with pointers to void.
> In article <hemnvf$stj$03$1...@news.t-online.com>,
> "Johannes Schaub (litb)" <schaub-...@web.de> wrote:
>
>> Vincent Lefevre wrote:
>
>> > 6.3.2.3#1 of N1362 says:
>> >
>> > 1 A pointer to void may be converted to or from a pointer to any
>> > incomplete or object type. A pointer to any incomplete or object
>> > type may be converted to a pointer to void and back again; the
>> > result shall compare equal to the original pointer.
>> >
>> > but isn't that already covered by 6.3.2.3#7, which is more accurate
>> > (see the restriction on the alignment, for which #1 says nothing)?
>> >
>> > 7 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. [...]
>> >
>
>> Just an educated guess: When is something correctly aligned for "void"?
>> Alignment is a "requirement that objects of a particular type be located
>> on storage boundaries with addresses that are particular multiples of a
>> byte address".
>
>> The additional paragraph about void will make it clear.
>
> I don't understand what you mean here. Only paragraph 7 makes alignment
> clear for pointers to void (something missing from paragraph 1). So,
> what does paragraph 1 make clear?
>
Paragraph 7 refers to "alignment" of void, but alignment is not defined for
void (what would it be? there are no "void objects" that are located
somewhere, as void can never be completed to be an object type, and the
standard does not seem to define a "work around" alignment for void that
would be compatible with any other object type / incomplete type).
Paragraph 1 is not based on alignment, but clearly says that any object or
incomplete type pointee may be converted to void and back.
So, according to paragraph 1, any pointer to T1 can be converted to
any pointer to T2 in the following way?
T1 *p;
T2 *q;
q = (T2 *) (void *) p;
Then, what's the point about the alignment between T1 * and T2 *?
Yes, or through intptr_t. Please don't, unless you are certain that T1
and T2 have compatible alignments (this usually means that T1's
alignment is the same as or a multiple of T2's).
(I can't find chapter and verse for the alignment requirements for
structs; I believe a struct has the same alignment requirements as the
strictest of those of its members?)
> Then, what's the point about the alignment between T1 * and T2 *?
The alignment rules exist because many CPU architectures (particularly
RISC architectures) disallow unaligned memory access. Programs that
violate alignment rules may crash, unless the compiler works around it
by e.g. generating code that loads multibyte values one byte at a time.
Needless to say, this is extremely inefficient.
Even on architectures that allow unaligned access to multibyte values,
there may be a significant performance hit; this is the case for the
i386 and amd64 architectures.
> Paragraph 7 refers to "alignment" of void, but alignment is not
> defined for void
After reading the standard again, this is wrong. Alignment is defined
for pointers to void:
6.2.5#27 from N1362:
A pointer to void shall have the same representation and alignment
requirements as a pointer to a character type.
So, I'd now say that paragraph 7 applies to pointers to void entirely
and as a consequence, paragraph 1 seems useless.
> In article <heo289$ids$01$1...@news.t-online.com>,
> "Johannes Schaub (litb)" <schaub-...@web.de> wrote:
>
>> Paragraph 7 refers to "alignment" of void, but alignment is not defined
>> for void (what would it be? there are no "void objects" that are located
>> somewhere, as void can never be completed to be an object type, and the
>> standard does not seem to define a "work around" alignment for void that
>> would be compatible with any other object type / incomplete type).
>
>> Paragraph 1 is not based on alignment, but clearly says that any object
>> or incomplete type pointee may be converted to void and back.
>
> So, according to paragraph 1, any pointer to T1 can be converted to
> any pointer to T2 in the following way?
>
> T1 *p;
> T2 *q;
> q = (T2 *) (void *) p;
>
Yes, both p1 and p7 say that: "A pointer to void may be converted to or from
a pointer to any incomplete or object type.", "A pointer to an object or
incomplete type may be converted to a pointer to a different object or
incomplete type.".
And p7 says furthermore: "If the resulting pointer is not correctly aligned
for the pointed-to type, the behavior is undefined.". That's p7's point: If
you convert *from* "void*" or another type to a non-"void*" and the
alignment does not fit, behavior is UB.
Notice that p1 says "... to a pointer to void and back again; ...": You are
not converting back again, but you convert further to another type.
> In article <heo289$ids$01$1...@news.t-online.com>,
> "Johannes Schaub (litb)" <schaub-...@web.de> wrote:
>
>> Paragraph 7 refers to "alignment" of void, but alignment is not
>> defined for void
>
> After reading the standard again, this is wrong. Alignment is defined
> for pointers to void:
>
> 6.2.5#27 from N1362:
>
> A pointer to void shall have the same representation and alignment
> requirements as a pointer to a character type.
>
> So, I'd now say that paragraph 7 applies to pointers to void entirely
> and as a consequence, paragraph 1 seems useless.
>
No, this is the alignment requirement of pointer to void ("void*"), but not
of "void" itself.
> Vincent Lefevre <vincen...@vinc17.org> writes:
> > So, according to paragraph 1, any pointer to T1 can be converted to
> > any pointer to T2 in the following way?
> >
> > T1 *p;
> > T2 *q;
> > q = (T2 *) (void *) p;
> Yes, or through intptr_t. Please don't, unless you are certain that
> T1 and T2 have compatible alignments (this usually means that T1's
> alignment is the same as or a multiple of T2's).
Still, I'm not certain that this is OK. IMHO, the standard is not clear.
Note that even with compatible alignments (but incompatible types),
dereferencing q is incorrect due to aliasing rules. For instance,
code like:
double d = 0.0 / 0.0;
printf ("d = %g [%016llx]\n", d, *((unsigned long long *) &d));
doesn't work with latest GCC snapshots (one gets random output for
%016llx). Inserting (void *) like
(unsigned long long *) (void *) &d
doesn't change the behavior.
> > Then, what's the point about the alignment between T1 * and T2 *?
> The alignment rules exist because many CPU architectures (particularly
> RISC architectures) disallow unaligned memory access. Programs that
> violate alignment rules may crash, unless the compiler works around it
> by e.g. generating code that loads multibyte values one byte at a time.
> Needless to say, this is extremely inefficient.
[...]
That wasn't exactly what I intended to ask. My point is that:
If the standard allows "(T2 *) (void *) p" (even though dereferencing
may not be allowed), why doesn't it allow "(T2 *) p" directly?
Also, why does the standard define pointer conversions in some
general way (i.e. even when types are not compatible) while
dereferencing is not allowed due to aliasing rules?
> Vincent Lefevre wrote:
I disagree: paragraph 6.3.2.3#7 says
"If the resulting pointer is not correctly aligned".
^^^^^^^
i.e. what is aligned is not the type, but the pointer.
> Vincent Lefevre wrote:
> > In article <heo289$ids$01$1...@news.t-online.com>,
> > "Johannes Schaub (litb)" <schaub-...@web.de> wrote:
> >
> >> Paragraph 7 refers to "alignment" of void, but alignment is not defined
> >> for void (what would it be? there are no "void objects" that are located
> >> somewhere, as void can never be completed to be an object type, and the
> >> standard does not seem to define a "work around" alignment for void that
> >> would be compatible with any other object type / incomplete type).
> >
> >> Paragraph 1 is not based on alignment, but clearly says that any object
> >> or incomplete type pointee may be converted to void and back.
> >
> > So, according to paragraph 1, any pointer to T1 can be converted to
> > any pointer to T2 in the following way?
> >
> > T1 *p;
> > T2 *q;
> > q = (T2 *) (void *) p;
> >
> Yes, both p1 and p7 say that: "A pointer to void may be converted to or from
^^^
> a pointer to any incomplete or object type.", "A pointer to an object or
> incomplete type may be converted to a pointer to a different object or
> incomplete type.".
> And p7 says furthermore: "If the resulting pointer is not correctly aligned
> for the pointed-to type, the behavior is undefined.". That's p7's point: If
> you convert *from* "void*" or another type to a non-"void*" and the
> alignment does not fit, behavior is UB.
So, now you're saying that p7 also applies to void*! (And the answer
above would be "no", not "yes" -- see the "any" in my question.)
This also means that p1 doesn't provide any useful information already
implied by p7.
> Notice that p1 says "... to a pointer to void and back again; ...": You are
> not converting back again, but you convert further to another type.
I was taking into account the first sentence only (which allows both
directions: "to or from"). Now there are two possibilities:
1. If you assume that p7 doesn't apply when one of the pointer is
void*, then "(T2 *) (void *) p" is *always* allowed due to the
first sentence of p1, but this is rather strange.
2. If you assume that p7 also applies when one of the pointer is
void*, then p1 doesn't add any useful information: everything
is covered by p7.
> In article <heod0q$e6t$00$1...@news.t-online.com>,
> "Johannes Schaub (litb)" <schaub-...@web.de> wrote:
>
>> Vincent Lefevre wrote:
>
>> > In article <heo289$ids$01$1...@news.t-online.com>,
>> > "Johannes Schaub (litb)" <schaub-...@web.de> wrote:
>> >
>> >> Paragraph 7 refers to "alignment" of void, but alignment is not
>> >> defined for void (what would it be? there are no "void objects" that
>> >> are located somewhere, as void can never be completed to be an object
>> >> type, and the standard does not seem to define a "work around"
>> >> alignment for void that would be compatible with any other object type
>> >> / incomplete type).
>> >
>> >> Paragraph 1 is not based on alignment, but clearly says that any
>> >> object or incomplete type pointee may be converted to void and back.
>> >
>> > So, according to paragraph 1, any pointer to T1 can be converted to
>> > any pointer to T2 in the following way?
>> >
>> > T1 *p;
>> > T2 *q;
>> > q = (T2 *) (void *) p;
>> >
>> Notice that p1 says "... to a pointer to void and back again; ...": You
>> are not converting back again, but you convert further to another type.
>
> I was taking into account the first sentence only (which allows both
> directions: "to or from"). Now there are two possibilities:
>
> 1. If you assume that p7 doesn't apply when one of the pointer is
> void*, then "(T2 *) (void *) p" is *always* allowed due to the
> first sentence of p1, but this is rather strange.
>
I assume that p7 applies when converting from "void*" but not to "void*",
because it says "If the resulting pointer is not correctly aligned for the
pointed-to type, the behavior is undefined. Otherwise, ...". "void" has no
alignment - at least i cannot spot wording saying so :)
In another branch of this thread you quote "A pointer to void shall have the
same representation and alignment requirements as a pointer to a character
type.", but this refers to the type "pointer to void", which is not the
"pointed-to type" of "void*", as referred to by p7. The quote has a foot-
note attached, which explains what it means to say - for instance it
supports code like the following:
void f(v)
void *v; { /* ... */ }
int main() { char *c = 0; f(c); }
Notice that "f" has as parameter "void*", which is not compatible with
"char*", but 6.5.2.2/6 makes an exception here, which makes that valid. To
make this work, the the pointer *objects*, not the pointer values need to
have compatible alignments. In other words, the following must be true:
void *p; (intptr_t)&p % alignof(char*) == 0
However, p7 refers not to the objects (there are no objects involved in a
cast expression), but to the pointer values. It makes that further clear by
saying "If the resulting pointer is not correctly aligned for the pointed-to
type" - i.e it concerns the alignment of the pointed-to type, and not the
alignment of the pointer type itself.
I agree with you that the wording is not clear (especially the foot-note to
p7 confuses me), and your interpretation is equally likely in my opinion.
The above is just my interpretation of the matter :)
This makes it required that any pointer can be converted to a void* and
back again without loss of the 'address' information
>
> but isn't that already covered by 6.3.2.3#7, which is more accurate
> (see the restriction on the alignment, for which #1 says nothing)?
>
> 7 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 aligned59) for the pointed-to type, the
> behavior is undefined. Otherwise, when converted back again, the
> result shall compare equal to the original pointer. [...]
>
This is less specific. Basically it requires that if you can convert
correctly one way then you can convert it back. I am a little unhappy
with this because it seems to assume that the pointers will have the
same storage capacity, but that is not true (remember that one feature
of coid* is that it must have sufficient storage to cope with object
pointers of any other type.) I do not think alignment is enough to cover
this issue.
--
Note that robinton.demon.co.uk addresses are no longer valid.
No because that id not 'back again' but on to some other type.
The void type consists of an empty set of values; it is an incomplete
> I assume that p7 applies when converting from "void*" but not to "void*",
> because it says "If the resulting pointer is not correctly aligned for the
> pointed-to type, the behavior is undefined. Otherwise, ...". "void" has no
> alignment - at least i cannot spot wording saying so :)
Well, I don't see why you're allowed to assume that p7 applies in one
way, but not the other. I could understand that *only* the sentence
"If the resulting pointer is not correctly aligned..." doesn't apply
when the resulting pointer is of type void * if you assume that a
"void *" pointer cannot be aligned (but as I understand the standard,
more than for pointer to objects, the standard defines alignment for
any pointer to an object or incomplete type, and for the values of
pointers to void, there are no alignment requirements).
> In another branch of this thread you quote "A pointer to void shall
> have the same representation and alignment requirements as a pointer
> to a character type.", but this refers to the type "pointer to
> void", which is not the "pointed-to type" of "void*", as referred to
> by p7.
OK, your interpretation is consistent with some other parts of the
standard. But the standard is not really clear as it sometimes says
something like "an object [of type T] is correctly aligned...", "an
address [of object T] is correctly aligned" and "a pointer [to T]
is correctly aligned", and when T is a pointer, this is ambiguous
(even though the context may make the intended meaning more clear).
> The quote has a foot- note attached, which explains what it means to
> say - for instance it supports code like the following:
> void f(v)
> void *v; { /* ... */ }
> int main() { char *c = 0; f(c); }
> Notice that "f" has as parameter "void*", which is not compatible with
> "char*", but 6.5.2.2/6 makes an exception here, which makes that valid. To
> make this work, the the pointer *objects*, not the pointer values need to
> have compatible alignments.
I don't see why the pointer objects need to have compatible alignments
in this example, as the pointers are not necessarily passed via
memory. That would be up to the implementation to decide what is
necessary.
> In other words, the following must be true:
> void *p; (intptr_t)&p % alignof(char*) == 0
> However, p7 refers not to the objects (there are no objects involved in a
> cast expression), but to the pointer values.
I agree.
> It makes that further clear by saying "If the resulting pointer is
> not correctly aligned for the pointed-to type" - i.e it concerns the
> alignment of the pointed-to type, and not the alignment of the
> pointer type itself.
Yes, with the context, it is clear. But IMHO, what "aligned" means
shouldn't be context-dependent.
> I agree with you that the wording is not clear (especially the foot-note to
> p7 confuses me), and your interpretation is equally likely in my opinion.
> The above is just my interpretation of the matter :)
--
Note that my (first) question was *not* whether q compared equal to p,
but whether these casts were allowed by the standard (with typically
implementation-defined behavior in case of bad alignment), only based
on the first sentence of Paragraph 1.
> The void type consists of an empty set of values; it is an incomplete
> type that cannot be completed.
Then, is the notion of alignment for a pointer to void (I mean its
value, or address, not the pointer object itself) defined?
I currently disagree with Johannes Schaub.
I'd say that since the void type consists of an empty set of values,
there are no requirements for a pointer to void, and the notion of
alignment is properly defined for the pointer value. The fact that
a "void object" doesn't exist is IMHO not a reason for saying that
alignment for void * is meaningless (objects of the other incomplete
types don't exist either anyway, even though p7 still fully applies
for such pointers).
> In article <LqudnQNel8pvWpLW...@bt.com>,
> Francis Glassborow <francis.g...@btinternet.com> wrote:
>
>> The void type consists of an empty set of values; it is an incomplete
>> type that cannot be completed.
>
> Then, is the notion of alignment for a pointer to void (I mean its
> value, or address, not the pointer object itself) defined?
>
> I currently disagree with Johannes Schaub.
>
> I'd say that since the void type consists of an empty set of values,
> there are no requirements for a pointer to void, and the notion of
> alignment is properly defined for the pointer value. The fact that
> a "void object" doesn't exist is IMHO not a reason for saying that
> alignment for void * is meaningless (objects of the other incomplete
> types don't exist either anyway, even though p7 still fully applies
> for such pointers).
>
I did not say that alignment for "void*" is meaningless. But alignment for
"void" is. Alignment is defined in 3.2/1: "requirement that objects of a
particular type be located on storage boundaries with addresses that are
particular multiples of a byte address".
That is, an address might or might not be correctly aligned for a given
type. But saying "pointer x is not correctly aligned for void" (as p7 forces
when converting to "void*") does not make sense to me.
That could have been phrased better, but I'm sure it refers to the
alignemnt of the pointed-to object, not to the alignment of the
pointer object itself.
Remember that conversions operate on and yield *values*, not objects.
There is no pointer object whose alignment needs to be considered.
And if you think about it, why should the alignment of a pointer
object make any difference to conversions from one pointer type to
another? On the other hand, it makes sense to consider the alignment
of the pointed-to object. If int objects have to be at even
addresses, and a pointer conversion yields an int* that points to an
odd address, you're in trouble.
--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
> Vincent Lefevre <vincen...@vinc17.org> writes:
> > In article <heod9v$e6t$00$2...@news.t-online.com>,
> > "Johannes Schaub (litb)" <schaub-...@web.de> wrote:
> [...]
> >> No, this is the alignment requirement of pointer to void ("void*"),
> >> but not of "void" itself.
> >
> > I disagree: paragraph 6.3.2.3#7 says
> >
> > "If the resulting pointer is not correctly aligned".
> > ^^^^^^^
> >
> > i.e. what is aligned is not the type, but the pointer.
> That could have been phrased better, but I'm sure it refers to the
> alignemnt of the pointed-to object, not to the alignment of the
> pointer object itself.
I agree, but I meant that when the standard says that the pointer
is (not) correctly aligned, it refers to the alignemnt of the
pointed-to object. The problem is that in 6.2.5#27, the standard
says:
A pointer to void shall have the same representation and alignment
requirements as a pointer to a character type.
so that I thought the standard also referred to the alignemnt of the
pointed-to object (even though there are no objects of type "void",
there are requirements so that a pointer to void can contain the
address of any object), but it refers here to the pointer object
itself.
Also "the resulting pointer" looks incorrect phrasing, because as
I understand the standard, this pointer does not necessarily exist
(as it is not necessarily representable) if alignment requirements
are not satisfied, in particular if a pointer to T does not have
the same size as a pointer to void.
> I did not say that alignment for "void*" is meaningless. But
> alignment for "void" is.
I repeat what the standard says:
7 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 aligned59) for the pointed-to type, the
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There are requirements for the values of a pointer to void, and I'm
saying that this is covered by the above paragraph.
> Alignment is defined in 3.2/1: "requirement that objects of a
> particular type be located on storage boundaries with addresses that
> are particular multiples of a byte address".
> That is, an address might or might not be correctly aligned for a
> given type. But saying "pointer x is not correctly aligned for void"
> (as p7 forces when converting to "void*") does not make sense to me.
If this doesn't make sense to you, why would this make sense for the
other incomplete types?
> I did not say that alignment for "void*" is meaningless. But
> alignment for "void" is.
I repeat what the standard says:
7 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 aligned59) for the pointed-to type, the
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There is an empty set of requirements for the values of a pointer to
void, and I'm saying that this is covered by the above paragraph.
> Alignment is defined in 3.2/1: "requirement that objects of a
> particular type be located on storage boundaries with addresses that
> are particular multiples of a byte address".
> That is, an address might or might not be correctly aligned for a
> given type. But saying "pointer x is not correctly aligned for void"
> (as p7 forces when converting to "void*") does not make sense to me.
If this doesn't make sense to you, why would this make sense for the
other incomplete types?
--
> In article <heonhb$7l2$02$1...@news.t-online.com>,
> "Johannes Schaub (litb)" <schaub-...@web.de> wrote:
>
>> I did not say that alignment for "void*" is meaningless. But
>> alignment for "void" is.
>
> I repeat what the standard says:
>
> 7 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 aligned59) for the pointed-to type, the
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> There is an empty set of requirements for the values of a pointer to
> void, and I'm saying that this is covered by the above paragraph.
>
There is a set of requirements, and you just quoted it: The requirement is
that the address is correctly aligned so it satisfies the alignment of void.
Since the alignment of void is not defined, p7 does not require anything
with regard to converting to "void*", if p1 is missing.
>> Alignment is defined in 3.2/1: "requirement that objects of a
>> particular type be located on storage boundaries with addresses that
>> are particular multiples of a byte address".
>
>> That is, an address might or might not be correctly aligned for a
>> given type. But saying "pointer x is not correctly aligned for void"
>> (as p7 forces when converting to "void*") does not make sense to me.
>
> If this doesn't make sense to you, why would this make sense for the
> other incomplete types?
>
Because the other incomplete types can be completed and then have a known
alignment. Objects can have object types as effective types, and then the
definition of alignment can apply.
If you convert to a pointer to an incomplete type, then you are on your own:
It may work, but it may also not work - if it later when the type is
complete turns out the alignment did not fit. You may live with the risk
when converting to struct pointers, but you don't live with that risk when
converting to "void*" because of p1.
See also the explanations of Keith, Francis and others.
Some operations try to compute the result such that the behavior is not
defined.
In such a situation, it's convenient to talk about the resulting value
anyway.
For instance, the addition of two values of type int is undefined if the
resulting value does not fit into the int type.
There is a resulting value in the abstract sense; the addition has
a mathematical result which we can imagine.
You have go out of your way to be deliberately obtuse to misunderstand this.
> Vincent Lefevre wrote:
> > In article <heonhb$7l2$02$1...@news.t-online.com>,
> > "Johannes Schaub (litb)" <schaub-...@web.de> wrote:
> >
> >> I did not say that alignment for "void*" is meaningless. But
> >> alignment for "void" is.
> >
> > I repeat what the standard says:
> >
> > 7 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 aligned59) for the pointed-to type, the
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >
> > There is an empty set of requirements for the values of a pointer to
> > void, and I'm saying that this is covered by the above paragraph.
> >
> There is a set of requirements, and you just quoted it: The requirement is
> that the address is correctly aligned so it satisfies the alignment of void.
The standard does not say that. There's an "if" clause, which can be
interpreted in slightly different ways (different, but equivalent),
but all what one can say is that this "if" clause is always false, so
that the behavior of the pointer conversion is always defined (this
is just logic).
> Since the alignment of void is not defined, p7 does not require anything
> with regard to converting to "void*", if p1 is missing.
The standard doesn't require the alignment of void to be defined; p7
doesn't even mention the alignment of void, just a property of the
pointer value.
As the set of requirements is satisfied, p7 becomes for void*:
A pointer to an object or incomplete type may be converted to
a pointer to void. When converted back again, the result shall
compare equal to the original pointer. [...]
and then, no need for p1.
> > If this doesn't make sense to you, why would this make sense for the
> > other incomplete types?
> >
> Because the other incomplete types can be completed and then have a known
> alignment.
That standard doesn't say that they are completed for the alignment
definition. Perhaps you can regard that as implicit, but one could
also say implicitly that the alignment requirement of a void* is the
same as the alignment requirement of a char* (the fact that both
pointers necessarily have the same representation is a start).