Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #82194 > unrolled thread
| Started by | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| First post | 2021-11-03 20:39 +0100 |
| Last post | 2021-11-06 07:33 +0100 |
| Articles | 7 on this page of 47 — 16 participants |
Back to article view | Back to comp.lang.c++
That's while I love C++ over C Bonita Montero <Bonita.Montero@gmail.com> - 2021-11-03 20:39 +0100
Re: That's while I love C++ over C Bart <bc@freeuk.com> - 2021-11-03 20:28 +0000
Re: That's while I love C++ over C Vir Campestris <vir.campestris@invalid.invalid> - 2021-11-05 21:59 +0000
Re: That's while I love C++ over C Lynn McGuire <lynnmcguire5@gmail.com> - 2021-11-05 17:25 -0500
Re: That's while I love C++ over C red floyd <no.spam.here@its.invalid> - 2021-11-05 16:24 -0700
Re: That's while I love C++ over C Bart <bc@freeuk.com> - 2021-11-05 23:46 +0000
Re: That's while I love C++ over C Tony Oliver <guinness.tony@gmail.com> - 2021-11-05 17:48 -0700
Re: That's while I love C++ over C Bart <bc@freeuk.com> - 2021-11-06 01:40 +0000
Re: That's while I love C++ over C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-11-06 02:32 +0000
Re: That's while I love C++ over C red floyd <no.spam.here@its.invalid> - 2021-11-05 20:18 -0700
Re: That's while I love C++ over C "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2021-11-06 04:48 +0100
Re: That's while I love C++ over C James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-11-06 00:34 -0400
Re: That's while I love C++ over C Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-05 22:48 -0700
Re: That's while I love C++ over C red floyd <no.spam.here@its.invalid> - 2021-11-05 22:26 -0700
Re: That's while I love C++ over C Bonita Montero <Bonita.Montero@gmail.com> - 2021-11-06 07:37 +0100
Re: That's while I love C++ over C Bonita Montero <Bonita.Montero@gmail.com> - 2021-11-06 07:36 +0100
Re: That's while I love C++ over C Ike Naar <ike@sdf.org> - 2021-11-06 06:59 +0000
Re: That's while I love C++ over C David Brown <david.brown@hesbynett.no> - 2021-11-06 11:12 +0100
Re: That's while I love C++ over C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-11-06 11:08 +0000
Re: That's while I love C++ over C Bonita Montero <Bonita.Montero@gmail.com> - 2021-11-06 15:03 +0100
Re: That's while I love C++ over C Manfred <noname@add.invalid> - 2021-11-06 19:12 +0100
Re: That's while I love C++ over C Bart <bc@freeuk.com> - 2021-11-06 18:57 +0000
Re: That's while I love C++ over C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-11-06 20:50 +0000
Re: That's while I love C++ over C Bart <bc@freeuk.com> - 2021-11-06 11:44 +0000
Re: That's while I love C++ over C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-11-06 13:18 +0000
Re: That's while I love C++ over C David Brown <david.brown@hesbynett.no> - 2021-11-06 10:58 +0100
Re: That's while I love C++ over C Bart <bc@freeuk.com> - 2021-11-06 12:00 +0000
Re: That's while I love C++ over C Öö Tiib <ootiib@hot.ee> - 2021-11-06 07:04 -0700
Re: That's while I love C++ over C David Brown <david.brown@hesbynett.no> - 2021-11-06 15:50 +0100
Re: That's while I love C++ over C scott@slp53.sl.home (Scott Lurndal) - 2021-11-06 14:43 +0000
[OT] Algol68 Was: That's while I love C++ over C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-11-06 17:13 +0000
Re: [OT] Algol68 Was: That's while I love C++ over C scott@slp53.sl.home (Scott Lurndal) - 2021-11-06 20:16 +0000
Re: [OT] Algol68 Was: That's while I love C++ over C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-11-06 20:25 +0000
Re: That's while I love C++ over C "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-11-05 21:59 -0700
Re: That's while I love C++ over C "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-11-05 22:23 -0700
Re: That's while I love C++ over C red floyd <no.spam.here@its.invalid> - 2021-11-05 22:27 -0700
Re: That's while I love C++ over C red floyd <no.spam.here@its.invalid> - 2021-11-05 22:28 -0700
Re: That's while I love C++ over C "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-11-05 22:46 -0700
Re: That's while I love C++ over C Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-05 22:46 -0700
Re: That's while I love C++ over C David Brown <david.brown@hesbynett.no> - 2021-11-06 12:25 +0100
Re: That's while I love C++ over C Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-06 13:27 -0700
Re: That's while I love C++ over C Manfred <noname@add.invalid> - 2021-11-07 00:38 +0100
Re: That's while I love C++ over C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-11-07 00:33 +0000
Re: That's while I love C++ over C David Brown <david.brown@hesbynett.no> - 2021-11-07 15:10 +0100
Re: That's while I love C++ over C James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-11-08 01:47 -0500
Re: That's while I love C++ over C Bart <bc@freeuk.com> - 2021-11-05 23:35 +0000
Re: That's while I love C++ over C Bonita Montero <Bonita.Montero@gmail.com> - 2021-11-06 07:33 +0100
Page 3 of 3 — ← Prev page 1 2 [3]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-11-06 13:27 -0700 |
| Message-ID | <87fss9xc5s.fsf@nosuchdomain.example.com> |
| In reply to | #82241 |
David Brown <david.brown@hesbynett.no> writes:
> On 06/11/2021 06:46, Keith Thompson wrote:
>> red floyd <no.spam.here@its.invalid> writes:
[...]
>>> As with everything else in C++, there's nothing wrong with the
>>> conditional operator ... in the right place. The left hand side of
>>> an assignment is NOT the right place. Using the result of a conditional
>>> as an rvalue is just fine, I use it all the time.
>>
>> Why?
>>
>> Seriously, the C++ standard (unlike the C standard) is clear that a
>> conditional expression can be an lvalue if its second and third operands
>> are both lvalues of the same type (I'm oversimplifying the rules a bit).
>> In other words, the language explicitly allows a conditional expression
>> to be the LHS of an assignment. Why do you object to taking advantage
>> of that feature?
>>
>> I don't think I knew about it before seeing this discussion, but now
>> that I do, the meaning of
>>
>> (x == y ? a : b) = c;
>>
>> seems perfectly clear to me. The alternative:
>>
>> if (x == y) {
>> a = c;
>> }
>> else {
>> b = c;
>> }
>>
>> is more verbose and could be problematic if c is a complicated
>> expression; the risk is that a later maintainer might modify one
>> instance of c and not the other.
>
> That is a poor argument, IMHO, as it is so easily solved :
>
> auto new_c = complicated_expression;
> if (x == y) {
> a = new_c;
> } else {
> b = new_c;
> }
To be clear, I respect your opinion. I just don't share it in this
case.
I don't see your replacement code as a "solution", because I don't see
the shorter version as a problem. Expanding one line to six can make
sense in some cases. I just don't see this as one of those cases.
In my humble opinion, the biggest barrier to understanding
(x == y ? a : b) = c;
is knowing that a conditional expression can appear on the LHS of an
assignment, i.e., that it can be an lvalue. Any C or C++ programmer
should already understand that the LHS of an assignment is an expression
that's evaluated to determine what object is to be assigned to. Once
you realize that a conditional expression can be an lvalue, the meaning
**IMHO** becomes obvious.
Of course in real code you very probably wouldn't call the variables
x, y, a, b, and c. With meaningful names, I suspect the intent of the
code would be clearer.
If I saw that line presented as C, my reaction would be that it's
illegal, but *if it were legal* the meaning would be obvious.
[...]
> "Always write code as though the person who will maintain it is a
> violent psychopath who knows where you live" (I've forgotten the source
> of that quotation). Also assume they are not as clever or experienced
> as you are.
Apparently it originated in a post by John F. Woods, right here on
comp.lang.c++ in 1991.
https://groups.google.com/g/comp.lang.c++/c/rYCO5yn4lXw/m/oITtSkZOtoUJ?pli=1
I've always liked that quotation.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2021-11-07 00:38 +0100 |
| Message-ID | <sm73mi$17vh$1@gioia.aioe.org> |
| In reply to | #82255 |
On 11/6/2021 9:27 PM, Keith Thompson wrote:
> David Brown <david.brown@hesbynett.no> writes:
[...]
>
> In my humble opinion, the biggest barrier to understanding
>
> (x == y ? a : b) = c;
>
> is knowing that a conditional expression can appear on the LHS of an
> assignment, i.e., that it can be an lvalue.
More precisely, the C++ standard says the "target type" of the operator
is (simplifying) "If E2 is an lvalue, the target type is “lvalue
reference to T2”" , the point being it's a reference.
Any C or C++ programmer
> should already understand that the LHS of an assignment is an expression
> that's evaluated to determine what object is to be assigned to. Once
> you realize that a conditional expression can be an lvalue, the meaning
> **IMHO** becomes obvious.
>
> Of course in real code you very probably wouldn't call the variables
> x, y, a, b, and c. With meaningful names, I suspect the intent of the
> code would be clearer.
>
> If I saw that line presented as C, my reaction would be that it's
> illegal, but *if it were legal* the meaning would be obvious.
>
The problem in C is not that it's illegal per se. It can't work because
C does not have references, which makes it somewhat hard to guess what
the construct would mean.
(unless by *if it were legal* you mean if C had references, but that's
quite wider a scope than the conditional itself)
It's obvious with function return values:
/* C++ */
int& foo()
{
static int n = 0;
return n;
}
foo() = 42; // OK
/* C */
int bar()
{
static int n = 0;
return n;
}
bar() = 42; /* ?!? error: lvalue required as left operand of assignment */
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-11-07 00:33 +0000 |
| Message-ID | <87a6ig6bzp.fsf@bsb.me.uk> |
| In reply to | #82257 |
Manfred <noname@add.invalid> writes: > On 11/6/2021 9:27 PM, Keith Thompson wrote: <snip> >> If I saw that line presented as C, my reaction would be that it's >> illegal, but *if it were legal* the meaning would be obvious. > > The problem in C is not that it's illegal per se. It can't work > because C does not have references, which makes it somewhat hard to > guess what the construct would mean. You don't need references for it to work, or even make sense, in C. In C, the LHS of an assignment must be an lvalue expression of which there are many (for example a[42] and *p). If the standard declared conditional expressions to be lvalues, the construct would be legal. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-11-07 15:10 +0100 |
| Message-ID | <sm8mo3$rhg$1@dont-email.me> |
| In reply to | #82255 |
On 06/11/2021 21:27, Keith Thompson wrote:
> David Brown <david.brown@hesbynett.no> writes:
>> On 06/11/2021 06:46, Keith Thompson wrote:
>>> red floyd <no.spam.here@its.invalid> writes:
> [...]
>>>> As with everything else in C++, there's nothing wrong with the
>>>> conditional operator ... in the right place. The left hand side of
>>>> an assignment is NOT the right place. Using the result of a conditional
>>>> as an rvalue is just fine, I use it all the time.
>>>
>>> Why?
>>>
>>> Seriously, the C++ standard (unlike the C standard) is clear that a
>>> conditional expression can be an lvalue if its second and third operands
>>> are both lvalues of the same type (I'm oversimplifying the rules a bit).
>>> In other words, the language explicitly allows a conditional expression
>>> to be the LHS of an assignment. Why do you object to taking advantage
>>> of that feature?
>>>
>>> I don't think I knew about it before seeing this discussion, but now
>>> that I do, the meaning of
>>>
>>> (x == y ? a : b) = c;
>>>
>>> seems perfectly clear to me. The alternative:
>>>
>>> if (x == y) {
>>> a = c;
>>> }
>>> else {
>>> b = c;
>>> }
>>>
>>> is more verbose and could be problematic if c is a complicated
>>> expression; the risk is that a later maintainer might modify one
>>> instance of c and not the other.
>>
>> That is a poor argument, IMHO, as it is so easily solved :
>>
>> auto new_c = complicated_expression;
>> if (x == y) {
>> a = new_c;
>> } else {
>> b = new_c;
>> }
>
> To be clear, I respect your opinion. I just don't share it in this
> case.
Fair enough. And discussing different opinions like this is a good way
to learn - whether we learn new ideas, or learn more about how other
people might see things, or learn something about ourselves when we are
pushed into thinking about our own opinions.
>
> I don't see your replacement code as a "solution", because I don't see
> the shorter version as a problem. Expanding one line to six can make
> sense in some cases. I just don't see this as one of those cases.
I have a preference towards spacing things out rather than having a
compact representation. That's a preference, not an absolute - there
can be many overriding factors, and the "best" choice at any given time
can vary significantly. (I think we can ignore the choice of brace
style for now - that's a different matter.)
Some of the reasons for usually preferring a layout with an "if" and
separate assignments, rather than a combined assignment, include:
1. It is clear when a given variable is assigned to. I believe it is
important to know what can be changed by a piece of code, and where each
piece of data can be changed. Along with this goes a bias towards
having multiple return value functions return structs (or tuples) rather
than taking a pointer to an variable to change. In my opinion it makes
it easier to see the data flow.
2. It is easier to change code if you later need to do other things in
connection with the conditional (i.e., if you want to do something else
when "x == y" other than assign "c" to "a").
3. A code layout with separate statements and avoiding doing too many
things in one line works much better with tools for version control or
comparison (diff tools) - it is easier to see what has changed and what
has not changed.
4. In my line of programming, C is dominant - the proportion of C++
coding is increasing, but still much less than C. And a sizeable
proportion of small-systems embedded programmers have a background from
hardware and electronics, rather than some kind of computer science
degree. This gives a different viewpoint and different experiences,
which can be a good thing and a bad thing (teams with mixed backgrounds
are useful). But it means that you sometimes have to be careful with
coding techniques that are relatively uncommon - there is a balance to
be found between confusing other people and having an opportunity to
teach new ideas. The kind of coding you use can be very different for a
dedicated team of higher-level, experienced C++ coders and when you are
working with one or two people who cover a broad range of tasks from
electronics design through to simple programming tasks. That does not
mean that "lowest common denominator" programming is the right tactic,
but you may have to have more justification before using a technique
that has a high chance of being unfamiliar.
5. Code needs to be tested and debugged. When dealing with
small-systems embedded work, techniques like simulation or unit testing
are often impractical or impossible - much of the close-to-the-metal
coding can only be tested in-system. Spacing out the code more makes it
far easier add breakpoints, logging, volatile variables, and other
debugging aids.
6. Sometimes code must be commented. I'm a great fan of expressing
things in code rather than in comments, by use of good names, clear
code, static asserts, etc., but comments are useful. With compact code,
it is rarely possible to put comments close to the action.
7. Sometimes the results from more compact form are significantly less
efficient. A quick test suggests that gcc on x86 will give the same
object code for an "if" with separate assignments as "(x == y ? a : b) =
c;". But the C equivalent, "*(x == y ? &a : &b) = c;", is massively
inefficient for local variables that would otherwise reside in
registers. (gcc is usually quite good at keeping local variables in
registers even if you take their address.) In the embedded world, some
compilers are not very good at optimising - I have seen the results of
conditional operator expressions produce very poor code even in the
right-hand side of expressions.
8. Coding standards often limit such expressions, whether or not a
particular programmer might think it is a good idea. If an embedded
programmer is working to the MISRA standards (which is common in the
industry), then even "c = (x == y ? a : b);" is not allowed - it must be
written "c = ((x == y) ? a : b);" or "c = (x == y) ? a : b;", and there
are limits to the complexities of the expressions "a" and "b".
>
> In my humble opinion, the biggest barrier to understanding
>
> (x == y ? a : b) = c;
>
> is knowing that a conditional expression can appear on the LHS of an
> assignment, i.e., that it can be an lvalue. Any C or C++ programmer
> should already understand that the LHS of an assignment is an expression
> that's evaluated to determine what object is to be assigned to. Once
> you realize that a conditional expression can be an lvalue, the meaning
> **IMHO** becomes obvious.
I think it is fairly obvious what the expression does - though not
obvious that it is allowed by the language (particularly because it is
allowed in C++ but not in C). However, just because it could only mean
one thing does not make it easy to follow - and if the reader is using
more effort to understand the mechanics of what the code is doing, they
have less brain power available for the important part - /why/ the code
is doing what it does.
>
> Of course in real code you very probably wouldn't call the variables
> x, y, a, b, and c. With meaningful names, I suspect the intent of the
> code would be clearer.
Indeed - and I think we all agree that context and names are vital, and
that the clearest way to express something in code depends on wider
circumstances and cannot be covered by simple fixed rules.
>
> If I saw that line presented as C, my reaction would be that it's
> illegal, but *if it were legal* the meaning would be obvious.
>
> [...]
>
>> "Always write code as though the person who will maintain it is a
>> violent psychopath who knows where you live" (I've forgotten the source
>> of that quotation). Also assume they are not as clever or experienced
>> as you are.
>
> Apparently it originated in a post by John F. Woods, right here on
> comp.lang.c++ in 1991.
> https://groups.google.com/g/comp.lang.c++/c/rYCO5yn4lXw/m/oITtSkZOtoUJ?pli=1
>
> I've always liked that quotation.
>
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2021-11-08 01:47 -0500 |
| Message-ID | <smah5v$a9f$2@dont-email.me> |
| In reply to | #82241 |
On 11/6/21 7:25 AM, David Brown wrote: ... > "Always write code as though the person who will maintain it is a > violent psychopath who knows where you live" (I've forgotten the source > of that quotation). Also assume they are not as clever or experienced > as you are. That reminds me a little too painfully of a subordinate that I knew to be incompetent, and suspected of being literally insane. After his actions got him reassigned with no replacement, I was left with the job of maintaining the code he'd written. It was bug-ridden, untested, inconsistent with the design documents, and he'd managed to accidentally erase all of the revision history for many of the files he'd worked on (I managed to get some of that history restored from backup). After his reassignment, he behaved in odd and vaguely threatening ways to me, such as stopping outside my office and just staring at me for long periods of time. Around that time I happened to receive some paperwork connected with his reassignment, which had home address on it, and I learned that he lived less than 100 meters from me. So I was the one who knew where he lived. I'm glad it was NOT the other way around.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-11-05 23:35 +0000 |
| Message-ID | <sm4f3j$dnd$1@dont-email.me> |
| In reply to | #82213 |
On 05/11/2021 21:59, Vir Campestris wrote: > On 03/11/2021 20:28, Bart wrote: >> On 03/11/2021 19:39, Bonita Montero wrote: >> >>> (x == y ? a : b) = c; >> >> Hey, I can do that: >> >> (x = y | a | b) := z >> >> and also: >> >> (n | a, b, c | d) := z >> >> (Assign to one of n lvalues.) Or even: >> >> if x then a elsif y then b else c fi := z >> >> Lots of such things in an expression-based language. But this is in a >> language not much higher than C in level; it doesn't require the vast >> complexity of C++. >> >> If C doesn't support this, that's a deliberate choice. It means >> someone having to instead write: >> >> *(x == y ? &a : &b) = c; >> >> It's not a big enough reason to switch. > > If you wrote that code in anything in my company I would downvote the > review. > > Any of those versions. Who said I would write it? It's a consequence of a flexible language. The OP was touting the ability to do similar in C++ as making it superior to C. But this is actually very mild compared to most C++ code. If, however, that the need ever come up to do that second example - assigning z to one of a, b, c, d depending on n being 1, 2, 3 or anything else (you can make it zero-based), how would you prefer that written in C++ in a way that doesn't get anyone fired? Assume that any terms could be arbitrarily complex. Assume a, b, c, d are the same type, and z is a compatible type (my implementation requires that).
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2021-11-06 07:33 +0100 |
| Message-ID | <sm57ki$ap3$1@dont-email.me> |
| In reply to | #82213 |
Am 05.11.2021 um 22:59 schrieb Vir Campestris: > On 03/11/2021 20:28, Bart wrote: >> On 03/11/2021 19:39, Bonita Montero wrote: >> >>> (x == y ? a : b) = c; >> >> Hey, I can do that: >> >> (x = y | a | b) := z >> >> and also: >> >> (n | a, b, c | d) := z >> >> (Assign to one of n lvalues.) Or even: >> >> if x then a elsif y then b else c fi := z >> >> Lots of such things in an expression-based language. But this is in a >> language not much higher than C in level; it doesn't require the vast >> complexity of C++. >> >> If C doesn't support this, that's a deliberate choice. It means >> someone having to instead write: >> >> *(x == y ? &a : &b) = c; >> >> It's not a big enough reason to switch. > > If you wrote that code in anything in my company I would downvote the > review. That's just a matter of habits and taste.
[toc] | [prev] | [standalone]
Page 3 of 3 — ← Prev page 1 2 [3]
Back to top | Article view | comp.lang.c++
csiph-web