Earlier quoted context omitted.
> Can anybody make a strong case to me as to why are buffer overflows considered an issue in C when it takes like 10 minutes to write and test an array implementation that prevents that from ever happening? The CVE database. Just because you 'can' write such an array implementation doesn't mean you will, doesn't mean your third party libs will, doesn't mean any of your legacy code uses it, and certainly doesn't mean…
Honestly, we need a few AI coders to replace most of the developers in the world and then this won't be an issue. Bounds checking arrays and calloc instead of malloc isn't rocket science. It's a simple formula. The problem isn't the language it's the developers.
Getting Past C
231–240 of 504 posts
Re: Getting Past C
#232Earlier quoted context omitted.
If you're relying on any random third-party Rust crates you haven't audited yourself, don't you lose the safety guarantee? A given crate might turn out to have implemented operations on some data-structure using unsafe blocks, and then to have failed to mark its own API functions as unsafe in turn (like the Rust stdlib does, but without the "extensive manual auditing" that the stdlib gets). AFAIK, cargo doesn't have…
There's a lot more unsafe code in Rust crates than there should be. That's a fixable problem. Some stuff from the early days predates the optimizer getting smart enough that unsafe code isn't needed. I wrote on this a few days ago in a Rust topic.
Auditing FFI is a whole other challenge, however :(
Re: Getting Past C
#233Earlier quoted context omitted.
A properly-designed Rust API will not allow code without error handling to compile, so 1) should be much less relevant in Rust. 2) I can't remember if a panic in Rust calls destructors, which would clean up that memory. Can someone answer that please? 3) is only relevant in FFI scenarios in Rust, and everywhere else is irrelevant because Rust does not require the use of such footguns for basic string manipulation.
A panic _may_ call destructors, but it cannot be relied upon. For example, aborting is a perfectly reasonable panic implementation, and your destructors won't get called. If you have unwinding panics, they will call destructors though.
More exotic panics (like an infinite loop panic on a microcontroller) would not call destructors though.
Most panic impls will either unwind (which will call destructors) or abort/exit, so this is usually not a problem.
Re: Getting Past C
#234Earlier quoted context omitted.
Honestly, we need a few AI coders to replace most of the developers in the world and then this won't be an issue. Bounds checking arrays and calloc instead of malloc isn't rocket science. It's a simple formula. The problem isn't the language it's the developers.
Considering that a change in language completely solves the problem, it's hard to get on board with your thesis.
New languages here and there every day. Replace this replace that. When, in the end everyone is simply reinventing the "wheel" over-and-over.
All these languages end up as assembly.
Re: Getting Past C
#235Earlier quoted context omitted.
A panic _may_ call destructors, but it cannot be relied upon. For example, aborting is a perfectly reasonable panic implementation, and your destructors won't get called. If you have unwinding panics, they will call destructors though.
I mean, in case of an abort the kernel generally cleans things up for you :) Not all things, but most things. More exotic panics (like an infinite loop panic on a microcontroller) would not call destructors though. Most panic impls will either unwind (which will call destructors) or abort/exit, so this is usually not a problem.
Re: Getting Past C
#236Earlier quoted context omitted.
No, you just allocate enough space to store an extra int at the start for the length, and return a typed pointer to the actual data. Then you need an accessor that checks bounds, if you want safe access. Both of these problems are solved by simple macros.
Arrays and pointers in C already have that int. That's why sizeof() works. The issue is an extra if statement on every single array and pointer access.
Re: Getting Past C
#237Earlier quoted context omitted.
It's crazy that it's not solved above the language level, if people really want zero cost abstraction and architecture friendliness at least tooling should check buffer logic and flag the binary in case Warnings have been ignored.
>if people really want zero cost abstraction That one "if" is (by definition) not zero-cost.
> C++ implementations obey the zero-overhead principle: What you don’t use, you don’t pay for. And further: What you do use, you couldn’t hand code any better.
Two points:
What you don't use, you don't pay for: if you don't use array indexing, you won't get a bounds check. In addition, you can call an access method without a bounds check as well, so it truly is only if you use the checked version.
What you do use, you couldn't hand-code any better: that bounds check is written the exact same way you'd write it in C.
Therefore, this is a zero-cost abstraction.
Re: Getting Past C
#238I wish more mention of D would happen. It is compatible with C and C++ libraries and features GC without sacrificing the good things of C and C++. I always loved the idea of Rust and Go but they are nowhere near C or C++ where it matters to me. D fits the bill, otherwise I just use Python. I like being able to design software in my own way as opposed to being told how to do it.
The truth is the Rust leadership did the hard work of building a community around the language, making high-quality tutorials and introductions to the language all before it stabilized for 1.0. Many developers claim to dislike "marketing", but Rust did its marketing/evangelism and D didn't. From a purely technical standpoint, Rust's borrow checker is able to catch data races, while D has no such functionality (unless…
Re: Getting Past C
#239Earlier quoted context omitted.
> I use the standard library function realloc. Realloc may automatically copy the range to a new memory block if the old block cannot be expanded, and when that happens the old range is freed. Any other pointers you had to items in that original array may become invalid every time realloc is called, and if it's automated by your dynamic array code, that could conceivably be any time you push an item onto that array.…
I am still perplexed why you think by using a dynamic array of chars for a buffer, it somehow involves me storing copies of the malloc'd memory anywhere . You can simply access data by copying it: https://ideone.com/OObuAt Note that it still prints 42 despite the allocated memory being freed. Line 7 copies the data at a specified index into x - x has no references to the malloc'd memory.
Because I'm not limiting the case to just core types. You don't only ever need arrays of chars, ints, doubles, floats, etc. Sometimes you need arrays of structs.
As a simplistic example, perhaps you have a large array of structs, and you want to iterate through them and add all the items that match your criteria to a shorter array of matches, which will be pointers to the real data. Adding a single item to the original array could cause realloc to invalidate every pointer in the array of matches. Of course there are ways around this, but someone starting work on the code might not necessarily expect that adding an item to an array would cause pointers elsewhere in the code to become invalid, unless they look at the implementation of your array code to understand what it's doing.
Re: Getting Past C
#240Earlier quoted context omitted.
Arrays and pointers in C already have that int. That's why sizeof() works. The issue is an extra if statement on every single array and pointer access.
They don't, sizeof is a compile-time constant. On a pointer, sizeof() just reports the size of the pointer itself (i.e. 4 or 8 bytes on most modern platforms), not the size of the data to which it points (and sizeof(*pointer) reports the size of the type to which pointer points, it doesn't know anything about how many values of that type are stored). For an array, the length is known statically (i.e. it's in the type…
> A beginner will often try something along the lines of size = sizeof( myarray ) (which is incorrect).