Discussion:
I believe this is a defect in the current standard draft N4713
(too old to reply)
Belloc
2018-01-31 13:53:24 UTC
Permalink
[basic.lval]/10 <http://eel.is/c++draft/basic.lval#10>:

An lvalue is modifiable unless its type is const-qualified or is a function
type. [ Note: A program that attempts to modify an object through a
nonmodifiable lvalue expression or through an rvalue expression is ill-formed
(8.5.18, 8.5.1.6, 8.5.2.2). —end note ]


An array name is also a non-modifiable lvalue, i.e., an array name cannot
be on the left hand side of an assignment expression.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Jens Maurer
2018-01-31 18:11:09 UTC
Permalink
An lvalue is modifiable unless its type is const-qualified or is a function type. [ Note: A program that attempts to modify an object through a nonmodifiable lvalue expression or through an rvalue expression is ill-formed (8.5.18, 8.5.1.6, 8.5.2.2). —end note ]
An array name is also a non-modifiable lvalue, i.e., an array name cannot be on the left hand side of an assignment expression.
An array name certainly is an lvalue; it represents the address of an object in memory.

(Any association of the term "lvalue" with "left hand side of an assignment
expression" should be, at best, an anecdotal historical note and bears
no impact on today's normative situation.)

Jens
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
'Johannes Schaub' via ISO C++ Standard - Discussion
2018-01-31 18:18:38 UTC
Permalink
Post by Jens Maurer
An lvalue is modifiable unless its type is const-qualified or is a function type. [ Note: A program that attempts to modify an object through a nonmodifiable lvalue expression or through an rvalue expression is ill-formed (8.5.18, 8.5.1.6, 8.5.2.2). —end note ]
An array name is also a non-modifiable lvalue, i.e., an array name cannot be on the left hand side of an assignment expression.
An array name certainly is an lvalue; it represents the address of an object in memory.
Isn't that what he's saying? Based on this quote (I haven't looked it
up), it says that "array" on the left side of "=" is a modifiable
lvalue, yet we cannot modify "array" through it, disregarding of what
is given as right hand side.

int array[10];
array = 10;

What purpose does "modifiable lvalue" have, if it doesn't classify a
non-modifiable lvalue as being not modifiable?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Jens Maurer
2018-01-31 18:34:00 UTC
Permalink
Post by 'Johannes Schaub' via ISO C++ Standard - Discussion
Post by Jens Maurer
An lvalue is modifiable unless its type is const-qualified or is a function type. [ Note: A program that attempts to modify an object through a nonmodifiable lvalue expression or through an rvalue expression is ill-formed (8.5.18, 8.5.1.6, 8.5.2.2). —end note ]
An array name is also a non-modifiable lvalue, i.e., an array name cannot be on the left hand side of an assignment expression.
An array name certainly is an lvalue; it represents the address of an object in memory.
Isn't that what he's saying? Based on this quote (I haven't looked it
up), it says that "array" on the left side of "=" is a modifiable
lvalue, yet we cannot modify "array" through it, disregarding of what
is given as right hand side.
int array[10];
array = 10;
What purpose does "modifiable lvalue" have, if it doesn't classify a
non-modifiable lvalue as being not modifiable?
Ah, ok, I was confused.

Yes, seems reasonable to add "array type" to the list of exclusions.

Jens
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Richard Smith
2018-02-01 01:38:17 UTC
Permalink
Post by 'Johannes Schaub' via ISO C++ Standard - Discussion
Post by Jens Maurer
Post by Belloc
An lvalue is modifiable unless its type is const-qualified or is a
function type. [ Note: A program that attempts to modify an object through
a nonmodifiable lvalue expression or through an rvalue expression is
ill-formed (8.5.18, 8.5.1.6, 8.5.2.2). —end note ]
Post by 'Johannes Schaub' via ISO C++ Standard - Discussion
Post by Jens Maurer
Post by Belloc
An array name is also a non-modifiable lvalue, i.e., an array name
cannot be on the left hand side of an assignment expression.
Post by 'Johannes Schaub' via ISO C++ Standard - Discussion
Post by Jens Maurer
An array name certainly is an lvalue; it represents the address of an
object in memory.
Post by 'Johannes Schaub' via ISO C++ Standard - Discussion
Isn't that what he's saying? Based on this quote (I haven't looked it
up), it says that "array" on the left side of "=" is a modifiable
lvalue, yet we cannot modify "array" through it, disregarding of what
is given as right hand side.
int array[10];
array = 10;
What purpose does "modifiable lvalue" have, if it doesn't classify a
non-modifiable lvalue as being not modifiable?
Ah, ok, I was confused.
Yes, seems reasonable to add "array type" to the list of exclusions.
Is there actually any existing rule that makes this program ill-formed:

int main() {
int a[10], b[10];
a = b;
}

? [expr.ass] appears to allow it and define its semantics as replacing the
value of 'a' with the value of 'b'. One would assume that the intent is
that the lvalue-to-rvalue, array-to-pointer, and function-to-pointer
conversions are applied to the right operand of an assignment operator, as
in C, but that doesn't seem to be explicitly stated.

(For what it's worth, I'm not personally convinced that calling a non-const
array lvalue non-modifiable is an improvement, since such an object *can*
be modified, albeit not by simple assignment. Similarly, we don't call a
non-const class lvalue non-modifiable if it has no viable operator=.)
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2018-02-01 12:29:25 UTC
Permalink
Post by Richard Smith
int main() {
int a[10], b[10];
a = b;
}
? [expr.ass] appears to allow it and define its semantics as replacing the
value of 'a' with the value of 'b'. One would assume that the intent is
that the lvalue-to-rvalue, array-to-pointer, and function-to-pointer
conversions are applied to the right operand of an assignment operator, as
in C, but that doesn't seem to be explicitly stated.
(For what it's worth, I'm not personally convinced that calling a non-const
Post by Richard Smith
array lvalue non-modifiable is an improvement, since such an object *can*
be modified, albeit not by simple assignment. Similarly, we don't call a
non-const class lvalue non-modifiable if it has no viable operator=.)
Sometimes I have a hard time understanding what you say. Are you saying
that the defect is not in [basic.lval]/10, but in [expr.ass]/1?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
'Johannes Schaub' via ISO C++ Standard - Discussion
2018-02-01 17:03:47 UTC
Permalink
Post by Richard Smith
int main() {
int a[10], b[10];
a = b;
}
? [expr.ass] appears to allow it and define its semantics as replacing the
value of 'a' with the value of 'b'. One would assume that the intent is that
the lvalue-to-rvalue, array-to-pointer, and function-to-pointer conversions
are applied to the right operand of an assignment operator, as in C, but
that doesn't seem to be explicitly stated.
(For what it's worth, I'm not personally convinced that calling a
non-const array lvalue non-modifiable is an improvement, since such an
object *can* be modified, albeit not by simple assignment. Similarly, we
don't call a non-const class lvalue non-modifiable if it has no viable
operator=.)
Sometimes I have a hard time understanding what you say. Are you saying that
the defect is not in [basic.lval]/10, but in [expr.ass]/1?
He's asking whether there's anything that makes the above "a = b"
ill-formed. The "modifiable lvalue" thing marks things that make
"lvalue = ...;" ill-formed. But it's not the only one that may make
"lvalue = ..." ill-formed. Having a deleted "op=" for a class lvalue
could also result in an ill-formed "lvalue = ...". Even a
"modifiable-int-lvalue = .." could result in ill-formed-ness if the
right side is of class type and the class has a deleted "operator
int&();", and so on and so forth. So Richard asks whether there's
actually any rule that make above "a = b" ill-formed.

But please note that the lvalue in the following refers to an
*nonconst* int object, which *can* be modified. But just not by that
particular lvalue. So if I have understood Richard correctly, this
weakens his argument a bit.

int a;
const int& ar = a;
ar = 0; // error: ar is not modifiable

I think that the "modifiable lvalue" stuff is not intended to be
applied for class types. Because the text actually says "All require a
modifiable lvalue as their left operand; their result is an lvalue
referring to the left operand.", and this is not true for class
objects. So assuming I understand correctly, this further weakens
Richard's argument. In fact we can have a const class lvalue that is
called "not modifiable" that we can assign to, if the "operator=" is
const. I haven't checked whether the overload-resolution rules play
any games on op= if one operand is of class type, prior to handing
over to the builtin-semantics, so some of this may be wrong, perhaps.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2018-02-01 19:45:37 UTC
Permalink
My understanding is very simple to explain: as it stands now there is no
place in the standard prohibiting an array name from appearing as the
left-operand of an assignment expression (see [expr.ass]/1
<http://eel.is/c++draft/expr.ass#1>), notwithstanding the fact that an
array name is a modifiable lvalue (according to [basic.lval]/10
<http://eel.is/c++draft/basic.lval#10>). So my first idea was to change
[basic.lval]/10 to make a named array a non-modifiable lvalue. I can accept
Richard's argument that a named array is not exactly non-modifiable, as you
can always modify the array object a, declared in global scope as int a[10];
with the assignment a[0] = 1;. So, it seems to me, his idea is to change
[expr.ass]/1. That's why I asked him to confirm this. Thanks for your input
anyway.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Richard Smith
2018-02-01 23:43:16 UTC
Permalink
Post by Belloc
My understanding is very simple to explain: as it stands now there is no
place in the standard prohibiting an array name from appearing as the
left-operand of an assignment expression (see [expr.ass]/1
<http://eel.is/c++draft/expr.ass#1>), notwithstanding the fact that an
array name is a modifiable lvalue (according to [basic.lval]/10
<http://eel.is/c++draft/basic.lval#10>). So my first idea was to change
[basic.lval]/10 to make a named array a non-modifiable lvalue. I can accept
Richard's argument that a named array is not exactly non-modifiable, as you
can always modify the array object a, declared in global scope as int
a[10]; with the assignment a[0] = 1;. So, it seems to me, his idea is to
change [expr.ass]/1. That's why I asked him to confirm this. Thanks for
your input anyway.
Here's what I'm thinking:

The term "modifiable" is only defined for the convenience of the
specification in the three places that use it (preincrement/decrement,
postincrement/decrement, and assignment). In two of those places (pre/post
increment/decrement), changing "modifiable" to exclude array types makes no
difference because they already restrict the types to which they can be
applied. The third place appears to currently have a bug, but I don't think
the bug is that it permits array assignment. Rather, I think the bug is
that it fails to say that a prvalue is required as the right operand. If we
fix that, then a change to the definition of "modifiable" to exclude array
types would have no effect.

So yes, I think we should change [expr.ass] to say that a prvalue is
required as the right operand, and we shouldn't change the definition of
"modifiable".

Incidentally, after fixing assignment to say that the lvalue-to-rvalue
conversion is performed, we do not need "modifiable" to talk about function
types either, and can delete the term "modifiable" entirely and simply
replace it with the much more obvious term "non-const".
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2018-02-02 16:37:22 UTC
Permalink
Post by Richard Smith
The term "modifiable" is only defined for the convenience of the
specification in the three places that use it (preincrement/decrement,
postincrement/decrement, and assignment). In two of those places (pre/post
increment/decrement), changing "modifiable" to exclude array types makes no
difference because they already restrict the types to which they can be
applied. The third place appears to currently have a bug, but I don't think
the bug is that it permits array assignment. Rather, I think the bug is
that it fails to say that a prvalue is required as the right operand. If we
fix that, then a change to the definition of "modifiable" to exclude array
types would have no effect.
So yes, I think we should change [expr.ass] to say that a prvalue is
required as the right operand, and we shouldn't change the definition of
"modifiable".
Incidentally, after fixing assignment to say that the lvalue-to-rvalue
conversion is performed, we do not need "modifiable" to talk about function
types either, and can delete the term "modifiable" entirely and simply
replace it with the much more obvious term "non-const".
That makes a lot of sense to me. Thanks for the clarification.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Columbo
2018-02-02 11:51:30 UTC
Permalink
What if... we just allow it?
Post by Richard Smith
Post by 'Johannes Schaub' via ISO C++ Standard - Discussion
Post by Jens Maurer
Post by Belloc
An lvalue is modifiable unless its type is const-qualified or is a
function type. [ Note: A program that attempts to modify an object through
a nonmodifiable lvalue expression or through an rvalue expression is
ill-formed (8.5.18, 8.5.1.6, 8.5.2.2). —end note ]
Post by 'Johannes Schaub' via ISO C++ Standard - Discussion
Post by Jens Maurer
Post by Belloc
An array name is also a non-modifiable lvalue, i.e., an array name
cannot be on the left hand side of an assignment expression.
Post by 'Johannes Schaub' via ISO C++ Standard - Discussion
Post by Jens Maurer
An array name certainly is an lvalue; it represents the address of an
object in memory.
Post by 'Johannes Schaub' via ISO C++ Standard - Discussion
Isn't that what he's saying? Based on this quote (I haven't looked it
up), it says that "array" on the left side of "=" is a modifiable
lvalue, yet we cannot modify "array" through it, disregarding of what
is given as right hand side.
int array[10];
array = 10;
What purpose does "modifiable lvalue" have, if it doesn't classify a
non-modifiable lvalue as being not modifiable?
Ah, ok, I was confused.
Yes, seems reasonable to add "array type" to the list of exclusions.
int main() {
int a[10], b[10];
a = b;
}
? [expr.ass] appears to allow it and define its semantics as replacing the
value of 'a' with the value of 'b'. One would assume that the intent is
that the lvalue-to-rvalue, array-to-pointer, and function-to-pointer
conversions are applied to the right operand of an assignment operator, as
in C, but that doesn't seem to be explicitly stated.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2018-02-02 16:20:11 UTC
Permalink
Post by Columbo
What if... we just allow it?
I don't think I need to say this. But anyway, I doubt CWG would approve an
initiative that duplicates something already existing in std::vector.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
b***@gmail.com
2018-02-05 17:58:55 UTC
Permalink
Post by Columbo
What if... we just allow it?
I don't think we want to get to a point where:

int a[10], b[10];
a = b; // copies 10 integers

but:

void foo(int a[10]);

int b[10];
foo(b); // copies zero integers

And I don't know how much code breaks if the latter starts doing copies?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Language Lawyer
2018-03-03 13:07:40 UTC
Permalink
Post by Richard Smith
int main() {
int a[10], b[10];
a = b;
}
? [expr.ass] appears to allow it and define its semantics as replacing the
value of 'a' with the value of 'b'. One would assume that the intent is
that the lvalue-to-rvalue, array-to-pointer, and function-to-pointer
conversions are applied to the right operand of an assignment operator, as
in C, but that doesn't seem to be explicitly stated.
Is it possible in C++ to get a value of an expression without
lvalue-to-rvalue conversion?
If it is not, then
[expr.ass]/2 In simple assignment (=), the value of the expression replaces
that of the object referred to by the left operand.
<http://eel.is/c++draft/expr.ass#2.sentence-1>
doesn't need to mention conversions explicitly, because they always happen
in such a context, where the value of an expression is needed.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2018-03-04 13:31:59 UTC
Permalink
Post by Language Lawyer
Post by Richard Smith
int main() {
int a[10], b[10];
a = b;
}
? [expr.ass] appears to allow it and define its semantics as replacing
the value of 'a' with the value of 'b'. One would assume that the intent is
that the lvalue-to-rvalue, array-to-pointer, and function-to-pointer
conversions are applied to the right operand of an assignment operator, as
in C, but that doesn't seem to be explicitly stated.
Is it possible in C++ to get a value of an expression without
lvalue-to-rvalue conversion?
If it is not, then
[expr.ass]/2 In simple assignment (=), the value of the expression
replaces that of the object referred to by the left operand.
<http://eel.is/c++draft/expr.ass#2.sentence-1>
doesn't need to mention conversions explicitly, *because they always
happen in such a context, where the value of an expression is needed*.
The emphasis above is not exactly correct. Objects of class type are not
subjected to an l-t-r conversion when assigned to an lvalue of the same
type.

After reexamining this issue a second time I came to the conclusion that
the amendment to [expr.ass], as suggested by Richard above
<https://groups.google.com/a/isocpp.org/d/msg/std-discussion/erohPEiZ8ps/uBJwQn37AgAJ>,
is really necessary. A Note in [basic.lval]/2
<http://eel.is/c++draft/basic.lval#2> says the following:

For example, the built-in assignment operators expect that the left operand
Post by Language Lawyer
is an lvalue and that the right operand is a prvalue and yield an lvalue as
the result.
as if this was already stated in [expr.ass]!
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Language Lawyer
2018-03-04 14:46:02 UTC
Permalink
Post by Belloc
Post by Language Lawyer
Post by Richard Smith
int main() {
int a[10], b[10];
a = b;
}
? [expr.ass] appears to allow it and define its semantics as replacing
the value of 'a' with the value of 'b'. One would assume that the intent is
that the lvalue-to-rvalue, array-to-pointer, and function-to-pointer
conversions are applied to the right operand of an assignment operator, as
in C, but that doesn't seem to be explicitly stated.
Is it possible in C++ to get a value of an expression without
lvalue-to-rvalue conversion?
If it is not, then
[expr.ass]/2 In simple assignment (=), the value of the expression
replaces that of the object referred to by the left operand.
<http://eel.is/c++draft/expr.ass#2.sentence-1>
doesn't need to mention conversions explicitly, *because they always
happen in such a context, where the value of an expression is needed*.
The emphasis above is not exactly correct. Objects of class type are not
subjected to an l-t-r conversion when assigned to an lvalue of the same
type.
In assignment expression for class type, the RHS expression is used to
initialize a parameter of an assignment operator and if it is of a
reference type (which is often the case), the value of the expression is
not needed to initialize a reference.
I have never claimed that conversions happen in contexts where the value of
an expression is not needed.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2018-03-04 19:13:47 UTC
Permalink
Post by Language Lawyer
In assignment expression for class type, the RHS expression is used to
initialize a parameter of an assignment operator and if it is of a
reference type (which is often the case), the value of the expression is
not needed to initialize a reference.
I have never claimed that conversions happen in contexts where the value
of an expression is not needed.
But [expr.ass]/2 <http://eel.is/c++draft/expr.ass#2>, that you quoted on
your first post, seems to me, to refer to the general case, where the RHS
is an expression of a built-in or class type. The next 2 paragraphs after
[expr.ass]/2 then make a distinction between the two cases.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Language Lawyer
2018-03-04 19:58:38 UTC
Permalink
Post by Belloc
Post by Language Lawyer
In assignment expression for class type, the RHS expression is used to
initialize a parameter of an assignment operator and if it is of a
reference type (which is often the case), the value of the expression is
not needed to initialize a reference.
I have never claimed that conversions happen in contexts where the value
of an expression is not needed.
But [expr.ass]/2 <http://eel.is/c++draft/expr.ass#2>, that you quoted on
your first post, seems to me, to refer to the general case, where the RHS
is an expression of a built-in or class type.
And how to name the situation when the operator=() of a class does not
replace the value of the object by the value of RHS, as [expr.ass]/2
requires, but just prints random stuff to the screen?

To me it seems that [expr.ass]/2 speaking about non-class types, by
exclusion, because the assignment of class types is described somewhere
else, as [expr.ass]/4 say.

The [expr.ass] section seems to be written very sloppy, with rules are in
the wrong order.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Chris Hallock
2018-03-04 23:49:41 UTC
Permalink
Post by Language Lawyer
Post by Belloc
Post by Language Lawyer
In assignment expression for class type, the RHS expression is used to
initialize a parameter of an assignment operator and if it is of a
reference type (which is often the case), the value of the expression is
not needed to initialize a reference.
I have never claimed that conversions happen in contexts where the value
of an expression is not needed.
But [expr.ass]/2 <http://eel.is/c++draft/expr.ass#2>, that you quoted on
your first post, seems to me, to refer to the general case, where the RHS
is an expression of a built-in or class type.
And how to name the situation when the operator=() of a class does not
replace the value of the object by the value of RHS, as [expr.ass]/2
requires, but just prints random stuff to the screen?
To me it seems that [expr.ass]/2 speaking about non-class types, by
exclusion, because the assignment of class types is described somewhere
else, as [expr.ass]/4 say.
[expr.compound], which includes [expr.ass], "defines the effects of
operators when applied to types for which they have not been overloaded" (
[expr.pre]/3 <https://timsong-cpp.github.io/cppwp/expr#pre-3.sentence-1>).
I think "overloaded" here means "user-provided
<https://timsong-cpp.github.io/cppwp/dcl.fct.def.default#5.sentence-2>",
but I'm not completely sure.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Belloc
2018-03-05 02:05:46 UTC
Permalink
Post by Chris Hallock
[expr.compound], which includes [expr.ass], "defines the effects of
operators when applied to types for which they have not been overloaded" (
[expr.pre]/3 <https://timsong-cpp.github.io/cppwp/expr#pre-3.sentence-1>).
I think "overloaded" here means "user-provided
<https://timsong-cpp.github.io/cppwp/dcl.fct.def.default#5.sentence-2>",
but I'm not completely sure.
I had completely forgotten [expr.pre]/3 and I take back what I said earlier
about [expr.ass]/2, that it seemed to refer to the general case where the
RHS is an expression of a built-in or class type. [expr.pre]/ 3 is clear
when it says that all the definitions in [expr.compound], which include
[expr.ass], are valid only for built-in operators. I'm sorry for the
confusion.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Language Lawyer
2018-03-04 20:04:12 UTC
Permalink
Post by Belloc
Post by Language Lawyer
In assignment expression for class type, the RHS expression is used to
initialize a parameter of an assignment operator and if it is of a
reference type (which is often the case), the value of the expression is
not needed to initialize a reference.
I have never claimed that conversions happen in contexts where the value
of an expression is not needed.
But [expr.ass]/2 <http://eel.is/c++draft/expr.ass#2>, that you quoted on
your first post, seems to me, to refer to the general case, where the RHS
is an expression of a built-in or class type. The next 2 paragraphs after
[expr.ass]/2 then make a distinction between the two cases.
[expr.ass]/1 also says "their result is an lvalue referring to the left
operand" which is also not always the case for class types.

Should the program with Class::operator= returning anything but lvalue
reference to the Class considered ill-formed?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Language Lawyer
2018-04-23 23:25:43 UTC
Permalink
Post by Richard Smith
int main() {
int a[10], b[10];
a = b;
}
?
This message was already discussed a lot (and I have participated in this
discussion).
But I haven't found a reference to [over.built] below (or did I just
overlook it?).
There is no built-in operator= for array types provided. Isn't it enough to
make the program ill-formed?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Richard Smith
2018-04-24 01:27:14 UTC
Permalink
Post by Language Lawyer
Post by Richard Smith
int main() {
int a[10], b[10];
a = b;
}
?
This message was already discussed a lot (and I have participated in this
discussion).
But I haven't found a reference to [over.built] below (or did I just
overlook it?).
There is no built-in operator= for array types provided. Isn't it enough
to make the program ill-formed?
[over.built] is irrelevant; per [over.match.oper]p1, [over.built] is not
even considered when neither operand has class or enumeration type.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
Continue reading on narkive:
Loading...