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


Groups > comp.lang.c > #128418

Re: lvalue types

From Tim Rentsch <txr@alumni.caltech.edu>
Newsgroups comp.lang.c
Subject Re: lvalue types
Date 2018-03-26 23:44 -0700
Organization A noiseless patient Spider
Message-ID <kfno9jam2zw.fsf@x-alumni2.alumni.caltech.edu> (permalink)
References (3 earlier) <lnefl0g9gs.fsf@kst-u.example.com> <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>

Show all headers | View raw


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.

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

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

>> with everything the Standard says, not just with parts of it.  In
>> particular the Standard is not like a logical system or a math
>> textbook - if a chain of logic based on one passage leads to a
>> contradiction with some other passage, there's a good chance that
>> how the first passage was interpreted is wrong.  So I think it's
>> important to look at other cases, such as the one mentioned,
>> before reaching a definite conclusion.
>>
>>>>> 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.

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