7 ms·
One thing that C should have is an automatic string type (more like a byte[] than a String) that knows its own size. A huge amount of programming bugs arise fro
by epx 9y ago
One thing that C should have is an automatic string type (more like a byte[] than a String) that knows its own size. A huge amount of programming bugs arise from the lack of strings, and I can't see the reason why they could not be supported even in small systems. Delphi/Object Pascal had something like 3 or 5 function pointers that support the string type (create, free, resize, things like that).
- rs86 9y agoArrays are actually pointers to the first element... They get translated to pointer arithmetic: adding an offset to the first element. You can easily create a struct with one field for the size and another with the pointer to the first character
- kqr 9y agoSemantically, arrays are different from pointers. They do, however, degrade into pointers in many situations, which causes that misunderstanding.
- petecox 9y agoA language with an array type, e.g. Java, distinguishes between a 'null' array reference and an array of zero length. which could substitute in languages that don't have an option type; SOME([]) vs NONE But a plain *char in C makes no such distinction.
- charliesome 9y agoThere is a difference. An empty string in C is a non-null char* pointer pointing to a zero byte. Passing a null pointer to strlen will crash.
- esrauch 9y agoA zero-length array can't ever be a valid cstring at all since they have to be null terminated. I don't think that is actually relevant to the claim you are replying to, which is about arrays and pointers and not strings.
- admax88q 9y agoThe funny thing is that the memory allocator typically knows the size of the string. You call free(foo) not free(foo, 12) or free(foo, strlen(foo)); But there's no standard way to ask for this size. Why doesn't strcpy just check with the allocator about how much memory is available and refuse to write past that.
- rootbear 9y agoNot every string is allocated from the heap. There is no way to know if a string passed to a function, for example, came from the heap or not.
- admax88q 9y agoThat's true, although there's no reason the stack allocator couldn't record this information somewhere as well. And if the memory allocator doesn't know about the string then you could just revert to the existing behaviour so you're no worse off.
- chrisseaton 9y agoThere's more ways to allocate memory than the heap and stack.
- stochastic_monk 9y agoWhat are you referring to? sbrk? mmap? I typically use either the heap or the stack myself.
- timClicks 9y agoStatic memory is at the bottom of the address space, below the heap. But that would really only be relevant in the case of string literals unless I'm mistaken.
- 9y ago
- peterevans 9y agoThe main issue is that there's already a lot of standard library support for classical strings--things that are just a pointer to a chunk of bytes, and no more; rewriting those functions would be destructive. The C standards group could add to the standard library, I suppose, but generally they are a bit reticent to do so. It is not the case that C has a benevolent dictator with a particular vision and drive for the language. It's more like a small group of people who don't want to mess things up. And so not much changes. This is neither good nor bad to me--it simply is; and anyway, these days, you have quite a few options that do offer automatic strings that can also compile into machine code (Go, Rust I suppose?).
- Gibbon1 9y ago> rewriting those functions would be destructive Getting rid of standard string functions would be the best thing to happen to the c language in the last 25 years. There are two types of c programs. Those that scrupulously avoid standard string functions and brittle programs shot through with security holes.
- kbenson 9y agoAt the point when you have to convert between string types and can no longer easily use much of libc without conversions, why not just use a different language that's already gone much farther in the name of safety, usability or other features? In other words, if your pseudo-c candidate already suffers from most the interop problems that Rust, D, Nim and Go do, why not just use one of those and at least reap the other benefits they provide?
- watersb 9y agoAnything to help legacy C code base is welcome. Hard part is knowing whether touching decades-old, tested code is worth the risk.
- peterevans 9y agoI mean, I guess it's the best thing if you want to wreak havoc and chaos? Which, perhaps, you do! Your suggested dichotomy is, of course, a little bit false. But I'm sure you knew that when you wrote it down. It's entirely possible to write secure programs in C, even with standard functions. Writing your own code does not somehow confer a level of security-consciousness that you lacked when sticking to strings.h. (It does give you a wonderful opportunity to write your own security holes that no one has discovered yet!) I mentioned this somewhere else, but we're in a pretty good place right now with languages; we finally have really solid alternatives to C that can compile to machine code, in both Go and Rust.
- userbinator 9y agoI've used something similar --- a null-terminated string, with a length prefix at a negative offset. Resizeable ones have an "allocated size" field before that one. This makes for strings that are both easy to manipulate and compatible with existing functions that only read a regular C string.
- zzzcpan 9y agoBasically this: https://github.com/antirez/sds https://github.com/antirez/sds
- userbinator 9y agoGood to see I'm not the only one who thought of that idea, although my implementation has a different order of the fields (and IMHO better, since it allows for statically allocated strings with only a length field --- a sort of subclassing.)
- timClicks 9y agoSo in a sense implementing Pascal strings in C?
- flukus 9y agoYes. But also "abusing" C's permissiveness with pointers to get pascal strings that interop with standard functions. It get's passed around as a pointer to a char array but the length function would return the value at that pointer - sizeof(size_T). In most languages this wouldn't be possible.
- nikanj 9y agoSo, BSTRs? They’re common in old-timey COM apis
- watersb 9y agoBSTR size field is at positive offset, IIRC.
- munin 9y agoWe have tried to do this by adding a "null terminated string" type. Start in section 2.4 of the specification (https://github.com/Microsoft/checkedc/releases/download/v0.7-final/checkedc-v0.7.pdf https://github.com/Microsoft/checkedc/releases/download/v0.7...).
- _sdegutis 9y agoThe point is to keep C small and flexible. It supports whatever kind of string implementation needed by the present environment, platform and algorithm. That said, several “high-level” string libraries for C exist that make it safer, more efficient, etc. Some of them are even pretty clever, allocating extra space right before the C pointer to a null terminated C string that it gives you, so it can do its own bookkeeping.
- isaachier 9y agoI think Fortran uses a number followed by a byte array to represent strings. This is the big argument with C which used null terminators. In retrospect, maybe Fortran was right after all. Edit: Actually seems I confused Fortran and Pascal. Also, Fortran uses an internal length variable.
- Gibbon1 9y agoI think the failure of C to support a built in array type is exactly like Steve Jobs refusing to give up one button mice. The reasons aren't technical or based on merit but on stubborn ideology.
- andrewmcwatters 9y agoThat type of thinking led to C++, a language whose contributors do not know how to stop adding features.