Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #127213 > unrolled thread
| Started by | supercat@casperkitty.com |
|---|---|
| First post | 2018-03-01 16:38 -0800 |
| Last post | 2018-03-26 23:04 -0700 |
| Articles | 20 on this page of 149 — 11 participants |
Back to article view | Back to comp.lang.c
lvalue types supercat@casperkitty.com - 2018-03-01 16:38 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 17:17 -0800
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-01 17:37 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 22:00 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 23:49 -0800
Re: lvalue types asetofsymbols@gmail.com - 2018-03-05 06:56 -0800
Re: lvalue types supercat@casperkitty.com - 2018-03-02 00:22 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 01:23 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 05:04 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 06:06 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 08:12 -0800
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-02 09:50 -0800
Re: lvalue types supercat@casperkitty.com - 2018-03-02 11:33 -0800
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-02 11:45 -0800
Re: lvalue types supercat@casperkitty.com - 2018-03-02 16:28 -0800
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-02 16:54 -0800
Re: lvalue types supercat@casperkitty.com - 2018-03-02 17:50 -0800
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-02 19:43 -0800
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-02 22:51 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 23:07 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-03 01:44 -0800
Re: lvalue types supercat@casperkitty.com - 2018-03-03 13:01 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-02 22:21 -0800
Re: lvalue types supercat@casperkitty.com - 2018-03-02 09:24 -0800
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-03 00:58 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-03 01:13 -0800
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-03 13:01 -0800
Re: lvalue types supercat <flatfinger@casperkitty.com> - 2018-03-03 17:43 -0800
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-04 02:22 -0800
Re: lvalue types supercat@casperkitty.com - 2018-03-04 13:03 -0800
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-04 13:03 -0800
Re: lvalue types bartc <bc@freeuk.com> - 2018-03-04 22:32 +0000
Re: lvalue types supercat@casperkitty.com - 2018-03-05 09:45 -0800
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-19 09:54 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-19 11:52 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-26 23:44 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-27 09:14 -0700
Re: lvalue types supercat@casperkitty.com - 2018-03-27 12:21 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-28 17:01 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-29 01:54 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-30 08:32 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-30 09:25 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-03-30 10:58 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-31 00:52 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-02 15:19 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-03 10:06 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-03 11:33 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-03 12:19 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-03 12:48 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-05 10:17 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-05 10:52 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-05 12:39 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-06 06:13 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-04 16:38 -0700
Re: lvalue types supercat@casperkitty.com - 2018-03-27 12:09 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-28 10:48 -0700
Re: lvalue types supercat@casperkitty.com - 2018-03-19 12:27 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-03 14:02 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-04 17:32 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-04 20:24 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-09 08:31 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-11 11:19 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-11 12:44 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-12 06:45 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-12 07:54 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-12 14:26 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-12 14:43 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-12 17:40 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-13 03:02 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-13 00:27 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-13 07:19 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-16 08:52 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-16 10:28 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-16 13:58 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-16 14:52 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-16 16:22 -0700
Re: lvalue types Richard Damon <Richard@Damon-Family.org> - 2018-04-16 21:51 -0400
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-16 19:42 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-16 21:30 -0700
Re: lvalue types Richard Damon <Richard@Damon-Family.org> - 2018-04-17 07:01 -0400
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-17 04:22 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-19 02:43 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-17 07:25 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-17 08:48 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-17 09:54 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-17 10:37 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-17 11:00 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-17 11:48 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-17 12:45 -0700
Re: lvalue types scott@slp53.sl.home (Scott Lurndal) - 2018-04-17 19:55 +0000
Re: lvalue types jameskuyper@verizon.net - 2018-04-17 13:13 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-17 14:00 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-17 19:45 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 08:27 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-18 09:12 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 10:13 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-18 11:01 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-18 11:51 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 12:15 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-18 12:30 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 13:25 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-19 10:51 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-18 12:38 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 14:39 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-18 21:17 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-19 02:40 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-19 03:01 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-19 06:49 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-19 07:58 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-20 08:19 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-19 12:17 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-19 12:51 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-19 13:37 -0700
Re: lvalue types scott@slp53.sl.home (Scott Lurndal) - 2018-04-19 21:08 +0000
Re: lvalue types supercat@casperkitty.com - 2018-04-19 14:50 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-19 14:56 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-19 16:13 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-21 10:27 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-23 11:37 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-18 16:07 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-18 09:20 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 11:25 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-04-17 14:13 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-17 15:05 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-17 19:57 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 08:43 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-18 09:36 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-17 11:37 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-17 20:23 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 09:23 -0700
Re: lvalue types scott@slp53.sl.home (Scott Lurndal) - 2018-04-18 17:29 +0000
Re: lvalue types supercat@casperkitty.com - 2018-04-18 10:47 -0700
Re: lvalue types bartc <bc@freeuk.com> - 2018-04-18 20:04 +0100
Re: lvalue types jameskuyper@verizon.net - 2018-04-18 10:48 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 13:23 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-18 14:26 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-18 15:36 -0700
Re: lvalue types jameskuyper@verizon.net - 2018-04-19 10:39 -0700
Re: lvalue types supercat@casperkitty.com - 2018-04-19 12:42 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-16 21:29 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-04-23 11:39 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-04-04 21:30 -0700
Re: lvalue types supercat@casperkitty.com - 2018-03-03 14:19 -0800
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-01 18:03 -0800
Re: lvalue types John Bode <jfbode1029@gmail.com> - 2018-03-21 10:33 -0700
Re: lvalue types Keith Thompson <kst-u@mib.org> - 2018-03-21 11:53 -0700
Re: lvalue types Steven Petruzzellis <frelwizzen@gmail.com> - 2018-03-22 00:11 -0700
Re: lvalue types supercat@casperkitty.com - 2018-03-21 11:53 -0700
Re: lvalue types Tim Rentsch <txr@alumni.caltech.edu> - 2018-03-26 23:04 -0700
Page 3 of 8 — ← Prev page 1 2 [3] 4 5 6 7 8 Next page →
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2018-03-30 08:32 -0700 |
| Message-ID | <kfnd0zllgtf.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #128449 |
Keith Thompson <kst-u@mib.org> writes:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
>
>> Keith Thompson <kst-u@mib.org> writes:
>>
>>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>>
>>>> Keith Thompson <kst-u@mib.org> writes:
>>>>
>>>>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>>>>
>>>>>> Keith Thompson <kst-u@mib.org> writes:
>>>>>>
>>>>>>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>>>>>>
>>>>>>>> Keith Thompson <kst-u@mib.org> writes:
>>>>>>>>
>>>>>>>>> [When using . or ->, what is "accessed"?]
>>>>>>>>> Let me make the point more succinctly.
>>>>>>>>>
>>>>>>>>> struct s { int m; };
>>>>>>>>> struct s obj;
>>>>>>>>> obj.m = 42;
>>>>>>>>>
>>>>>>>>> obj.m is an lvalue of type int. The assignment accesses
>>>>>>>>> (specifically modifies) the object obj.m, which is of type int;
>>>>>>>>> that's perfectly fine under 6.5p7. It also accesses (i.e.,
>>>>>>>>> modifies) the object obj, which is of type struct s.
>>>>>>>>
>>>>>>>> I don't subscribe to this view, more specifically the last
>>>>>>>> sentence. Consider a union rather than a struct:
>>>>>>>
>>>>>>> [snip]
>>>>>>>
>>>>>>> Let's consider the original struct.
>>>>>>>
>>>>>>> N1570 3.1 defines "access" as
>>>>>>>
>>>>>>> <execution-time action> to read or modify the value of an object
>>>>>>>
>>>>>>> Wouldn't you agree that `obj.m = 42;` modifies the value of obj?
>>>>>>
>>>>>> I would say no. It does change some, or in this particular case
>>>>>> maybe all, of the bytes that hold the object representation of
>>>>>> obj, but that's not the same thing.
>>>>>
>>>>> I truly do not understand what you're saying here.
>>>>>
>>>>> Consider this program:
>>>>>
>>>>> #include <stdio.h>
>>>>> int main(void) {
>>>>> struct s { int m; };
>>>>> struct s obj = { 0 };
>>>>> printf("obj.m = %d\n", obj.m);
>>>>> obj.m = 42;
>>>>> printf("obj.m = %d\n", obj.m);
>>>>> }
>>>>>
>>>>> The output is:
>>>>>
>>>>> obj.m = 0
>>>>> obj.m = 42
>>>>>
>>>>> Assume, for simplicity, that struct s has no padding bytes
>>>>> (sizeof (struct s) == sizeof (int)) and int has no padding
>>>>> bits (the latter probably doesn't matter).
>>>>>
>>>>> Before the assignment, obj has one value. After the assignment,
>>>>> obj has a different value. The value changed because of the
>>>>> assignment.
>>>>>
>>>>> To "access" is, by definition, "to read or modify the value of an
>>>>> object".
>>>>>
>>>>> And you're saying that that assignment, which caused the value of
>>>>> obj to change, did not modify the value of obj?
>>>>>
>>>>> Are you using a different meaning than I am for some seemingly
>>>>> straighforward word? (value? object? modify?)
>>>>
>>>> I suspect the key difference is you assume the Standard uses
>>>> language in a precise and rigorous way (at least I am guessing
>>>> you assume that), and I don't. Take for example the word
>>>> "value". Strictly speaking, values aren't stored in objects.
>>>> What is stored is some representation (not guaranteed to be
>>>> unique) for the value. Sometimes the Standard recognizes this
>>>> distinction, and sometimes it doesn't.
>>>
>>> I assume that the Standard at least attempts to use language precisely.
>>> Since it's written in English, it can't do that with 100% reliability.
>>> (I think there have been attempts to define C using a more formal
>>> notation, but even if successful such a definition might not be useful
>>> to implementers and/or users.)
>>>
>>> I know that the Standard is imprecise in places.
>>>
>>>> Another example is "object". The term "object" is defined as a
>>>> region of storage (in the execution environment, plus some other
>>>> stuff that doesn't matter for present purposes). Yet, in 6.2.4,
>>>> discussing object lifetimes, there is this statement:
>>>>
>>>> If the block is entered recursively, a new instance of the
>>>> object is created each time.
>>>>
>>>> But this is absurd. If a block is entered recursively, we don't
>>>> make a new instance of a certain region of storage. Rather what
>>>> happens is we allocate a different, unrelated region of storage.
>>>> In the quoted sentence the word "object" is being used in a way
>>>> that belies its definition. And it is used in other, different
>>>> ways in other places.
>>>
>>> Sure, I see what you mean. I think the intent is clear enough,
>>> though. It might be possible to change either the definition
>>> of "object" or the description of what happens when a block is
>>> entered recursively. I haven't taken the time to think through
>>> what would be required, and I don't necessarily suggest that it
>>> would be worthwhile.
>>
>> My point is not that the wording is wrong in this case. The
>> point is, text in the Standard often is a little bit sloppy
>> about what words mean, and as a result we shouldn't take any
>> word literally until we've looked to see that doing so doesn't
>> lead to an inconsistency.
>>
>>> But your vague statement about how precise the Standard's wording is
>>> or isn't does not, as far as I can tell, begin to answer my question.
>>>
>>> Given that the Standard's wording is often imprecise, we have to fall
>>> back to common sense, interpreting words as we might in everday written
>>> English.
>>
>> This model is different from mine. My model is that words in the
>> Standard often mean different things in different places, and we
>> shouldn't assume that a meaning that looks sensible in one place
>> will necessarily be sensible in another place, especially if doing
>> so leads to a paradox of some sort. The idea of falling back on
>> common sense is not really compatible with the multiple-meanings
>> perspective.
>
> Your model leads to no actual conclusions. You don't depend on the
> meanings of English words or on common sense to determine what the
> Standard means. You have reached a specific conclusion (that obj.m
> = 42 doesn't access obj), but nothing in what you've said in this
> thread helps me understand how or why you reached that conclusion
> rather than the opposite one (that obj.m = 42 does access obj).
If you don't understand my model, how can you claim it leads to no
actual conclusions, especially when you give an example of such a
conclusion yourself?
>>> Given:
>>>
>>> struct s { int m; };
>>> struct s obj = { 0 };
>>> obj.m = 42;
>>>
>>> (I've added an initializer to guarantee that the value actually
>>> changes), I cannot think of any interpretation of the wording or intent
>>> of the standard, precise or imprecise, that would lead to the conclusion
>>> that the assignment modifies obj.m but does not modify obj.
>>>
>>> obj.m has a value before the assignment. It has a different value
>>> after the assignment. obj has a value before the assignment.
>>> It has a different value after the assignment.
>>>
>>> If you're saying that the assignment does not modify the value of obj,
>>> how did you reach that conclusion? If you're saying that the standard
>>> doesn't say whether the assignment modifies the value of obj or not, how
>>> did you reach that conclusion?
>>>
>>> I don't think you mean to say that the standard is imprecise, therefore
>>> you can reach any conclusion you like.
>>>
>>> The definition of "access" is "to read or modify the value of an
>>> object". We can nitpick the imprecise ways the Standard uses the terms
>>> "value" and "object", but I don't see that that leads us anywhere
>>> useful.
>>
>> My model for how to reason here is simply different from yours.
>
> You've told me at length what your model isn't. You haven't told me
> what it is.
I haven't given a complete description, but I have given some
positive statements (ie, about what it is). Giving a full
description is hard because a lot of it happens in ways that I am
not fully aware of, just as it does for other people. To be able
to describe it requires some serious introspection, and I haven't
had time to do that. Even though I can't give a full description,
here are some affirmative statements that may help:
(1) A given word (or phrase) sometimes means different things at
different places, depending on context.
(2) Definitions given in the Standard are not always symmetric.
To give a specific example, if an object is accessed then it is
either inspected or written (or perhaps both), but if a memory
location is inspected or written that does not imply that any
object whose memory region overlaps that memory location is
necessarily accessed. The definition goes one way but not the
other.
>> don't think "this byte of memory was changed, therefore an object
>> that contains that byte of memory must have been accessed."
>> Suppose a byte is changed by being zapped by a cosmic ray, or
>> maybe as a side effect of a volatile access. There is no lvalue
>> expression involved, so under effective type rules both of those
>> are undefined behavior.
>
> This is irrelevant. There is no undefined behavior and no influence
> outside the defined execution of the program in my example. (Unless
> you're claiming that `obj.m = 42` has undefined behavior, but I don't
> think you're saying that.)
I gave an example that, as I understand your reasoning process,
leads to a paradoxical conclusion. How is that not relevant if
what I am trying to do is better understand your reasoning process
(which is partly what I am trying to do)?
>> I don't know to answer your question
>> because it doesn't make sense in my reasoning model. To me the
>> key question is what object (or sometimes objects plural) does
>> a particular expression access. There is a distinction between
>> an object being accessed and a byte of memory being read or
>> written that happens to fall in a particular object. It is the
>> expression being evaluated that determines which object is being
>> accessed, regardless of what other circumstances may be in force.
>> I know that may not make sense to you, but that's how I think
>> in this particular domain.
>
> You're right, it doesn't make sense to me. `obj.m = 42` is clearly
> intended to have defined behavior, and I presume you agree that it does.
> (I think it doesn't if the standard is interpreted painfully literally,
> but the intent is clear.) That behavior modifies the value of obj.m,
> and it modifies the value of obj. That is by definition an "access" of
> both obj.m and obj.
>
> You vaguely wave your hands and claim that obj.m isn't really being
> accessed.
What I'm trying to give is an explanation, not an argument. You
are (probably unconsciously) wedded to a particular worldview. I
have a different worldview, and I am trying to convey that. I'm
not asking you to agree with it, just try to understand it. Is
that so unreasonable?
>>>>>> Instead of being used in an assignment, suppose we have obj.m
>>>>>> being used to get the value of member m.
>>>>>
>>>>> No, let's concentrate for now on the assignment.
>>>>
>>>> This reaction sounds like confirmation bias - focusing on cases
>>>> that support your theory, and disregarding cases that may be in
>>>> conflict with it.
>>>
>>> No, I'm simply trying to understand your take on an example that seems
>>> straightforward to me. Certainly any interpretation of the Standard
>>> should apply to all cases -- which means that your interpretation should
>>> apply to the assignment. If you can explain that, I'll be willing to
>>> move on to other examples.
>>
>> The paragraph I just wrote is the best explanation I have at the
>> present time.
>
> That's a pity. If you can't explain it, I have to wonder whether you
> understand it yourself.
I think it's important to distinguish between being able to
explain it and being able to explain it to your satisfaction.
> Again, nothing in what you've written so far explains to me how you
> reached the conclusion that `obj.m = 42` doesn't access obj, rather than
> the opposite conclusion that it does.
I acknowledge your reaction, and I'm sorry for it being the case.
I believe the key to overcoming that is for each of us to better
understand the other's worldview, which unfortunately hasn't made
as much progress as I would like.
>>>>>>> Are you saying that
>>>>>>> obj.m = 42;
>>>>>>> only modifies obj.m, but
>>>>>>> obj = (struct s){.obj = 42};
>>>>>>> (which has an equivalent effect) modifies both obj and obj.m?
>>>>>>
>>>>>> It isn't quite right to say the two assignments have equivalent
>>>>>> effect. The effects are allowed to be equivalent, but they are
>>>>>> not guaranteed to be equivalent. (In fact I believe there are
>>>>>> compilers for which the effects are different, and deliberately
>>>>>> so, if not for this exact case then for similar ones.)
>>>>>
>>>>> Can you provide a concrete example? If you're talking about
>>>>> padding bytes, then sure, there can be a difference. Does your
>>>>> statement apply only when there are padding bytes? (I note that
>>>>> the particular struct type I used in the example is very unlikely
>>>>> to have padding bytes.)
>>>>
>>>> What you are saying, in effect, is that the results may be
>>>> equivalent in some implementations. And that's true, they may
>>>> be. My point is that they are not guaranteed to be equivalent in
>>>> all implementations. This is similar to my last comment - for a
>>>> theory to be right it has to be right in all possible situations,
>>>> not just a few convenient situations. That is important when
>>>> what we are doing (as we are doing here) is trying to evaluate a
>>>> theory about what the Standard means.
>>>
>>> Is there some reason you're not answering my questions? If I ask
>>> you a question, it's because I think your answer will help me to
>>> understand what you're talking about.
>>>
>>> Can you provide a concrete example where the two assignments do
>>> not have identical effects? Are you talking about padding bytes?
>>
>> I didn't think it was important to give an example when you gave
>> one yourself. There may be other cases besides padding bytes (eg,
>> padding bits, or members with non-unique representations, or maybe
>> some other possibilities), but for me padding bytes is enough and
>> I didn't want to get into a long discussion trying to exhaustively
>> identify all ways that the two might be different.
>
> I believe I'm writing in English.
>
> I didn't ask you to exhaustively identify all the ways they might be
> different. This is the first time you've mentioned padding bytes, after
> I specifically asked you whether you referring to padding bytes.
>
> You seem determined to withhold information. I still suspect that you
> have some valid point, but dragging it out of you seems to be
> impossible.
If I don't directly answer a question usually it means I think doing
so would be unuseful or maybe even counterproductive. You don't
answer every question that I ask. Given that, I don't think it's
reasonable for you to be upset if I don't answer every question that
you ask. Your right to ask a question does not supersede my right
to respond in a way that I believe most helps the conversation.
> My conclusions:
>
> obj.m = 42 access both obj.m and obj. obj is an object of type struct
> s. obj.m is an lvalue of type int. The effective type rules do not
> permit (more precisely, do not define the behavior of) modify an object
> of type struct s by an lvalue of type int. This is an oversight in the
> standard. The intent is clear, but the wording needs to be updated to
> cover this case (and probably other cases as well).
>
> You clearly disagree, but I've now given up on coaxing you to explain
> how and why.
To understand my comments, I think you will have to accept (at least
provisionally) operating in a different worldview. You seem unable
or unwilling to do that. I don't mean to imply anything negative by
that comment, just to make an observation that may help explain why
we have gotten to the place we currently are.
(PS - sorry for not snipping anything, I just wasn't sure which
context was relevant so I left everything.)
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-03-30 09:25 -0700 |
| Message-ID | <lnmuypttsx.fsf@kst-u.example.com> |
| In reply to | #128584 |
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>> Keith Thompson <kst-u@mib.org> writes:
[...]
>>> This model is different from mine. My model is that words in the
>>> Standard often mean different things in different places, and we
>>> shouldn't assume that a meaning that looks sensible in one place
>>> will necessarily be sensible in another place, especially if doing
>>> so leads to a paradox of some sort. The idea of falling back on
>>> common sense is not really compatible with the multiple-meanings
>>> perspective.
>>
>> Your model leads to no actual conclusions. You don't depend on the
>> meanings of English words or on common sense to determine what the
>> Standard means. You have reached a specific conclusion (that obj.m
>> = 42 doesn't access obj), but nothing in what you've said in this
>> thread helps me understand how or why you reached that conclusion
>> rather than the opposite one (that obj.m = 42 does access obj).
>
> If you don't understand my model, how can you claim it leads to no
> actual conclusions, especially when you give an example of such a
> conclusion yourself?
OK, perhaps there's something in your model that leads to the
conclusions you say it does. I don't just see how.
>>>> Given:
>>>>
>>>> struct s { int m; };
>>>> struct s obj = { 0 };
>>>> obj.m = 42;
>>>>
>>>> (I've added an initializer to guarantee that the value actually
>>>> changes), I cannot think of any interpretation of the wording or intent
>>>> of the standard, precise or imprecise, that would lead to the conclusion
>>>> that the assignment modifies obj.m but does not modify obj.
>>>>
>>>> obj.m has a value before the assignment. It has a different value
>>>> after the assignment. obj has a value before the assignment.
>>>> It has a different value after the assignment.
>>>>
>>>> If you're saying that the assignment does not modify the value of obj,
>>>> how did you reach that conclusion? If you're saying that the standard
>>>> doesn't say whether the assignment modifies the value of obj or not, how
>>>> did you reach that conclusion?
>>>>
>>>> I don't think you mean to say that the standard is imprecise, therefore
>>>> you can reach any conclusion you like.
>>>>
>>>> The definition of "access" is "to read or modify the value of an
>>>> object". We can nitpick the imprecise ways the Standard uses the terms
>>>> "value" and "object", but I don't see that that leads us anywhere
>>>> useful.
>>>
>>> My model for how to reason here is simply different from yours.
>>
>> You've told me at length what your model isn't. You haven't told me
>> what it is.
>
> I haven't given a complete description, but I have given some
> positive statements (ie, about what it is). Giving a full
> description is hard because a lot of it happens in ways that I am
> not fully aware of, just as it does for other people. To be able
> to describe it requires some serious introspection, and I haven't
> had time to do that. Even though I can't give a full description,
> here are some affirmative statements that may help:
>
> (1) A given word (or phrase) sometimes means different things at
> different places, depending on context.
Sure.
> (2) Definitions given in the Standard are not always symmetric.
> To give a specific example, if an object is accessed then it is
> either inspected or written (or perhaps both), but if a memory
> location is inspected or written that does not imply that any
> object whose memory region overlaps that memory location is
> necessarily accessed. The definition goes one way but not the
> other.
And I have no idea how you've reached that conclusion.
It seems obvious to me, from the meanings of ordinary English words
such as "modify", that `obj.m = 42` modifies the vallue of the
object obj. obj had one value before the assignment was evaluated,
and a different value after it was evaluated.
What does "modify" mean if it doesn't apply when the value of an
object is changed?
I'm not unwilling to try to understand your model, but I have so
far been unable to do so. I simply don't see how it makes sense.
>>> don't think "this byte of memory was changed, therefore an object
>>> that contains that byte of memory must have been accessed."
>>> Suppose a byte is changed by being zapped by a cosmic ray, or
>>> maybe as a side effect of a volatile access. There is no lvalue
>>> expression involved, so under effective type rules both of those
>>> are undefined behavior.
>>
>> This is irrelevant. There is no undefined behavior and no influence
>> outside the defined execution of the program in my example. (Unless
>> you're claiming that `obj.m = 42` has undefined behavior, but I don't
>> think you're saying that.)
>
> I gave an example that, as I understand your reasoning process,
> leads to a paradoxical conclusion. How is that not relevant if
> what I am trying to do is better understand your reasoning process
> (which is partly what I am trying to do)?
Memory being changed by cosmic rays is outside the scope of behavior
defined by the standard. Assign a value to a member of a structure is
not.
The only possible "paradoxical" conclusion is that the effective type
rules do not seem to cover the case of assigning a value to a struct
member. This is the oversight I've been talking about all along.
I don't see it as a paradox, just an error in the standard.
[...]
> What I'm trying to give is an explanation, not an argument. You
> are (probably unconsciously) wedded to a particular worldview. I
> have a different worldview, and I am trying to convey that. I'm
> not asking you to agree with it, just try to understand it. Is
> that so unreasonable?
You have conveyed to me that you have a different worldview.
You have not conveyed to me (or, if you prefer, I have failed to
understand) what that worldview is.
[...]
>> My conclusions:
>>
>> obj.m = 42 access both obj.m and obj. obj is an object of type struct
>> s. obj.m is an lvalue of type int. The effective type rules do not
>> permit (more precisely, do not define the behavior of) modify an object
>> of type struct s by an lvalue of type int. This is an oversight in the
>> standard. The intent is clear, but the wording needs to be updated to
>> cover this case (and probably other cases as well).
>>
>> You clearly disagree, but I've now given up on coaxing you to explain
>> how and why.
>
> To understand my comments, I think you will have to accept (at least
> provisionally) operating in a different worldview. You seem unable
> or unwilling to do that. I don't mean to imply anything negative by
> that comment, just to make an observation that may help explain why
> we have gotten to the place we currently are.
I am unable to get a consistent model of your worldview. The
simplest way I can think of to explain this is that a worldview
in which `obj.m = 42` does not modify the value of obj either is
internally inconsistent, or uses the word "modify" in some odd
and unexplained sense that is incompatible with either the normal
English meaning of the word "modify" or any technical definition
I've encountered, or I'm missing something.
[...]
Let me ask two direct yes/no questions. I think I know what your
answers will be, but I'd like to get your answers explicitly.
Given this program:
#include <stdio.h>
int main(void) {
struct s { int m; };
struct s obj = { 0 };
obj.m = 42;
printf("%d\n", obj.m);
}
Does the assignment `obj.m = 42;` modify the value of the object `obj.m`?
Does the assignment `obj.m = 42;` modify the value of the object `obj`?
(The phrase "modify the value of [the] object" is from the standard's
definition of "access".)
If your answers are "yes" and "no", respectively, then that's the
clearest statement I can think of that your worldview is one that
I do not understand.
If you think you can explain what the word "modify" means, preferably
in a manner that would clarify your answers to these two questions,
feel free to do so.
Again, obj has a value before the assignment, it has a different
value after the assignment, and you say the assignment did not
modify obj.
--
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 | jameskuyper@verizon.net |
|---|---|
| Date | 2018-03-30 10:58 -0700 |
| Message-ID | <6b475a5b-0888-4f6a-a02a-188b47ad48c0@googlegroups.com> |
| In reply to | #128587 |
On Friday, March 30, 2018 at 12:25:15 PM UTC-4, Keith Thompson wrote:
...
> Let me ask two direct yes/no questions. I think I know what your
> answers will be, but I'd like to get your answers explicitly.
>
> Given this program:
>
> #include <stdio.h>
> int main(void) {
> struct s { int m; };
> struct s obj = { 0 };
> obj.m = 42;
> printf("%d\n", obj.m);
> }
>
> Does the assignment `obj.m = 42;` modify the value of the object `obj.m`?
> Does the assignment `obj.m = 42;` modify the value of the object `obj`?
> (The phrase "modify the value of [the] object" is from the standard's
> definition of "access".)
>
> If your answers are "yes" and "no", respectively, then that's the
> clearest statement I can think of that your worldview is one that
> I do not understand.
>
> If you think you can explain what the word "modify" means, preferably
> in a manner that would clarify your answers to these two questions,
> feel free to do so.
>
> Again, obj has a value before the assignment, it has a different
> value after the assignment, and you say the assignment did not
> modify obj.
Let me add one more intermediate step: the assignment to obj.m is 100%
of the reason why the value of obj after the assignment is different
from the value of obj before the assignment - the change wasn't just
something that accidentally happened during roughly the same time
period.
To me, causing a change in the value is essentially the definition of
what it means to modify the value, so this doesn't feel like a separate
statement from the final conclusion. However, Tim will either agree that
it has the same meaning, and deny that it applies in this case, or he
will agree that it applies in this case, and deny that it has the same
meaning, or he will pick a third option I haven't even anticipated.
However he responds, we'll have one more piece of information toward
figuring how he can feel justified in claiming that the assignment to
obj.m doesn't modify obj.
[toc] | [prev] | [next] | [standalone]
| From | Steven Petruzzellis <frelwizzen@gmail.com> |
|---|---|
| Date | 2018-03-31 00:52 -0700 |
| Message-ID | <8dafd372-710b-4d06-a740-c43a16e143fc@googlegroups.com> |
| In reply to | #128587 |
On Friday, March 30, 2018 at 9:25:15 AM UTC-7, Keith Thompson wrote:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
> > Keith Thompson <kst-u@mib.org> writes:
> >> Tim Rentsch <txr@alumni.caltech.edu> writes:
> >>> Keith Thompson <kst-u@mib.org> writes:
> [...]
> >>> This model is different from mine. My model is that words in the
> >>> Standard often mean different things in different places, and we
> >>> shouldn't assume that a meaning that looks sensible in one place
> >>> will necessarily be sensible in another place, especially if doing
> >>> so leads to a paradox of some sort. The idea of falling back on
> >>> common sense is not really compatible with the multiple-meanings
> >>> perspective.
> >>
> >> Your model leads to no actual conclusions. You don't depend on the
> >> meanings of English words or on common sense to determine what the
> >> Standard means. You have reached a specific conclusion (that obj.m
> >> = 42 doesn't access obj), but nothing in what you've said in this
> >> thread helps me understand how or why you reached that conclusion
> >> rather than the opposite one (that obj.m = 42 does access obj).
> >
> > If you don't understand my model, how can you claim it leads to no
> > actual conclusions, especially when you give an example of such a
> > conclusion yourself?
>
> OK, perhaps there's something in your model that leads to the
> conclusions you say it does. I don't just see how.
>
> >>>> Given:
> >>>>
> >>>> struct s { int m; };
> >>>> struct s obj = { 0 };
> >>>> obj.m = 42;
> >>>>
> >>>> (I've added an initializer to guarantee that the value actually
> >>>> changes), I cannot think of any interpretation of the wording or intent
> >>>> of the standard, precise or imprecise, that would lead to the conclusion
> >>>> that the assignment modifies obj.m but does not modify obj.
> >>>>
> >>>> obj.m has a value before the assignment. It has a different value
> >>>> after the assignment. obj has a value before the assignment.
> >>>> It has a different value after the assignment.
> >>>>
> >>>> If you're saying that the assignment does not modify the value of obj,
> >>>> how did you reach that conclusion? If you're saying that the standard
> >>>> doesn't say whether the assignment modifies the value of obj or not, how
> >>>> did you reach that conclusion?
> >>>>
> >>>> I don't think you mean to say that the standard is imprecise, therefore
> >>>> you can reach any conclusion you like.
> >>>>
> >>>> The definition of "access" is "to read or modify the value of an
> >>>> object". We can nitpick the imprecise ways the Standard uses the terms
> >>>> "value" and "object", but I don't see that that leads us anywhere
> >>>> useful.
> >>>
> >>> My model for how to reason here is simply different from yours.
> >>
> >> You've told me at length what your model isn't. You haven't told me
> >> what it is.
> >
> > I haven't given a complete description, but I have given some
> > positive statements (ie, about what it is). Giving a full
> > description is hard because a lot of it happens in ways that I am
> > not fully aware of, just as it does for other people. To be able
> > to describe it requires some serious introspection, and I haven't
> > had time to do that. Even though I can't give a full description,
> > here are some affirmative statements that may help:
> >
> > (1) A given word (or phrase) sometimes means different things at
> > different places, depending on context.
>
> Sure.
>
> > (2) Definitions given in the Standard are not always symmetric.
> > To give a specific example, if an object is accessed then it is
> > either inspected or written (or perhaps both), but if a memory
> > location is inspected or written that does not imply that any
> > object whose memory region overlaps that memory location is
> > necessarily accessed. The definition goes one way but not the
> > other.
>
> And I have no idea how you've reached that conclusion.
>
> It seems obvious to me, from the meanings of ordinary English words
> such as "modify", that `obj.m = 42` modifies the vallue of the
> object obj. obj had one value before the assignment was evaluated,
> and a different value after it was evaluated.
>
> What does "modify" mean if it doesn't apply when the value of an
> object is changed?
>
> I'm not unwilling to try to understand your model, but I have so
> far been unable to do so. I simply don't see how it makes sense.
>
> >>> don't think "this byte of memory was changed, therefore an object
> >>> that contains that byte of memory must have been accessed."
> >>> Suppose a byte is changed by being zapped by a cosmic ray, or
> >>> maybe as a side effect of a volatile access. There is no lvalue
> >>> expression involved, so under effective type rules both of those
> >>> are undefined behavior.
> >>
> >> This is irrelevant. There is no undefined behavior and no influence
> >> outside the defined execution of the program in my example. (Unless
> >> you're claiming that `obj.m = 42` has undefined behavior, but I don't
> >> think you're saying that.)
> >
> > I gave an example that, as I understand your reasoning process,
> > leads to a paradoxical conclusion. How is that not relevant if
> > what I am trying to do is better understand your reasoning process
> > (which is partly what I am trying to do)?
>
> Memory being changed by cosmic rays is outside the scope of behavior
> defined by the standard. Assign a value to a member of a structure is
> not.
>
> The only possible "paradoxical" conclusion is that the effective type
> rules do not seem to cover the case of assigning a value to a struct
> member. This is the oversight I've been talking about all along.
> I don't see it as a paradox, just an error in the standard.
>
> [...]
>
> > What I'm trying to give is an explanation, not an argument. You
> > are (probably unconsciously) wedded to a particular worldview. I
> > have a different worldview, and I am trying to convey that. I'm
> > not asking you to agree with it, just try to understand it. Is
> > that so unreasonable?
>
> You have conveyed to me that you have a different worldview.
> You have not conveyed to me (or, if you prefer, I have failed to
> understand) what that worldview is.
>
> [...]
>
> >> My conclusions:
> >>
> >> obj.m = 42 access both obj.m and obj. obj is an object of type struct
> >> s. obj.m is an lvalue of type int. The effective type rules do not
> >> permit (more precisely, do not define the behavior of) modify an object
> >> of type struct s by an lvalue of type int. This is an oversight in the
> >> standard. The intent is clear, but the wording needs to be updated to
> >> cover this case (and probably other cases as well).
> >>
> >> You clearly disagree, but I've now given up on coaxing you to explain
> >> how and why.
> >
> > To understand my comments, I think you will have to accept (at least
> > provisionally) operating in a different worldview. You seem unable
> > or unwilling to do that. I don't mean to imply anything negative by
> > that comment, just to make an observation that may help explain why
> > we have gotten to the place we currently are.
>
> I am unable to get a consistent model of your worldview. The
> simplest way I can think of to explain this is that a worldview
> in which `obj.m = 42` does not modify the value of obj either is
> internally inconsistent, or uses the word "modify" in some odd
> and unexplained sense that is incompatible with either the normal
> English meaning of the word "modify" or any technical definition
> I've encountered, or I'm missing something.
>
> [...]
>
> Let me ask two direct yes/no questions. I think I know what your
> answers will be, but I'd like to get your answers explicitly.
>
> Given this program:
>
> #include <stdio.h>
> int main(void) {
> struct s { int m; };
> struct s obj = { 0 };
> obj.m = 42;
> printf("%d\n", obj.m);
> }
>
> Does the assignment `obj.m = 42;` modify the value of the object `obj.m`?
> Does the assignment `obj.m = 42;` modify the value of the object `obj`?
> (The phrase "modify the value of [the] object" is from the standard's
> definition of "access".)
>
> If your answers are "yes" and "no", respectively, then that's the
> clearest statement I can think of that your worldview is one that
> I do not understand.
>
> If you think you can explain what the word "modify" means, preferably
> in a manner that would clarify your answers to these two questions,
> feel free to do so.
>
> Again, obj has a value before the assignment, it has a different
> value after the assignment, and you say the assignment did not
> modify obj.
>
> --
> 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"
Lots of posters keep replying to Daniel Lewis. I can't blame Autumn Nissen for his hissy fit but, in the end, I can not figure out why he stays here after all this nonsense. Autumn Nissen is expecting discussions as done in a Facebook venue and trolling forums simply aren't it.
I have worked for the PC design field for nearly 20 years. I have served top businesses making deals with NASA and the health industry. Never, with even a hint, was I at any point under a contractual obligation to not install any version of Linux. We sold OS/2, Mac, Symbian, and so forth in addition to Windows. Please show a case study of a profitable company that has gained its wealth by not giving a hoot about its customers or merchandise.
Too much glue for you, Daniel Lewis.
Do you have a MCSE certification? Protected code is being built into KDE. So what is Daniel Lewis's poison for the flooding deluge? Access? That is the only tool he knows, and it is a joke. He must be using it to create these goofy "flooding" posts. Lemme idea, Daniel Lewis took a PGP program that he hacked and try to sell online... he is feeding it Google Groups data, grabbing hand-picked paragraphs, then scrambling those using a Markv model and then he annoyingly posts them because his mental health issues enables him to do that practically round-the-clock. How is Blender on Linux doing anything above the lowest common denominator?
-
Get Rich Slow!!
https://youtu.be/TETJEkaUoY4
Jonas Eklundh
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-04-02 15:19 -0700 |
| Message-ID | <lnlge5s13c.fsf@kst-u.example.com> |
| In reply to | #128587 |
Keith Thompson <kst-u@mib.org> writes:
[...]
> Given this program:
>
> #include <stdio.h>
> int main(void) {
> struct s { int m; };
> struct s obj = { 0 };
> obj.m = 42;
> printf("%d\n", obj.m);
> }
>
> Does the assignment `obj.m = 42;` modify the value of the object `obj.m`?
> Does the assignment `obj.m = 42;` modify the value of the object `obj`?
> (The phrase "modify the value of [the] object" is from the standard's
> definition of "access".)
[...]
I thought for a while that there might be something that would resolve
the oversight I saw in 6.5p7.
In the assignment expression
obj.m = 42
there are two lvalues, `obj` and `obj.m`. One could argue that obj is
accessed by the value `obj`, which is of type `struct s`.
But on further thought, that doesn't resolve it:
struct s { int m; };
struct s obj = { 0 };
int *ptr = &obj.m;
*ptr = 42;
In this assignment, there is no lvalue of type `struct s`, but the
object `obj` of type `struct s` is modified.
Oh well.
(I remain convinced that both obj.m and obj are accessed/modified
by the assignment.)
--
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-04-03 10:06 -0700 |
| Message-ID | <d36fce32-7231-42f7-a914-9a0411a248bd@googlegroups.com> |
| In reply to | #128647 |
On Monday, April 2, 2018 at 5:19:48 PM UTC-5, Keith Thompson wrote:
> Keith Thompson <kst-u@mib.org> writes:
> [...]
> > Given this program:
> >
> > #include <stdio.h>
> > int main(void) {
> > struct s { int m; };
> > struct s obj = { 0 };
> > obj.m = 42;
> > printf("%d\n", obj.m);
> > }
> >
> > Does the assignment `obj.m = 42;` modify the value of the object `obj.m`?
> > Does the assignment `obj.m = 42;` modify the value of the object `obj`?
> > (The phrase "modify the value of [the] object" is from the standard's
> > definition of "access".)
> [...]
>
> I thought for a while that there might be something that would resolve
> the oversight I saw in 6.5p7.
>
> In the assignment expression
>
> obj.m = 42
>
> there are two lvalues, `obj` and `obj.m`. One could argue that obj is
> accessed by the value `obj`, which is of type `struct s`.
>
> But on further thought, that doesn't resolve it:
>
> struct s { int m; };
> struct s obj = { 0 };
> int *ptr = &obj.m;
> *ptr = 42;
>
> In this assignment, there is no lvalue of type `struct s`, but the
> object `obj` of type `struct s` is modified.
>
> Oh well.
>
> (I remain convinced that both obj.m and obj are accessed/modified
> by the assignment.)
They are, but the assignment to *ptr involves the lvalue "obj" in a way
which would be visible to any compiler that makes any effort to see it.
The address-of operator would be rather silly if it didn't allow a derived
lvalue to be used to access storage within the parent at least in cases
where it is the most recently derived lvalue that will be used to access
the storage in question, and a non-blind compiler can see its derivation.
The $64,000 question is whether P6.5p7 is meant to be interpreted as saying
that lvalues used for access must be visibly derived from lvalues of the
proper type, or as saying that the visible derivation of a pointer to a
union member may be ignored if some other member was last used to access the
union.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-04-03 11:33 -0700 |
| Message-ID | <ln8ta4rvh3.fsf@kst-u.example.com> |
| In reply to | #128664 |
supercat@casperkitty.com writes:
> On Monday, April 2, 2018 at 5:19:48 PM UTC-5, Keith Thompson wrote:
>> Keith Thompson <kst-u@mib.org> writes:
>> [...]
>> > Given this program:
>> >
>> > #include <stdio.h>
>> > int main(void) {
>> > struct s { int m; };
>> > struct s obj = { 0 };
>> > obj.m = 42;
>> > printf("%d\n", obj.m);
>> > }
>> >
>> > Does the assignment `obj.m = 42;` modify the value of the object `obj.m`?
>> > Does the assignment `obj.m = 42;` modify the value of the object `obj`?
>> > (The phrase "modify the value of [the] object" is from the standard's
>> > definition of "access".)
>> [...]
>>
>> I thought for a while that there might be something that would resolve
>> the oversight I saw in 6.5p7.
>>
>> In the assignment expression
>>
>> obj.m = 42
>>
>> there are two lvalues, `obj` and `obj.m`. One could argue that obj is
>> accessed by the value `obj`, which is of type `struct s`.
>>
>> But on further thought, that doesn't resolve it:
>>
>> struct s { int m; };
>> struct s obj = { 0 };
>> int *ptr = &obj.m;
>> *ptr = 42;
>>
>> In this assignment, there is no lvalue of type `struct s`, but the
>> object `obj` of type `struct s` is modified.
>>
>> Oh well.
>>
>> (I remain convinced that both obj.m and obj are accessed/modified
>> by the assignment.)
>
> They are, but the assignment to *ptr involves the lvalue "obj" in a way
> which would be visible to any compiler that makes any effort to see it.
Compilers are not required to make that effort, but that's not relevant
anyway. Even if `*ptr = 42` involves an lvalue of type `struct s`, it
doesn't matter whether the compiler is able to determine that it does.
The effective type rules describe which accesses do or do not have
defined behavior.
If we were to argue that `*ptr = 42` involves an lvalue of type
`struct s`, that argument would be based on the lvalue(s) in the
expression being "derived" from an lvalue of type `struct s`,
not on whether the compiler knows that.
> The address-of operator would be rather silly if it didn't allow a derived
> lvalue to be used to access storage within the parent at least in cases
> where it is the most recently derived lvalue that will be used to access
> the storage in question, and a non-blind compiler can see its derivation.
In the assignment `*ptr = 42`, the value of obj is not modified "by" the
lvalue `obj` that appears on a previous line. The only lvalues in that
assignment are `ptr` (which undergoes lvalue conversion, yielding a
value of type int*) and `*ptr` (which is used to access obj.m).
I don't believe that the effective type rules in 6.5p7 are intended to
include the type of an lvalue that does not appear in the expression
that actually accesses the object. That would IMHO be a very strained
reading of what the standard actually says.
> The $64,000 question is whether P6.5p7 is meant to be interpreted as saying
> that lvalues used for access must be visibly derived from lvalues of the
> proper type, or as saying that the visible derivation of a pointer to a
> union member may be ignored if some other member was last used to access the
> union.
--
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-04-03 12:19 -0700 |
| Message-ID | <f22455ea-6bf6-4e34-9efc-2f268dacca82@googlegroups.com> |
| In reply to | #128666 |
On Tuesday, April 3, 2018 at 1:33:27 PM UTC-5, Keith Thompson wrote:
> supercat@casperkitty.com writes:
> > They are, but the assignment to *ptr involves the lvalue "obj" in a way
> > which would be visible to any compiler that makes any effort to see it.
>
> Compilers are not required to make that effort, but that's not relevant
> anyway. Even if `*ptr = 42` involves an lvalue of type `struct s`, it
> doesn't matter whether the compiler is able to determine that it does.
> The effective type rules describe which accesses do or do not have
> defined behavior.
The stated purpose of the rules is to allow compilers to make assumptions
about what things do and do not alias. If a derived pointer were used to
access some storage at a time after some other pointer not derived from it
was used in a fashion related to the storage, it would alias that other
pointer. Use of references to derive other references in LIFO fashion,
however, is not aliasing in any normal sense of the word.
All a compiler that caches values in registers would need to do to handle
this situation is flush any cached registers associated with the union
object whenever the address-of operator is applied to a member thereof,
and note that the resulting pointer is associated with the original lvalue
(so any registers associated with it can be flushed the next time that
lvalue is accessed).
Such a thing would have been trivial when the Standard was written, and I
see no reason to believe the authors of the Standard expected compiler
writers would design their compilers so as to be incapable of doing so.
> If we were to argue that `*ptr = 42` involves an lvalue of type
> `struct s`, that argument would be based on the lvalue(s) in the
> expression being "derived" from an lvalue of type `struct s`,
> not on whether the compiler knows that.
The only times a compiler would need to really keep track of anything would
be when a parent lvalue is used after a derived lvalue, in which case it
would need to make sure the cached derived lvalue was retired before the
next use of the parent. If one allows retirement of an lvalue that was
derived before the start of a function or loop to be hoisted up to the start
of that function or loop [implying a requirement that any storage accessed
by an lvalue derived before the start of a particular execution of a
function or loop must be accessed exclusively via that lvalue or others
derived from it *during* that execution] a simple static analysis of the
syntax tree would suffice to identify places where cached lvalues need
to be flushed.
> > The address-of operator would be rather silly if it didn't allow a derived
> > lvalue to be used to access storage within the parent at least in cases
> > where it is the most recently derived lvalue that will be used to access
> > the storage in question, and a non-blind compiler can see its derivation.
>
> In the assignment `*ptr = 42`, the value of obj is not modified "by" the
> lvalue `obj` that appears on a previous line. The only lvalues in that
> assignment are `ptr` (which undergoes lvalue conversion, yielding a
> value of type int*) and `*ptr` (which is used to access obj.m).
So if I copy "obj" to s1 before the assignment to *ptr, and I copy it to
s2 after, then s1 and s2 will end up holding the same values?
> I don't believe that the effective type rules in 6.5p7 are intended to
> include the type of an lvalue that does not appear in the expression
> that actually accesses the object. That would IMHO be a very strained
> reading of what the standard actually says.
All that would be necessary would be to say that accesses must "use" an
lvalue of the proper type, for a reasonable definition of "use". Note
that under a literal reading of the Standard, even something like:
char ch;
ch=5;
would invoke Undefined Behavior, because the lvalue ch doesn't modify
the storage, and the expression that does modify the storage isn't an
lvalue.
By your reading of the Standard, given:
struct s1 {int x1; ...};
struct s2 {int x2; ...};
int test1(struct s1 *p1, struct s2 *p2)
{
struct s2 *p2b = (struct s2*)p2;
if (p1->x1)
p2b->x2 += 4;
return p1->x1;
}
int test2(struct s1 *p1, struct s1 *p2)
{
if (p1->x1)
{
struct s2 *p2b = (struct s2*)p2;
p2b->x2 += 4;
}
return p1->x1;
}
for which function, if either, would a compiler be required to acknowledge
that p1 and p2 might identify the same storage? My interpretation of your
reading is that p1->x1 is simply an lvalue expression of type "int", and
likewise p2b->x2, and thus a compiler would be required to allow for
aliasing between them. GCC's behavior would not recognize it in either
case. By my reading, invoking test1 with matching pointers p1 and p2 would
result in aliasing between p2b and p1 (since p1 is not derived from p2b,
but is used between the time p2b is derived and when it is used), but test2
would not (since p2b would be created after the first use of p1->x, and
all uses of p2b would precede the next use of p1->x). All a compiler would
need to do to make the second code work is recognize the second as:
int test2(struct s1 *p1, struct s1 *p2)
{
if (p1->x1)
{
...Retire any cached lvalues that might match p2 [including
...anything of "struct s1" which p2 might identify, such as *p1].
struct s2 *p2b = (struct s2*)p2;
...Recognize p2b as a cached lvalue that might match p2
p2b->x2 += 4;
}
... Retire any cached lvalues that might match p1 [including
... anything of "struct s1" which p1 might identify, such as *p2
... or things derived from it, like p2b].
return p1->x1;
}
True, I'd interpret the footnote as normative, but that seems less of a
stretch than pretending that objects aren't accessed in cases where they
clearly are.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-04-03 12:48 -0700 |
| Message-ID | <lnwoxoqdfe.fsf@kst-u.example.com> |
| In reply to | #128669 |
supercat@casperkitty.com writes:
> On Tuesday, April 3, 2018 at 1:33:27 PM UTC-5, Keith Thompson wrote:
[...]
>> In the assignment `*ptr = 42`, the value of obj is not modified "by" the
>> lvalue `obj` that appears on a previous line. The only lvalues in that
>> assignment are `ptr` (which undergoes lvalue conversion, yielding a
>> value of type int*) and `*ptr` (which is used to access obj.m).
>
> So if I copy "obj" to s1 before the assignment to *ptr, and I copy it to
> s2 after, then s1 and s2 will end up holding the same values?
No. Why would you think that?
>> I don't believe that the effective type rules in 6.5p7 are intended to
>> include the type of an lvalue that does not appear in the expression
>> that actually accesses the object. That would IMHO be a very strained
>> reading of what the standard actually says.
>
> All that would be necessary would be to say that accesses must "use" an
> lvalue of the proper type, for a reasonable definition of "use". Note
> that under a literal reading of the Standard, even something like:
>
> char ch;
> ch=5;
>
> would invoke Undefined Behavior, because the lvalue ch doesn't modify
> the storage, and the expression that does modify the storage isn't an
> lvalue.
The wording is a bit sloppy. It says "An object shall have its stored
value accessed only by an lvalue expression that has one of the
following types: [...]", and you're right, objects are not accessed "by"
lvalues. The only reasonable interpretation is that in your example:
char ch;
ch=5;
the "lvalue expression" being referred to is `ch`, the LHS of the
assignment (which has "a type compatible with the effective type of the
object").
I haven't thought about how to reword it to make the intent clearer.
[snip]
To repeat what I've said earlier, it seems obvious to me that
`obj.m = 42` has defined behavior and that it accesses (specifically
modifies) both the object `obj.m` and the object `obj`. Adding a level
of indirection:
int *ptr = &obj.m;
*ptr = 42;
doesn't, or shouldn't, fundamentally change anything. My reading of
6.5p7 is that the access of the object `obj` violates the effective
type rules as they are currently written. I believe this to be
an oversight (and effectively a fairly minor one, given that I
expect that every compiler in the real world does the right thing).
Of course doing the "right thing" still conforms to the standard as
it's currently written, since the behavior appears to be undefined.
(At this time, I'm not going to worry too much about aliasing of
distinct members of a struct with the same type. I'm concentrating
on the simplest case I can think of, modifying a single member of
a single struct object.)
--
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-04-05 10:17 -0700 |
| Message-ID | <ffcac6dc-aea6-4e10-a340-2ed2ef14ba0e@googlegroups.com> |
| In reply to | #128666 |
On Tuesday, April 3, 2018 at 1:33:27 PM UTC-5, Keith Thompson wrote:
> I don't believe that the effective type rules in 6.5p7 are intended to
> include the type of an lvalue that does not appear in the expression
> that actually accesses the object. That would IMHO be a very strained
> reading of what the standard actually says.
If the applying the address-of operator to a struct or union member does
not yield a pointer that can be dereferenced to access the parent object,
what exactly is its purpose?
The stated purpose of the 6.5p7 is to let compilers make assumptions about
what things may or may not be aliased. Interpreting the rule as applying
even in contexts where storage has one clearly-identifiable active reference
at all times would make structs and unions essentially useless. Interpreting
it as applying only in cases where reference lifetimes overlap would not
have such an effect.
Given something like:
struct s1 {int x; ...};
void useS1(struct s1 * restrict p1) { ... }
union u { struct s1 v1; ...};
void test(union u * restrict p2)
{
...
useS1(&p2->v1);
...
}
a compiler that is only generating code for s1 that needs to be callable
from any context would have no way of knowing whether "p1" might actually
be used to access a "union u", but it would also have no reason to care
since nothing that isn't derived from "p1", whether of type "union u" or
any other type, is going to be used in ways that could alias "*p1" within
the execution of the function. If the code for "useS1" is being in-lined
in "test", a compiler would have reason to care that p1 might access
something that is also accessed via lvalue of type "union u", but that's
because it generated code to derive p from an lvalue of that type. The
authors of the Standard may not have forbidden compilers from using the
rules to "prove" that p2 can't actually identify an object of type "union u"
despite the fact that it is a pointer of that type, because that address
is used with an lvalue of type "struct s1", but IMHO that's because they
didn't think any compiler writer would be crazy enough to think that would
be a good idea.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2018-04-05 10:52 -0700 |
| Message-ID | <lnh8opr15p.fsf@kst-u.example.com> |
| In reply to | #128789 |
supercat@casperkitty.com writes:
> On Tuesday, April 3, 2018 at 1:33:27 PM UTC-5, Keith Thompson wrote:
>> I don't believe that the effective type rules in 6.5p7 are intended to
>> include the type of an lvalue that does not appear in the expression
>> that actually accesses the object. That would IMHO be a very strained
>> reading of what the standard actually says.
>
> If the applying the address-of operator to a struct or union member does
> not yield a pointer that can be dereferenced to access the parent object,
> what exactly is its purpose?
When did I say that that's not its purpose? Given:
struct s { int m; };
struct s obj = { 0 };
int *ptr = &obj.m;
*ptr = 42;
*of course* the assignment modifies the value of obj.m. My complaint
is that the current wording of the effective type rules does not
cover this case, assuming that the assignment modifies/access obj
as well as obj.m. (Tim has posted another followup on that subject,
which I'll reply to Real Soon Now.)
> The stated purpose of the 6.5p7 is to let compilers make assumptions about
> what things may or may not be aliased.
That purpose is stated in a footnote, which is non-normative. Knowing
the purpose behind a set of rules is interesting, and it can help
resolve ambiguities, but it doesn't alter the rules themselves as they
are written.
> Interpreting the rule as applying
> even in contexts where storage has one clearly-identifiable active reference
> at all times would make structs and unions essentially useless.
Which is exactly why I advocate fixing the wording.
> Interpreting
> it as applying only in cases where reference lifetimes overlap would not
> have such an effect.
I'm not sure what "reference lifetimes overlap" means, but I
think you're stretching the wording beyond its breaking point.
6.5p7 says "An object shall have its stored value accessed only
by an lvalue expression that has one of the following types: ...".
It says nothing about "reference lifetimes".
[...]
--
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-04-05 12:39 -0700 |
| Message-ID | <45cb3d0a-4c15-4714-a65a-12e1c39dd1c3@googlegroups.com> |
| In reply to | #128791 |
On Thursday, April 5, 2018 at 12:52:47 PM UTC-5, Keith Thompson wrote: > That purpose is stated in a footnote, which is non-normative. Knowing > the purpose behind a set of rules is interesting, and it can help > resolve ambiguities, but it doesn't alter the rules themselves as they > are written. The normative rules are nonsensical as written. The only way to make them sensible is to add something beyond the normative text. Bringing in the stated intention from a non-normative footnote seems better than inventing things out of whole cloth.
[toc] | [prev] | [next] | [standalone]
| From | Steven Petruzzellis <frelwizzen@gmail.com> |
|---|---|
| Date | 2018-04-06 06:13 -0700 |
| Message-ID | <bd62dd69-9bcb-455b-885d-4ee00f9ab5d3@googlegroups.com> |
| In reply to | #128791 |
On Thursday, April 5, 2018 at 10:52:47 AM UTC-7, Keith Thompson wrote:
> supercat@casperkitty.com writes:
> > On Tuesday, April 3, 2018 at 1:33:27 PM UTC-5, Keith Thompson wrote:
> >> I don't believe that the effective type rules in 6.5p7 are intended to
> >> include the type of an lvalue that does not appear in the expression
> >> that actually accesses the object. That would IMHO be a very strained
> >> reading of what the standard actually says.
> >
> > If the applying the address-of operator to a struct or union member does
> > not yield a pointer that can be dereferenced to access the parent object,
> > what exactly is its purpose?
>
> When did I say that that's not its purpose? Given:
>
> struct s { int m; };
> struct s obj = { 0 };
> int *ptr = &obj.m;
> *ptr = 42;
>
> *of course* the assignment modifies the value of obj.m. My complaint
> is that the current wording of the effective type rules does not
> cover this case, assuming that the assignment modifies/access obj
> as well as obj.m. (Tim has posted another followup on that subject,
> which I'll reply to Real Soon Now.)
>
> > The stated purpose of the 6.5p7 is to let compilers make assumptions about
> > what things may or may not be aliased.
>
> That purpose is stated in a footnote, which is non-normative. Knowing
> the purpose behind a set of rules is interesting, and it can help
> resolve ambiguities, but it doesn't alter the rules themselves as they
> are written.
>
> > Interpreting the rule as applying
> > even in contexts where storage has one clearly-identifiable active reference
> > at all times would make structs and unions essentially useless.
>
> Which is exactly why I advocate fixing the wording.
>
> > Interpreting
> > it as applying only in cases where reference lifetimes overlap would not
> > have such an effect.
>
> I'm not sure what "reference lifetimes overlap" means, but I
> think you're stretching the wording beyond its breaking point.
> 6.5p7 says "An object shall have its stored value accessed only
> by an lvalue expression that has one of the following types: ...".
> It says nothing about "reference lifetimes".
>
> [...]
>
> --
> 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"
Peter the Klöwn insists that he uses macOS, while of course he never recorded it on a modern device and fully worked with it.
Autumn Nissen of Prescott Valley's computer has more memory than Peter the Klöwn's. Autumn Nissen of Prescott Valley wins. Peter the Klöwn loses. So take that, Peter the Klöwn.
Clearly, the lone thing that concerns Peter the Klöwn is being "moral", and if he can not have that he will post more evidence to actively beat Autumn Nissen of Prescott Valley down, effectively destroying every group he goes to. "You are never up to anything good" said Peter the Klöwn's girlfriend.
--
This broke the Internet
https://prescottareapsychopaths.wordpress.com/shawn-ulman-psychopath
https://youtu.be/IhOfBmWwCVY
Jonas Eklundh
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2018-04-04 16:38 -0700 |
| Message-ID | <kfnbmeyilum.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #128587 |
Keith Thompson <kst-u@mib.org> writes:
> Tim Rentsch <txr@alumni.caltech.edu> writes:
>
>> [... lots ...]
I'm trying a different mode of responding in hopes that it
may help the conversation.
> Let me ask two direct yes/no questions. I think I know what your
> answers will be, but I'd like to get your answers explicitly.
>
> Given this program:
>
> #include <stdio.h>
> int main(void) {
> struct s { int m; };
> struct s obj = { 0 };
> obj.m = 42;
> printf("%d\n", obj.m);
> }
>
> Does the assignment `obj.m = 42;` modify the value of the object `obj.m`?
Yes.
> Does the assignment `obj.m = 42;` modify the value of the object `obj`?
> (The phrase "modify the value of [the] object" is from the standard's
> definition of "access".)
No, not in the sense that the phrase is used in the definition of
access, in particular in the way "access" is used in 6.5 p{6,7}.
> If your answers are "yes" and "no", respectively, then that's the
> clearest statement I can think of that your worldview is one that
> I do not understand.
>
> If you think you can explain what the word "modify" means, preferably
> in a manner that would clarify your answers to these two questions,
> feel free to do so.
I think the key point is that the definition of access is not
bi-directional. If something is accessed then it is read or
modified; but if a memory location is inspected ("read") or
stored into ("modified"), that does not necessarily mean an
object that overlaps that memory location has been accessed.
> Again, obj has a value before the assignment, it has a different
> value after the assignment, and you say the assignment did not
> modify obj.
Your focus seems to be on "modify". Mine is on "access". What
is being modified is not the object 'obj' but some bytes of
memory that happen to be part of the object 'obj'. I guess you
don't distinguish between those two. I do.
If you don't mind I would like to ask some questions. Given the
following program, and assuming 'unsigned' has the same size as
'float', with no padding bits (disclaimer: not compiled, just
typed in):
#include <stdio.h>
int main(void) {
union u { unsigned u; float f; };
union u obj = { 0 };
obj.f = 42;
printf( "%u\n", obj.u );
return 0;
}
Does the program have any undefined behavior?
Does the assignment to obj.f access the object obj.u?
If the assignment to obj.f does access the object obj.u, is
that a violation of effective type rules?
My answers are no, no, and not applicable. I welcome any
comments or comparisons that you think would be helpful.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2018-03-27 12:09 -0700 |
| Message-ID | <267ef83a-3ab5-4837-9034-17faf0c11c74@googlegroups.com> |
| In reply to | #128418 |
On Tuesday, March 27, 2018 at 1:44:46 AM UTC-5, Tim Rentsch wrote: > This model is different from mine. My model is that words in the > Standard often mean different things in different places, and we > shouldn't assume that a meaning that looks sensible in one place > will necessarily be sensible in another place, especially if doing > so leads to a paradox of some sort. The idea of falling back on > common sense is not really compatible with the multiple-meanings > perspective. The biggest problem word is probably "object", which can either refer to what most languages would call "variables", or members/fields of aggregates, or elements of arrays, targets of pointers, etc. The lack of a term for "variable" is perhaps the biggest difficulty. A related problem is that C has no term for what is done with the lvalue "a[i++].intMember" during the execution of "int *p = &a[i++].intMember". The lvalue isn't *evaluated*, nor is it *accessed*, but *something* clearly happens to it, since it has a visible side-effect. > My model for how to reason here is simply different from yours. I > don't think "this byte of memory was changed, therefore an object > that contains that byte of memory must have been accessed." > Suppose a byte is changed by being zapped by a cosmic ray, or > maybe as a side effect of a volatile access. There is no lvalue > expression involved, so under effective type rules both of those > are undefined behavior. I don't know to answer your question > because it doesn't make sense in my reasoning model. To me the > key question is what object (or sometimes objects plural) does > a particular expression access. There is a distinction between > an object being accessed and a byte of memory being read or > written that happens to fall in a particular object. It is the > expression being evaluated that determines which object is being > accessed, regardless of what other circumstances may be in force. > I know that may not make sense to you, but that's how I think > in this particular domain. Under that model, any pointer yielded by taking the address of a struct or union member may be used at any time to access anything of the member type. If a struct has two members of type "int", and one has two pointers to the struct such that &p1->m1 == &p2->m2, it could freely access the storage using p1->m1 or p2->m2, since both lvalues are of the same type "int". Such an interpretation might be somewhat workable, but would needlessly impair many useful optimizations. Better would be to recognize the derivation of an lvalue or pointer of one type from an lvalue of another as being an action upon any storage which will be accessed using that lvalue/pointer or others derived from it. Recognizing that will make the Standard meaningful, and should be much easier than trying to probe all the intricacies of C99's unworkable "effective type" rules.
[toc] | [prev] | [next] | [standalone]
| From | Steven Petruzzellis <frelwizzen@gmail.com> |
|---|---|
| Date | 2018-03-28 10:48 -0700 |
| Message-ID | <60c868b4-c546-429b-9850-7f689088695d@googlegroups.com> |
| In reply to | #128459 |
On Tuesday, March 27, 2018 at 12:09:19 PM UTC-7, supe...@casperkitty.com wrote: > On Tuesday, March 27, 2018 at 1:44:46 AM UTC-5, Tim Rentsch wrote: > > This model is different from mine. My model is that words in the > > Standard often mean different things in different places, and we > > shouldn't assume that a meaning that looks sensible in one place > > will necessarily be sensible in another place, especially if doing > > so leads to a paradox of some sort. The idea of falling back on > > common sense is not really compatible with the multiple-meanings > > perspective. > > The biggest problem word is probably "object", which can either refer to > what most languages would call "variables", or members/fields of aggregates, > or elements of arrays, targets of pointers, etc. The lack of a term for > "variable" is perhaps the biggest difficulty. > > A related problem is that C has no term for what is done with the lvalue > "a[i++].intMember" during the execution of "int *p = &a[i++].intMember". > The lvalue isn't *evaluated*, nor is it *accessed*, but *something* clearly > happens to it, since it has a visible side-effect. > > > My model for how to reason here is simply different from yours. I > > don't think "this byte of memory was changed, therefore an object > > that contains that byte of memory must have been accessed." > > Suppose a byte is changed by being zapped by a cosmic ray, or > > maybe as a side effect of a volatile access. There is no lvalue > > expression involved, so under effective type rules both of those > > are undefined behavior. I don't know to answer your question > > because it doesn't make sense in my reasoning model. To me the > > key question is what object (or sometimes objects plural) does > > a particular expression access. There is a distinction between > > an object being accessed and a byte of memory being read or > > written that happens to fall in a particular object. It is the > > expression being evaluated that determines which object is being > > accessed, regardless of what other circumstances may be in force. > > I know that may not make sense to you, but that's how I think > > in this particular domain. > > Under that model, any pointer yielded by taking the address of a struct or > union member may be used at any time to access anything of the member type. > If a struct has two members of type "int", and one has two pointers to the > struct such that &p1->m1 == &p2->m2, it could freely access the storage > using p1->m1 or p2->m2, since both lvalues are of the same type "int". > Such an interpretation might be somewhat workable, but would needlessly > impair many useful optimizations. > > Better would be to recognize the derivation of an lvalue or pointer of > one type from an lvalue of another as being an action upon any storage > which will be accessed using that lvalue/pointer or others derived from it. > Recognizing that will make the Standard meaningful, and should be much > easier than trying to probe all the intricacies of C99's unworkable "effective > type" rules. Until or unless Takuya Saitoh offers up his 'superior' open source solution for evaluation, there is no threat, just wild contentions. I am a complete groupie of Tmux, because that's where all the compelling usability improvements are happening. Vennie Bowden, REALTOR - BloomTree Realty just wiped his ass with Takuya Saitoh. Turns out Takuya Saitoh's non-stop flooding comments of Vennie Bowden, REALTOR - BloomTree Realty met the agreed on criteria of trolling, so he abandoned that, too. Being decentralized as it is, the email infrastructure will never go away but it'll never be very useful. -- Eight things to never feed your cat http://tinyurl.com/proof-about-ebot http://tinyurl.com/proof-about-ebot Jonas Eklundh Communication AB
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2018-03-19 12:27 -0700 |
| Message-ID | <1c2af94d-5f05-48f4-be3f-c7a3ae4109fc@googlegroups.com> |
| In reply to | #128009 |
On Monday, March 19, 2018 at 11:54:14 AM UTC-5, Tim Rentsch wrote:
> I suspect the key difference is you assume the Standard uses
> language in a precise and rigorous way (at least I am guessing
> you assume that), and I don't. Take for example the word
> "value". Strictly speaking, values aren't stored in objects.
> What is stored is some representation (not guaranteed to be
> unique) for the value. Sometimes the Standard recognizes this
> distinction, and sometimes it doesn't.
The problem is that compiler writers regard the fact that a literal
reading of the Standard would forbid certain actions as justification
for assuming that code won't do them, even in cases where the Standard
is obviously sloppy.
> Another example is "object". The term "object" is defined as a
> region of storage (in the execution environment, plus some other
> stuff that doesn't matter for present purposes). Yet, in 6.2.4,
> discussing object lifetimes, there is this statement:
>
> If the block is entered recursively, a new instance of the
> object is created each time.
>
> But this is absurd. If a block is entered recursively, we don't
> make a new instance of a certain region of storage. Rather what
> happens is we allocate a different, unrelated region of storage.
> In the quoted sentence the word "object" is being used in a way
> that belies its definition. And it is used in other, different
> ways in other places.
Here the sloppiness stems from the use of "object" to refer both to the
region of storage, and the binding of the associated name. Other
languages use the term "variable" to refer to such things; the C Standard
could benefit from doing likewise.
> Pulling back and looking at a somewhat larger view, consider this
> situation:
>
> union { double d; int i; } it = { 1 };
> it.i = 2;
>
> Does the assignment to it.i modify the object it.d? If so then
> that assignment runs afoul of effective type rules, and so means
> evaluating it gives undefined behavior. Surely that can't be
> right. There are two ways of resolving this dilemma (perhaps
> more than two, but at least two):
>
> (1) Decide the effective type rules are horribly wrong, or at
> least incomplete, and need radical revisions to account for
> other possibilities like this one; or
>
> (2) Decide that the definition of "access" is unclear about
> which object, or objects, are accessed in the case of
> objects that overlap.
Or interpret the footnote as saying that the rule is only meant to apply
in cases that would genuinely involve aliasing if code were executed *as
written*. Two references cannot alias each other for purposes of accessing
a piece of storage if a visibly-older one is never used between the time the newer one is created and the last time it (or anything that is derived
from it) accesses the storage.
Given the code:
{
int *p1 = struct1->member;
*p1 += 1;
int *p2 = struct2->member;
*p2 ^= 1;
int *p3 = struct1->member;
*p3 -= 1;
}
the three pointers won't alias, even if struct1 and struct2 identify the
same structure, because that structure will never be used (as its own
type) between the time p1 is created and the last use thereof, nor likewise
p2 or p3.
If the operation which uses p3 had instead used p1, then p1 would alias
struct2 if they occupy the same storage, so a compiler would be justified
in assuming that wouldn't happen. A compiler would not, however, be
justified in deciding that since p1 and p3 both identify the same object,
it can safely substitute p1 for p3 *unless* it can ensure that behavior
will not be changed as a consequence of *the compiler's having introduced
aliasing where none existed*.
> I believe (2) is more likely than (1), in particular with respect
> to what meaning the authors intended.
If the Standard recognizes that access made to the lvalue that is most
recently visibly derived from another is an lvalue to the parent, at
least in cases that don't actually involve aliasing, that would take
care of everything else. I think it would be cleaner to specify that
if a region of storage is modified within a particular execution of a
function, all lvalues used to access it must be visibly derived (during
that execution) from lvalues of a common type, but the cases where that
would matter won't involve aliasing in the code as written.
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2018-04-03 14:02 -0700 |
| Message-ID | <5fe67088-8e80-478e-a622-02d16b64166a@googlegroups.com> |
| In reply to | #127348 |
On Sunday, March 4, 2018 at 5:22:47 AM UTC-5, Tim Rentsch wrote:
> Keith Thompson <kst-u@mib.org> writes:
>
> > Tim Rentsch <txr@alumni.caltech.edu> writes:
> >
> >> Keith Thompson <kst-u@mib.org> writes:
> >>
> >>> [When using . or ->, what is "accessed"?]
> >>>
> >>> Let me make the point more succinctly.
> >>>
> >>> struct s { int m; };
> >>> struct s obj;
> >>> obj.m = 42;
...
> > Let's consider the original struct.
> >
> > N1570 3.1 defines "access" as
> >
> > <execution-time action> to read or modify the value of an object
> >
> > Wouldn't you agree that `obj.m = 42;` modifies the value of obj?
>
> I would say no. It does change some, or in this particular case
> maybe all, of the bytes that hold the object representation of
> obj, but that's not the same thing.
...
> Which object, or objects, are accessed by a given lvalue expression
> should be the same whether the expression is used for reading or
> writing. Following this principle, I conclude that 'obj.m = 42;'
> accesses only the member, not the object of the struct.
I've a series of questions that I'd like you to answer, with a goal of better understanding what it is you mean by that. I'll modify Keith's example, because the fact that 'm' is the only member of 'obj' muddles some of the issues I'm trying to ask you about.
Given
struct {int i; double *p} obj = {5, NULL};
obj.i = 3;
double d;
obj.p = &d;
What was the last value stored in obj before the first assignment?
What was the last value stored in obj between the two assignments?
What was the last value stored in obj after the second assignment?
Which expressions, if any, caused a new value to be stored in obj?
Which expressions, if any, modified the value of obj?
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2018-04-04 17:32 -0700 |
| Message-ID | <kfn7epmijc1.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #128673 |
jameskuyper@verizon.net writes:
> On Sunday, March 4, 2018 at 5:22:47 AM UTC-5, Tim Rentsch wrote:
>
>> Keith Thompson <kst-u@mib.org> writes:
>>
>>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>>
>>>> Keith Thompson <kst-u@mib.org> writes:
>>>>
>>>>> [When using . or ->, what is "accessed"?]
>>>>>
>>>>> Let me make the point more succinctly.
>>>>>
>>>>> struct s { int m; };
>>>>> struct s obj;
>>>>> obj.m = 42;
>
> ...
>
>>> Let's consider the original struct.
>>>
>>> N1570 3.1 defines "access" as
>>>
>>> <execution-time action> to read or modify the value of an object
>>>
>>> Wouldn't you agree that `obj.m = 42;` modifies the value of obj?
>>
>> I would say no. It does change some, or in this particular case
>> maybe all, of the bytes that hold the object representation of
>> obj, but that's not the same thing.
>
> ...
>
>> Which object, or objects, are accessed by a given lvalue expression
>> should be the same whether the expression is used for reading or
>> writing. Following this principle, I conclude that 'obj.m = 42;'
>> accesses only the member, not the object of the struct.
>
> I've a series of questions that I'd like you to answer, with a goal
> of better understanding what it is you mean by that. I'll modify
> Keith's example, because the fact that 'm' is the only member of
> 'obj' muddles some of the issues I'm trying to ask you about.
> Given
>
> struct {int i; double *p} obj = {5, NULL};
>
> obj.i = 3;
> double d;
> obj.p = &d;
>
> What was the last value stored in obj before the first assignment?
I don't know if an initialization is meant to count as storing a
value or not. (I guess the first "Semantics" paragraph in the
section on initialization says that it is.) If an initialization
is meant to count as storing a value, or values, I don't know if
it is meant to store values in individual members, or the struct
object as a whole. If an initialization of a struct is meant to
count as storing a value in the struct object as a whole, then
the last value stored is a struct value whose first component is
5 of type int and whose second component is a null pointer of
type double *.
> What was the last value stored in obj between the two assignments?
The assignment 'obj.i = 3;' stores an int value into the member
object 'obj.i'. There is no assignment that stores a struct
value into the struct 'obj'. I'm not sure what meaning you
intend for the phrase "last value stored". The Standard seems
to use the phrase "value stored" in different ways in different
places, so I'm not sure what meaning to attach to the question.
> What was the last value stored in obj after the second assignment?
Same as the last answer, except that the assignment stores a
pointer value into the member object 'obj.p'.
> Which expressions, if any, caused a new value to be stored in obj?
I don't know if you mean "stored" in the sense of "held" or
"stored" in the sense of "delivered into".
> Which expressions, if any, modified the value of obj?
If you mean "modify" in the sense it is used in the definition of
"access", as access is used in 6.5 p{6,7}, none of them. If you
mean "modify" in some different sense, I don't know what sense
that is.
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2018-04-04 20:24 -0700 |
| Message-ID | <65e621e1-9bc2-4558-a36d-9712e792494f@googlegroups.com> |
| In reply to | #128739 |
On Wednesday, April 4, 2018 at 8:32:41 PM UTC-4, Tim Rentsch wrote:
> jameskuyper@verizon.net writes:
...
> > I've a series of questions that I'd like you to answer, with a goal
> > of better understanding what it is you mean by that. I'll modify
> > Keith's example, because the fact that 'm' is the only member of
> > 'obj' muddles some of the issues I'm trying to ask you about.
> > Given
> >
> > struct {int i; double *p} obj = {5, NULL};
> >
> > obj.i = 3;
> > double d;
> > obj.p = &d;
> >
> > What was the last value stored in obj before the first assignment?
>
> I don't know if an initialization is meant to count as storing a
> value or not. (I guess the first "Semantics" paragraph in the
> section on initialization says that it is.)
6.7.9p8 seems, to me, to say so quite unambiguously.
> If an initialization
> is meant to count as storing a value, or values, I don't know if
> it is meant to store values in individual members, or the struct
> object as a whole.
As I understand it, initialization stores a new value in the struct as a
whole by storing new values in all of the members of the struct, and
also in the padding bytes (6.2.6.1p6). Being an aggregate, the value
stored in obj is an aggregate of the values stored in it's members.
> ... If an initialization of a struct is meant to
> count as storing a value in the struct object as a whole, then
> the last value stored is a struct value whose first component is
> 5 of type int and whose second component is a null pointer of
> type double *.
I consider that sentence to be an excessively and unnecessarily clumsy
way to convey that information. For convenience, I would use the
notation {5, NULL} to express the same meaning. Do you object? If you
do, could you propose a comparably compact alternative notation? Please
understand my use of that notation for similar purposes down below as
expanding into sentences comparable to that one.
> > What was the last value stored in obj between the two assignments?
>
> The assignment 'obj.i = 3;' stores an int value into the member
> object 'obj.i'. There is no assignment that stores a struct
> value into the struct 'obj'. I'm not sure what meaning you
> intend for the phrase "last value stored". The Standard seems
> to use the phrase "value stored" in different ways in different
> places, so I'm not sure what meaning to attach to the question.
The purpose of the question is to determine what the following clause of
the standard has to say about this code:
"An object exists, has a constant address, 33) and retains
its last-stored value throughout its lifetime." (6.2.4p2).
If assigning a value of 3 to obj.i does not count as storing a new value
in obj, (an interpretation that seems quite nonsensical to me), then
6.2.4p2 would imply that obj must still retain the value {5, NULL},
which would be ridiculous (but no more so than anything you've said
before about this issue).
> > What was the last value stored in obj after the second assignment?
>
> Same as the last answer, except that the assignment stores a
> pointer value into the member object 'obj.p'.
My answer to the previous question is {3, NULL}, and my answer to this
question is {3, &d}, and the reason why those two answers differ is
entirely due to the exception that you mention. So saying that your
answer to both questions is the same, while citing that exception, does
nothing to clarify your answer. Telling me precisely what your answer
actually is to either question would be far more useful. Answering both
questions specifically, so I can understand how the answer could be "the
same" despite that exception, would be even better.
> > Which expressions, if any, caused a new value to be stored in obj?
>
> I don't know if you mean "stored" in the sense of "held" or
> "stored" in the sense of "delivered into".
I'm using "stored" in the sense that the standard uses the term, as I
understand it. Since you claim that the standard uses the term
inconsistently, that doesn't answer your question. Since I don't see
it's use of the term as being significantly inconsistent, that's the
best answer I can give you. But, it is in particular the sense in which
the standard uses the term in 6.2.4p2 that matters the most for purposes
of these questions.
I don't understand the distinction you're making. As I understand the
matter, the assignment delivered a new value into obj.i; since obj is an
aggregate object of which obj.i is a part, delivering a new value to
obj.i means that a new value has also inherently been delivered to obj
itself. The delivery having been completed, obj.i now holds the new
value of 3, and obj itself now holds the new value of {3, NULL}. The
delivery of the new value and the subsequent holding of the new value go
hand-in-hand, and I don't see your point in distinguishing those aspects
of the process.
I realize that you consider my interpretation nonsense, for reasons that
you've been incapable of clarifying - your comments on the issue seem
nonsensical to me. These questions are part of an effort on my part to
try to get a better idea of how you could possibly be thinking about
these issues in a way that allows you to say those things without
fearing being considered insane. That effort has not, so far, been
successful.
> > Which expressions, if any, modified the value of obj?
>
> If you mean "modify" in the sense it is used in the definition of
> "access", as access is used in 6.5 p{6,7}, none of them. If you
> mean "modify" in some different sense, I don't know what sense
> that is.
I mean modify as it is used in the definition of access, which as I
understand it, is very different from the meaning you attach to that
term in that context. I'm trying to figure out what that meaning is,
and you continue to waffle whenever I ask you a question intended to
clarify that issue. As I understand it, to modify the value stored in an
object basically means to be the cause of a change in the stored value.
The standard explicitly treats storing a new value in an object that
happens to be the same as the existing value as a modification - but I
consider that a deviation from the normal meaning, something that the
standard did to simplify the wording of clauses that use the term.
Wiktionary's first definition for the word "modify"
<https://en.wiktionary.org/wiki/modify> is "To make partial changes
to.", so changing only the part of obj that is obj.i would count as a
modification to obj itself. However, taken literally, that would imply
that a complete change to an object's value does not constitute a
modification, whereas I believe that the standard uses the term to
include even complete changes, not just partial ones.
[toc] | [prev] | [next] | [standalone]
Page 3 of 8 — ← Prev page 1 2 [3] 4 5 6 7 8 Next page →
Back to top | Article view | comp.lang.c
csiph-web