4 ms·
> signed sizes are the way Well, I should probably just say "We're done here." and stop reading the rest of the article. "Signed sizes" are an extremely surpr
by bsder 3y ago
> signed sizes are the way
Well, I should probably just say "We're done here." and stop reading the rest of the article. "Signed sizes" are an extremely surprising abstraction break that are just asking for disaster.
> No const. It serves no practical role in optimization, and I cannot recall an instance where it caught, or would have caught, a mistake.
Should you even be writing C if you haven't hit this? People mix up "in buffers" and "out buffers" all the time. "const" flags this immediately.
> Declare all functions static except for entry points. Again, with everything compiled as a single translation unit there’s no reason to do otherwise.
And when you go trying to debug something and get at a variable or function that you can't find because everything is "static", you'll curse the one who wrote the code.
> Another change has been preferring structure returns instead of out parameters.
Which is a great way to accidentally return a pointer to your stack and open a big ass security hole. Passing in the output buffers makes clear the ownership semantics.
This guy seems like he mostly writes code for 64-bit systems. The coding advice is ... okay, I guess? Maybe? In that domain?
In a 32-bit embedded domain, some of these guidelines are a good way to get youself into a lot of trouble in a real hurry.
- tom_ 3y agoThe no-const people will never be satisfied, so just use const as necessary, propagate as required, and ignore them when they complain. If they take it out, put it back in. They'll always get bored first. I've been doing this for 25 years, and I'm still here. (The static thing might depend on the tooling. I went static-by-default about 15 years ago, around the same time I went full size_t, and I've yet to have a problem with it.)
- thefourthchime 3y agoI’ve been her 30 years. I’ve never found much use for const. I value brief simple code that doesn’t rely on things like const to tell people what’s going on. Codebases have their own conventions and design patterns. If you have that const is a needless formality. Code should be being simple and clean first, constantly stating things that are obvious 90% of the time isn’t that.
- ripe 3y ago> signed sizes are an extremely surprising abstraction break that are just asking for disaster. Bjarne Stroustrup wrote a detailed memo advocating for signed sizes: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1428r0.pdf https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p14...
- josephg 3y agoEh, I hard disagree with this memo. He's either dismissing or unaware of the biggest advantage of unsigned types, namely they make invalid state unrepresentible. And essentially all of his criticism of unsigned types is really criticism of the sloppy way old C and C++ compilers let you mix signed and unsigned numbers in math operations. Modern C/C++ compilers can and will warn you (quite aggressively) if you mix signed and unsigned numbers without thinking about it. A lot of the examples also seem weird. Eg, he gives a negative example of a function: unsigned area(unsigned x, unsigned y) { return x * y; } In this, he complains that you can still write buggy code: area(height1-height2, length1-length2); He's right - that is potentially buggy, But, that code would be buggy whether the area function took signed or unsigned numbers as input. However, the signed version of this function is still worse imo because it could hide the logic bug for longer. If the area function should always return a positive number, I'd much rather that invalid input results in an area number like 4294967250 than a small negative number. Similarly, accidentally passing a negative index to a vec is much more dangerous with signed indexes because v[-2] will probably quietly work (but corrupt memory). However, v[4294967294] will segfault on the problematic line of code. That'll be much easier to find & debug. And a lot of the examples he gives, you'd get nice clear compiler warnings in most modern compilers if you use unsigned integers. You won't get any warnings with signed integers. Your program will just misbehave. And thats much worse. I'd rather an easy to find bug than a hard to find bug any day of the week.
- uecker 3y agoThe advantage of using signed types is that you can reliably find overflow bugs using UBSan and protect against exploiting such errors by trapping at run time. For unsigned types, wrap-around bugs are much harder to find and your program will silently misbehave.