Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #126772 > unrolled thread
| Started by | lee@ansync.com |
|---|---|
| First post | 2018-02-15 17:20 -0800 |
| Last post | 2018-02-26 10:17 -0800 |
| Articles | 20 on this page of 83 — 14 participants |
Back to article view | Back to comp.lang.c
Opinion sought: Is this strictly conforming C? lee@ansync.com - 2018-02-15 17:20 -0800
Re: Opinion sought: Is this strictly conforming C? James Kuyper <jameskuyper@verizon.net> - 2018-02-15 22:15 -0500
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-16 08:44 -0800
Re: Opinion sought: Is this strictly conforming C? jameskuyper@verizon.net - 2018-02-16 11:47 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-16 13:00 -0800
Re: Opinion sought: Is this strictly conforming C? Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-19 12:25 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-19 13:21 -0800
Re: Opinion sought: Is this strictly conforming C? Randy Howard <rhoward.mx@EverybodyUsesIt.com> - 2018-02-19 15:26 -0600
Re: Opinion sought: Is this strictly conforming C? Keith Thompson <kst-u@mib.org> - 2018-02-19 13:59 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-19 14:38 -0800
Re: Opinion sought: Is this strictly conforming C? Keith Thompson <kst-u@mib.org> - 2018-02-19 15:21 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-19 15:59 -0800
Re: Opinion sought: Is this strictly conforming C? Keith Thompson <kst-u@mib.org> - 2018-02-19 17:11 -0800
Re: Opinion sought: Is this strictly conforming C? David Brown <david.brown@hesbynett.no> - 2018-02-20 09:17 +0100
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-20 07:58 -0800
Re: Opinion sought: Is this strictly conforming C? David Brown <david.brown@hesbynett.no> - 2018-02-20 18:21 +0100
Re: Opinion sought: Is this strictly conforming C? Keith Thompson <kst-u@mib.org> - 2018-02-20 09:25 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-20 11:52 -0800
Re: Opinion sought: Is this strictly conforming C? Richard Damon <Richard@Damon-Family.org> - 2018-02-20 22:27 -0500
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-20 23:07 -0800
Re: Opinion sought: Is this strictly conforming C? Manfred <noname@invalid.add> - 2018-02-21 14:07 +0100
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-21 09:02 -0800
Re: Opinion sought: Is this strictly conforming C? Keith Thompson <kst-u@mib.org> - 2018-02-21 09:50 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-21 12:46 -0800
Re: Opinion sought: Is this strictly conforming C? Keith Thompson <kst-u@mib.org> - 2018-02-21 13:09 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-21 15:15 -0800
Re: Opinion sought: Is this strictly conforming C? Keith Thompson <kst-u@mib.org> - 2018-02-21 15:51 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-21 17:06 -0800
Re: Opinion sought: Is this strictly conforming C? Keith Thompson <kst-u@mib.org> - 2018-02-21 17:46 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-22 00:18 -0800
Re: Opinion sought: Is this strictly conforming C? Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-21 22:14 -0800
Re: Opinion sought: Is this strictly conforming C? Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-21 11:39 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-21 14:59 -0800
Re: Opinion sought: Is this strictly conforming C? Richard Damon <Richard@Damon-Family.org> - 2018-02-21 22:14 -0500
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-22 00:50 -0800
Re: Opinion sought: Is this strictly conforming C? Richard Damon <Richard@Damon-Family.org> - 2018-02-22 07:22 -0500
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-22 12:40 -0800
Re: Opinion sought: Is this strictly conforming C? Keith Thompson <kst-u@mib.org> - 2018-02-22 13:00 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-22 13:48 -0800
Re: Opinion sought: Is this strictly conforming C? scott@slp53.sl.home (Scott Lurndal) - 2018-02-22 22:14 +0000
Re: Opinion sought: Is this strictly conforming C? Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-21 23:05 -0800
Re: Opinion sought: Is this strictly conforming C? Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-21 23:39 -0800
Re: Opinion sought: Is this strictly conforming C? Keith Thompson <kst-u@mib.org> - 2018-02-22 10:39 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-22 13:20 -0800
Re: Opinion sought: Is this strictly conforming C? asetofsymbols@gmail.com - 2018-02-23 00:30 -0800
Re: Opinion sought: Is this strictly conforming C? Manfred <noname@invalid.add> - 2018-02-16 20:05 +0100
Re: Opinion sought: Is this strictly conforming C? lee@ansync.com - 2018-02-16 11:14 -0800
Re: Opinion sought: Is this strictly conforming C? Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-19 11:30 -0800
Re: Opinion sought: Is this strictly conforming C? Steve Carroll <frelwizzen@gmail.com> - 2018-03-01 09:01 -0800
Re: Opinion sought: Is this strictly conforming C? Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-19 11:08 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-19 17:16 -0800
Re: Opinion sought: Is this strictly conforming C? Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-21 23:16 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-22 00:25 -0800
Re: Opinion sought: Is this strictly conforming C? Richard Damon <Richard@Damon-Family.org> - 2018-02-22 07:41 -0500
Re: Opinion sought: Is this strictly conforming C? Tim Rentsch <txr@alumni.caltech.edu> - 2018-02-24 13:24 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-25 12:07 -0800
Re: Opinion sought: Is this strictly conforming C? Richard Damon <Richard@Damon-Family.org> - 2018-02-25 18:34 -0500
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-26 08:21 -0800
Re: Opinion sought: Is this strictly conforming C? Richard Damon <Richard@Damon-Family.org> - 2018-02-26 22:22 -0500
Re: Opinion sought: Is this strictly conforming C? David Brown <david.brown@hesbynett.no> - 2018-02-27 09:16 +0100
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-27 08:48 -0800
Re: Opinion sought: Is this strictly conforming C? David Brown <david.brown@hesbynett.no> - 2018-02-28 10:24 +0100
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-28 09:03 -0800
Re: Opinion sought: Is this strictly conforming C? David Brown <david.brown@hesbynett.no> - 2018-02-28 22:31 +0100
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-28 15:19 -0800
Re: Opinion sought: Is this strictly conforming C? David Brown <david.brown@hesbynett.no> - 2018-03-01 12:37 +0100
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-03-01 11:03 -0800
Re: Opinion sought: Is this strictly conforming C? Keith Thompson <kst-u@mib.org> - 2018-03-01 11:22 -0800
Re: Opinion sought: Is this strictly conforming C? Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 11:48 -0800
Re: Opinion sought: Is this strictly conforming C? Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 15:11 -0800
Re: Opinion sought: Is this strictly conforming C? Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 16:14 -0800
Re: Opinion sought: Is this strictly conforming C? Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 19:53 -0800
Re: Opinion sought: Is this strictly conforming C? Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 21:27 -0800
Re: Opinion sought: Is this strictly conforming C? Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 00:52 -0800
Re: Opinion sought: Is this strictly conforming C? Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 01:54 -0800
Re: Opinion sought: Is this strictly conforming C? Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-03 06:11 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-03-01 12:31 -0800
Re: Opinion sought: Is this strictly conforming C? Keith Thompson <kst-u@mib.org> - 2018-03-01 13:15 -0800
Re: Opinion sought: Is this strictly conforming C? Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 14:55 -0800
Re: Opinion sought: Is this strictly conforming C? Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-03 02:19 -0800
Re: Opinion sought: Is this strictly conforming C? Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-03 03:03 -0800
Re: Opinion sought: Is this strictly conforming C? Keith Thompson <kst-u@mib.org> - 2018-02-25 15:36 -0800
Re: Opinion sought: Is this strictly conforming C? supercat@casperkitty.com - 2018-02-26 10:17 -0800
Page 3 of 5 — ← Prev page 1 2 [3] 4 5 Next page →
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2018-02-21 23:05 -0800 |
| Message-ID | <kfn4lm9v6zx.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #126960 |
supercat@casperkitty.com writes: > On Wednesday, February 21, 2018 at 1:39:27 PM UTC-6, Tim Rentsch wrote: > >> its shape. Consider an example like the following (disclaimer: >> just typed in, not compiled) - >> >> int p[10000]; >> int (*q)[100] = (int (*)[100]) &p; >> // inthexdump() is like hexdump() but uses int * to access >> // elements. (also inthexdump() uses the parameter passed >> // in rather than a constant '35' as the loop limit.) >> inthexdump( q, 10000 ); >> inthexdump( q[0], 10000 ); >> >> The first call to inthexdump() is meant to be defined behavior, >> because q can refer to all of p. >> >> The second call to inthexdump() is meant to be undefined behavior, >> because q[0] refers only to the first 100 elements of p. It >> doesn't matter how p was declared. > > It would certainly be useful to have a way of distinguishing a pointer > which might be used to access an entire array from one which will only be > used to access a small part of it, but for compilers to blithely assume > that the address of an inner object will never be used to derive pointers > to the outer object would be dangerous, and would irredeemably break a lot > of code. [...] Life is hard.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2018-02-21 23:39 -0800 |
| Message-ID | <kfnvaeptqwb.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #126863 |
supercat@casperkitty.com writes:
> On Monday, February 19, 2018 at 2:25:29 PM UTC-6, Tim Rentsch wrote:
>
>> supercat@casperkitty.com writes:
>>
>>> C99 changed some rules from C89, [...]
>>
>> What changes are those? Specifically, which sections and
>> paragraphs in the two Standards are you talking about?
>> If you don't cite specific sections and paragraphs, along
>> with a statement of what change you think was made in each
>> case, you're just blowing smoke.
>
> From N1570 Annex J.2:
>
> -- An array subscript is out of range, even if an object is
> apparently accessible with the given subscript (as in the
> lvalue expression a[1][7] given the declaration int a[4][5])
> (6.5.6).
There are several problems with this theory:
The statement is in informative text, not normative text.
The referenced normative text (ie 6.3.6 in C90 IIRC, and 6.5.6 in
C99 and later) did not change in any significant way.
The corresponding section of C90 (ie, corresponding to Annex J)
also says something about array references. It's more vague, and
references a different normative section (for the * indirection
operator), but it's there.
The Rationale document doesn't say anything about a change. If
what was intended was a change in the language, the Rationale
document surely would have mentioned something this significant.
Last but not least, the text change you mention didn't happen
as part of C99, but much earlier, as part of a response to
a Defect Report filed in 1992:
http://www.open-std.org/JTC1/SC22/WG14/www/docs/dr_017.html
The response makes clear that the new text is a clarification of
the intended meaning, not a rule change.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-02-22 10:39 -0800 |
| Message-ID | <lneflclvh7.fsf@kst-u.example.com> |
| In reply to | #126980 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
[...]
> Last but not least, the text change you mention didn't happen
> as part of C99, but much earlier, as part of a response to
> a Defect Report filed in 1992:
>
> http://www.open-std.org/JTC1/SC22/WG14/www/docs/dr_017.html
>
> The response makes clear that the new text is a clarification of
> the intended meaning, not a rule change.
It's question 16 (of 39) in the cited DR.
Question 16
Pointer to multidimensional array
Given the declaration:
char a[3][4], (*p)[4]=a[1];
Does the behavior become undefined when:
1. p no longer points within the slice of the array, or
2. p no longer points within the object a?
This case should be explicitly stated.
Arguments for/against:
The standard refers to a pointed-to object. There does not
appear to be any concept of a slice of an array being an
independent object.
Response
For an array of arrays, the permitted pointer arithmetic in
subclause 6.3.6, page 47, lines 12-40 is to be understood
by interpreting the use of the word ``object'' as denoting
the specific object determined directly by the pointer's
type and value, not other objects related to that one
by contiguity. Therefore, if an expression exceeds these
permissions, the behavior is undefined. For example, the
following code has undefined behavior:
int a[4][5];
a[1][7] = 0; /* undefined */
Some conforming implementations may choose to diagnose an "array
bounds violation," while others may choose to interpret such
attempted accesses successfully with the "obvious" extended
semantics.
Correction
Add to subclause G.2, page 201:
- An array subscript is out of range, even if an object is
apparently accessible with the given subscript (as in the lvalue
expression a[1][7] given the declaration int a[4][5]) (6.3.6).
--
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 | supercat@casperkitty.com |
|---|---|
| Date | 2018-02-22 13:20 -0800 |
| Message-ID | <b8355bca-dc19-4da3-804e-a1ffbefc180a@googlegroups.com> |
| In reply to | #126991 |
On Thursday, February 22, 2018 at 12:39:49 PM UTC-6, Keith Thompson wrote:
> For an array of arrays, the permitted pointer arithmetic in
> subclause 6.3.6, page 47, lines 12-40 is to be understood
> by interpreting the use of the word ``object'' as denoting
> the specific object determined directly by the pointer's
> type and value, not other objects related to that one
> by contiguity. Therefore, if an expression exceeds these
> permissions, the behavior is undefined. For example, the
> following code has undefined behavior:
The Standard overuses the term "object" to refer to a number of different
concepts in addition to identifying a region of storage. If the term
lvalue were adjusted to refer to a an expression which, when evaluated,
yields a region of storage *or portion thereof*, that would have avoided
the need to pretend that regions of storage have type or contain anything
other than a bunch of bits. Any semantics beyond lifetime and the values
of bits held should be attached to lvalues or things given other names
(e.g. varibles, arrays, etc.).
As it is, given something like:
int arr[10] = {0};
arr[0] = 3;
If one views the storage associated with "a" as being an object of type
int[10], then the stored value of that type may only be accessed using
lvalues of the following types:
- int[10]
- a qualified versions of the type int[10]
- a qualified version of the type unsigned[10]
- an aggregate or union type that contains an int[10] as a member
- a character type
I don't think the type "int" falls into any of those categories. The
only way the assignment to arr[4] can be defined is if it doesn't access
the stored value of an int[10]. Since it would seem unlikely that the
authors of the Standard intended to make just about any use of a non-
character-type array invoke UB, the only way I can figure for the behavior
to be defined would be to suggest that while the lvalue a[0] is being
evaluated the storage identified thereby holds an object of type "int[10]",
but then during the assignment it doesn't.
[toc] | [prev] | [next] | [standalone]
| From | asetofsymbols@gmail.com |
|---|---|
| Date | 2018-02-23 00:30 -0800 |
| Message-ID | <0d216c72-c8ea-409c-b413-6a6f87c57ad9@googlegroups.com> |
| In reply to | #126991 |
In Axiom and in Apl such problem on array out of memory allocated, do not exist because system know index is out of bound and it stop execution (if I remember good) The same problem on pointers ( only few programming languages have that concept) Yes C is as assembly, low level Possibly the work around on that it is the pointer type it is a range 2 addresses one of start one of end
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@invalid.add> |
|---|---|
| Date | 2018-02-16 20:05 +0100 |
| Message-ID | <p67a0r$hl$1@gioia.aioe.org> |
| In reply to | #126775 |
On 2/16/2018 4:15 AM, James Kuyper wrote: > On 02/15/2018 08:20 PM, lee@ansync.com wrote: >> I am involved in a debate on StackOverflow about whether this code, >> which accesses the same chunk of memory as both a 1D and 2D array, is >> strictly conforming, well-defined C with no undefined behavior: >> >> ---- >> >> #include <stdio.h> >> >> int a1[100]; >> int (*a2)[10] = (int (*)[10])a1; > > In this context, a1 is implicitly converted into a pointer to the first > element of a1. Here's what the standard has to say about the conversion > of a pointer to int into a pointer to int[10]: > "If the resulting pointer is not correctly aligned 68) 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." (6.3.2.3p7). > > It's permissible for an object of type 'int[10]' to have stricter > alignment requirements than an object of type int[100], but it's not at > all likely. As a practical matter, we can ignore that issue - but as far > as the standard is concerned, it is a possible problem. Using C2011, > it's possible to check for that possibility using the _Alignof() feature. > > However, there's a much more important problem, and one which is so > subtle that it might be hard to notice. It's about what the standard > doesn't say, which is much harder to notice than what it does say. The > ONLY thing the standard says about the result of the conversion is that > it can be reversed. I understand what you are saying, but I am not sure that this is the only thing. My doubt arises primarily from the fact that according to such a strict interpretation, any converted pointer would be substantially unusable. Also, I think that it is intentional that the 'special case' of pointer to char is defined within the same clause as for generic pointers, and together with the requirement of correct alignment. I think (but this should be more formally substantiated) that the committee intended to give a definition of 'definedness' of the resulting pointer by ensuring that the representation of the referenced object is valid: - First, the alignment requirement of the resulting pointer is enforced. - Then, self-consistency of the pointer value is enforced (when converted back it will compare equal) - Then, it is IMHO relevant here that note 68) recalls that the concept of "correctly aligned" is transitive, so that in order to access the object representation one can assume something like: - a1: pointer to int - a2: pointer to int[10] - a3: pointer to char are all correctly aligned for the type of interest (int[10] in this case) - Finally, the conversion rules for pointer to char ensure that: a) the converted pointer points to the first byte of the object b) the byte sequence that constitutes the object representation can be accessed byte-by-byte through a converted pointer to char which will keep the byte ordering of the object representation. Since the object representation is /defined/ as a byte sequence (6.2.6.1 p2), and "Two values (other than NaNs) with the same object representation compare equal" (6.2.6.1 p4), I would understand that: /If/ a1 (pointer to int) actually points to (has a value of the address of) an object representation (sequence of bytes) of an int[10] object, /Then/ a1 and a2 both point to (have the same value of the address of) the object representation of the int[10] object (and thus a2 can be used to access the int[10] object). Obviously this only holds if a1 points to an int[10], i.e. if the pointer to be converted actually points to an object of the converted type, which is under the responsibility of the programmer. This is why the standard cannot specify anything more than a byte-by-byte guarantee on the sequence of bytes that can be accessed by a converted pointer. Since int[10] is not a character type, that clause > does doesn't tell you anything else that you can do with the resulting > pointer. Note, in particular, that it doesn't bother telling you what, > if anything, the resulting pointer points at. What happens when you do > anything to such a pointer other than converting it back to it's > original type is undefined behavior, by "omission of any explicit > definition of the behavior" (4p2). > > This interpretation of the words of the standard tends to be > controversial, primarily because code like this will, in fact, generally > work as you may have mistakenly thought it was guaranteed to work. That > fact can make it very hard for people to accept that it is not, in fact, > guaranteed to work.
[toc] | [prev] | [next] | [standalone]
| From | lee@ansync.com |
|---|---|
| Date | 2018-02-16 11:14 -0800 |
| Message-ID | <8ad38303-6a6b-4016-b1db-c1378a2c3a58@googlegroups.com> |
| In reply to | #126807 |
That was more or less my take: that if pointer-casting isn't usable in a case like this, then the concept itself is completely pointless. But I can understand that the spec just doesn't want to guarantee it, even though code like this is commonplace and has been well-understood and used for decades.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2018-02-19 11:30 -0800 |
| Message-ID | <kfnwoz8wzeh.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #126807 |
Manfred <noname@invalid.add> writes: >> [when converting a pointer type, is the only thing allowed >> converting the value back to the original type?] > > I understand what you are saying, but I am not sure that this is the > only thing. > My doubt arises primarily from the fact that according to such a > strict interpretation, any converted pointer would be substantially > unusable. > > Also, I think that it is intentional that the 'special case' of > pointer to char is defined within the same clause as for generic > pointers, and together with the requirement of correct alignment. > > I think (but this should be more formally substantiated) that the > committee intended to give a definition of 'definedness' of the > resulting pointer [...] I agree with the general thrust of your comments. Converting a pointer is meant to work how people think it works. It's hard to say that in precise formal language, so they did what they could and the text in the Standard is what came out. If the question were brought up now, the likely response would be, "Everyone understands what is meant so there is no reason to change it." I don't always agree with that last sentiment, but I do at least understand it. If there isn't any disagreement between what WG14 thinks and what implementors think, making a change to the text is just wasted effort, and might even cause some problems. What language-lawyer Joe Smith thinks is of no importance.
[toc] | [prev] | [next] | [standalone]
| From | Steve Carroll <frelwizzen@gmail.com> |
|---|---|
| Date | 2018-03-01 09:01 -0800 |
| Message-ID | <8250eae9-ce8f-4adc-a7ea-9fba678fa333@googlegroups.com> |
| In reply to | #126807 |
On Friday, February 16, 2018 at 12:05:18 PM UTC-7, Manfred wrote: > On 2/16/2018 4:15 AM, James Kuyper wrote: > > On 02/15/2018 08:20 PM, lee@ansync.com wrote: > >> I am involved in a debate on StackOverflow about whether this code, > >> which accesses the same chunk of memory as both a 1D and 2D array, is > >> strictly conforming, well-defined C with no undefined behavior: > >> > >> ---- > >> > >> #include <stdio.h> > >> > >> int a1[100]; > >> int (*a2)[10] = (int (*)[10])a1; > > > > In this context, a1 is implicitly converted into a pointer to the first > > element of a1. Here's what the standard has to say about the conversion > > of a pointer to int into a pointer to int[10]: > > "If the resulting pointer is not correctly aligned 68) 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." (6.3.2.3p7). > > > > It's permissible for an object of type 'int[10]' to have stricter > > alignment requirements than an object of type int[100], but it's not at > > all likely. As a practical matter, we can ignore that issue - but as far > > as the standard is concerned, it is a possible problem. Using C2011, > > it's possible to check for that possibility using the _Alignof() feature. > > > > However, there's a much more important problem, and one which is so > > subtle that it might be hard to notice. It's about what the standard > > doesn't say, which is much harder to notice than what it does say. The > > ONLY thing the standard says about the result of the conversion is that > > it can be reversed. > > I understand what you are saying, but I am not sure that this is the > only thing. > My doubt arises primarily from the fact that according to such a strict > interpretation, any converted pointer would be substantially unusable. > > Also, I think that it is intentional that the 'special case' of pointer > to char is defined within the same clause as for generic pointers, and > together with the requirement of correct alignment. > > I think (but this should be more formally substantiated) that the > committee intended to give a definition of 'definedness' of the > resulting pointer by ensuring that the representation of the referenced > object is valid: > > - First, the alignment requirement of the resulting pointer is enforced. > > - Then, self-consistency of the pointer value is enforced (when > converted back it will compare equal) > > - Then, it is IMHO relevant here that note 68) recalls that the concept > of "correctly aligned" is transitive, so that in order to access the > object representation one can assume something like: > - a1: pointer to int > - a2: pointer to int[10] > - a3: pointer to char > are all correctly aligned for the type of interest (int[10] in this case) > > - Finally, the conversion rules for pointer to char ensure that: > a) the converted pointer points to the first byte of the object > b) the byte sequence that constitutes the object representation can > be accessed byte-by-byte through a converted pointer to char which will > keep the byte ordering of the object representation. > > Since the object representation is /defined/ as a byte sequence (6.2.6.1 > p2), and "Two values (other than NaNs) with the same object > representation compare equal" (6.2.6.1 p4), I would understand that: > > > /If/ a1 (pointer to int) actually points to (has a value of the address > of) an object representation (sequence of bytes) of an int[10] object, > /Then/ a1 and a2 both point to (have the same value of the address of) > the object representation of the int[10] object (and thus a2 can be used > to access the int[10] object). > > Obviously this only holds if a1 points to an int[10], i.e. if the > pointer to be converted actually points to an object of the converted > type, which is under the responsibility of the programmer. > This is why the standard cannot specify anything more than a > byte-by-byte guarantee on the sequence of bytes that can be accessed by > a converted pointer. > > > > Since int[10] is not a character type, that clause > > does doesn't tell you anything else that you can do with the resulting > > pointer. Note, in particular, that it doesn't bother telling you what, > > if anything, the resulting pointer points at. What happens when you do > > anything to such a pointer other than converting it back to it's > > original type is undefined behavior, by "omission of any explicit > > definition of the behavior" (4p2). > > > > This interpretation of the words of the standard tends to be > > controversial, primarily because code like this will, in fact, generally > > work as you may have mistakenly thought it was guaranteed to work. That > > fact can make it very hard for people to accept that it is not, in fact, > > guaranteed to work. I still am unconvinced that these never ending posts are not from Tatiana Spearman Kister, clearly they are from The Holy Ghost. These posts are clearly *not* automated, they are made by The Holy Ghost who is a glue sniffing pervert with a personal vendetta who has way too much time on his hands (with maybe some scripted pre-processing). Of course, the sole undertaking that matters to The Holy Ghost is arguing he is "accurate", and if he can not have that he will flood to successfully slap Tatiana Spearman Kister down... there is no way to stop him. - Best CMS Solution of 2017!! http://prescottcomputerguy.com/screenflow https://www.reddit.com/r/linux/comments/6sfkup/what_desktop_tasks_does_linux_handle_better_than/= Jonas Eklundh Communication
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2018-02-19 11:08 -0800 |
| Message-ID | <kfn1shgyeyp.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #126772 |
lee@ansync.com writes:
> I am involved in a debate on StackOverflow about whether this code,
> which accesses the same chunk of memory as both a 1D and 2D array, is
> strictly conforming, well-defined C with no undefined behavior:
>
> ----
>
> #include <stdio.h>
>
> int a1[100];
> int (*a2)[10] = (int (*)[10])a1;
>
> int main(int argc, char *argv[]) {
> for (int i = 0; i < 100; i += 1) a1[i] = i + 1;
>
> for (int i = 0; i < 10; i += 1) {
> for (int j = 0; j < 10; j += 1) {
> printf("%2d ", a2[i][j]);
> }
> printf("\n");
> }
> }
Allow me to offer some counterpoint to some of the other
commentary.
First, the program is certainly not strictly conforming. However
that observation is incidental to the question you want answered,
so we can ignore it for now. (Spoiler below if anyone is
interested.)
Second, there is a minor point that what is casted is a pointer to
the first element of a1 rather than the whole array. This point
is just a special case of conversion questions generally, but we
also can simply sidestep it by using '&a1'. Let's assume that
change has been made.
Third, some of what's been brought up is irrelevant. I tracked
down the SO thread you mentioned and read through the comments.
The stuff about effective types, aliasing, allocated memory
versus non-allocated memory, and variable lifetime is all just
smoke. None of that has anything to do with the question you're
asking. Pointer conversions work the same way no matter which
kind of memory they reference. All the other stuff is a pathetic
meta-argument trying to show that your understanding of pointer
values is weak. IMO you are right be skeptical of arguments
made by people who would drag in such irrelevancies.
Fourth, there may be some confusion about what question is being
asked versus what question is being answered. On SO at least the
main responder seems to be answering in a "language-lawyer" mode.
However the question I think you want answered is not what would
language-lawyer Joe Smith say, but what would the WG14 committee
say. This distinction is important because it does happen (and
more often than I would like) that the answers in the two cases
are different.
With the understanding that the question I am addressing is what
would WG14 say, let's proceed. (Disclaimer: of course I can't
be sure what WG14 would say but I will do my best to answer from
that perspective. If a more definitive answer is needed the only
surefire way to do that is to submit a Defect Report asking the
question.)
There are three issues to consider: (1) alignment; (2) does the
converted pointer "point to the right place"; and (3) does the
address arithmetic done in indexing a2 satisfy the semantic rules
for that. We will take these questions in reverse order.
For indexing a2, the key passage is 6.2.6 p8. What is meant to
be required by this paragraph is notoriously vague. However,
the usual principle is that the implied arithmetic is allowed
if it falls within the extent of the original pointer in the
provenance of the pointer being used. Because the extent of
the original pointer (ie, &a1) is the entire array, the indexing
operation a2[i][j] does not violate those constraints. (Fine
point: including the restriction that 0 <= j < 10, which is
implied by using a2 to do the indexing.)
Next question: does the converted pointer "point to the right
place"? Language-lawyer types like to cite 6.3.2.3 p7 and say the
only thing that can be done with a converted pointer is to convert
it back to the original type (and even then the only thing that
can be done with the re-converted value is compare it to the
original). This is a ridiculous argument. People who want to be
language lawyers should try spending some time in an actual
courtroom. An argument that leads to an absurd conclusion holds
no value and generally is ignored, simply because the conclusion
is absurd. Here the conclusion is absurd because pointer casting
was well-established long before the C standardization effort
started, and people on the standards committee wouldn't just throw
that way, _especially_ without saying something about it.
(Remember, one of the people involved in that effort was Dennis
Ritchie.) I find no mention anywhere - not in the Standard, not
in the Rationale, not in Defect Reports, not in any of the minutes
or meeting notes or other documents I've looked at on the
open-std.org website - suggesting that how pointer conversion
works is somehow different in standard C than how it worked
before.
Let me run down a list of observations that bolster support for
the idea that pointer conversions work the way we expect:
(1) Generally the Standard does not say what it considers to
be implied by other passages (except in non-normative
text, eg, the footnote about union member access and type
punning). If it was thought that the usual semantics of
pointer conversion was implied by text in other areas
there would be no reason to say so explicitly.
(2) The point of the statement about converting back to the
original type could be about alignment. The Standard says
very little about how alignment works, and 6.3.2.3 p7
could be making a point about that.
(3) Or, the statement "a converted pointer can be converted
back to the original type and will compare equal to the
original pointer" could be a Standardese way of saying that
the two pointers "point to the same place". This actually
wouldn't be that surprising. It's hard to express what is
supposed to happen in formal language (try it and see!),
and the Standard tends to stay away from being overly
formal. The audience is engineers, not mathematicians.
(4) It's worth noting that the very first sentence in 6.3 says
"Several operators convert operand values from one type to
another". Converting a pointer /value/ could be taken to
mean the base address is preserved by the conversion
(subject to alignment constraints, of course). And if the
standards committee thought that would be understood by the
expected audience, chances are they would not repeat
themselves and say so in other language.
Two other passages are worth citing. From the C99 Rationale:
The offsetof macro was added to provide a portable means of
determining the offset, in bytes, of a member within its
structure. This capability is useful in programs, such as
are typical in database implementations, which declare a
large number of different data structures: it is desirable
to provide "generic" routines that work from descriptions of
the structures, rather than from the structure declarations
themselves.
The only way this could work is if pointer conversion works the
way people expect. The next point is from the introductory
paragraph on memory management functions malloc() and friends:
The pointer returned if the allocation succeeds is suitably
aligned so that it may be assigned to a pointer to any type
of object and then used to access such an object or an array
of such objects in the space allocated
How the text here is phrased lets us infer two things:
(1) Alignment is important for how pointer conversions work;
of course we knew this already, but also
(2) Alignment is the only thing that /does/ matter: if the
alignment is right, how pointer conversions work takes
care of the rest. In other words, pointer conversion
works how people think it will.
Considering all the above together, and especially including the
non-mention of any change in pointer conversion semantics, I
think it's a pretty safe bet that WG14 would say the converted
pointer points to the same place as the original and is usable as
such.
Last but not least there is the alignment question: might an
array of 10 ints have a more strict alignment than an array of
100 ints? I don't remember seeing any explicit comment on this
question (including in the Rationale, DR's, etc). The Standard
doesn't say these must be the same, but neither does it say they
can be different. Does the Standard imply with other text, or is
it meant to be understood, that arrays of the same element type
all have the same alignment, regardless of their respective
lengths? I think so but I am not 100% sure. Here is the program
again, re-written slightly so that it is legal C90 and also with
a few other changes (eg, no warnings under -Wall -Wextra).
#include <stdio.h>
int a1[100];
int
main( int argc, char *argv[] ){
int (*ax)[] = &a1;
int (*a2)[10] = ax;
int i, j;
for( i = 0; i < 100; i += 1 ) a1[i] = i + 1;
for( i = 0; i < 10; i += 1 ){
for( j = 0; j < 10; j += 1 ){
printf( " %3d", a2[i][j] );
}
printf( "\n" );
}
return 0;
(void) &argc, (void) &argv;
}
The most significant change is the introduction of 'ax', which
allows the pointer conversions to be done without casting. Why
is this important? Follow:
(1) The types of *a1 and *a2 are not compatible with each
other, but each is compatible with the type of *ax.
(2) Assignment of pointers to compatible types is allowed
without casting.
(3) Pointers to compatible types have the same representation
and alignment requirements.
(4) In C90, the rules for converting between object types was
not under 6.3.2.3 (or its equivalent in C90, which may have
had a different number), but under the semantic rules for
casting. In particular the alignment restriction for
pointer conversions was not a general statement but one
made only as part of the description of casting.
The point here is not about giving a logical proof but to try to
understand what was in the mind of the authors. The combination
of (2) and (3), especially when supported by (4), suggests that
assignments allowed under these conditions are meant to be (or at
least were thought of as being) safe, ie, would never have any
problem with alignment. If that is so then casting can't have
any alignment problems either for the particular case of pointers
to arrays with the same element type.
(Also, as a practical matter, if alignment considerations are
thought to be important here, it's pretty straightforward to
protect against that programmatically in a way that works on
every implementation one is likely to encounter, and will fail
at compile time in the unlikely event of running into one where
it doesn't.)
Bottom line: Regarding alignment, I'd like an official response
before reaching a final conclusion, but it's very unlikely to be a
problem in practice, and we can write the program in a way to
protect against even that remote possibility. For all the rest,
no sensible person thinks there is any undefined behavior there:
arguments about pointer conversions being usable only for changing
back to the original type are silly, and clearly at odds with
other statements made in the Standard and also other official WG14
documents.
(Spoiler: the original program has implementation-defined behavior
by virtue of writing a space before a newline.)
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2018-02-19 17:16 -0800 |
| Message-ID | <5e795363-40ed-4405-9f4c-86ba404dad77@googlegroups.com> |
| In reply to | #126856 |
On Monday, February 19, 2018 at 1:09:06 PM UTC-6, Tim Rentsch wrote: > Next question: does the converted pointer "point to the right > place"? Language-lawyer types like to cite 6.3.2.3 p7 and say the > only thing that can be done with a converted pointer is to convert > it back to the original type (and even then the only thing that > can be done with the re-converted value is compare it to the > original). This is a ridiculous argument. People who want to be > language lawyers should try spending some time in an actual > courtroom. An argument that leads to an absurd conclusion holds > no value and generally is ignored, simply because the conclusion > is absurd. Here the conclusion is absurd because pointer casting > was well-established long before the C standardization effort > started, and people on the standards committee wouldn't just throw > that way, _especially_ without saying something about it. > (Remember, one of the people involved in that effort was Dennis > Ritchie.) I find no mention anywhere - not in the Standard, not > in the Rationale, not in Defect Reports, not in any of the minutes > or meeting notes or other documents I've looked at on the > open-std.org website - suggesting that how pointer conversion > works is somehow different in standard C than how it worked > before. From what I can tell, the authors of C89 expected that compiler writers would behave in a fashion consistent with K&R and existing precedents when practical if the Standard allowed it, without regard for whether the Standard required it. Their focus was on situations where guarantees that would be practical for some implementations would be impractical for others, but they didn't presume themselves capable of identifying all such places. Leaving things as UB even in cases where existing precedents had been 100% consistent avoided accidentally tying the hands of someone targeting some obscure platform the Committee had never heard of which could not cheaply guarantee a behavior that was 100% consistent on every other platform. The place where I think the Committee has frequently gone badly wrong is in identifying some cases where it would often be useful for a compiler to make certain kinds of optimizations, and some other cases where compilers should be forbidden from doing so, and then drafting rules which focus solely on the latter. If compiler writers fill in any "gaps" in the Standard by looking to K&R or existing precedents whenever possible, it won't matter if the Standard fails to 100% nail down all corner cases. If, however, compiler writers seek to behave in a fashion consistent with K&R and precedents without regard for whether the Standard requires it, that would imply ignoring places where the Standard would invite optimizations. If the authors of the Standard had specified examples of cases where certain optimizations would be allowed, as well as where they would be forbidden, such an approach would have made it practical to allow more optimizations than the Standard presently does, without encouraging compilers to break as much code as it presently allows.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2018-02-21 23:16 -0800 |
| Message-ID | <kfnzi41trxl.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #126873 |
supercat@casperkitty.com writes: > On Monday, February 19, 2018 at 1:09:06 PM UTC-6, Tim Rentsch wrote: > >> Next question: does the converted pointer "point to the right >> place"? Language-lawyer types like to cite 6.3.2.3 p7 and say the >> only thing that can be done with a converted pointer is to convert >> it back to the original type (and even then the only thing that >> can be done with the re-converted value is compare it to the >> original). This is a ridiculous argument. People who want to be >> language lawyers should try spending some time in an actual >> courtroom. An argument that leads to an absurd conclusion holds >> no value and generally is ignored, simply because the conclusion >> is absurd. Here the conclusion is absurd because pointer casting >> was well-established long before the C standardization effort >> started, and people on the standards committee wouldn't just throw >> that way, _especially_ without saying something about it. >> (Remember, one of the people involved in that effort was Dennis >> Ritchie.) I find no mention anywhere - not in the Standard, not >> in the Rationale, not in Defect Reports, not in any of the minutes >> or meeting notes or other documents I've looked at on the >> open-std.org website - suggesting that how pointer conversion >> works is somehow different in standard C than how it worked >> before. > > From what I can tell, the authors of C89 expected that compiler > writers would behave in a fashion consistent with K&R and existing > precedents when practical if the Standard allowed it, without regard > for whether the Standard required it. [...] Like many of the statements you make, this seems based more on your imagination than on any evidence I'm aware of.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2018-02-22 00:25 -0800 |
| Message-ID | <f50cd5f8-a0e9-4926-8b18-b683ba21bec8@googlegroups.com> |
| In reply to | #126979 |
On Thursday, February 22, 2018 at 1:16:48 AM UTC-6, Tim Rentsch wrote: > supercat@casperkitty.com writes: > > From what I can tell, the authors of C89 expected that compiler > > writers would behave in a fashion consistent with K&R and existing > > precedents when practical if the Standard allowed it, without regard > > for whether the Standard required it. [...] > > Like many of the statements you make, this seems based more on > your imagination than on any evidence I'm aware of. For the authors of the Standard to have intended otherwise would have meant that they were lying about their desire to avoid breaking existing code. While I can't completely rule out such a possibility, I would think it far more likely that the authors of the Standard were being honest. Are you suggesting that the authors were trying to usurp the name C for a language which isn't supposed to be compatible with code written for the language described by K&R?
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2018-02-22 07:41 -0500 |
| Message-ID | <eUyjC.39878$nY2.10807@fx28.iad> |
| In reply to | #126982 |
On 2/22/18 3:25 AM, supercat@casperkitty.com wrote: > On Thursday, February 22, 2018 at 1:16:48 AM UTC-6, Tim Rentsch wrote: >> supercat@casperkitty.com writes: >>> From what I can tell, the authors of C89 expected that compiler >>> writers would behave in a fashion consistent with K&R and existing >>> precedents when practical if the Standard allowed it, without regard >>> for whether the Standard required it. [...] >> >> Like many of the statements you make, this seems based more on >> your imagination than on any evidence I'm aware of. > > For the authors of the Standard to have intended otherwise would have meant > that they were lying about their desire to avoid breaking existing code. > While I can't completely rule out such a possibility, I would think it far > more likely that the authors of the Standard were being honest. > > Are you suggesting that the authors were trying to usurp the name C > for a language which isn't supposed to be compatible with code written > for the language described by K&R? > I don't think that phrase means what you think it does, as your interpretation is IMPOSSIBLE. The authors of the Standard tried very hard to make it so that in every case possible, implementation were allowed to continue acting in the way they did before, at least if it was fairly compatible with the original definitions. This is where a LOT of Undefined Behavior comes in the language. By being UB, the implementation can do what it did before, and the other implementation that did something different can do what it did before, and both are still conforming. The writers of the Standard decided that they couldn't come up with suitable words to try to require a given implementation (or more precisely a family of implementations, as a new version of a given compiler really is a new implementation) to broadly maintain its own existing behavior. Try it, remembering that a Standard is reasonably self contained, and every other document it incorporates, it references by name. You duplication of past behavior in the presence of undefined behavior isn't something that can be guaranteed in a Standard, but became a quality of implementation issue. Which I will note, generally when a new version of an implementation comes out, there is almost always a way to maintain old behaviors when using it. Can you name a compiler that behaved one way as on original K&R compiler that COULDN'T duplicate that behavior as a C90 compiler (not that didn't by default, but couldn't) when targeting the exact same machine.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2018-02-24 13:24 -0800 |
| Message-ID | <kfneflat717.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #126982 |
supercat@casperkitty.com writes: > On Thursday, February 22, 2018 at 1:16:48 AM UTC-6, Tim Rentsch wrote: > >> supercat@casperkitty.com writes: >> >>> From what I can tell, the authors of C89 expected that compiler >>> writers would behave in a fashion consistent with K&R and existing >>> precedents when practical if the Standard allowed it, without regard >>> for whether the Standard required it. [...] >> >> Like many of the statements you make, this seems based more on >> your imagination than on any evidence I'm aware of. > > For the authors of the Standard to have intended otherwise would > have meant that they were lying about their desire to avoid breaking > existing code. [...] Your understanding of what you read is so colored by what you want to be true rather than what is true that it is effectively impossible to say anything useful there. This isn't what they said. If you think it is, you're deluded.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2018-02-25 12:07 -0800 |
| Message-ID | <b58c0bac-85cd-459b-af95-6e477a638914@googlegroups.com> |
| In reply to | #127018 |
On Saturday, February 24, 2018 at 3:25:03 PM UTC-6, Tim Rentsch wrote: > supercat@casperkitty.com writes: > > For the authors of the Standard to have intended otherwise would > > have meant that they were lying about their desire to avoid breaking > > existing code. [...] > > Your understanding of what you read is so colored by what you > want to be true rather than what is true that it is effectively > impossible to say anything useful there. This isn't what they > said. If you think it is, you're deluded. There are a number of situations where the behavior of some action would be described by the combination of the Standard and an implementation's documentation and yet also classified as Undefined. There are at least two ways one can interpret such an apparent contradiction: 1. Interpret the statement that the behavior is undefined as saying that the Standard imposes no requirements on the behavior of that action on any implementation, *even those where it would be defined elsewhere*. 2. Interpret the statement that the behavior is undefined as saying that there is no requirement that implementations treat the behavior as defined *except when it is defined elsewhere*. The Standard makes no distinction between these two forms; applying the first consistently would yield a silly language in which many constructs would be all but useless [e.g. arrays of non-character types, or structures or unions that contain non-character members, could only have their elements or members accessed using memcpy other character-based means], while applying the second consistently would yield a language which both useful and practical to implement. If the first interpretation should be used in some places, but the second should be used in others, different terminology should be used to distinguish them. You may regard the second interpretation as delusional, but the first would be absurd and I don't really see any basis for saying that the first interpretation is correct in places where it is too totally absurd, in which case the second should apply.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2018-02-25 18:34 -0500 |
| Message-ID | <bKHkC.56165$tK5.48659@fx03.iad> |
| In reply to | #127045 |
On 2/25/18 3:07 PM, supercat@casperkitty.com wrote: > On Saturday, February 24, 2018 at 3:25:03 PM UTC-6, Tim Rentsch wrote: >> supercat@casperkitty.com writes: >>> For the authors of the Standard to have intended otherwise would >>> have meant that they were lying about their desire to avoid breaking >>> existing code. [...] >> >> Your understanding of what you read is so colored by what you >> want to be true rather than what is true that it is effectively >> impossible to say anything useful there. This isn't what they >> said. If you think it is, you're deluded. > > There are a number of situations where the behavior of some > action would be described by the combination of the Standard > and an implementation's documentation and yet also classified > as Undefined. There are at least two ways one can interpret > such an apparent contradiction: > > 1. Interpret the statement that the behavior is undefined as > saying that the Standard imposes no requirements on the > behavior of that action on any implementation, *even those > where it would be defined elsewhere*. > Yes, THE STANDARD provides no requirement, but that does not prevent some other requirements document (including the implementation documentation) from providing a definition of behavior. Nothing in the standard provides any indication that the a declaration of Undefined Behavior by the C Standard negates any other definition of behavior (and I am unsure if there would be any way to try to give it such authority) This statement is like making an arguement like telling a police officer they can't give you a ticket for reckless driving because you were going under the speed limit. > 2. Interpret the statement that the behavior is undefined as > saying that there is no requirement that implementations > treat the behavior as defined *except when it is defined > elsewhere*. Yes, an Implementation needs to follow all the definitions, both those provided by the C standard, as well as all the other standards or rules it claims to conform to. The fact that the C standard doesn't impose a restriction doesn't mean nothing else might. I see NO contradictions in these two statememts. > > The Standard makes no distinction between these two forms; applying > the first consistently would yield a silly language in which many > constructs would be all but useless [e.g. arrays of non-character > types, or structures or unions that contain non-character members, > could only have their elements or members accessed using memcpy > other character-based means], while applying the second > consistently would yield a language which both useful and practical > to implement. > > If the first interpretation should be used in some places, but > the second should be used in others, different terminology should > be used to distinguish them. > > You may regard the second interpretation as delusional, but the > first would be absurd and I don't really see any basis for saying > that the first interpretation is correct in places where it is too > totally absurd, in which case the second should apply. > Fundamentally, you issue is that you want the C Standard to be the sole and final definition of everything that an implementation must be/do, but that isn't what the Standard is. There are intentionally many things left undefined by the Standard, in order to leave room for other bodies to provide definitions of behavior. In fact, defining behavior can lead to an issue that if two bodies define the behavior in a given situation, there is a real danger that slight differences in definition might make it hard, if not impossible, to conform to both. This is a reason that in my experience, most specification documents have a precedence section giving instructions on how to handle such conflicts, and will explicitly put some things ahead of that document, like federal and local law, and explicit statements in the purchasing document.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2018-02-26 08:21 -0800 |
| Message-ID | <262d947a-00ed-45bd-b65d-3c22eb172bad@googlegroups.com> |
| In reply to | #127056 |
On Sunday, February 25, 2018 at 5:34:42 PM UTC-6, Richard Damon wrote:
> Fundamentally, you issue is that you want the C Standard to be the sole
> and final definition of everything that an implementation must be/do,
> but that isn't what the Standard is.
My complaint is that the authors of gcc and clang seem to regard the C
Standard as the final authority as to what programmers should expect from
a compiler when not using compiler-specific directives, but the Standard
is not adequate to fill that role.
The C Standard's One Program rule gives implementations blanket permission
to behave in arbitrary fashion if they are unable to behave as defined by
the Standard. The authors recognize this, but trust that *quality*
implementations will not abuse that privilege. Many parts of the Standard
lack the precision necessary for it to be any kind of meaningful complete
specification of requirements, but some compiler writers seem intent on
pushing the limits of what the Standard would allow.
For the Standard to be beneficial to the development of the language, it
needs to do one of two things:
1. Be more explicit in granting implementers the latitude to deviate
from what the Standard would otherwise require when necessary, but
with a caution that they should refrain from doing so in ways that
would make their implementation unsuitable for its documented
purpose. Note that there would be no need for the Standard to
explicitly "undefine" behavior that would otherwise be defined,
since implementations would have the authority to do so in cases
where supporting the behavior would be impractical.
2. Systematically identify all cases cases where consistent corner-case
behavior would be needed by any significant number of programs and,
for those which could be practically supported on many but not all
implementations, specify means by which programs can demand such
features and refuse compilation on implementations that don't support
them. Code which relies upon such features without demanding them
could be deprecated, but could easily be fixed simply by adding the
appropriate demands.
Either approach would be fine if the Standard were clear about its
direction, but perhaps because of "design by committee" syndrome it
instead hits the worst of both worlds. It decides there should only be
two recognized categories of C implementation, which would make sense if
implementations could be expected to define behaviors based upon the
target platform and application field, but not if implementations use the
Standard as justification to violate such expectations.
If a piece of code needs features that would be practically supportable on
90% of implementations, a language suitable for writing portable programs
should make it possible to write code which uses those features and will
work on the 90% of implementations that can support them, without the
programmer having to to read the documentation for every one of the
implementations upon which the code might be used.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2018-02-26 22:22 -0500 |
| Message-ID | <aa4lC.185862$qv.84846@fx33.iad> |
| In reply to | #127081 |
On 2/26/18 11:21 AM, supercat@casperkitty.com wrote: > On Sunday, February 25, 2018 at 5:34:42 PM UTC-6, Richard Damon wrote: >> Fundamentally, you issue is that you want the C Standard to be the sole >> and final definition of everything that an implementation must be/do, >> but that isn't what the Standard is. > > My complaint is that the authors of gcc and clang seem to regard the C > Standard as the final authority as to what programmers should expect from > a compiler when not using compiler-specific directives, but the Standard > is not adequate to fill that role. from what I remember, gcc without the use of options or compiler specific directives is NOT a compliant implementation, but actually implement a language that highly resembles, but isn't quite, C, incorporating what they feel are useful (but non-compliant) extensions. If you want a 'Standard C' compiler, they document and provide option switches to turn the compiler into a basically compliant implementation. The minimal-option set to do so, uses a lot of the freedom in the Standards definition of undefined behavior to improve the performance of the resulting program, but they do provide a lot of options to provide more definition to what could be considered undefined behavior. They clearly don't consider the standard to be what programmers should expect from a compiler without using options, as they don't obey it in that condition. They seem to expect that their users will realize they have a powerful tool in their hands and will look at the instruction manual before trying anything significant, but still, it does fairly good at meeting the needs of the casual programmer out of the box. > > The C Standard's One Program rule gives implementations blanket permission > to behave in arbitrary fashion if they are unable to behave as defined by > the Standard. The authors recognize this, but trust that *quality* > implementations will not abuse that privilege. Many parts of the Standard > lack the precision necessary for it to be any kind of meaningful complete > specification of requirements, but some compiler writers seem intent on > pushing the limits of what the Standard would allow. I think you give the One Program rule too much power. The rule allows the implementation to fail to translate and execute, but such failure is NOT undefined behavior. > > For the Standard to be beneficial to the development of the language, it > needs to do one of two things: > > 1. Be more explicit in granting implementers the latitude to deviate > from what the Standard would otherwise require when necessary, but > with a caution that they should refrain from doing so in ways that > would make their implementation unsuitable for its documented > purpose. Note that there would be no need for the Standard to > explicitly "undefine" behavior that would otherwise be defined, > since implementations would have the authority to do so in cases > where supporting the behavior would be impractical. A Standard that grants latitude to deviate from true requirements is not a Standard. Also note, no where does the C Standard 'undefine' something that is truely defined elsewhere. Remember, the C Standard specifically defines it use of the term Undefined Behavior to mean that THIS standard, provides no definition for behavior in that case, it provides absolutely no grounds to not follow some other recognized requirement of behavior (now, if you have unfounded expectations that are never actually promised, then you have your own problems) > > 2. Systematically identify all cases cases where consistent corner-case > behavior would be needed by any significant number of programs and, > for those which could be practically supported on many but not all > implementations, specify means by which programs can demand such > features and refuse compilation on implementations that don't support > them. Code which relies upon such features without demanding them > could be deprecated, but could easily be fixed simply by adding the > appropriate demands. You keep on asking for something like this, and it will keep on be thrown back at you, are YOU willing to do at least some of the leg work to document even a list of these cases. I see that this can be an enormous task, something I can understand the Standard Committee not wanting to take on by themselves. > > Either approach would be fine if the Standard were clear about its > direction, but perhaps because of "design by committee" syndrome it > instead hits the worst of both worlds. It decides there should only be > two recognized categories of C implementation, which would make sense if > implementations could be expected to define behaviors based upon the > target platform and application field, but not if implementations use the > Standard as justification to violate such expectations. > > If a piece of code needs features that would be practically supportable on > 90% of implementations, a language suitable for writing portable programs > should make it possible to write code which uses those features and will > work on the 90% of implementations that can support them, without the > programmer having to to read the documentation for every one of the > implementations upon which the code might be used. > Yes, reading documentation is VITAL to use a C compiler. Live with it.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2018-02-27 09:16 +0100 |
| Message-ID | <p73452$fje$1@dont-email.me> |
| In reply to | #127109 |
On 27/02/18 04:22, Richard Damon wrote: > On 2/26/18 11:21 AM, supercat@casperkitty.com wrote: >> On Sunday, February 25, 2018 at 5:34:42 PM UTC-6, Richard Damon wrote: >>> Fundamentally, you issue is that you want the C Standard to be the sole >>> and final definition of everything that an implementation must be/do, >>> but that isn't what the Standard is. >> >> My complaint is that the authors of gcc and clang seem to regard the C >> Standard as the final authority as to what programmers should expect from >> a compiler when not using compiler-specific directives, but the Standard >> is not adequate to fill that role. > > > from what I remember, gcc without the use of options or compiler > specific directives is NOT a compliant implementation, but actually > implement a language that highly resembles, but isn't quite, C, > incorporating what they feel are useful (but non-compliant) extensions. > > If you want a 'Standard C' compiler, they document and provide option > switches to turn the compiler into a basically compliant implementation. > The minimal-option set to do so, uses a lot of the freedom in the > Standards definition of undefined behavior to improve the performance of > the resulting program, but they do provide a lot of options to provide > more definition to what could be considered undefined behavior. > > They clearly don't consider the standard to be what programmers should > expect from a compiler without using options, as they don't obey it in > that condition. They seem to expect that their users will realize they > have a powerful tool in their hands and will look at the instruction > manual before trying anything significant, but still, it does fairly > good at meeting the needs of the casual programmer out of the box. They also understand that programmers' needs and wants can differ, and provide options to define certain key types of behaviour that the standards don't define (access via incompatible pointer types and signed integer overflow behaviour being the obvious cases). It baffles me why certain people complain so much about the behaviour of gcc, when the gcc developers make such an effort to let users fine-tune exactly the behaviour they want. There are many different requirements out there - some people want a compiler that is stricter to the standards, others want helpful extensions, some want more optimisations while others want a "dumb translator". Some want to use constructs that many think are questionable but are legal C, others want an error message for them to catch mistakes. gcc (and clang) give you a myriad of options to let you use the compiler as /you/ want to use it - and then the moaners complain that it does not suit /their/ personal preferences by default, and that it has too many options! <snip> > Yes, reading documentation is VITAL to use a C compiler. Live with it. A lot of people forget that one.
[toc] | [prev] | [next] | [standalone]
Page 3 of 5 — ← Prev page 1 2 [3] 4 5 Next page →
Back to top | Article view | comp.lang.c
csiph-web