A very great resource!
Essential C (2003) [pdf]
61–70 of 84 posts
Re: Essential C (2003) [pdf]
#62Earlier quoted context omitted.
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/3327379b151445c602ad... https://gist.github.com/cellularmi…
> 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…
> 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.Re: Essential C (2003) [pdf]
#63Earlier quoted context omitted.
Yep so if we're going with style I'm very happy with the functions dashed off there. Nobody will confuse those even when very, very tired (similar effect on the brain to being drunk). There is zero difference in the generated output. Calling those functions tells you exactly what they are and what they do. Vertical space is not an issue at all with 3 line functions. Relying on post-increment? Make sure it's a one lin…
> Make sure it's a one line block that is totally unbraced with only single letter variable names if you do it because otherwise it's just faux-macho C and that's /weak/. I think you're projecting. The point being made was that when you're writing a simple stack (as you often might do in C, since the standard library and the language itself conspire against providing you one) and you don't have the overhead to write…
int abc(int a, int b, int c)
{
}
I can do postincrement. I learned C the macho way. We all still have to read that crap. Now I know better when I'm writing it. I strongly disagree that a = *stack--;
*++stack = b
is better in any way beyond "I'm a macho C guy" than a = pop_int();
push_int(b);
https://en.wikipedia.org/wiki/Duff%27s_deviceIt's fun when you first see it. Sure.
Re: Essential C (2003) [pdf]
#64Earlier quoted context omitted.
> 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…
> 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: *st…
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 :)
Re: Essential C (2003) [pdf]
#65Earlier quoted context omitted.
Yes. ssize_t is signed.
ssize_t should never be used. It's not guaranteed to have a full negative range, only to be able to represent -1. Use ptrdiff_t as a signed size type.
Re: Essential C (2003) [pdf]
#66Earlier quoted context omitted.
> 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: *st…
> 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 :)
Thanks, I just realized I had that wrong :) https://pastebin.com/n7sHzW3p
Re: Essential C (2003) [pdf]
#67Earlier quoted context omitted.
ssize_t should never be used. It's not guaranteed to have a full negative range, only to be able to represent -1. Use ptrdiff_t as a signed size type.
Out of curiosity, do you know of any implementations where ssize_t has that kind of range limitation?
Re: Essential C (2003) [pdf]
#68This guide is short (which is always nice) but not has a couple of flaws in places in the brief skim I gave it. For example: > In particular, if you are designing a function that will be implemented on several different machines, it is a good idea to use typedefs to set up types like Int32 for 32 bit int and Int16 for 16 bit int. Use please > The char constant 'A' is really just a synonym for the ordinary integer val…
Re: Essential C (2003) [pdf]
#69This is a pretty neat guide if you’re cheap and have moral qualms about pirating K&R. Still, I think the best introduction to C remains K&R.
K&R is woefully out of date. Gives you no info on how to do things safely and sanely. And encourages a leet style of programming that results in catastrophic edge case bugs. As you can see in comments above where naive code that iterates backwards through an array fails when the array size is 0. Worse K&R leet style buys you absolutely nothing with a optimizing compiler written in the last 30 years.
Re: Essential C (2003) [pdf]
#70I don't want to learn C but certain types of applications there's really no practical alternative.
I typically see Rust marketed as a better replacement for C. In what cases isn't it a practical replacement?