Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #141843 > unrolled thread
| Started by | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| First post | 2019-03-09 16:53 +0000 |
| Last post | 2019-03-19 14:17 -0700 |
| Articles | 20 on this page of 35 — 13 participants |
Back to article view | Back to comp.lang.c
Remembering C's operator precedence rules Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-03-09 16:53 +0000
Re: Remembering C's operator precedence rules Richard Damon <Richard@Damon-Family.org> - 2019-03-09 15:21 -0500
Re: Remembering C's operator precedence rules Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-03-09 21:41 +0000
Re: Remembering C's operator precedence rules Keith Thompson <kst-u@mib.org> - 2019-03-09 12:32 -0800
Re: Remembering C's operator precedence rules Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-03-09 21:21 +0000
Re: Remembering C's operator precedence rules Richard Damon <Richard@Damon-Family.org> - 2019-03-09 16:42 -0500
Re: Remembering C's operator precedence rules "Rick C. Hodgin" <rick.c.hodgin@gmail.com> - 2019-03-09 14:01 -0800
Re: Remembering C's operator precedence rules Keith Thompson <kst-u@mib.org> - 2019-03-09 14:17 -0800
Re: Remembering C's operator precedence rules Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-03-10 00:42 +0000
Re: Remembering C's operator precedence rules Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-03-09 13:54 -0700
Re: Remembering C's operator precedence rules Bart <bc@freeuk.com> - 2019-03-09 21:37 +0000
Re: Remembering C's operator precedence rules Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-03-09 22:01 +0000
Re: Remembering C's operator precedence rules Richard Damon <Richard@Damon-Family.org> - 2019-03-09 18:59 -0500
Re: Remembering C's operator precedence rules Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-03-13 09:26 -0700
Re: Remembering C's operator precedence rules Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-03-13 10:11 -0700
Re: Remembering C's operator precedence rules Bart <bc@freeuk.com> - 2019-03-13 17:40 +0000
Re: Remembering C's operator precedence rules Keith Thompson <kst-u@mib.org> - 2019-03-13 15:24 -0700
Re: Remembering C's operator precedence rules Bart <bc@freeuk.com> - 2019-03-13 23:43 +0000
Re: Remembering C's operator precedence rules Keith Thompson <kst-u@mib.org> - 2019-03-13 17:43 -0700
Re: Remembering C's operator precedence rules Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-03-18 08:53 -0700
Re: Remembering C's operator precedence rules Wouter Verhelst <w@uter.be> - 2019-03-13 22:24 +0200
Re: Remembering C's operator precedence rules Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-03-13 14:06 -0700
Re: Remembering C's operator precedence rules Ian Collins <ian-news@hotmail.com> - 2019-03-14 14:28 +1300
Re: Remembering C's operator precedence rules scott@slp53.sl.home (Scott Lurndal) - 2019-03-14 13:35 +0000
Re: Remembering C's operator precedence rules Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2019-03-14 06:55 -0700
Re: Remembering C's operator precedence rules Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-03-14 16:39 +0000
Re: Remembering C's operator precedence rules scott@slp53.sl.home (Scott Lurndal) - 2019-03-14 17:37 +0000
Re: Remembering C's operator precedence rules Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-03-14 20:42 +0000
Re: Remembering C's operator precedence rules Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2019-03-14 10:42 -0700
Re: Remembering C's operator precedence rules Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-03-14 23:08 +0000
Re: Remembering C's operator precedence rules Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2019-03-15 02:53 -0700
Re: Remembering C's operator precedence rules Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2019-03-15 17:52 -0600
Re: Remembering C's operator precedence rules Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-03-13 12:56 -0700
Re: Remembering C's operator precedence rules Jens Stuckelberger <Jens_Stuckelberger@nowhere.net> - 2019-03-13 20:14 +0000
Re: Remembering C's operator precedence rules fir <profesor.fir@gmail.com> - 2019-03-19 14:17 -0700
Page 1 of 2 [1] 2 Next page →
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2019-03-09 16:53 +0000 |
| Subject | Remembering C's operator precedence rules |
| Message-ID | <87lg1o9efx.fsf@bsb.me.uk> |
I was going to post this as a reply, but once finished I thought it should be a new thread. Prompted by recent posts about remembering C's 15 precedence levels for its 49 operators, I thought I would gather together some remarks about why I think you can work most of it out for yourself. I certainly don't know them all, but I think of them in big blocks (unary, arithmetic, relational, and so on) which are easy to relate to each other, and only every now and then do I need to consider the structure within these blocks of operators. It's obvious that all the postfix operators will be grouped together in one level, as will the prefix operators. What would multiple levels of prefix operator even mean? It simply would not make sense to have more than one level for each group. Similarly, the two groups must be separate. However, which group is higher can be remembered because it's natural. Consider -sin(x) *s.member &a[1] You would not want to have to write -(sin(x)) *(s.member) &(a[1]) to get the desired result for these common forms. If you need another clue, remember that -> is provided precisely because you'd have to write (*p).member otherwise. The structure within the arithmetic operators is easy as we all learn it in school. You just have to remember to include % as a multiplicative operator. And you can extend that, by analogy, to & binding tighter than | and && tighter than ||. This may be more natural for mathematically inclined programmers, but I think the convention is common in electronic engineering circles too. The fact that ^ has it's own level between & and | is so rarely remembered that it's not one I'd blithely assume everyone knows. I never remember it, except when I'm writing things like this. Within the big block of relational operators, another grouping that looks odd at first is that == and != have their own precedence level just below <, >, <= and >=. This is another case that it's probably wise to assume not everyone knows, but /you/ might remember it if you consider that == and != make sensible logical connectives, rather like && and ||. For example, to test if four variables are in order -- either ascending or descending -- you can write a <= b == b <= c == c <= d Compare that with a <= b && b <= c && c <= d for a single order. There's no reason for the assignment operators to be in more than one group, and they must bind very low since almost any expression should be permitted without () on the right hand side of an assignment. The exception is the comma operator, but again, that's natural. It acts like ; for statements so any expression, even assignments, should un-parenthesised within a comma expression. So what's left? Well there's << and >> and the conditional operator. These are arithmetic in nature (I'm using the term more loosely here, not as in arithmetic vs logical shift) so they will be somewhere in amongst *, /, + and so on. However, I need a cue to remember that the shift operators come just below addition. The fact that C++ uses them for streams does the trick for me. You could not naturally write std::cout << x + 1 otherwise. The conditional operator is so different it needs a switch in perspective. Because the ? and : can, unambiguously, delimit any expression, you can make it fit the pattern of the others if you consider ?<exp>: to be a single binary operator. Obviously you want it to bind very loosely (below the logical connectives that will often occur in the condition), but should it be above or below assignment? To work it out, I ask which form is more common: <cond> ?<exp>: var = val or var = <cond> ?<exp>: val I think I write the second much more than the first, and it is indeed that form that needs no parentheses. (As written, the first is a constraint violation. To get the assignment /in/ the conditional you need to write <cond> ?<exp>: (var = val).) Finally, is the overall relationship between the big blocks of operators logical? By and large I think it is. The unary operators must come top, and comma and assignment must come bottom. Between these, the arithmetic operators must come above the relational operators, and these much come above the logical connectives. The fly in the ointment (acknowledged by DMR as an unfortunate import from B) is that &, ^ and | sit rather unnaturally low. They were used as logical connectives as well as bit-wise operators in B, so it's not too hard to remember that they are low, but still, it's not ideal. So how do you either remember these, or work them out from first principles? Do you have any handy mnemonics or idiomatic examples to share? -- Ben.
[toc] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2019-03-09 15:21 -0500 |
| Message-ID | <_eVgE.15123$sd4.6824@fx48.iad> |
| In reply to | #141843 |
On 3/9/19 11:53 AM, Ben Bacarisse wrote:
> For example, to test if four variables are in order --
> either ascending or descending -- you can write
>
> a <= b == b <= c == c <= d
That doesn't work for descending order,
false == false == false
becomes
true == false
becomes
false
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2019-03-09 21:41 +0000 |
| Message-ID | <878sxnafpl.fsf@bsb.me.uk> |
| In reply to | #141845 |
Richard Damon <Richard@Damon-Family.org> writes: > On 3/9/19 11:53 AM, Ben Bacarisse wrote: >> For example, to test if four variables are in order -- >> either ascending or descending -- you can write >> >> a <= b == b <= c == c <= d > > That doesn't work for descending order, > false == false == false > becomes > true == false > becomes > false Yes, and it returns 1 in all sorts of cases it shouldn't as well! I was dimly remembering the three variable case: a <= b == b <= c It's all wrong for four. You can correct it with another test and an && a <= b == b <= c && b <= c == c <= d but that's not neat enough to act as a reminder. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2019-03-09 12:32 -0800 |
| Message-ID | <lna7i3lrf0.fsf@kst-u.example.com> |
| In reply to | #141843 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
[...]
> Within the big block of relational operators, another grouping that
> looks odd at first is that == and != have their own precedence level
> just below <, >, <= and >=. This is another case that it's probably
> wise to assume not everyone knows, but /you/ might remember it if you
> consider that == and != make sensible logical connectives, rather like
> && and ||. For example, to test if four variables are in order --
> either ascending or descending -- you can write
>
> a <= b == b <= c == c <= d
>
> Compare that with
>
> a <= b && b <= c && c <= d
>
> for a single order.
I think you forgot about associativity.
x == y == z
means
(x == y) == z
not
(x == y) && (y == z)
(Some languages do chain comparison operators, and some forbid
expressions that would be ambiguous. C just sits back and lets you
shoot yourself in the foot.)
[...]
> So how do you either remember these, or work them out from first
> principles? Do you have any handy mnemonics or idiomatic examples to
> share?
I usually have a copy of n1570.pdf open. When necessary, look at the
table of contents and check the subsection names in section 6.5.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2019-03-09 21:21 +0000 |
| Message-ID | <87ftrvaglt.fsf@bsb.me.uk> |
| In reply to | #141846 |
Keith Thompson <kst-u@mib.org> writes: > Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > [...] >> Within the big block of relational operators, another grouping that >> looks odd at first is that == and != have their own precedence level >> just below <, >, <= and >=. This is another case that it's probably >> wise to assume not everyone knows, but /you/ might remember it if you >> consider that == and != make sensible logical connectives, rather like >> && and ||. For example, to test if four variables are in order -- >> either ascending or descending -- you can write >> >> a <= b == b <= c == c <= d >> >> Compare that with >> >> a <= b && b <= c && c <= d >> >> for a single order. > > I think you forgot about associativity. > x == y == z > means > (x == y) == z > not > (x == y) && (y == z) Thanks. I should have looked for a better example as this one gets messy when corrected. Do you know of an example that would motivate the otherwise rather surprising separation between relational an equality operators? -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2019-03-09 16:42 -0500 |
| Message-ID | <5rWgE.190267$%l2.181350@fx42.iad> |
| In reply to | #141848 |
On 3/9/19 4:21 PM, Ben Bacarisse wrote: > Keith Thompson <kst-u@mib.org> writes: > >> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >> [...] >>> Within the big block of relational operators, another grouping that >>> looks odd at first is that == and != have their own precedence level >>> just below <, >, <= and >=. This is another case that it's probably >>> wise to assume not everyone knows, but /you/ might remember it if you >>> consider that == and != make sensible logical connectives, rather like >>> && and ||. For example, to test if four variables are in order -- >>> either ascending or descending -- you can write >>> >>> a <= b == b <= c == c <= d >>> >>> Compare that with >>> >>> a <= b && b <= c && c <= d >>> >>> for a single order. >> >> I think you forgot about associativity. >> x == y == z >> means >> (x == y) == z >> not >> (x == y) && (y == z) > > Thanks. I should have looked for a better example as this one gets > messy when corrected. Do you know of an example that would motivate the > otherwise rather surprising separation between relational an equality > operators? > It works for 3 numbers, just not 4.
[toc] | [prev] | [next] | [standalone]
| From | "Rick C. Hodgin" <rick.c.hodgin@gmail.com> |
|---|---|
| Date | 2019-03-09 14:01 -0800 |
| Message-ID | <66163672-fa48-46d7-a228-9cb03a416e9c@googlegroups.com> |
| In reply to | #141851 |
It's easy to remember. Just use a reference:
https://en.cppreference.com/w/c/language/operator_precedence
--
Rick C. Hodgin
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2019-03-09 14:17 -0800 |
| Message-ID | <ln5zsrlmju.fsf@kst-u.example.com> |
| In reply to | #141848 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>> [...]
>>> Within the big block of relational operators, another grouping that
>>> looks odd at first is that == and != have their own precedence level
>>> just below <, >, <= and >=. This is another case that it's probably
>>> wise to assume not everyone knows, but /you/ might remember it if you
>>> consider that == and != make sensible logical connectives, rather like
>>> && and ||. For example, to test if four variables are in order --
>>> either ascending or descending -- you can write
>>>
>>> a <= b == b <= c == c <= d
>>>
>>> Compare that with
>>>
>>> a <= b && b <= c && c <= d
>>>
>>> for a single order.
>>
>> I think you forgot about associativity.
>> x == y == z
>> means
>> (x == y) == z
>> not
>> (x == y) && (y == z)
>
> Thanks. I should have looked for a better example as this one gets
> messy when corrected. Do you know of an example that would motivate the
> otherwise rather surprising separation between relational an equality
> operators?
You could use the same method to determine whether 3 values are in
either ascending or descending order:
a <= b == b <= c
It just breaks down when you need more than one "==" operator.
(I'd parenthesize that myself.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2019-03-10 00:42 +0000 |
| Message-ID | <87tvgb8squ.fsf@bsb.me.uk> |
| In reply to | #141854 |
Keith Thompson <kst-u@mib.org> writes: <cut> > You could use the same method to determine whether 3 values are in > either ascending or descending order: > a <= b == b <= c > It just breaks down when you need more than one "==" operator. Yes, that was the example I was remembering, but on its own, it seems rather weak as a justification for splitting == and !== off from <, <= et. al. Is equality testing of relations more widely useful? I don't think I've used it more than maybe once or twice in many decades. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Joe Pfeiffer <pfeiffer@cs.nmsu.edu> |
|---|---|
| Date | 2019-03-09 13:54 -0700 |
| Message-ID | <1bh8cb93bi.fsf@pfeifferfamily.net> |
| In reply to | #141843 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: > I was going to post this as a reply, but once finished I thought it > should be a new thread. > > Prompted by recent posts about remembering C's 15 precedence levels for > its 49 operators, I thought I would gather together some remarks about > why I think you can work most of it out for yourself. I certainly don't > know them all, but I think of them in big blocks (unary, arithmetic, > relational, and so on) which are easy to relate to each other, and only > every now and then do I need to consider the structure within these > blocks of operators. <snip> This isn't unexpected; they are in the order that seemed most intuitive to K&R in 1974 or thereabouts (doing something like putting + above * would have been downright perverse). The thing is, what's most intuitive depends on everything from context in the program to the current phase of the moon. By the time you've got 15 levels for 49 operators, any sane programmer will be putting in some extra parentheses here and there because it's faster than googling to find out if they're necessary, and if I don't remember for sure in my own code it probably isn't fair to expect someone coming along later (possibly even me under a full moon) to have the same intuition.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2019-03-09 21:37 +0000 |
| Message-ID | <UmWgE.67704$U64.2717@fx20.am4> |
| In reply to | #141847 |
On 09/03/2019 20:54, Joe Pfeiffer wrote:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>
>> I was going to post this as a reply, but once finished I thought it
>> should be a new thread.
>>
>> Prompted by recent posts about remembering C's 15 precedence levels for
>> its 49 operators, I thought I would gather together some remarks about
>> why I think you can work most of it out for yourself. I certainly don't
>> know them all, but I think of them in big blocks (unary, arithmetic,
>> relational, and so on) which are easy to relate to each other, and only
>> every now and then do I need to consider the structure within these
>> blocks of operators.
>
> <snip>
>
> This isn't unexpected; they are in the order that seemed most intuitive
> to K&R in 1974 or thereabouts (doing something like putting + above *
> would have been downright perverse).
That doesn't explain why there are so many.
WHY do &, | and ^ each need, not only a separate level from all other
operators, but even separate from each other?! What could possibly be
the advantage?
> The thing is, what's most intuitive depends on everything from context
> in the program to the current phase of the moon.
There is nothing intuitive about C's operators apart from the 4 levels
that everyone should know:
* / (from school)
+ -
== etc (from use of 'equals' in school)
&& (from use of 'and' in English)
One more level for || needs to be added (I don't know the reasoning for
that one although I can guess), but after that there was no reason for
any more really:
All compare operators can share with ==.
All <<, >> that scale numbers so do a similar job, can go with * and /
(throw % in there too).
All others (I'm excluding assignment), since they don't do scaling, and
they are not compare ops, can be lumped in with + and -. Job done.
As for the rest, some I don't consider operators, so it's a question of
syntax, not precedence.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2019-03-09 22:01 +0000 |
| Message-ID | <87zhq3906t.fsf@bsb.me.uk> |
| In reply to | #141849 |
Bart <bc@freeuk.com> writes: > On 09/03/2019 20:54, Joe Pfeiffer wrote: >> Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >> >>> I was going to post this as a reply, but once finished I thought it >>> should be a new thread. >>> >>> Prompted by recent posts about remembering C's 15 precedence levels for >>> its 49 operators, I thought I would gather together some remarks about >>> why I think you can work most of it out for yourself. I certainly don't >>> know them all, but I think of them in big blocks (unary, arithmetic, >>> relational, and so on) which are easy to relate to each other, and only >>> every now and then do I need to consider the structure within these >>> blocks of operators. >> >> <snip> >> >> This isn't unexpected; they are in the order that seemed most intuitive >> to K&R in 1974 or thereabouts (doing something like putting + above * >> would have been downright perverse). > > That doesn't explain why there are so many. > > WHY do &, | and ^ each need, not only a separate level from all other > operators, but even separate from each other?! What could possibly be > the advantage? The advantage could possibly be having to use fewer ()s. Note (because I know how you flip arguments around) that I am not saying that there is no associated disadvantage. Another might be to allow the language to gain operators during its development without breaking any old code. That is explanation given for two of them. >> The thing is, what's most intuitive depends on everything from context >> in the program to the current phase of the moon. > > There is nothing intuitive about C's operators apart from the 4 levels > that everyone should know: > > * / (from school) > + - > == etc (from use of 'equals' in school) > && (from use of 'and' in English) That unary operators are above these is also, I suspect, intuitive even to you. And I can't see how you could argue that having pre- and post-fix operators separate, and in the order they come, is not also intuitive. What else could be done with them without making code clumsy. > One more level for || needs to be added (I don't know the reasoning > for that one although I can guess), but after that there was no reason > for any more really: Where do assignment operators come? If you put them in with something else you might still need another rule because assignment should be right-associative and most other groups should probably associate to the left. So what would be your preferred table? -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2019-03-09 18:59 -0500 |
| Message-ID | <zrYgE.56434$Ar5.42856@fx37.iad> |
| In reply to | #141849 |
On 3/9/19 4:37 PM, Bart wrote: > > WHY do &, | and ^ each need, not only a separate level from all other > operators, but even separate from each other?! What could possibly be > the advantage? Convention from the domain that created them. Just as in algebra we treat w*x+y*z as (w*x)+(y*z) in Boolean Algebra w&x|y&Z is assumed to mean (w&x)|(y&Z), and xor is in the middle so w&x^y&z does the xor last, and w^x|y^z does the or last. It also comes in handy when building up a word for a device register from the component parts, mask each variable with the field mask it is providing and or them together. C probably could have put & and * at the same level and | and + on the same level (with ^ in between) to meat this need, but there may have been some common usage that made it better to put them where they are as a distinct set of levels.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2019-03-13 09:26 -0700 |
| Message-ID | <86wol2rb9o.fsf@mailhub.linuxsc.com> |
| In reply to | #141858 |
Richard Damon <Richard@Damon-Family.org> writes: > C probably could have put & and * at the same level and | and + on > the same level (with ^ in between) to meat this need, but there > may have been some common usage that made it better to put them > where they are as a distinct set of levels. I thought it was well known that early C didn't have && and ||, so the bitwise operators &, ^, and | were put below the comparison operators so they could be used as logical connectives.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2019-03-13 10:11 -0700 |
| Message-ID | <86sgvqr96y.fsf@mailhub.linuxsc.com> |
| In reply to | #141847 |
Joe Pfeiffer <pfeiffer@cs.nmsu.edu> writes: > By the time you've got 15 levels for 49 operators, any sane > programmer will be putting in some extra parentheses here and > there Sure, if there is no particular structure to the levels and which operators go where. In C there is quite a bit of structure (and at the risk of repeating myself, there are better ways to indicate grouping than using parentheses). > [...], and if I don't remember for sure in my own code It isn't hard to remember if one makes an effort to learn. Fifteen to thiry minutes, tops, and that's a one-time cost. > it probably isn't fair to expect someone coming along later > (possibly even me under a full moon) to have the same intuition. This is a circular pattern. We expect people won't remember, and because they aren't expected to learn and remember they don't learn and remember, and since they don't we have low expectations... and the cycle continues. We should reverse the direction of the cycle.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2019-03-13 17:40 +0000 |
| Message-ID | <mgbiE.394290$Apg.172496@fx36.am4> |
| In reply to | #141938 |
On 13/03/2019 17:11, Tim Rentsch wrote: > Joe Pfeiffer <pfeiffer@cs.nmsu.edu> writes: > >> By the time you've got 15 levels for 49 operators, any sane >> programmer will be putting in some extra parentheses here and >> there > > Sure, if there is no particular structure to the levels and > which operators go where. In C there is quite a bit of > structure (and at the risk of repeating myself, there are > better ways to indicate grouping than using parentheses). > >> [...], and if I don't remember for sure in my own code > > It isn't hard to remember if one makes an effort to learn. > Fifteen to thiry minutes, tops, and that's a one-time cost. > >> it probably isn't fair to expect someone coming along later >> (possibly even me under a full moon) to have the same intuition. > > This is a circular pattern. We expect people won't remember, and > because they aren't expected to learn and remember they don't learn > and remember, and since they don't we have low expectations... > and the cycle continues. We should reverse the direction of the > cycle. > People want to write code so that it is clear to everyone else. Including those more used to other languages which have different precedences. There is NO advantage to writing expressions whose meanings are critically dependent on the relative precedences of &, | and ^. Plus, many operators just have the wrong precedence, so you want to employ them in the most natural manner. And that requires parentheses. Which, as a bonus, makes code more portable.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2019-03-13 15:24 -0700 |
| Message-ID | <lnwol2jtu7.fsf@kst-u.example.com> |
| In reply to | #141939 |
Bart <bc@freeuk.com> writes:
[...]
> People want to write code so that it is clear to everyone else.
> Including those more used to other languages which have different
> precedences.
>
> There is NO advantage to writing expressions whose meanings are
> critically dependent on the relative precedences of &, | and ^.
>
> Plus, many operators just have the wrong precedence, so you want to
> employ them in the most natural manner. And that requires parentheses.
I mostly agree. I suspect we'd differ about how much readers can
reasonably be expected to know, but let's not get into that.
> Which, as a bonus, makes code more portable.
In what sense is it more portable? If I write C code that depends
on all 15 precedence levels, it's likely to be difficult for
human readers to understand it, but every C compiler will parse
it correctly. I've never heard of a C compiler having an operator
precedence bug. It's just too easy to get it right.
If you mean "portable" in the sense that it's easier to translate
to a different language, that's hardly ever worth worrying about.
(And a lot of languages uses the same precedence levels as C.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2019-03-13 23:43 +0000 |
| Message-ID | <YAgiE.62819$Vy.42137@fx39.am4> |
| In reply to | #141944 |
On 13/03/2019 22:24, Keith Thompson wrote: > Bart <bc@freeuk.com> writes: > [...] >> People want to write code so that it is clear to everyone else. >> Including those more used to other languages which have different >> precedences. >> >> There is NO advantage to writing expressions whose meanings are >> critically dependent on the relative precedences of &, | and ^. >> >> Plus, many operators just have the wrong precedence, so you want to >> employ them in the most natural manner. And that requires parentheses. > > I mostly agree. I suspect we'd differ about how much readers can > reasonably be expected to know, but let's not get into that. > >> Which, as a bonus, makes code more portable. > > In what sense is it more portable? If I write C code that depends > on all 15 precedence levels, it's likely to be difficult for > human readers to understand it, but every C compiler will parse > it correctly. I've never heard of a C compiler having an operator > precedence bug. It's just too easy to get it right. > > If you mean "portable" in the sense that it's easier to translate > to a different language, that's hardly ever worth worrying about. You've really never needed to write the same program in another language? (Was it you with that big list of the same program all in different languages or am I thinking of something else? I think fizzbuzz/whatever were all in C.) > (And a lot of languages uses the same precedence levels as C.) A lot do borrow from C, notable ones with links to the that language (derived from it, or people using C to implement theirs, as a target language etc). But there is still a wide enough variation that you don't really want to rely on code relying on such a peculiar and unwieldy set of precedecdes: https://rosettacode.org/wiki/Operator_precedence
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2019-03-13 17:43 -0700 |
| Message-ID | <lnsgvqjnex.fsf@kst-u.example.com> |
| In reply to | #141945 |
Bart <bc@freeuk.com> writes:
> On 13/03/2019 22:24, Keith Thompson wrote:
[...]
>> If you mean "portable" in the sense that it's easier to translate
>> to a different language, that's hardly ever worth worrying about.
>
> You've really never needed to write the same program in another
> language? (Was it you with that big list of the same program all in
> different languages or am I thinking of something else? I think
> fizzbuzz/whatever were all in C.)
I've hardly ever *needed* to. (Yes, I've written FizzBuzz in 100
or so different langauges, but (a) that was purely for fun and
had no practical justification, and (b) most of the programs are
not translations.)
>> (And a lot of languages uses the same precedence levels as C.)
>
> A lot do borrow from C, notable ones with links to the that language
> (derived from it, or people using C to implement theirs, as a target
> language etc).
>
> But there is still a wide enough variation that you don't really want to
> rely on code relying on such a peculiar and unwieldy set of precedecdes:
>
> https://rosettacode.org/wiki/Operator_precedence
There are valid reasons not to rely on too many precedence levels,
and to use parentheses for the benefit of the reader. I just don't
think that the prospect of translating code from C to a different
language is one of them.
When I write C, I write C. I don't expect anyone who doesn't know C to
be able to read and understand my code. But I don't expect a typical C
programmer to know the relative precedences of bitwise and, or, and xor.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2019-03-18 08:53 -0700 |
| Message-ID | <86d0mop4a3.fsf@mailhub.linuxsc.com> |
| In reply to | #141939 |
Bart <bc@freeuk.com> writes: > On 13/03/2019 17:11, Tim Rentsch wrote: > >> Joe Pfeiffer <pfeiffer@cs.nmsu.edu> writes: >> >>> By the time you've got 15 levels for 49 operators, any sane >>> programmer will be putting in some extra parentheses here and >>> there >> >> Sure, if there is no particular structure to the levels and >> which operators go where. In C there is quite a bit of >> structure (and at the risk of repeating myself, there are >> better ways to indicate grouping than using parentheses). >> >>> [...], and if I don't remember for sure in my own code >> >> It isn't hard to remember if one makes an effort to learn. >> Fifteen to thiry minutes, tops, and that's a one-time cost. >> >>> it probably isn't fair to expect someone coming along later >>> (possibly even me under a full moon) to have the same intuition. >> >> This is a circular pattern. We expect people won't remember, and >> because they aren't expected to learn and remember they don't learn >> and remember, and since they don't we have low expectations... >> and the cycle continues. We should reverse the direction of the >> cycle. > > People want to write code so that it is clear to everyone > else. Including those more used to other languages which have > different precedences. [...] Yes, some people have all sorts of idiotic ideas. They are welcome to think what they like, as long as they don't try to force their ideas on people who don't want them.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web