11 ms·
I can't see how incrementally improving the approach of the C standard library is the right design decision here. They need to just include a standard, well des
by antirez 7y ago
I can't see how incrementally improving the approach of the C standard library is the right design decision here. They need to just include a standard, well designed dynamic strings library to C, that stores the length alongside with the (binary safe) string itself, and that's all. Every serious C program uses it, null terminated strings are a joke. However because of this huge background with null terminated strings in C, such library should make sure to always automatically terminate strings with a null term, so that people can trivially print them, call strlen() against them and so forth when needed and when there is no binary data inside.
- mehrdadn 7y agoSounds an awful lot like C should just become C++ already...
- antirez 7y agoNo need, C dynamic string libraries totally look like plain C.
- doboyy 7y agoNo doubt, but they are all non standard which is irritating for people who expect that out of the box.
- flohofwoe 7y agostd::string has its own share of problems, but at least it's useful for C programmers as a warning on how not to implement a string library (for instance: a string shouldn't be important enough to give it its own allocation, it shouldn't be mutable by default, there should be string manipulation functions which are actually useful in real world situations instead of being an academic exercise, and so on...).
- saagarjha 7y agoI’m not sure I understand your first and third complaints and the second one is why const exists.
- astrobe_ 7y agoWhat they really want is to find a way to convince their boss to rewrite everything in Go.
- doboyy 7y agoThis is bait but whatever. Keeping some properties of C is very hard if you go this route. It also seems you'll end up playing lanaguage design whack-a-mole problems which manifests its self in C++ and co.
- segfaultbuserr 7y agoHere's a stupid but somewhat relevant case: Recently, I saw a surprisingly insidious variation of the "FizzBuzz" question in C. Like the usual FizzBuzz, but with a twist: You are required to return your answer as "char (star)" with a separator "\n", the memory should be allocated dynamically, assuming the user calls free(). A naive implementation that strcat() / realloc() the string and repeats it a thousand times, a better solution is to overestimate the required memory and malloc(). Adding a different constraint can make the question quickly become effectively "reimplement std::vector in C", and in real applications, something like this occurs daily, all C programmers have their own standard library, so I guess C++ is at least useful for its standard library...
- ben7799 7y agoHow is this a stupid interview question? There are a lot of positions this would be a great indicator of whether or not the candidate could do the job. If low level programming is involved the candidate better be able to handle this. Just cause you don't have to solve this problem every doesn't mean you're not going to need those skills for systems programming, writing drivers, embedded programming, etc.. I suspect this would have an extremely high weed out rate actually. A very large % of so called software engineers would fail this, certainly anyone who did all their learning in a dynamic language with automatic garbage collection and who had not branched out into lower level programming. It's a dumb question if the job position is for a Javascript UI dev of course.. it's not a good question for all positions. I would also say it's a travesty for any school to award anyone a bachelor's degree in computer science to someone who would fail this question. I've interviewed a large # of candidates with master's degrees who would fail this. Thankfully most of those candidates didn't have a bachelors in computer science + a masters in computer science from a highly ranked US institution. Also someone who groks this problem and solves it is way less likely to write memory leaks into code in a garbage collected language.
- segfaultbuserr 7y agoI didn't really meant to criticize the question itself, just use it to make a point on C's stdlib that the OP was talking about.
- nicoburns 7y agoAgreed. I feel like such a library probably also ought to support slices/arrays in the same style. I get that the C community is conservative, but this seems like a pretty non-invasive change that would make C code much less bug prone, and faster to boot!
- antirez 7y agoYep, ISO C should get an optional library, that embedded systems may want to skip, offering things like: dynamic strings, linked lists with iterator, an ordered dictionary data structure with iterator (API will be like a hash table basically), a PRNG that is not a joke. With just that it will feel like programming in a different language.
- jcranmer 7y agoISO C already mandates that most of its library is optional for "freestanding" implementations. (float.h, iso646.h, limits.h, stdalign.h, stdarg.h, stdbool.h, stddef.h, stdint.h, and stdnoreturn.h are the only headers required even for freestanding implementations).
- derefr 7y agoWhat if we just created a standard [and related working group] that exists "downstream" of ISO C, where there is one release of the "C-with-batteries" per ISO C release (e.g. Cwb11 would descend from C11; Cwb18 from C18; etc.) that just adds these sort of "obvious" libc parts (or libcwb parts, I guess) that the C standards committees don't seem to want to bring into the "base" libc, without changing C itself otherwise? Then compilers wanting to support the "with-batteries" superset standard could just allow their flag that looks like "-std=c90" to be extended like "-std=c90+batteries".
- dooglius 7y agoWhy would you need compiler support? It's not like C doesn't already support libraries.
- billziss 7y agoWhile I often implement strings along the lines you suggest I disagree that this feature belongs in the standard library. For one thing how big (sizeof) should the length prefix be? 16-bits? 32-bits? 64-bits? The beauty of the C string is that it is minimal and straightforward: if you have a pointer to it, you know where it ends. And it works with pretty much any OS out there. (My personal variant of dynamic strings are refcounted, length prefixed and nul-terminated with the pointer pointing to the traditional C string.)
- kzrdude 7y agoUsing size_t as the common solution seems like the way to go. struct string { char *data; size_t size; size_t alloc_size; }; struct string_view { char *data; size_t size; }; And we have the same design that C++ uses.
- billziss 7y agoI do not think I have ever seen a string that needs more than 64K, but then again I do not read whole files in memory in C. (I do in Python.) So this would be wasteful in many cases. My personal variant uses 32-bits for length and 32-bits for refcount, which aligns well on most platforms, including 64-bit ones. Something like: struct string_header { int32_t refcnt; int32_t length; // character content starts here }; Given a char pointer to get to the header you must do: ((struct string_header *)p)[-1]
- Steven_Vellon 7y agoA lot of C developers I know see value in keeping the C standard library small. I implemented my own `l_string` (length-string) struct and associated libraries for a class (we weren't allowed to use external libraries) and it was not prohibitively difficult. Something like this probably covers most use cases: https://github.com/antirez/sds https://github.com/antirez/sds
- deleted 7y ago[deleted]
- sdegutis 7y agoI really love his trick of returning a pointer to the inside of his own allocated memory which is then compatible with C's stdlib string functions, while having his own string functions use pointer arithmetic to get the real struct back out and operate on that. Genius! This is the kind of thing that keeps drawing me to C every once in a while. C is almost like a puzzle, to figure out how you can accomplish what would be trivial in JavaScript, but with all these restrictions caused by an almost extreme simplicity. (Granted, C is not actually simple when you start hitting all the weird edge-cases and surprising UB, etc.)
- stkdump 7y agoI don't love this trick. To get this to work, they had to typedef the string type to char*, which means the API will also accept any normal string and probably crash at runtime. So to get this little convenience feature, type safety was sacrificed.
- tmp0258 7y agoSeems to me that it would also prevent tools like the address sanitizer and valgrind from detecting some invalid memory accesses (corresponding to negative indexes). A "more conventional" string library [1] might be safer. [1] for example: https://github.com/websnarf/bstrlib/blob/master/bstrlib.txt https://github.com/websnarf/bstrlib/blob/master/bstrlib.txt
- 7y ago
- B1FF_PSUVM 7y ago> null terminated strings are a joke. There was a quiet market war some forty years ago about that, and Pascal lost. But yeah, now we can afford it, the downsides vastly exceed the vanishing cost.
- stkdump 7y agoI think the problem with Pascal's strings wasn't that they stored a length. The problem was that every string variable always occupied 256 bytes of RAM and no string could ever be bigger than 255 characters.
- greiskul 7y agoAnd looking at modern languages, I would say that C strings also lost, just latter, since none of them do strings that way anymore.
- Gibbon1 7y agoA good reason for adding a modern string type to C would be for better interop between other languages and C.
- kazinator 7y agoNo matter what string manipulation method you use, you have to produce linear, null-terminated strings for passing into all sorts of existing API's, standard and not.
- masklinn 7y agoThat's really not an issue when done for you. std::string does it just fine.
- m463 7y agoserious question: why doesn't C improve much? I understand there are benefits to small or no changes whatsoever. I also understand there are a number of standards (1990, 95, 2011...) Is it that all the people who would be interested in improving C just naturally migrate to C++ which is getting improvements? Your example of better strings is good, but why not lists and hashes as language elements? If not in the language directly, then ok in the library. But speaking of the library, why limit to just a few things, why not batteries fully included. shoot for knuth in the standard library!
- flukus 7y agoIn the case of strings it's because in practice it's just not that much of a problem. If your not in a highly constrained environment you'd just use one of several libraries like glib that have strings and other stuff you'd typically find in the standard libraries of other languages. These libraries have the freedom evolve faster, break backward compatibility, not have to worry about committee design and keeping everyone happy, limit themselves to certain classes of machines and do all sorts of things you can't in a standard library. C has an anemic standard library but many libraries you can use as your standard, this keeps everyone happy. I'd expect the javascript/npm world to evolve this way in future.
- crpatino 7y agoIt all depends on your definition of improvement... C is a bit like a Formula One car. Regardless of the historic reasons that caused it to evolve the way it did, it ended up occupying a niche and being very well suited to it, while at the same time being ill suited for other, more general purpose, uses. Under that perspective, change is slow because the people most invested in it want to make improvement happen in a very narrow and precise direction. McLaren, after all, is not going to bat an eye if you complain about its latest model lacking a baby seat!!! C++, on the other hand, started sort of like NASCAR racing. It wanted to make a racing car out of a mundane, everyday car, and it got very, very good at it. Unfortunatelly, because C++ is based in an everyday car, and because it is Designed-by-Committee (TM), it shows lots and lots of "improvements" that individually kind of make sense, but in the bulk lack any coherence. Nowadays, C++ may perform like the Batmobile (from "Batman Begins" movie) on a good day; but you never know when it is going to bite you in the ass and turn into the Homermobile from the 90's Simpson's TV show. It is a mix of necessity and lack of insight that many of the people in my generation had to learn how to drive in fucking racing carts!!! But when it's all said and done it gives you a little perspective on how things work and helps you appreciate the differences.
- amelius 7y agoOne problem is that POSIX uses null-terminated strings everywhere.
- colejohnson66 7y agoSo can’t you bill terminate your length prefixed string and pass a pointer to the data to POSIX. From what I understand, that’s how C++’s std::string works with ::c_str()
- saagarjha 7y agoStarting from C++11, yes.
- emmelaich 7y ago> length alongside with the (binary safe) string itself, What is the type of the length? What is the type of the length+string? What lengths is it limited to? Do we need a 32 bit and 64 bit version? And 128+ bit version? Can you provide an implementation? What is its best and worst case efficiency? What is its expected efficiency for the typical string operations?
- kazinator 7y ago> null terminated strings are a joke I think that the null-terminated representation of the raw string data is a fantastic design; the best of all conceivable alternatives.