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


Groups > comp.lang.c > #128449

Re: lvalue types

From Keith Thompson <kst-u@mib.org>
Newsgroups comp.lang.c
Subject Re: lvalue types
Date 2018-03-27 09:14 -0700
Organization None to speak of
Message-ID <ln370lwl52.fsf@kst-u.example.com> (permalink)
References (4 earlier) <kfnh8pwqgwn.fsf@x-alumni2.alumni.caltech.edu> <lna7vnft8l.fsf@kst-u.example.com> <kfnin9snh05.fsf@x-alumni2.alumni.caltech.edu> <lnin9rrj8u.fsf@kst-u.example.com> <kfno9jam2zw.fsf@x-alumni2.alumni.caltech.edu>

Show all headers | View raw


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

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

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

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.

[...]

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

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.

If anyone else understands what you're talking about, perhaps they can
jump in and explain it to me.

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

Back to comp.lang.c | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

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

csiph-web