4 ms·
I don't see how this proves the point. For someone who doesn't have the operator precedence rules memorized, it isn't clear whether the above code means this:
by cellularmitosis 6y ago
I don't see how this proves the point.
For someone who doesn't have the operator precedence rules memorized, it isn't clear whether the above code means this:
x = *stack;
stack--;
or this:
stack--;
x = *stack;
Combining those two operations into one line is a trade-off I will never agree with. And I'm a fan of C myself: https://gist.github.com/cellularmitosis/3327379b151445c602ad1406729fa4b4 https://gist.github.com/cellularmitosis/3327379b151445c602ad... https://gist.github.com/cellularmitosis/d8d4034c82b0ef817913a01138b115bf https://gist.github.com/cellularmitosis/d8d4034c82b0ef817913...
The two-liner is actually the one which is simpler and more direct, as it requires less knowledge of operator precedence rules. The one-liner and two-liner compile to the same number of instructions, so I don't see how either "avoids inconsistent state".
Many expert-level C programmers tend towards one-liners. Here's an example from the original "Red book":
c = ((((i&0x8)==0)^((j&0x8))==))*255;
nooooo don't do it sadpanda.jpg
- saagarjha 6y agoSaving characters on spacing is a terrible thing to do. In fact that jumble is missing a zero on the equality, which is made less evident because all the the characters are not spaced in a way that makes this mistake obvious.
- moonchild 6y ago> The one-liner and two-liner compile to the same number of instructions, so I don't see how either "avoids inconsistent state". It's about performance, or thread safety, or anything like that; it's about having a coherent mental model of the code. A statement should, if possible, represent a single, complete operation. Invariants should not be violated by a statement, with respect to its environment. (This more true for 'push' than 'pop'.) One way of solving that is to bundle the 'push' and 'pop' operations up into functions; someone else in this thread did that. But why bother with the mental overhead of a function call when you could just represent the operation directly? To be sure, there are cases where the abstraction is warranted, but a two~three-line stack operation isn't abstraction, it's just indirection. > For someone who doesn't have the operator precedence rules memorized, it isn't clear whether the above code means [snipped] or [snipped] > The two-liner [...] requires less knowledge of operator precedence rules It's not operator precedence—that's a separate issue; despite having implemented c operator precedence, I don't know all of them by heart—but simply behaviour of pre- and post-increment/decrement operations. It's even mnemonic—when the increment symbol goes before the thing being incremented, the increment happens first; else after—but even if not, it's a fairly basic language feature. Even beyond that, though, it's an idiom. Code is not written in a vacuum. Patterns of pre- and post-increment fall into common use over time and become part of an established lexicon which is not specified anywhere. Natural language works the same way. Nothing wrong with that.
- cellularmitosis 6y ago> It's not operator precedence—that's a separate issue > It's even mnemonic—when the increment symbol goes before the thing being incremented, the increment happens first; else after—but even if not, it's a fairly basic language feature. I think you missed the issue. This is 100% about operator precedence, and has nothing to do with the decrement operator being in front of or behind the variable. This expression: *stack-- means either this: (*stack)-- or this: *(stack--) depending on the operator precedence rules. If this is the layout of memory: ~~~~~~ stack-1: | 52 | stack: | 23 | stack+1: | 19 | ~~~~~~ (* stack)-- evaluates to 22, while *(stack--) evaluates to 52. https://godbolt.org/z/P7Ghfc https://godbolt.org/z/P7Ghfc
- moonchild 6y ago> operator precedence Right, yes. I got confused by your example, because the example is definitely about pre- vs post-increment. My point about idioms still stands, though. > (* stack)-- evaluates to 22, while * (stack--) evaluates to 52. Actually, (* stack)-- evaluates to 23, but changes *stack to 22 :)
- cellularmitosis 6y ago> Actually, (* stack)-- evaluates to 23, but changes *stack to 22 :) Thanks, I just realized I had that wrong :) https://pastebin.com/n7sHzW3p https://pastebin.com/n7sHzW3p