On Fri, Aug 23, 2013 at 10:34 PM, Mike Stump <mikest...@comcast.net> wrote: > On Aug 23, 2013, at 5:53 PM, Gabriel Dos Reis <g...@integrable-solutions.net> > wrote: >> If you quoted the standard to back up your assertions, I would have been >> able to "feel free to point this out" :-) >> >> The thing is I am still trying to figure out what (1) what you would have >> liked; > > I've directly stated it, not sure how you missed it. The life of the > original object does not end.
You made a statement. It was not clear whether it was what you want or whether it is what the standards mandate. >> (2) what you believe the standards mandate, with appropriate quote; and > > The life of the original object does not end. See below for the quote. Your assertion or a quote from the standards? > >>>> Really? >>> >>>>> statement, or, is it merely changing the value? >>>> >>>> That is an assignment to an existing int storage. >>> >>>>> And what if we do a memcpy (ip, &j, sizeof (int)); >>>> >>>> Well, the case of 'memcpy' isn't defined by the standard >>> >>> Odd, in the c++98 standard memcpy was defined by the standard, as well as >>> the open code that memcpy would be. I find memcpy in [diff.library]. I >>> can quote all the requirements that makes the open code work as well. It >>> is defined. >> >> When I say "the case of 'memcpy' isn't defined", I was not saying that >> the function "memcpy" itself isn't defined by the standard. I was discussing >> its effect in the scope of this discussion, e.g. lifetime vs. assignment. >> That isn't defined in the standard. > > And yet memcpy is exactly defined and all interactions with the entire rest > of the standard are as specified. Those semantics that are defined and > required, are, by definition. You can't make them go away by claiming they > are undefined. I have no idea what exactly you are talking about. If you have a rule in that standards that say that mempcy is assignment, please share it with us. > > int i = 1, j = 2; > { > memcpy (&i, &j) > // here i exists and is 2. > } > > 3.7.1 Static storage duration [basic.stc.static] > > 1 All objects which neither have dynamic storage duration nor are local > have static storage duration. The storage for these objects shall > last for the duration of the program (_basic.start.init_, > _basic.start.term_). > > This covers why i exists. The storage duration of an object is not necessarily the same as its lifetime. > As for why i has the value 2, gosh: > > 7.21.2.1 The memcpy function > > Synopsis > > [#1] > > #include <string.h> > void *memcpy(void * restrict s1, > const void * restrict s2, > size_t n); > > Description > > [#2] The memcpy function copies n characters from the object > pointed to by s2 into the object pointed to by s1. If > copying takes place between objects that overlap, the > behavior is undefined. > > > 1.6 The C++ memory model [intro.memory] > > 1 The fundamental storage unit in the C++ memory model is the byte. > > An object of POD4) type > (_basic.types_) shall occupy contiguous bytes of storage. > > 5.3.3 Sizeof [expr.sizeof] > > 1 The sizeof operator yields the number of bytes in the object represen- > tation of its operand. The operand is either an expression, which is > not evaluated, or a parenthesized type-id. The sizeof operator shall > > 4 The object representation of an object of type T is the sequence of N > unsigned char objects taken up by the object of type T, where N equals > sizeof(T). The value representation of an object is the set of bits > that hold the value of type T. For POD types, the value representa- > tion is a set of bits in the object representation that determines a > value, which is one discrete element of an implementation-defined set > of values.37) Yes, but what is the relevance? > >>> You can see evidence that we meant for it to work here: >>> >>> 2 For any complete POD object type T, whether or not the object holds a >>> valid value of type T, the underlying bytes (_intro.memory_) making up >>> the object can be copied into an array of char or unsigned char.36) If >>> the content of the array of char or unsigned char is copied back into >>> the object, the object shall subsequently hold its original value. >>> [Example: >>> #define N sizeof(T) >>> char buf[N]; >>> T obj; // obj initialized to its original value >>> memcpy(buf, &obj, N); // between these two calls to memcpy, >>> // obj might be modified >>> memcpy(&obj, buf, N); // at this point, each subobject of obj of >>> scalar type >>> // holds its original value >>> >>> thought, I view this as completely redundant with the standard and should >>> just be a note. From the base standard, in C99 is it defined in 7.24.4.2.3 >>> and I suspect remains largely unchanged from previous standards. >>> >> >> This does not say whether the effect of memcpy is assigment or copy >> construction. > > Right, because it doesn't define taking the bytes of one object and assigning > another object to have those bytes. The definition of memcpy does that. Chapter and verse, please. > > char c1, c2; > > c1 = c2; > > This is defined to take the bytes that comprise c2 (1 byte, by definition), > and slam them into c1. After this runs, c1 will have the value of c2. This, > is, by definition. We can plainly see the assignment operator. This is > assignment, the hint is the spelling of the operator. It is spelled =. This > is what the C standard means, when they say copies. copies is defined to > mean, =. so? What is the relevance exactly? > >> Which was the point I was making. > > Sure it does. Directly, please read the statement again: > > The memcpy function copies n characters from the object > pointed to by s2 into the object pointed to by s1. Yes, but why is that assignment not copy construction as in new (p) T (v); ? That is the question. > I said what the words mean. I'd said copy means the = operator. Copy in C++ does not necessarily mean assignment. > Here is the text for =: > > [#3] An assignment operator stores a value in the object > designated by the left operand. This does not say that storying a value in an object is assignment. > This is the very definition of the word copy, trust me. This is how the > standard was meant to be read. See above. > >>>>> I think the most logical line of reasoning is that when the requirements >>>>> of [basic.lval] are met, the, this is a change of value of an object, not >>>>> a modification to it's lifetime. >>>> >>>> Why? >>> >>> Because if you end the lifetime of the original int, you destroy the >>> semantic that everyone knows for C. This cannot be done. >> >> But: >> (1) we are not talking about C > > Sure we are. No, we are not. Please look back at my original message that you replied to. > The semantics of memcpy and its behavior come from C, and are identical to > it. Since this is true, I can freely quote the required semantics of the C > standard, they are identical. > >> (2) C does not have a notion of lifetime -- at least not in the sense of >> C++. > > It absolutely does: Let me quote: > > [#1] An object has a storage duration that determines its > lifetime. Please give the definition of 'lifetime'. > > [#17] Note that if a for loop were used instead of a while | > loop, the lifetime of the unnamed object would be the body > of the loop only, and on entry next time around p would be > pointing to an object which is no longer guaranteed to | > exist, which would result in undefined behavior. > > expression is evaluated. The size of each instance of a > variable length array type does not change during its > lifetime. > > > 214The buffer has to have a lifetime at least as great as > the open stream, so the stream should be closed before a > buffer that has automatic storage duration is deallocated > upon block exit. > > environment. All objects in static storage shall be > initialized (set to their initial values) before program > startup. The manner and timing of such initialization are > > [#5] An instance of each object with automatic storage > duration is associated with each entry into its block. Such > an object exists and retains its last-stored value during > the execution of the block and while the block is suspended > (by a call of a function or receipt of a signal). > > [#2] The malloc function allocates space for an object whose > size is specified by size and whose value is indeterminate. > > -- The value of a pointer that refers to space deallocated > by a call to the free or realloc function is used > (7.20.3). > > [#2] The free function causes the space pointed to by ptr to > be deallocated, that is, made available for further > allocation. But this is not the lifetime in the C++ sense. > I'll note that C++ merely sought to explain and formalize the rules of C. Strongly disagree with that note. > We extended and added a few bits, but, the object model is based upon the C > model. The object model may have been based on C, but it went way beyond C in say that C++ object model is expressible in C any more -- think empty base optimization. This isn't just a few bits. > I can't begin to fathom how you could have possibly missed the notion of > lifetime in C. Most likely because I didn't miss it. > It right there, an just about exactly matches C++. Not at all. We tried to make certain constructs have similar byte-level interpretation, but the conceptual models are completely different. > >> So, whatever notion of semantics you think everyone knows of C >> is largely irrelevant. > > No, you must not understand C++ to say this. Guilty as charged. I must also confess that I do not know of any body who understands C++ -- not even the collective body of the C++ standards committee. > C++ is defined to be, exactly what C is, I cannot understand the source of this confusion. > with a few exceptions here and there, and in this case, there are no > exceptions. This is by design. I'm sorry if you didn't realize this. > Please don't be sorry, the confusion isn't necessarily where you believe it is. >>>>> So, in the case quoted, since the type of the accesses are both int, we >>>>> don't reuse the storage, since the requirements of [basic.lval] are met. >>>> >>>> Consider: >>>> >>>> struct S { >>>> S(int); >>>> ~S(); >>>> // … >>>> }; >>>> >>>> int main() { >>>> S s(8); >>>> >>>> new (&s) S(9); // #1 >>>> } >>>> >>>> Is #1 a reuse of storage to create a new object or assignment? >>> >>> Behaves as assignment, s exists post the new, til the closing }. >> >> What does not mean concretely? > > Concretely, it means exactly what is stated in the standard. Great! The standards does not state it is assignment. > I've quoted all the words. copy means =. No; I am sorry but you are plain wrong on this. > = is an assignment operator. Yep, and C++ makes a distinction between copy and assignment. > Concretely, where did you get lost? Trying to connect what the standards say and your assertions. > In the //, one can imagine you're asking about > > S (int v) { val = v; } > int val; That is one possible imagination; but it isn't the only one. > to be concrete. We can see the = operator. In that imagination you just created, yes. But it wasn't there to begin with. > This is the assignment operator, by definition. Yes, but see above. >>>>> Indeed, the programmer expects that they can access i after *ip = j; and >>>>> that the _value_ that object, while changed from the original 1, will be >>>>> 2 just after the *ip = j; statement. >>>>> >>>>> Since we know that i must be 3 at the end, we then know what the wording, >>>>> reused, must mean, cause other meanings that could possibly make it work >>>>> for you in the case you are considering, would destroy this property of >>>>> pointers, and everyone knows the semantics of pointers, they are >>>>> undisputed. Or put another way, you cannot misread reused in this way. >>>> >>>> And why do you assert that I misread 'reused' in this way? >>> >>> See your email that I originally replied to. >>> >>> Let me quote it here: >>> >>>> If the user-supplied operator new returns &a, then it must >>>> also ensure that 'a' is not used anywhere else -- e.g. I you can't >>>> do lvalue-to-value conversion on 'a' to see what is written there. >>>> Because its storage has been reused. >>> >>> You said it was reused, this is wrong. >> >> You keep saying it is wrong without quoting the standards that is the >> basis for that. > > I've quoted the required semantics of the standard. What part was unclear to > you? See above. > >>> You use that as backing to say that the lifetime of the original object >>> ends, this is wrong. >> >> You *assert* it is wrong. > > I quoted the required semantics of the language standard. What part was > unclear to you? The part where you assert imaginary things :-) -- Gaby