7 ms·
C’s biggest sins (also inherited by C++): - unspecified default type sizes. Should have had i8, u16, i32, u64, f32, f64 from the beginning. - aliasing pointer
by smallstepforman 8mo ago
C’s biggest sins (also inherited by C++):
- unspecified default type sizes. Should have had i8, u16, i32, u64, f32, f64 from the beginning.
- aliasing pointers being restricted by default (ie an alias keyword should have been added). Performance matters. All these benchmarks which show something beating C or C++ are mostly due to dealing with aliasing pointers. C++26 still doesnt have standardised restrict keyword.
There are more but I understand the logic/usability/history behind them. The above points should have been addressed in the 80’s.
- abcd_f 8mo agoArrays decaying to pointers is probably the biggest non-platform specific design oversight. As you said, it's easy to see where it came from, but it should've been fixed long ago.
- 1718627440 8mo ago> but it should've been fixed long ago. Is 27 years for you not long ago enough? That's more than a generation away and closer to the invention of the language than today.
- pjmlp 8mo agoWorse than that, lets remember that WG14 rejected Dennis Ritchie proposal for fat pointers, and the C authors decided it was more fun to keep their own way with other programming languages than try to improve C from WG14. https://www.nokia.com/bell-labs/about/dennis-m-ritchie/vararray.pdf https://www.nokia.com/bell-labs/about/dennis-m-ritchie/varar...
- abcd_f 8mo agoI read through the RFC and I think it's fair it was rejected, because this was ultimately a half-measure, with severe usability restrictions. Fat pointers are clearly a way to deal with arrays (and also get "slices" and non-zero terminated strings for free!), but it's just not possible to retrofit them into the language without breaking existing code.
- 1718627440 8mo agoI think we are talking past each other. I was saying that passing an array with a size to a function was standardized 27 years ago, asking if that isn't long enough. Sure, some may don't like how it was standardized, but it is possible. Beside the sibling comment about this specific proposal, I also think that fat pointers don't belong in the C standard. There is nothing in the C standard that says that pointers on the abstract C machine don't come with the allocated size, in fact the behaviour is described as if they do. Pointers are essentially scoped by allocation. All that is missing is code for that in a C implementation, the language allows that just fine.
- krior 8mo agoNot the error "handling"? The array implementation? The weak type system? The barebones-macro-system? The nearly unuseable standard-library? The standard itself, a 750-page-tome you have to memorize, lest C is allowed to erase your hard drive? C is sin incarnated.
- 1718627440 8mo agoIn my opinion error handling in C is great. It forces you to actually think about it, deal with them as close as possible and makes you write it in a forward compatible way. Much better than exceptions were you never no what one might throw in another version. > The barebones-macro-system? The CPP is a different language and designed that way so you can use another language that suits you better, most don't do that, because the default is fine.
- 1718627440 8mo ago> - unspecified default type sizes. Should have had i8, u16, i32, u64, f32, f64 from the beginning. I strongly disagree. The programmer should rather prescribe intent and shouldn't constantly think about what size this should exactly have. Does this variable represent the size of an object, an address, a difference or just a random positive integer? Then use size_t, uintptr_t, ptrdiff_t and unsigned int respectively. Why should I care what exact sizes these are? I hate that modern (system) languages completely throw away that concept. "I want a unsigned integer" "oh, you mean u32" "No! I really mean an unsigned integer." Also when I do want e.g. 32 bit available, there is no reason, I need to use a suboptimal 32 bit wrapping behaviour when I don't need it. The correct type to use for computation for that would be uint32_fast_t and the implementation chooses what makes sense to use for this.
- danhau 8mo agoHow will you know if your integer type is adequate for the problem at hand, if you don‘t know its size? Choosing the right type is a function of signedness, upper/lower bound (number of things), and sometimes alignment. These are fundamental properties of the problem domain. Guesstimating is simply not doing the required work.
- donkeybeer 8mo agoThe idea is mostly that we shouldn't worry. The user of the lib on an arduino will feed it arduino sized problems and the amd64 user will likewise larger problems. Again I think just think of the transition from 32 to 64 bit. Most ranges are "input"/"user " dependent and it would have been needlessly messy to have to even with automatic conversion help rewrite say every i32 to i64 or which ones to convert.
- direwolf20 8mo agoThat's size_t. What about counting milliseconds?
- 8mo ago
- donkeybeer 8mo agoWhich systems in the 70s or even 90s would have had good hardware support for all these lengths? I think overall perhaps its better that the thing named int works on both the arduino and my amd64 otherwise we might needlessly need to rename all types for each platform to fit the most natural type lengths there. Imagine the 32 bit to 64 bit transition under those conditions.
- danhau 8mo agoAll of them, through software implementation, as assembly programmers have done since forever. You simply choose the integer type that your problem or task requires. If the hardware genuinely can‘t cope with it (performance), you reevaluate your requirements, define new constraints and choose new types. This is basic requirements engineering, which C only made more convoluted.
- donkeybeer 8mo agoI think overall it's better to provide "natural" default types but also have had something like stdint.h. But then again mandatong even a stdint.h that early would have made writing implementations quite difficult. I think it was and is an alright tradeoff.
- direwolf20 8mo agoBut it doesn't work. You use an int to hold milliseconds, it works on your machine, and when compiled for Arduino (16–bit int) it wraps around every minute.
- donkeybeer 8mo agoWe have stdint in modern systems so when the length of a type is a hard requirement then we can use whatever type or software emulate a larger word. Otherwise I think keeping the default types for things like eg number of elements seems alright.
- direwolf20 8mo ago