24 ms·
This always seemed to me like a flaw in the standard C library - there was no good/built-in true array type that held the array size and was incorporated into s
by ryanianian 9y ago
This always seemed to me like a flaw in the standard C library - there was no good/built-in true array type that held the array size and was incorporated into stdlib functions (especially string functions).
I haven't done C in a while, but I lost track of how many times I had to create `struct array` to ensure I always passed the `*` with its length - it always felt like I was doing something wrong. Maybe I was. But the prevalence of overflow errors that could be fixed by size-checking makes me think there's something missing in the language or standard-libraries that could have helped a lot for many years.
- milesvp 9y agoFrom what I understand, much of what seems missing, and possibly broken in C comes primarily from the vast number of platforms it supports. It's actually surprisingly hard to build a language that supports both x86, and 4bit microcontrollers, and everything in between. That extra couple of bytes attached to an array with it's size is huge for embedded systems.
- ryanianian 9y agoYa that was my intuition - C's always giving you enough rope to hang yourself and everyone around you. But I also wonder how many arbitrary-length strings are handled by embedded systems. Maybe don't define an `array` type with length, but maybe one just for `char*` (string) that included size and all the `str` functions used it, that would solve a huge number of exploits.
- pjmlp 9y agoA PC running MS-DOS 3.3 (512KB) would be an embedded systems, micro-controller for today's standards. I never had an issue with a Turbo Pascal application size due to string/arrays.
- earenndil 9y agoBut why not add such capabilities in the standard library and not use them in code running on 4-bit microcontrollers? That's sort of similar to what c11 is doing with its 'safe' variants on stdlib string functions.
- taeric 9y agoIsn't the problem simply that the pointer to the first element and the pointer to the array are the same address? And that this is a key reason you can actually alias one array into many sub arrays at runtime? That is you have an allocator that views it as a free list of tracked size. You have the exact same memory loaned out to other parts of the system for various other uses. Some of which are other arrays.
- ryanianian 9y agoKinda? I think the problem is you have to keep the array and its length together and always remember to call the appropriate array functions with the appropriate lengths. This isn't made easier by the fact that many string/array methods have variants that expect (and only respect) null-terminated strings (i.e. where you actually don't keep a length and rely on a terminal null-byte). The language could have decided that the first byte is the length and used that convention in string/array functions, but instead we have the convention you point out that the array is really referenced only by its first element and array-indexes are just sleight-of-hand for pointer addition.
- taeric 9y agoI get that. I'm saying the reason you can't universally have an array type with the length attached as a struct is because of aliasing. Precisely because you couldn't have two arrays use the same values in memory. Otherwise, the allocator couldn't keep track of the memory with an array like reference. Consider, in c, you can have an array and pass it in two parts to two different functions. Each getting passed a different length. You couldn't do that if the array had it's length as an intrinsic property. You could have split the function space into operations that work on parts of an array and those that work on a full array. So, not claiming this as a full blocker. And I don't know which is ultimately better. We know where we are. Seems easy to speculate we could have avoided a lot of errors. I just don't know if I agree it is guaranteed.
- ryanianian 9y agoOh I see what you're saying - you can have `char * x = "foo"` and `char * y = &x[1]` (or something - I forget the exact syntax). That's a very good point! So to be regular you'd need a whole host of other commands to deal with substrings. I guess that makes the point that what they chose is probably correct, but it's still quite disappointing that the stdlib doesn't help more to prevent you from shooting yourself in the foot with pretty common operations and data-types.