Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.std.c > #1805 > unrolled thread
| Started by | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| First post | 2013-01-04 02:08 -0500 |
| Last post | 2013-01-06 22:02 -0800 |
| Articles | 20 on this page of 21 — 5 participants |
Back to article view | Back to comp.std.c
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 →
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-01-04 02:08 -0500 |
| Subject | C11 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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2013-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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-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]
| From | lawrence.jones@siemens.com |
|---|---|
| Date | 2013-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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-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]
| From | lawrence.jones@siemens.com |
|---|---|
| Date | 2013-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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Wojtek Lerch <wojtek_l@yahoo.ca> |
|---|---|
| Date | 2013-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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2013-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]
| From | Wojtek Lerch <wojtek_l@yahoo.ca> |
|---|---|
| Date | 2013-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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Wojtek Lerch <wojtek_l@yahoo.ca> |
|---|---|
| Date | 2013-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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Wojtek Lerch <wojtek_l@yahoo.ca> |
|---|---|
| Date | 2013-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2013-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]
| From | Shao Miller <sha0.miller@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2013-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