nullplan wrote:
eekee wrote:
These were traditionally considered to be slow.
"Slow" is relative. But yes, this idea that it is slow is why in C++ std::vector doesn't do bounds checking in operator[], and why the recalcitrant old farts in the standards committee nixed bounds checking from Microsoft's std::span proposal, so that the standard version again doesn't have it.
In reality, a bounds check is going to be at most a subtract, compare, and conditional branch. That is slower than branchless code, but faster than, say, a cache miss. And way faster than a system call. I can see applications where it matters, but for the vast majority of them it doesn't.
Thanks for the reminder; that isn't much overhead at all. Still, I can see a reason for not doing it in a tight loop on a big array. `foreach itm in items` seems like a good construct for that case, but there are some things which are easier to code with an indexed loop. Oh, I suppose this is what those `map` and `zip` functions were for in that Lisp tutorial I took years ago. Map applied a function to each element of a list. Zip applied a function to elements from multiple lists. (I might have got the names wrong.)
Octocontrabass wrote:
rdos wrote:
The most common problems causing this is pointers that are misused (casted to an incorrect type),
Pointer casts are bypassing the language's type checking, they're always going to be dangerous no matter which language you're using. Even C has pointer type checks! The solution is to make pointer casts unnecessary by designing better APIs.
I thought for a while that CAL-4700 (to give the specific version of the plain English compiler I'm using and its language) was quite type safe, but there was a time I had to code a cast from buffer to string type. The types are the same; "a buffer is a string" is right there in the code, but the compiler refuses to pass buffers to string routines. I had to code up a cast myself, which on the one hand worries me more than using a built-in cast, but on the other hand isn't something I'm going to do lightly. Here's the code, and yes I know it's bad to use a literal non-ASCII character like that; I was going to change it after I sorted the other issues. Comments are italicized. "A string" is actually 2 pointers; the string is stored elsewhere in malloc'd memory.
To decide if a buffer is png-format:
\If the buffer starts with "‰PNG", say yes. \ compiler doesn't know a buffer is a string, even though it's been told.
\Slap a substring on the buffer. If the substring starts with "‰PNG", say yes. \ compiler doesn't know a *substring* is a string, even though it's been told.Put the buffer's first into a string's first.
Put the buffer's length into the string's last.
If the string starts with "‰PNG", say yes.
Say no.
I should email the author and see what they say, but I keep thinking I'll do it when I'm feeling less confused. It'll never happen until I have some RL support, I think. I've been thinking, the last time I coded something I'm proud of, I had help with life stuff. As a result of that help, I was healthier.
Octocontrabass wrote:
rdos wrote:
pointers that are freed but still used,
Rust prevents this.
rdos wrote:
and using completely incorrect pointers loaded from memory trash.
Any language that forces memory initialization before use prevents this.
Good practice using CAL-4700 prevents these, but if I have to break good practice as in the code I pasted...
I worry!