11 ms·
I'll bet he can give you an array_read() function that does what you ask. I know I could.
by civility 10y ago
I'll bet he can give you an array_read() function that does what you ask. I know I could.
- deleted 10y ago[deleted]
- lacampbell 10y agoThe fact that it doesn't occur to people to build safe abstractions in C to deal with things like buffer overflows still shocks me. C is fairly low level by todays standards. You 100% have to build abstractions using the standard library and then use those abstractions, rather than just using standard library functions everywhere. This isn't an argument against safer languages, or higher level languages, or languages with built in bounds checking or anything else. This is more an argument against programming in a "close to the metal" language like C so thoughtlessly that buffer overflows are actually a serious issue. Maybe you just need a pedantic mind. When first learning C, as soon as I figured out that writing "char buffer[BUFFER_LEN];" could cause your program to crash, I immediately set out to write a safe dynamic array implementation I could push chars onto it and I didn't have to worry. And I am by no means an expert C programmer.
- munin 10y agoIs this abstraction zero-cost? What's the overhead? Can you give me a similar set of primitives to manipulate memory in a temporally safe manner as well? What is the cost of that abstraction? How does it compare to a runtime's GC?
- civility 10y ago> Is this abstraction zero-cost? What's the overhead? It will cost a single correctly predicted branch, which is effectively free on modern architectures. Any "safe" language will have to make this conditional branch too (Rust's File::read method will check the size of the slice).
- Ericson2314 10y agoNope. Iterators in Rust can be used to safely avoid bounds checking in ways that would be impossible to enforce in C.
- civility 10y agoWe were talking about reading into a bounds checked array. Rust does not user iterators for this.
- Ericson2314 10y agoI cannot trust people to correctly iterate in order through an array in C, and thus must resort to bounds checking them.
- civility 10y agoThis still has nothing to do with what I've said. Take care.
- lacampbell 10y agoI never made the argument that you shouldn't use a safe GC'd language. I merely made the argument (now flagged for whatever reason) that buffer overflows are an easily solvable issue in C, and if you are having issues with them you really need up your game and learn to create abstractions. As for the cost of the abstraction of bound checked arrays of arbitrary length, I can't imagine it being any slower than rust. I could be wrong. If you'd care to provide an example program in whatever language you are advocating, I can give you an implementation in C using a bounds checked array ADT, and we can compare notes.
- jdmichal 10y agoObviously, if you have to check an index length you're going to be doing a branch. However, because the index checks are intrinsic to the Rust compiler, it can remove them when it proves the code is safe. So, for instance, an iteration loop over an array won't have any index checks in the generated machine code.
- dbaupp 10y agoThere's two problems with this statement: - index checks aren't intrinsic for all cases where it is done, e.g. https://github.com/rust-lang/rust/blob/8f62c2920077eb5cb81323142fc5dbe6ae8813c0/src/libcore/slice.rs#L610-L618 https://github.com/rust-lang/rust/blob/8f62c2920077eb5cb8132... - being intrinsic is absolutely not required for the checks to be removed. Bounds checks are just a normal branch with a fairly straight-forward condition, and the always-true nature of those conditions is inferred in the same way for both the built-in indexing and non-built-in indexing. This is true in languages other than Rust. An iterator is designed to just not do any indexing at all (neither using the built-in [] operator or one of the functions that implements manual bounds checks), because it instead just manually (unsafely) walks a pointer along the array.
- jdmichal 10y ago> An iterator is designed to just not do any indexing at all (neither using the built-in [] operator or one of the functions that implements manual bounds checks), because it instead just manually (unsafely) walks a pointer along the array. It obviously still has to bound-check that it's not about to walk right out of the array. If you want to call this something other than a "bound-check", I think that's being overly pedantic.
- civility 10y agoCompletely agree. The same is true at a slightly higher level in C++. All of the "dangling reference" problems can be avoided by using a value-based collection library and not creating references. Then upgrade to a unique or shared pointer when copying values is too expensive.
- kbenson 10y agoBecause the fact that you have to write that secure abstraction means the majority of people won't do it, and even if they do, the vast amounts of code that you'll interface with in C that doesn't expect it and will happily index out of bounds if you call it incorrectly means you'll always be fighting an uphill battle. I imagine many people do what you did and write abstractions, and then the more they end up dealing with external libraries, the more they realize they aren't buying themselves as much security as they think they are, and it isn't just a one-time up-front cost, any time they need to interface with code that doesn't use their implementation, they may have to make sure everything is sane afterwards. > I could push chars onto it and I didn't have to worry And how did you implement this? Are you stitching together chunks of memory, or are you reallocating and copying? If you are reallocating and copying, what do you do when you have a point to the old address space that still exists? Now instead of manually updating memory and knowing you have to take care of pointers, your dynamic implementation might change stuff from underneath you without you noticing.
- lacampbell 10y agoBecause the fact that you have to write that secure abstraction means the majority of people won't do it What's your point? My only argument has been that it's very easy and achievable to avoid buffer overruns in C. The fact that you assert most people won't do it is completely orthogonal to that. And how did you implement this? Are you stitching together chunks of memory, or are you reallocating and copying? If you are reallocating and copying, what do you do when you have a point to the old address space that still exists? Now instead of manually updating memory and knowing you have to take care of pointers, your dynamic implementation might change stuff from underneath you without you noticing. I use the standard library function realloc. The dynamic array is written in a fairly standard way, IE, I am not returning pointers to the allocated memory of the internal array. I access values inside the dynamic array by value (eg they are copied), not as a raw pointer to a slice of memory that could be realloc'd. It would never even occur to me to do that, so your example seems strange and far fetched.
- yazaddaruvala 10y agoThis is the age old debate: X is possible! X is not probable! Its not a winnable debate. You are both different kinds of people. The prior an idealist, the latter a pragmatist. Both philosophies are good, both are correct. Before both of you continue your debate, you should both recognize this difference.