Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.std.c > #1805 > unrolled thread

C11 6.3.2.3p7 Referenced Type

Started byShao Miller <sha0.miller@gmail.com>
First post2013-01-04 02:08 -0500
Last post2013-01-06 22:02 -0800
Articles 20 on this page of 21 — 5 participants

Back to article view | Back to comp.std.c


Contents

  C11 6.3.2.3p7 Referenced Type Shao Miller <sha0.miller@gmail.com> - 2013-01-04 02:08 -0500
    Re: C11 6.3.2.3p7 Referenced Type Keith Thompson <kst-u@mib.org> - 2013-01-04 08:09 -0800
      Re: C11 6.3.2.3p7 Referenced Type Shao Miller <sha0.miller@gmail.com> - 2013-01-04 12:25 -0500
      Re: C11 6.3.2.3p7 Referenced Type lawrence.jones@siemens.com - 2013-01-04 13:47 -0500
        Re: C11 6.3.2.3p7 Referenced Type Shao Miller <sha0.miller@gmail.com> - 2013-01-04 14:56 -0500
          Re: C11 6.3.2.3p7 Referenced Type lawrence.jones@siemens.com - 2013-01-04 17:10 -0500
            Re: C11 6.3.2.3p7 Referenced Type Shao Miller <sha0.miller@gmail.com> - 2013-01-04 20:34 -0500
    Re: C11 6.3.2.3p7 Referenced Type Wojtek Lerch <wojtek_l@yahoo.ca> - 2013-01-04 23:45 -0500
      Re: C11 6.3.2.3p7 Referenced Type Shao Miller <sha0.miller@gmail.com> - 2013-01-05 02:07 -0500
        Re: C11 6.3.2.3p7 Referenced Type Shao Miller <sha0.miller@gmail.com> - 2013-01-05 02:16 -0500
      Re: C11 6.3.2.3p7 Referenced Type Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-06 17:25 -0800
        Re: C11 6.3.2.3p7 Referenced Type Wojtek Lerch <wojtek_l@yahoo.ca> - 2013-01-06 22:13 -0500
          Re: C11 6.3.2.3p7 Referenced Type Shao Miller <sha0.miller@gmail.com> - 2013-01-06 23:30 -0500
            Re: C11 6.3.2.3p7 Referenced Type Wojtek Lerch <wojtek_l@yahoo.ca> - 2013-01-07 00:07 -0500
              Re: C11 6.3.2.3p7 Referenced Type Shao Miller <sha0.miller@gmail.com> - 2013-01-07 01:29 -0500
                Re: C11 6.3.2.3p7 Referenced Type Shao Miller <sha0.miller@gmail.com> - 2013-01-07 02:18 -0500
                Re: C11 6.3.2.3p7 Referenced Type Wojtek Lerch <wojtek_l@yahoo.ca> - 2013-01-10 17:45 -0500
            Re: C11 6.3.2.3p7 Referenced Type Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-06 22:30 -0800
              Re: C11 6.3.2.3p7 Referenced Type Shao Miller <sha0.miller@gmail.com> - 2013-01-07 01:58 -0500
                Re: C11 6.3.2.3p7 Referenced Type Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-06 23:16 -0800
          Re: C11 6.3.2.3p7 Referenced Type Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-06 22:02 -0800

Page 1 of 2  [1] 2  Next page →


#1805 — C11 6.3.2.3p7 Referenced Type

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-04 02:08 -0500
SubjectC11 6.3.2.3p7 Referenced Type
Message-ID<kc5v4n$ing$1@dont-email.me>
I noticed a change between N1256 and N1570:

   "A pointer to an object type may be converted to a pointer to a 
different object type. If the resulting pointer is not correctly 
aligned68) for the referenced 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."

"Referenced type"?  Is this:
   1. The original type of the value to undergo conversion?
   2. The target type of the converted value?
   3. The original type of the pointee that is pointed-to by the value 
to undergo conversion?
   4. The pointed-to type that is the type whence the target type is 
derived?

The C99 wording:

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

Has this already been discussed, before?  Has this been adjusted in the 
actual Standards?

I wouldn't've guessed that a conversion resulting in an rvalue would 
have any alignment concerns for the rvalue itself, so I'd cross out #1 
and #2.  The C99 "pointed-to" following closely after "resulting 
pointer" makes me think #4, but now it's gone from C11, so I'm more 
concerned about which is right.

- Shao Miller

[toc] | [next] | [standalone]


#1806

FromKeith Thompson <kst-u@mib.org>
Date2013-01-04 08:09 -0800
Message-ID<ln8v8953rm.fsf@nuthaus.mib.org>
In reply to#1805
Shao Miller <sha0.miller@gmail.com> writes:
> I noticed a change between N1256 and N1570:
>
>    "A pointer to an object type may be converted to a pointer to a 
> different object type. If the resulting pointer is not correctly 
> aligned68) for the referenced 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."
>
> "Referenced type"?  Is this:
>    1. The original type of the value to undergo conversion?
>    2. The target type of the converted value?
>    3. The original type of the pointee that is pointed-to by the value 
> to undergo conversion?
>    4. The pointed-to type that is the type whence the target type is 
> derived?
>
> The C99 wording:
>
>    "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. 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."
>
> Has this already been discussed, before?  Has this been adjusted in the 
> actual Standards?

I don't think this is a significant change.  Diffing the two versions of
the paragraph, the changes are:

- "object or incomplete type" --> "object type" (due to C11's change in
  the definition of "object type" to include incomplete types;

- "pointed-to type" to "referenced type"

(and a change in the footnote number).

Probably the committee, or perhaps just the editor, thought that
"referenced type" was a better wording than "pointed-to type".

I believe it simply refers to the type to which the pointer resulting
from the conversion points, your option #4.  I don't see a mystery
here; the wording, and its meaning, seem fairly straightforward.

The alignment of the object pointed to by the pointer *before* the
conversion (option #3) isn't relevant; if that pointed-to object
isn't correctly aligned, the construction of that pointer value
itself would have had undefined behavior, before the conversion in
question is evaluated.

> I wouldn't've guessed that a conversion resulting in an rvalue would 
> have any alignment concerns for the rvalue itself, so I'd cross out #1 
> and #2.  The C99 "pointed-to" following closely after "resulting 
> pointer" makes me think #4, but now it's gone from C11, so I'm more 
> concerned about which is right.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#1807

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-04 12:25 -0500
Message-ID<kc73b1$26o$1@dont-email.me>
In reply to#1806
On 1/4/2013 11:09, Keith Thompson wrote:
> Shao Miller <sha0.miller@gmail.com> writes:
>> I noticed a change between N1256 and N1570:
>>
>>     "A pointer to an object type may be converted to a pointer to a
>> different object type. If the resulting pointer is not correctly
>> aligned68) for the referenced 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."
>>
>> "Referenced type"?  Is this:
>>     1. The original type of the value to undergo conversion?
>>     2. The target type of the converted value?
>>     3. The original type of the pointee that is pointed-to by the value
>> to undergo conversion?
>>     4. The pointed-to type that is the type whence the target type is
>> derived?
>>
>> The C99 wording:
>>
>>     "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. 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."
>>
>> Has this already been discussed, before?  Has this been adjusted in the
>> actual Standards?
>
> I don't think this is a significant change.  Diffing the two versions of
> the paragraph, the changes are:
>
> - "object or incomplete type" --> "object type" (due to C11's change in
>    the definition of "object type" to include incomplete types;
>
> - "pointed-to type" to "referenced type"
>
> (and a change in the footnote number).
>
> Probably the committee, or perhaps just the editor, thought that
> "referenced type" was a better wording than "pointed-to type".
>
> I believe it simply refers to the type to which the pointer resulting
> from the conversion points, your option #4.  I don't see a mystery
> here; the wording, and its meaning, seem fairly straightforward.
>

Thank you, Keith.  Someone else who I respect really didn't interpret 
C99's version the same way (they held #2), then found the change in C11 
as further evidence to support that other interpretation.  Something 
along the lines of "C99 could have led to #4 due to ambiguity, but C11 
removed the ambiguity, so it's been recognized as needing fixing and 
been fixed so it doesn't lead to #4."  D'oh.

> The alignment of the object pointed to by the pointer *before* the
> conversion (option #3) isn't relevant; if that pointed-to object
> isn't correctly aligned, the construction of that pointer value
> itself would have had undefined behavior, before the conversion in
> question is evaluated.
>

That makes sense.  I find #3 a bit difficult to grok, actually.

   A a;
   (B *) &a;

I guess it asks "does the alignment requirement of a 'B' satisfy any 
'A'," where a 'B' could have a weaker alignment than an 'A', so could be 
false.  The explicit mention of character pointers and the earlier 
paragraph for 'void *' could potentially be construed to support that 
interpretation. *boggle*

Anyway, thanks again.

>> I wouldn't've guessed that a conversion resulting in an rvalue would
>> have any alignment concerns for the rvalue itself, so I'd cross out #1
>> and #2.  The C99 "pointed-to" following closely after "resulting
>> pointer" makes me think #4, but now it's gone from C11, so I'm more
>> concerned about which is right.
>

- Shao Miller

[toc] | [prev] | [next] | [standalone]


#1808

Fromlawrence.jones@siemens.com
Date2013-01-04 13:47 -0500
Message-ID<tnkjr9-gn9.ln1@jones.homeip.net>
In reply to#1806
Keith Thompson <kst-u@mib.org> wrote:
> 
> Probably the committee, or perhaps just the editor, thought that
> "referenced type" was a better wording than "pointed-to type".

"Referenced type" is a defined term in 6.2.5p20 (bullet 5).  It also
appears in the index.
-- 
Larry Jones

The game's called on account of sudden death. -- Calvin

[toc] | [prev] | [next] | [standalone]


#1809

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-04 14:56 -0500
Message-ID<kc7c5b$pq3$1@dont-email.me>
In reply to#1808
On 1/4/2013 13:47, lawrence.jones@siemens.com wrote:
> Keith Thompson <kst-u@mib.org> wrote:
>>
>> Probably the committee, or perhaps just the editor, thought that
>> "referenced type" was a better wording than "pointed-to type".
>
> "Referenced type" is a defined term in 6.2.5p20 (bullet 5).  It also
> appears in the index.
>

D'oh!  Thanks.  Can I believe that in the context of pointer conversion, 
that the discussion is for the reference type of the conversion-target 
pointer type?  That's my current belief.

- Shao Miller

[toc] | [prev] | [next] | [standalone]


#1810

Fromlawrence.jones@siemens.com
Date2013-01-04 17:10 -0500
Message-ID<gk0kr9-or9.ln1@jones.homeip.net>
In reply to#1809
Shao Miller <sha0.miller@gmail.com> wrote:
> On 1/4/2013 13:47, lawrence.jones@siemens.com wrote:
> > Keith Thompson <kst-u@mib.org> wrote:
> >>
> >> Probably the committee, or perhaps just the editor, thought that
> >> "referenced type" was a better wording than "pointed-to type".
> >
> > "Referenced type" is a defined term in 6.2.5p20 (bullet 5).  It also
> > appears in the index.
> 
> D'oh!  Thanks.  Can I believe that in the context of pointer conversion, 
> that the discussion is for the reference type of the conversion-target 
> pointer type?  That's my current belief.

You can believe whatever you want to. :-)

But yes, that's the intent.
-- 
Larry Jones

Why can't I ever build character in a Miami condo or a casino somewhere?
-- Calvin

[toc] | [prev] | [next] | [standalone]


#1811

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-04 20:34 -0500
Message-ID<kc7vug$ej0$1@dont-email.me>
In reply to#1810
On 1/4/2013 17:10, lawrence.jones@siemens.com wrote:
> Shao Miller <sha0.miller@gmail.com> wrote:
>> On 1/4/2013 13:47, lawrence.jones@siemens.com wrote:
>>> Keith Thompson <kst-u@mib.org> wrote:
>>>>
>>>> Probably the committee, or perhaps just the editor, thought that
>>>> "referenced type" was a better wording than "pointed-to type".
>>>
>>> "Referenced type" is a defined term in 6.2.5p20 (bullet 5).  It also
>>> appears in the index.
>>
>> D'oh!  Thanks.  Can I believe that in the context of pointer conversion,
>> that the discussion is for the reference type of the conversion-target
>> pointer type?  That's my current belief.
>
> You can believe whatever you want to. :-)
>
> But yes, that's the intent.
>

Thank you, sir!  Please forgive my earlier lack of diligence...  For 
some silly reason, I assumed that "referenced type" was some kind of C++ 
import into C11, and I neglected to search for the term before asking, 
here.  I'll try not to do that again.

- Shao Miller

[toc] | [prev] | [next] | [standalone]


#1812

FromWojtek Lerch <wojtek_l@yahoo.ca>
Date2013-01-04 23:45 -0500
Message-ID<akppc6Favm8U1@mid.individual.net>
In reply to#1805
On 04/01/2013 2:08 AM, Shao Miller wrote:
...

>    "A pointer to an object type may be converted to a pointer to a
> different object type. If the resulting pointer is not correctly
> aligned) for the referenced type, the behavior is undefined.

What I don't like about this wording (both old and new) is that it talks 
about the alignment of the *resulting* pointer, even though the standard 
does not generally specify what the result of the conversion is (other 
than that it's a pointer that can be converted back; a few exceptions 
include conversions to char*, between pointers to a struct and to the 
type of its first member, etc.).  Would it be wrong to say, instead, 
that the behaviour is undefined if the *original* pointer, the one 
before the conversion, is not correctly aligned for the type referenced 
by the type of the result?  Or to say, separately, that if the original 
pointer satisfies the alignment requirements of some type, then the 
converted pointer satisfies them too?

Or maybe even that the converted pointer points at the same byte in 
memory than the original pointer did (using some more formal wording)? 
I've seen claims that this follows from some other requirements of the 
standard (C99 at the time), but I never managed to find them.

[toc] | [prev] | [next] | [standalone]


#1813

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-05 02:07 -0500
Message-ID<kc8jfp$uk6$1@dont-email.me>
In reply to#1812
On 1/4/2013 23:45, Wojtek Lerch wrote:
> On 04/01/2013 2:08 AM, Shao Miller wrote:
> ...
>
>>    "A pointer to an object type may be converted to a pointer to a
>> different object type. If the resulting pointer is not correctly
>> aligned for the referenced type, the behavior is undefined.
>
> What I don't like about this wording (both old and new) is that it talks
> about the alignment of the *resulting* pointer, even though the standard
> does not generally specify what the result of the conversion is (other
> than that it's a pointer that can be converted back; a few exceptions
> include conversions to char*, between pointers to a struct and to the
> type of its first member, etc.).  Would it be wrong to say, instead,
> that the behaviour is undefined if the *original* pointer, the one
> before the conversion, is not correctly aligned for the type referenced
> by the type of the result?  Or to say, separately, that if the original
> pointer satisfies the alignment requirements of some type, then the
> converted pointer satisfies them too?
>
> Or maybe even that the converted pointer points at the same byte in
> memory than the original pointer did (using some more formal wording)?
> I've seen claims that this follows from some other requirements of the
> standard (C99 at the time), but I never managed to find them.
>

Agreed.  That was part of the discussion I had yesterday or so...  My 
interpretation is that it means:

   "A pointer to an object type may be converted to a pointer to a 
different object type.  If the resulting pointer does not address 
storage that is correctly aligned for the referenced type of the 
converted pointer type, the behavior is undefined. ..."

C99 was a touch clearer, in my opinion, because it's not intuitive (to 
me, at least) that the _result_'s alignment requirement should have 
anything at all to do with "the pointed-to type", at least in part 
because it's at least sometimes an rvalue (whose alignment requirement 
doesn't seem intuitive to care about).  So I make the leap from:

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

to:

   "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 does not address storage that is correctly aligned57) for the 
pointed-to type of the converted pointer type, the behavior is 
undefined. ..."

A bit of a boggle, to be sure.

- Shao Miller

[toc] | [prev] | [next] | [standalone]


#1814

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-05 02:16 -0500
Message-ID<kc8k00$dv$1@dont-email.me>
In reply to#1813
On 1/5/2013 02:07, Shao Miller wrote:
>
>    "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 does not address storage that is correctly aligned57) for the
> pointed-to type of the converted pointer type, the behavior is
> undefined. ..."
>

But in fact, even that's not quite right...  "converted" in the last 
sentence could be ambiguous for "to-be-converted" or "result of the 
conversion's".  D'oh.  - Shao

[toc] | [prev] | [next] | [standalone]


#1818

FromTim Rentsch <txr@alumni.caltech.edu>
Date2013-01-06 17:25 -0800
Message-ID<kfn1udxdbru.fsf@x-alumni2.alumni.caltech.edu>
In reply to#1812
Wojtek Lerch <wojtek_l@yahoo.ca> writes:

> On 04/01/2013 2:08 AM, Shao Miller wrote:
> ...
>
>>    "A pointer to an object type may be converted to a pointer to a
>> different object type. If the resulting pointer is not correctly
>> aligned) for the referenced type, the behavior is undefined.
>
> What I don't like about this wording (both old and new) is that it
> talks about the alignment of the *resulting* pointer, even though the
> standard does not generally specify what the result of the conversion
> is (other than that it's a pointer that can be converted back; a few
> exceptions include conversions to char*, between pointers to a struct
> and to the type of its first member, etc.).  Would it be wrong to say,
> instead, that the behaviour is undefined if the *original* pointer,
> the one before the conversion, is not correctly aligned for the type
> referenced by the type of the result?  Or to say, separately, that if
> the original pointer satisfies the alignment requirements of some
> type, then the converted pointer satisfies them too?

I think it's instructive to trace the history of the rules for
pointer conversions, starting with C89/C90, through C99, and
finally to C11 (which has basically the same rules as C99 but
also gives a more well-defined notion of alignment, for the
purposes of the new alignment-related constructs).  It's hard to
talk about alignment without talking about the addressing
structure used by the underlying hardware;  an example in the
Rationale illustrates the issue.  To avoid giving any reference
to whatever underlying addressing scheme is used, the notion of
alignment for pointer types is defined only for a pointer of the
type whose alignment requirements might be violated.  (Of course
the alignment I'm referring to here is the alignment of whatever
the pointer might refer to, not the alignment of an object that
holds the pointer value.)  Compare the rules for converting one
pointer type to another to the rules for converting an integer
value to a pointer type.  Clearly there was some idea that these
would be parallel constructions, which can work if the condition
of being properly aligned is defined just in terms of the type
after conversion.

Returning to your questions - I don't think either statement is
wrong, but I also don't think putting them in the Standard (ie, as
normative text - footnotes are different) would really help, and
might make things worse:  we take out one poorly defined notion (a
pointer value not being aligned for its type), but we get back a
much larger poorly defined notion (a pointer value being aligned or
not aligned, separately, for _every_ object type).  I sympathize
with the desire for better language here to express what is meant
more clearly.  I'm just not sure how much benefit there would be
to shift the burden of "being correctly defined for type X" from
the destination pointer to the source pointer.  And there is the
question of how to talk about converting an integer value to a
pointer type.

> Or maybe even that the converted pointer points at the same byte in
> memory than the original pointer did (using some more formal wording)?
> I've seen claims that this follows from some other requirements of the
> standard (C99 at the time), but I never managed to find them.

I believe there is no real doubt about how the committee expects
the existing language should be read:  when converting from type
A* to type B*, if the first byte of the A object is suitably
positioned in the addressing structure (as used in the A* pointer)
so that an object of type B may begin there (under the appropriate
addressing structure for B, given that the B* value is converted
from the A* pointer), then the conversion will succeed with
alignment requirements being satisfied;  the object designated by
the post-conversion pointer has the same first byte as the object
designated by the pre-conversion pointer;  and converting back and
forth works, changing the types but preserving the same first byte
property between the two objects (so first converting to (char *)
or (void *) and then converting to the target type would give the
same result as converting directly to the target type).

Assuming there is general agreement that this basically is what
the Standard is supposed to say, the question is how to say it
in a way that can be used consistently with what all else the
Standard says about alignment, but without tying the wording to
any underlying addressing structure.  I suspect that's not an
easy proposition, which is why we have the somewhat convoluted
wording describing how pointer conversions work, still, in C11.

[toc] | [prev] | [next] | [standalone]


#1819

FromWojtek Lerch <wojtek_l@yahoo.ca>
Date2013-01-06 22:13 -0500
Message-ID<akusqqFg0qhU1@mid.individual.net>
In reply to#1818
On 06/01/2013 8:25 PM, Tim Rentsch wrote:
> I believe there is no real doubt about how the committee expects
> the existing language should be read:  when converting from type
> A* to type B*, if the first byte of the A object is suitably
> positioned in the addressing structure (as used in the A* pointer)
> so that an object of type B may begin there (under the appropriate
> addressing structure for B, given that the B* value is converted
> from the A* pointer), then the conversion will succeed with
> alignment requirements being satisfied;

I agree that that's probably what "everybody knows" is expected to 
happen.  But I really don't see where the standard says it.

>   the object designated by
> the post-conversion pointer

There's not always a guarantee that the post-conversion pointer points 
to an object (of its referenced type).  There may not be enough memory 
there.  (But even if there isn't, the pointer conversion is still defined.)

>  has the same first byte as the object
> designated by the pre-conversion pointer;  and converting back and
> forth works, changing the types but preserving the same first byte
> property between the two objects (so first converting to (char *)
> or (void *) and then converting to the target type would give the
> same result as converting directly to the target type).

> Assuming there is general agreement that this basically is what
> the Standard is supposed to say, the question is how to say it
> in a way that can be used consistently with what all else the
> Standard says about alignment, but without tying the wording to
> any underlying addressing structure.  I suspect that's not an
> easy proposition, which is why we have the somewhat convoluted
> wording describing how pointer conversions work, still, in C11.

First I would like to know whether the standard already says it or not.

Consider this simple example:

   int main( void ) {
     if ( _Alignof(int) <= _Alignof(float) ) {
       float f;
       int n, *p = (int*) &f;
       if ( p == &n )
         puts( "They're equal!" );
     }
   }

It this program produces output on some implementation, which 
requirement of the standard does the implementation violate?  (Chapter 
and verse please.)

[toc] | [prev] | [next] | [standalone]


#1820

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-06 23:30 -0500
Message-ID<kcdj0t$g3v$1@dont-email.me>
In reply to#1819
On 1/6/2013 22:13, Wojtek Lerch wrote:
>
> Consider this simple example:
>
>    int main( void ) {
>      if ( _Alignof(int) <= _Alignof(float) ) {
>        float f;
>        int n, *p = (int*) &f;
>        if ( p == &n )
>          puts( "They're equal!" );
>      }
>    }
>
> It this program produces output on some implementation, which
> requirement of the standard does the implementation violate?  (Chapter
> and verse please.)
>

I enjoyed the co-incidence that my news-reader interpreted the two 
asterisks and made the contained text bold, effectively highlighting 
nearby what seems to be "the important part." :)

If I've followed along correctly, the question is: Is a converted 
pointer defined to point to the same object as the original, or only the 
result of its conversion back to the original pointer type?

I don't see why this example should be prohibited.  'n' is never 
accessed, so an implementation could choose to put it in the same place 
where 'f' is.  As an implementation, I'd enjoy that kind of freedom, for 
conservation of storage.

I think a quirkier example would use the result of 'malloc'.  Would a 
'float *' pointing into allocated storage, converted to 'int *', 
suddenly be permitted to point someplace else?  We already know the 
alignments are satisfactory.

- Shao Miller

[toc] | [prev] | [next] | [standalone]


#1821

FromWojtek Lerch <wojtek_l@yahoo.ca>
Date2013-01-07 00:07 -0500
Message-ID<akv3c8Fh7f0U1@mid.individual.net>
In reply to#1820
On 06/01/2013 11:30 PM, Shao Miller wrote:
> On 1/6/2013 22:13, Wojtek Lerch wrote:
>>
>>    int main( void ) {
>>      if ( _Alignof(int) <= _Alignof(float) ) {
>>        float f;
>>        int n, *p = (int*) &f;
>>        if ( p == &n )
>>          puts( "They're equal!" );
>>      }
>>    }
>>
>> If this program produces output on some implementation, which
>> requirement of the standard does the implementation violate?  (Chapter
>> and verse please.)
...
> If I've followed along correctly, the question is: Is a converted
> pointer defined to point to the same object as the original, or only the
> result of its conversion back to the original pointer type?

Yes.  And if it's the first one, then where does the standard say it?

> I don't see why this example should be prohibited.
>   'n' is never
> accessed, so an implementation could choose to put it in the same place
> where 'f' is.

The implementation is free to completely optimize them out and not put 
them anywhere at all, but that does not change the fact that in the 
abstract machine their addresses must be different.  If I changed the 
check to "if ( (char*)&f == (char*)&n )", it would be required to return 
false, regardless of whether f and n are accessed or not.  Of course, 
any decent implementation will generate the same code that it would if I 
wrote if(0), without any actual comparing of addresses at runtime.

How about this then:

   float f;
   int n, *p = (int*) &f;
   char *x = (char*)&f, *y = (char*) p;
   if ( x != y ) ...

In other words, does the standard guarantee that (char*)(int*)&x, if 
defined, must be equal to (char*)&x?


>   As an implementation, I'd enjoy that kind of freedom, for
> conservation of storage.

Sure, as long you follow the observable behaviour of the abstract 
machine.  In the abstract machine, n and f are distinct objects and they 
don't overlap.

[toc] | [prev] | [next] | [standalone]


#1824

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-07 01:29 -0500
Message-ID<kcdpvu$adf$1@dont-email.me>
In reply to#1821
On 1/7/2013 00:07, Wojtek Lerch wrote:
> On 06/01/2013 11:30 PM, Shao Miller wrote:
>> On 1/6/2013 22:13, Wojtek Lerch wrote:
>>>
>>>    int main( void ) {
>>>      if ( _Alignof(int) <= _Alignof(float) ) {
>>>        float f;
>>>        int n, *p = (int*) &f;
>>>        if ( p == &n )
>>>          puts( "They're equal!" );
>>>      }
>>>    }
>>>
>>> If this program produces output on some implementation, which
>>> requirement of the standard does the implementation violate?  (Chapter
>>> and verse please.)
> ...
>> If I've followed along correctly, the question is: Is a converted
>> pointer defined to point to the same object as the original, or only the
>> result of its conversion back to the original pointer type?
>
> Yes.  And if it's the first one, then where does the standard say it?
>
>> I don't see why this example should be prohibited.
>>   'n' is never
>> accessed, so an implementation could choose to put it in the same place
>> where 'f' is.
>
> The implementation is free to completely optimize them out and not put
> them anywhere at all, but that does not change the fact that in the
> abstract machine their addresses must be different.  If I changed the
> check to "if ( (char*)&f == (char*)&n )", it would be required to return
> false, regardless of whether f and n are accessed or not.  Of course,
> any decent implementation will generate the same code that it would if I
> wrote if(0), without any actual comparing of addresses at runtime.
>

Agreed.  And of course, you didn't use that 'if'. :)

> How about this then:
>
>    float f;
>    int n, *p = (int*) &f;
>    char *x = (char*)&f, *y = (char*) p;
>    if ( x != y ) ...
>
> In other words, does the standard guarantee that (char*)(int*)&x, if
> defined, must be equal to (char*)&x?
>

(I think you meant to ask about '(char*)(int*)&f' and '(char*)&f', and 
'n' seems to have lost its relevance.)

I think that example has the same consideration as the last one.  If 'p' 
(or '(int*)&f' can point to an object than than 'f', then '(char*)p' can 
point to the lowest-addressed byte of that other object.  But 
'(float*)p' had better point to 'f' again.

One way this might happen is if, for the values of 'int *' and 'float 
*', pointers are simply indices, and '&f' means "the first float in the 
program" and '&n' means "the first int in the program".  'char *' and 
'void *' (etc.) might have a greater range of meanings/values.

   &f              : "First float in the program"
   x = (char *) &f : "Address such-and-such of first float"
   (float *) x     : "Address - all floats = First float again"

   p = (int *) &f  : "First int in the program?!"
   (int *) 1       : "First int in the program" (why not?)
   y = (char *) p  : "Address such-and-such of first int"
   (float *) y     : "Address - all floats = Wrong table/segment!"
   (float *) p     : "First float in the program"

Eep.  This would be scary.

>
>>   As an implementation, I'd enjoy that kind of freedom, for
>> conservation of storage.
>
> Sure, as long you follow the observable behaviour of the abstract
> machine.  In the abstract machine, n and f are distinct objects and they
> don't overlap.

Agreed.  Perhaps there's a mention of "same object" somewhere...

- Shao Miller

[toc] | [prev] | [next] | [standalone]


#1828

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-07 02:18 -0500
Message-ID<kcdsrv$li0$1@dont-email.me>
In reply to#1824
On 1/7/2013 01:29, Shao Miller wrote:
> On 1/7/2013 00:07, Wojtek Lerch wrote:
>> On 06/01/2013 11:30 PM, Shao Miller wrote:
>>> On 1/6/2013 22:13, Wojtek Lerch wrote:
>>>>
>>>>    int main( void ) {
>>>>      if ( _Alignof(int) <= _Alignof(float) ) {
>>>>        float f;
>>>>        int n, *p = (int*) &f;
>>>>        if ( p == &n )
>>>>          puts( "They're equal!" );
>>>>      }
>>>>    }
>>>>
>>>> If this program produces output on some implementation, which
>>>> requirement of the standard does the implementation violate?  (Chapter
>>>> and verse please.)
>> ...
>>> If I've followed along correctly, the question is: Is a converted
>>> pointer defined to point to the same object as the original, or only the
>>> result of its conversion back to the original pointer type?
>>
>> Yes.  And if it's the first one, then where does the standard say it?
>>
>>> I don't see why this example should be prohibited.
>>>   'n' is never
>>> accessed, so an implementation could choose to put it in the same place
>>> where 'f' is.
>>
>> The implementation is free to completely optimize them out and not put
>> them anywhere at all, but that does not change the fact that in the
>> abstract machine their addresses must be different.  If I changed the
>> check to "if ( (char*)&f == (char*)&n )", it would be required to return
>> false, regardless of whether f and n are accessed or not.  Of course,
>> any decent implementation will generate the same code that it would if I
>> wrote if(0), without any actual comparing of addresses at runtime.
>>
>
> Agreed.  And of course, you didn't use that 'if'. :)
>
>> How about this then:
>>
>>    float f;
>>    int n, *p = (int*) &f;
>>    char *x = (char*)&f, *y = (char*) p;
>>    if ( x != y ) ...
>>
>> In other words, does the standard guarantee that (char*)(int*)&x, if
>> defined, must be equal to (char*)&x?
>>
>
> (I think you meant to ask about '(char*)(int*)&f' and '(char*)&f', and
> 'n' seems to have lost its relevance.)
>
> I think that example has the same consideration as the last one.  If 'p'
> (or '(int*)&f' can point to an object than than 'f', then '(char*)p' can
> point to the lowest-addressed byte of that other object.  But
> '(float*)p' had better point to 'f' again.
>
> One way this might happen is if, for the values of 'int *' and 'float
> *', pointers are simply indices, and '&f' means "the first float in the
> program" and '&n' means "the first int in the program".  'char *' and
> 'void *' (etc.) might have a greater range of meanings/values.
>

Please allow me to re-phrase:

If this is really permitted for a conforming implementation, one way a 
particularly counter-intuitive implementation might make use of that 
allowance is if, for the values of 'int *' and 'float *', pointers are 
simply indices, and '&f' means "the first float in the program" and '&n' 
means "the first int in the program".  'char *' and 'void *' (etc.) 
might have a greater range of meanings/values.

>    &f              : "First float in the program"
>    x = (char *) &f : "Address such-and-such of first float"
>    (float *) x     : "Address - all floats = First float again"
>
>    p = (int *) &f  : "First int in the program?!"
>    (int *) 1       : "First int in the program" (why not?)
>    y = (char *) p  : "Address such-and-such of first int"
>    (float *) y     : "Address - all floats = Wrong table/segment!"
>    (float *) p     : "First float in the program"
>
> Eep.  This would be scary.
>
>>
>>>   As an implementation, I'd enjoy that kind of freedom, for
>>> conservation of storage.
>>
>> Sure, as long you follow the observable behaviour of the abstract
>> machine.  In the abstract machine, n and f are distinct objects and they
>> don't overlap.
>
> Agreed.  Perhaps there's a mention of "same object" somewhere...
>
> - Shao Miller

[toc] | [prev] | [next] | [standalone]


#1832

FromWojtek Lerch <wojtek_l@yahoo.ca>
Date2013-01-10 17:45 -0500
Message-ID<al8ujmFovdiU1@mid.individual.net>
In reply to#1824
On 07-Jan-13 1:29 AM, Shao Miller wrote:
> On 1/7/2013 00:07, Wojtek Lerch wrote:
>> In other words, does the standard guarantee that (char*)(int*)&x, if
>> defined, must be equal to (char*)&x?
>
> (I think you meant to ask about '(char*)(int*)&f' and '(char*)&f', and
> 'n' seems to have lost its relevance.)

Actually I meant to ask generally, without necessarily referring to the 
code above -- substitute "(char*)(int*)&lval" and "(char*)&lval"...  The 
only relevance of "n" was as a possible reference in "What if 
(int*)&lval points to some other object, let's call it 'n'?"

> I think that example has the same consideration as the last one.  If 'p'
> (or '(int*)&f' can point to an object than than 'f', then '(char*)p' can
> point to the lowest-addressed byte of that other object.  But
> '(float*)p' had better point to 'f' again.

Right.  But maybe it's a better example.

> One way this might happen is if, for the values of 'int *' and 'float
> *', pointers are simply indices, and '&f' means "the first float in the
> program" and '&n' means "the first int in the program".  'char *' and
> 'void *' (etc.) might have a greater range of meanings/values.

> Eep.  This would be scary.

Sure; this doesn't sound like a practical rule that a sane 
implementation might reasonably want to apply to all programs. 
Typically for C, unions and pointers to allocated memory mess things up. 
  But as far as I know, implementations aren't required to apply the 
same rules to all programs -- if a compiler only applies your 
index-based implementation of pointers only for programs that are simple 
enough to make it work, that's good enough as an example.

[toc] | [prev] | [next] | [standalone]


#1825

FromTim Rentsch <txr@alumni.caltech.edu>
Date2013-01-06 22:30 -0800
Message-ID<kfnk3rpbj3b.fsf@x-alumni2.alumni.caltech.edu>
In reply to#1820
Shao Miller <sha0.miller@gmail.com> writes:

> On 1/6/2013 22:13, Wojtek Lerch wrote:
>>
>> Consider this simple example:
>>
>>    int main( void ) {
>>      if ( _Alignof(int) <= _Alignof(float) ) {
>>        float f;
>>        int n, *p = (int*) &f;
>>        if ( p == &n )
>>          puts( "They're equal!" );
>>      }
>>    }
>>
>> It this program produces output on some implementation, which
>> requirement of the standard does the implementation violate?  (Chapter
>> and verse please.)
>
> [snip]
>
> I don't see why this example should be prohibited.  'n' is never
> accessed, so an implementation could choose to put it in the same
> place where 'f' is.  [snip elaboration]

You've made a common mistake here.  You start with a statement
about something you think an implementation might benefit from
doing, and use that to draw a conclusion about what the Standard
allows.  The reasoning process needs to go the other direction:
start with what the Standard allows (or more importantly in this
case, what it effectively prohibits), and show that a conforming
implementation could act as suggested and still not violate any
requirements.  The reasoning given above proves nothing at all.

[toc] | [prev] | [next] | [standalone]


#1826

FromShao Miller <sha0.miller@gmail.com>
Date2013-01-07 01:58 -0500
Message-ID<kcdrm0$h48$1@dont-email.me>
In reply to#1825
On 1/7/2013 01:30, Tim Rentsch wrote:
> Shao Miller <sha0.miller@gmail.com> writes:
>
>> On 1/6/2013 22:13, Wojtek Lerch wrote:
>>>
>>> Consider this simple example:
>>>
>>>     int main( void ) {
>>>       if ( _Alignof(int) <= _Alignof(float) ) {
>>>         float f;
>>>         int n, *p = (int*) &f;
>>>         if ( p == &n )
>>>           puts( "They're equal!" );
>>>       }
>>>     }
>>>
>>> It this program produces output on some implementation, which
>>> requirement of the standard does the implementation violate?  (Chapter
>>> and verse please.)
>>
>> [snip]
>>
>> I don't see why this example should be prohibited.  'n' is never
>> accessed, so an implementation could choose to put it in the same
>> place where 'f' is.  [snip elaboration]
>
> You've made a common mistake here.  You start with a statement
> about something you think an implementation might benefit from
> doing, and use that to draw a conclusion about what the Standard
> allows.  The reasoning process needs to go the other direction:
> start with what the Standard allows (or more importantly in this
> case, what it effectively prohibits), and show that a conforming
> implementation could act as suggested and still not violate any
> requirements.  The reasoning given above proves nothing at all.
>

Actually, you're mistaken.  The statement is _not_ offered as rationale 
for a conclusion for what the Standard allows.  It's just about how a 
particular implementation (I always wonder about one that might seem 
particularly nasty) might _make_use_ of such an allowance, _if_ it exists.

My instinct tells me there's some bit of Standard that's been missed in 
this discussion so far which _prohibits_ the scenario described, but 
that instinct could be mistaken.  _Without_ such a bit of Standard 
having yet been brought forth, "I don't see why this example should be 
prohibited."  Perhaps I should've split that into two paragraphs. :)

I am not an expert on the C11 Standard, so I do not and ought not to 
make any claim about its rationale.  The discussion in this newsgroup 
often seems to yield just the right references to the Standard to 
clarify misunderstandings.  I'm grateful for that.

My apologies for the misunderstanding. :)

- Shao Miller

[toc] | [prev] | [next] | [standalone]


#1827

FromTim Rentsch <txr@alumni.caltech.edu>
Date2013-01-06 23:16 -0800
Message-ID<kfnbod1bgzd.fsf@x-alumni2.alumni.caltech.edu>
In reply to#1826
Shao Miller <sha0.miller@gmail.com> writes:

> On 1/7/2013 01:30, Tim Rentsch wrote:
>> Shao Miller <sha0.miller@gmail.com> writes:
>>
>>> On 1/6/2013 22:13, Wojtek Lerch wrote:
>>>>
>>>> Consider this simple example:
>>>>
>>>>     int main( void ) {
>>>>       if ( _Alignof(int) <= _Alignof(float) ) {
>>>>         float f;
>>>>         int n, *p = (int*) &f;
>>>>         if ( p == &n )
>>>>           puts( "They're equal!" );
>>>>       }
>>>>     }
>>>>
>>>> It this program produces output on some implementation, which
>>>> requirement of the standard does the implementation violate?  (Chapter
>>>> and verse please.)
>>>
>>> [snip]
>>>
>>> I don't see why this example should be prohibited.  'n' is never
>>> accessed, so an implementation could choose to put it in the same
>>> place where 'f' is.  [snip elaboration]
>>
>> You've made a common mistake here.  You start with a statement
>> about something you think an implementation might benefit from
>> doing, and use that to draw a conclusion about what the Standard
>> allows.  The reasoning process needs to go the other direction:
>> start with what the Standard allows (or more importantly in this
>> case, what it effectively prohibits), and show that a conforming
>> implementation could act as suggested and still not violate any
>> requirements.  The reasoning given above proves nothing at all.
>
> Actually, you're mistaken.  The statement is _not_ offered as
> rationale for a conclusion for what the Standard allows.

The statement

    'n' is never accessed, so an implementation could choose to
    put it in the same place where 'f' is.

is one I think most c.s.c readers would say draws an inference
about what the Standard allows.  That does seem like the most
natural reading, given the context.

> It's just about how a particular implementation (I always
> wonder about one that might seem particularly nasty) might
> _make_use_ of such an allowance, _if_ it exists.  [snip]

I will amend my earlier statement.  Either you have made a common
mistake, or you are thinking or writing like an idiot.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.std.c


csiph-web