8 ms·
sp.h: Fixing C by giving it a high quality, ultra portable standard library
- Kab1r 5mo agoBest library name.
- TZubiri 5mo ago> Every language that depends on third party libraries, like js and python, is getting massively infected with supply chain worms > Only couple of languages not affected are those that don't have a culture of downloading third party code, like C and C++ > Ex js and python developer publishes a 'library' > Library is vibe coded > Published on github amidst GitHub being hit by supply chain attacks, had their source code leaked. The timing is terrible for starters, and I don't trust the vibe coded code at all. Imagine a pandemic and the cities are on fire, and you arrive to a rural town asking to kiss people.
- skybrian 5mo agoMy impression of the sample programs is that they're unreadably noisy, but maybe this would be a good compiler target if you're writing your own language?
- dboon 5mo agoHow would you write https://github.com/tspader/sp/blob/main/example/ls.c https://github.com/tspader/sp/blob/main/example/ls.c in your statically typed language of choice? To be fair, this is definitely the kindest example to my library, but one reason I felt this project was worth pursuing was that that example reads basically like a slightly worse TypeScript to me. In other words, quite nice for how low level the code really is.
- skybrian 5mo agoIn a higher-level language, you wouldn't need to write code like this: const sp_fs_entry_t* a = (const sp_fs_entry_t*)pa; const sp_fs_entry_t* b = (const sp_fs_entry_t*)pb; return sp_str_compare_alphabetical(a->name, b->name); Instead it would just be: return sp_str_compare_alphabetical(pa->name, pb->name) With the correct types declared for the parameter types instead of void pointers. Or if you do need a cast, not having to write "sp_fs_entry_t*" twice in the same line because the local variable's type is inferred. Maybe after reading C for a while, you don't see all the noise anymore?
- tom_ 5mo agoBecause it's const void *pa, you don't need the cast. A void * pointer will convert to any other kind of pointer. Now you only need to mention the type once. (I forget the const-related rules, but since the consts match in this case I don't think it'll be relevant.)
- Retr0id 5mo ago> Program directly against syscalls Works nicely on Linux where the syscall interface is explicitly stable, but on many (most?) other platforms this is not the case. > There Is No Heap I don't understand what this means, when it's followed by the definition of a heap allocation interface. The paragraph after the code block conveys no useful information. > Null-terminated strings are the devil’s work Agreed! I also find the stance regarding perf optimization agreeable.
- quuxplusone 5mo agoThe "definition of a heap allocation interface" indicates that there is no standard heap. Instead, there's a standard interface for the use to define their own heaps. Any standard library function that needs to allocate will take a sp_allocator_t parameter, and use that to allocate. As opposed to e.g. strdup, which hard-codes a call to malloc internally. Sp.h's strdup-alike would take an sp_allocator_t as input and call into that to get the memory it needs. A C++ programmer might describe this as "PMR, but not default-constructible. And std::stable_sort takes a PMR allocator parameter. And PMR is the default, and there's no implementation of std::allocator (or new or delete)."
- Retr0id 5mo agoLooks like the default allocator uses mmap(2) for every single allocation, which is horribly inefficient - you map a whole PAGE_SIZE worth of memory for every tiny string. Aside from just wasting memory this will make the TLB very unhappy. It looks like sp_log's string formatting is entirely unbuffered which results in lots of tiny write syscalls.
- AlotOfReading 5mo agoThat seems to be a pretty consistent quality level for the entire library. Look at the implementations in sp_math, yikes.
- jcranmer 5mo ago"How bad can it be, I mean I know that numerics are not many people's strong suit, but..." ... ... ... oh wow, the math functions are really bad implementations. The range reduction on the sin/cos functions are yikes-level. Like the wrong input gives you an infinite loop level of yikes.
- nextaccountic 5mo ago> Principles > Be extremely portable > sp.h is written in C99, and it compiles against any compiler and libc imaginable. It works on Linux, on Windows, on macOS. It works under a WASM host. It works in the browser. It works with MSVC, and MinGW, it works with or without libc, or with weird ones like Cosmopolitan. It works with the big compilers and it works with TCC. > And, best of all, it does all all of that because it’s small, not because it’s big. vs > Non-goals > Obscure architectures and OSes > I write code for x86_64 and aarch64. WASM is becoming more important, but is still secondary to native targets. I don’t care to bloat the library to support a tiny fraction of use cases. > That being said, if you’re interested in using the library on an unsupported platform, I’m more than happy to help, and if we can make the patch reasonable, to merge it. Those are contradictory. Either the code is extremely portable, or it can't support "obscure" platforms, but not both.
- ktpsns 5mo agoExactly. This shows that "extremely portable" is actually marketing for "It supports a number of platforms. In my opinion, this number is big".
- noosphr 5mo agoWe support extreme portability for sufficiently large values of two.
- lelanthran 5mo ago> This shows that "extremely portable" is actually marketing for "It supports a number of platforms. In my opinion, this number is big". The number might just be zero - did anyone check if this compiles? I am trying to track down where the function `sp_mem_allocator_alloc_type` is defined (used in 3x places) but it doesn't appear in the GH search results. I'm not going to clone and build this (too dangerous).
- flohofwoe 5mo ago> I am trying to track down where the function `sp_mem_allocator_alloc_type` is defined A quick glance at the source on github and here you go: https://github.com/tspader/sp/blob/e64697aa649907ce3357a7dd00ff259bb3928498/sp.h#L7997-L7999 https://github.com/tspader/sp/blob/e64697aa649907ce3357a7dd0... `sp_mem_allocator_alloc_type ` is going through a couple of macro resolutions which ends up at `sp_mem_allocator_alloc` > I'm not going to clone and build this (too dangerous). Your computer won't explode just from downloading and compiling some C code, don't worry ;) The github repo builds and the examples run just fine on macOS by just running `make` in the project directory, although with one warning: warning: 'posix_spawn_file_actions_addchdir_np' is deprecated: first deprecated in macOS 26.0
- JSR_FDED 5mo agoI love how hyper-opinionated this is.
- smitty1e 5mo agoFamily saying: "It ain't bragging if you can do it." When one is competent to work at this level, strong opinions are in order. Their correctness is something I cannot gage. I'm barely competent to follow the conversation.
- rmunn 5mo agoConsidering the first thing I saw in the thread was https://news.ycombinator.com/item?id=48244891 https://news.ycombinator.com/item?id=48244891 where the values returned from sp's sine function was compared to the correct values, I'm going to take any such opinions with a few grains of salt. Because the correct sine for the number they tested (31337 radians) is 0.3772 (0.3771522646 according to my calculator), sp's implementation returned 0.4385. That's not even close to right.
- JSR_FDED 5mo agoIt’s still alpha
- CyberDildonics 5mo agoI was promised by the title that it is "high quality"
- dboon 5mo agoThank you!
- nektro 5mo agonot one mention of Zig on the whole page?
- dboon 5mo agoI had half of a manifesto about how C programmers should be embarrassed on account of Zig but I ended up paring it down to be more focused on what the library is plainly. Zig is obviously incredible and this library would not exist without it being the standard bearer for systems programming in many ways
- pyrolistical 5mo agoWe should port the zig std lib as a c lib
- dboon 5mo agoHaha jk…but really? Lol just kidding…unless?
- zzo38computer 5mo agoI agree with most of the criticisms they make. I agree that pointer and length is better than null-terminated strings (although it is difficult in C, and as they mention you will have to use a macro (or some additional functions) to work this in C). Making the C standard library directly against syscalls is also a good idea, although in some cases you might have an implementation that needs to not do this for some reason, generally it is better for the standard library directly against syscalls. FILE object is sometimes useful especially if you have functions such as fopencookie and open_memstream; but it might be useful (although probably not with C) to be able to optimize parts of a program that only use a single implementation of the FILE interface (or a subset of its functions, e.g. that does not use seeking).
- fithisux 5mo agoNull terminated strings have some merits but they should be a completely different data type like in Freebasic.
- Sankozi 5mo agoAre there other merits than availability of literals in C? It seems like one of the worst data structures ever - lookup complexity of a linked list with a expansion complexity of an array list with security problems added as a bonus.
- boricj 5mo agoIt's fine as a serialization/deserialization primitive for on-disk files, as long as the NULL character is invalid. String tables in most object file formats work like that, a concatenated series of ASCIIZ strings. One byte of overhead (NUL), requires only an offset into one to address a string and you can share strings with common suffixes. It's a very compact layout.
- diffuse_l 5mo agoNothing prevents you from using a shared pool of strings that don't have null terminator. It can even be more efficient, since you don't have the null byte to handle at string end. Depending on the maximum string length you want to support, it doesn't even have to take more space.
- KnuthIsGod 5mo agoWonderful ! Yet another slop coded library. What could possibly go wrong...
- KnuthIsGod 5mo ago"The library’s stance, to put it simply, that the juice ain’t worth the squeeze when it comes to low level, compute-bound performance. Designing software and data structures for performance against unknown use cases on unknown hardware is extremely difficult and the resulting code is much more complicated. Even then, it’s often better to use code written against your actual use case and hardware when performance is that critical. Things that are off the table might be: SIMD A highly optimized hash table rewrite Figuring out where inlining or LIKELY causes the compiler to produce better code." LOL... Classic vibe coder.
- pjmlp 5mo agoWe should have left C in the 90's already, but then FOSS happened, "Using a language other than C is like using a non-standard feature: it will cause trouble for users. Even if GCC supports the other language, users may find it inconvenient to have to install the compiler for that other language in order to build your program. So please write in C." The GNU Coding Standard in 1994, http://web.mit.edu/gnu/doc/html/standards_7.html#SEC12 http://web.mit.edu/gnu/doc/html/standards_7.html#SEC12
- yjftsjthsd-h 5mo agoThat sounds like GNU reacted to the problem rather than causing it.
- mjevans 5mo agoFor reference, Dialup Internet (E.G. ~2-3KByte/sec transfer) was NOT uncommon even into the early 2000s. In 1994 even dialup internet connections were rare and most software distribution occurred by floppy disk (encased in hardshell plastic). _storage_ space was also at a major premium with internal hard disk size indexed in CHS rather than LBA and new (rarely seen by most end consumers) models barely passing 1GB in capacity. https://en.wikipedia.org/wiki/Seagate_Barracuda https://en.wikipedia.org/wiki/Seagate_Barracuda Even in the early 'dot com' era as DSL and early cable modem became common downloading software updates could still be painful, though far less so than hours or days on dialup.
- troad 5mo agoIt's been interesting seeing the retrospective flattening of computer history. I suppose it's inevitable over time. I wonder how bad it will get. "In the 1990s, 'hackers' would 'dial up' their flip phones to local BBSes (called 'phreaking'), where they played and exchanged small Flash games (the 'demo scene')." /s
- ozgrakkurt 5mo agoC is the only language I found where it is possible to isolate yourself from the "AMAZING" ideas of programming language creators. There is no language other than C and C++ that is mature enough that you can actually discard the implicit runtime stuff and still be able to code in the language. C++ is too complex in my opinion so I only get to use C as a minimal language. Even if you look at a language like Zig. You have implicit error trace printing stuff that is inaccurate when using optimized builds, you get a very bad fuzz implementation that doesn't work properly, you get comptime reflection which will be insane in the hands of the people that are writing rust now. Also a bunch of features you would want to use to discard the runtime are not documented/stable. You can't even use Odin without libc as far as I can understand. Hare doesn't even have inline asm. Contrast with using C with clang/gcc where you can do '-nostdinc' '-nostdlib', then implement memcpy etc. and you can do w/e you want after that. Rust as a nother example is trash for doing low level projects without pulling the 10billion lines of code that comes with using rust like libc/stdlib/binding libaries etc. etc. You can use libraries that other people built in Rust but doing it yourself takes much more time than doing it in a language like C or Zig. Another thing is, C is easy to implement. Implementing Rust/C++/Zig or any of the other languages is basically impossible in comparison. Also I found that C is the only language that you can go into a very big project and open a random file and roughly understand what is going on. This is not possible in any of these other laguages other than Zig and I suspect it will get very bad in Zig when(if) the lower skill level people that are currently writing Rust start moving to writing Zig.
- Panzerschrek 5mo agoIt's a disadvantage, that it's header-only. It needs to include <windows.h> and a bunch of other stuff, which slow-downs compilation. Splitting it into a couple of files (a header and an implementation) would be much better.
- flohofwoe 5mo agoThis normally isn't a problem since windows.h and other big system headers are usually only needed in the implementation part, not in the declaration part of the header (this is an STB-style header where the implementation is isolated in an `#ifdef IMPL` section). Unfortunately though this particular header seems to include the system headers up in the declaration part of the header.
- 504118318 5mo agoJust taking a quick look at the atomics section: First, (on unix) it's wrapping pthread mutex. That's part of libc! (Technically it might not be libc.so, but it's still the standard library.) Also, none of the atomics talk about the memory model. You don't _have_ to use the C11 memory model (Linux, for example, doesn't). But if you're not using the C11 memory model and letting the compiler insert fences for you, you definitely need to have fence instructions, yourself. While C11 atomics do rely on libgcc, so do the __sync* functions that this library uses (see https://godbolt.org/z/bW1f7xGas https://godbolt.org/z/bW1f7xGas) for an example. Oops... apparently this is vibecoded. Welp, I just wasted ten minutes of my life reviewing slop that I'm not going to get back.
- dboon 5mo agoYes, unfortunately the threading primitives require libc. Ditto subprocesses. It's on my list. But regarding: "Oops... apparently this is vibecoded. Welp, I just wasted ten minutes of my life reviewing slop that I'm not going to get back." Do not talk to people like this. I don't care if you don't like the library, or if you found a flaw in it. I am a regular person who wrote this code for no other reason than I thought it would be good to exist. It's unbelievably rude to call it vibecoded slop, or a waste of your life, and it makes me sad that someone who would write an otherwise thoughtful comment would say something like that.
- 504118318 5mo agoYou're absolutely right. I should have expressed my late-night frustration more kindly.
- dboon 5mo agoNo problem and thanks for the apology. Happens to the best of us. Regardless, thanks for the comment — I definitely didn’t mean to slip by the pthread stuff on a “well technically this isn’t libc.so”. It’s just code that’s pretty hard to get right and I haven’t had a chance to rewrite it!
- Panzerschrek 5mo agoThis doesn't look good: c8 buf [SP_PATH_MAX] = sp_zero; sp_cstr_copy_to_n(path, len, buf, SP_PATH_MAX); since #define SP_PATH_MAX 4096 There should be a fallback for very long paths.
- dboon 5mo agoCan you show me a realistic case with a longer path?
- scott01 5mo agoI have email backups from a provider where filenames are extremely long.
- magicalhippo 5mo agoI guess the c8 means you don't plan on supporting Unicode on Windows? If you do, there's the 32768 "character" max path which since Win10 is opt-in without jumping through hoops. https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation https://learn.microsoft.com/en-us/windows/win32/fileio/maxim...
- fc417fc802 5mo agoI'm inclined to agree with you that paths can be arbitrarily long as a matter of principle. However in practice I believe PATH_MAX on most distros defaults to 4096 so if you're going to insist on a hard upper limit it's at least within reason.
- Panzerschrek 5mo agoHow does this library work in programs with parts still requiring libc? How does it deal with code executing before main? Libc does a bunch of necessary stuff, like calling initializers for global variables.
- dboon 5mo agoIf your code depends on a bunch of initialization from libc, then you should continue to link to and use libc. sp.h can coexist with libc just fine; if you link to it, the library makes sure to conform where it needs to (e.g. not stomping on the register that holds the TLS base pointer). What sp.h does not do is reimplement all of libc's initialization code. If you want to build a freestanding binary, there are a few utilities in there for defining a _start so the loader can actually jump to your code. But it's not, and isn't meant to be, a libc replacement in this sense.
- charcircuit 5mo agoI do not want to include and compile a standard library for every file that includes it. Why do standard library headers always have to be insane?
- dboon 5mo agoHave you considered compiling it into a binary of your choice? It works perfectly well as a traditional library. The only cost you pay is re-parsing the header part once per TU. Because C is so simple, this is virtually free. In any case, calling it insane makes me feel disrespected and I would prefer if you didn't do that.
- charcircuit 5mo ago>The only cost you pay is re-parsing the header part once per TU. You are not just parsing it. The header includes the implementation too which will get compiled. Then the linker has to do extra work in order to deduplicate all of this extra code that was made. >Because C is so simple, this is virtually free. This is not virtually free needing to compile a standard library for every file in one's project. >In any case, calling it insane makes me feel disrespected I would recommend you not take it personally. Fortunately, for better or worse software ends up being pretty robust so it can tolerate a lot. Even if you have to recompile the same standard library hundreds of times, it will eventually compile.
- deleted 5mo ago[deleted]
- gjvc 5mo agoDJB was saying similar things in the 1990s -- eg https://cr.yp.to/proto/netstrings.txt https://cr.yp.to/proto/netstrings.txt
- dboon 5mo agoThanks for reading and thanks for the link. I'll read anything DJB wrote.
- p4bl0 5mo agoFirst, thanks for sharing this link, it was an interesting read! A few remarks below. I had a hard time reading the wc code in the article. First I had to go to the GitHub to understand that "da" stands for dynamic array, and then understand that what the author calls wc is not at all the wc linux commands, which by default gives you the number of lines, words, and characters in a file, not the count of occurrences of each word in the file, which is what the proposed code does. Also, since I had to read the GitHub README, another remark: it says that sp_io uses pthreads rather than fork and exec. Both of those approach (but especially pthreads) are contradictory to the explicit goals of programming against lowest level interfaces. I believe the lowest level syscall is clone3 [1], which gives you more fine grained control on what is shared between the parent and child processes, allowing to implement fork or threads. [1] https://manpages.debian.org/trixie/manpages-dev/clone3.2.en.html https://manpages.debian.org/trixie/manpages-dev/clone3.2.en....
- eqvinox 5mo agoBy the time you know enough to reasonably use clone3, you have also learned that doing so is an exceptionally bad idea save for very rare circumstances.
- fc417fc802 5mo agoTo be portable it's probably best to use the pthreads API for everything, make no additional assumptions, and rely on the user to provide the implementation. Consider what happens when someone is working with OpenMP, CUDA, or similar and attempts to make use of a dependency that in turn makes use of your library. The easier it is to understand the assumptions made by your library the better.
- p4bl0 5mo agoI agree with that. I'm just stating that it's contradictory with the project's own principles. > Program directly against syscalls It's the very first one of the listed principles. In the paragraph after this title it even says it "must" be the case in italic to insist on it, and there's a footnote to define what they mean, which is very clear in that pthreads should be out according to this principle.
- lifthrasiir 5mo agoZig, one of the giants upon whose shoulders this library stands, coined a name for this almost-but-not-quite-UTF encoding: WTF-8 and WTF-16. These encodings mean, simply, the same as their UTF counterpart but allowing unpaired surrogates to pass through. To give credit where credit is due, both WTF-8 and WTF-16 were devised by Simon Sapin [1] and Zig simply picked them up. [1] https://wtf-8.codeberg.page/ https://wtf-8.codeberg.page/ sizeof((T){0} = $value) Wait, is a compound literal an l-value in that sense (as opposed to, just being able to take its reference)?! Take a look at the C99 standard Oh my, it indeed is (C99 §6.5.2.5 p5). Good to know!
- abcd_f 5mo agoThe WTF name really lies on the surface, there's no authoritative source of its origin. I have a wtf.c from 10+ years ago when I was re-implementing Windows-style Unicode handling for some project. You keep running into various quirks, which accumulate and you inevitably arrive at your WTF moment. So WTF as name comes up naturally, no special wit required.
- lifthrasiir 5mo agoThat might be possible, but Simon Sapin was who tried to specify what exactly are WTF encodings so that should mark sort of milestone.
- dboon 5mo agoThanks! I didn’t know this.
- tialaramex 5mo ago> I’ve been working on fixing C by giving it a high quality, ultra portable standard library If the only problem with C was that the stdlib is terrible that would be a very different situation. There are much more fundamental problems with the language. Problems that are entirely understandable in K&R C but aren't acceptable half a century later. A "high quality" standard library can't fix these problems. In some cases it can paper over them though not others, and even then the actual problem wasn't fixed it's just not obvious with superficial examination any more. First, the type system is crap. The array types don't work across function boundaries, there's no Empty type at all, you are provided with a user defined product type with names, but not one without names etc. There is no fat pointer type, slice reference, nothing like that. Second, naming is also crap. There's no namespacing feature provided so you're left with the convention of picking a few letters as a prefix and hoping it doesn't overlap and yet is succinct enough to not be annoying. Third, everything coerces, all the coercions you could want if you like coercions, and then ten times that many on top. Some people really like coercions, C will see them learn that actually they don't like them that much.
- IshKebab 5mo agoSure but it's definitely true that a significant part of the problem with C is that it's standard library is crap. So if you are forced to use C for some reason this could help.
- flohofwoe 5mo agoThese are all just your personal preferences. Just use another language instead which better matches your taste, nobody forces you to use C and there are plenty of more opinionated alternatives. FWIW, the standard library being stuck in the K&R era is an actual problem since it doesn't make use of more modern language features and some functions are downright footgun magnets, but nobody quite agrees what a modern stdlib should look like, so a stdlib2 probably will never happen.
- tialaramex 5mo agoNah, I spent many years writing C for a living. That library isn't from the K&R era, it's from C89, the problems I'm talking about are much more fundamental. Of course nobody forces me to use C, which is why I stopped writing C a few years ago.
- teo_zero 5mo agoInteresting project! I'm eagerly reading through it. Probably I would have made different choices. For example, I'd rather have many modules that can be individually included, than one giant file. Also from a purely aesthetic point of view, I would have opted for more readable function and type names: no sp_ prefix, recognizable names like dict istead of ht, vec instead of da, etc. And I know there are compilers out there still stuck in the 90s, but I would have targeted C23, these days. But that would be my highly opinionated library! P.S. be aware that word frequency is not what the standard 'wc' does.
- feelamee 5mo agoHow do they all know that it is vibe-coded? I missed the meeting where they were handing out vibe-code-detectors? Please, describe.. P.S. sad to see that HN becomes a witch hunting place
- dboon 5mo agoYeah, AI has done a number to this place
- Onavo 5mo agoBun and Anthropic wants to know your location.
- dzhar11 5mo ago[flagged]
- WalterBright 5mo agohttps://spader.zone/sp/#null-terminated-strings-are-the-devils-work https://spader.zone/sp/#null-terminated-strings-are-the-devi... Pointer/length is not just for strings - but for all arrays. See my proposal: https://www.digitalmars.com/articles/C-biggest-mistake.html https://www.digitalmars.com/articles/C-biggest-mistake.html
- dboon 5mo agoA comment from a legend. Thanks for reading and thanks for the response! I agree; the dynamic array is typed as a T* for ergonomics sake but is similarly a pointer and a length (and an allocator). Could I pick your brain a little more on the design? I'm spader at spader.zone; if you have time, drop me an email. I promise not to take too much of your time and I'd love to hear from you.
- WalterBright 5mo agoThanks for the kind words! This can get you started: https://dlang.org/spec/arrays.html https://dlang.org/spec/arrays.html Strings (and arrays) being length/ptr is a freaking enormous win, in simplicity, performance, and overflow bug elimination. One of D's secret features is that string literals still have a 0 appended to them, even though the length of the string does not include the 0. This makes it super slick to call C functions, like printf, using a string literal for the format string. I'm baffled why C spends its energy doing things like normalized Unicode identifiers (an abomination) instead of something incredibly useful like length/ptr arrays.
- x0re4x 5mo agoI suggest using a slightly different array operator syntax for fat pointer arrays: "char a[|..|]" instead of just "char a[..]" to make them visually distinct and indicate that element access has additional bounds check. (syntax inspired by ocaml)
- WalterBright 5mo agoThank you for the idea! I have no experience with Ocaml, so have no opinion on it. My experience is the simpler the syntax, the more people will use it.
- Luker88 5mo ago> C is valuable because it’s simple This is funny to me because just today some friends gave me a link to a C quiz: https://stefansf.de/c-quiz/ https://stefansf.de/c-quiz/ From which I gathered that it is a much more cursed language than I remembered. Maybe we all just got used to C and just happen to use a minimal subset. The problems with C are not mainly with the standard library, but any effort to improve things should be lauded.
- uecker 5mo agoThe quiz is not entirely accurate though. For example, pointers to the same address must compare equal. Other stuff is ancient and some of it was already removed in C23. Again other things are entirely irrelevant in practice and kept only for backwards compatibility or for specific technical reasons. In practice, C is very simple, at least compared to the alternatives.
- skydhash 5mo agoThere's C the standard, and there's C the implementation (compiler & platform). The standard is nice to have on a bookshelf, but your main reference should be the implementation.
- pjmlp 4mo agoUntil one cares about writing portable code across implementations.
- WalterBright 5mo agoWhenever I review C code, I always look for the string functions. About 90% of the time, I find a bug in it. The bug is always about forgetting to account for the terminating 0 byte. The functions strncpy, snprintf, strncat, are fountains of bugs.
- WalterBright 5mo agoP.S. For these reasons I have abandoned the "n" functions, such as strncpy, strncat, etc. I still use snprintf, though, because it is so darned useful. But I wrap it up in another function after carefully ensuring it is called correctly.
- NelsonMinar 5mo ago[dead]
- xorvoid 5mo agoThey're just inventing another language here. That's fine if you want to do that. Just do THAT. C is horribly and unfixably broken. We've known that for many decades. Just let it die already! Let's move on.
- schaefer 5mo ago> C is horribly and unfixably broken. ... Let's move on. I love that you are both making this argument and that you have a link to a boutique C compiler written in assembly on your home page. While I'm commenting on your home page - I recognize that photo as being Red Rock. Possibly pine creek? but can I ask which route specifically?
- YourDadVPN 4mo agoThere isn't a language that achieves C's performance, access to hardware and portability while also having superior syntax. The reason C is hard is because it makes sacrifices to enable the above. A Rust (for example) compiler targeting many microcontrollers (8/16-bit word size (not all), Harvard architectures like AVR, non-8-bit byte) simply can't be written due to assumptions made by the spec. Many such architectures are still in use.
- ndesaulniers 5mo agoI spent a bit of time implementing parts of a C runtime for the brief tenure I had maintaining LLVM's libc. I quickly came the realization that a lot of the interfaces that made it all the way to standardization were trash. How the language is standardized is still comical to me. I agree with TFA that C style strings are trash.
- gritzko 5mo agoIn this day and age, the value of C standard library is approaching zero. Is is basically an unfirm looping trajectory of CS thought left over 50 years. That amount of code can be recreated pretty quick today. So why bother. Unless it is a syscall or somehow specially treated by the compiler (memcpy etc), there is no special value in it.
- saidnooneever 4mo agoprovide performance benchmarks + specs of the machine that ran them. provide similar code between for e.g. libc and this lib and then show how its compiled / disassembled to show what is more optimal. i doubt many people will go through the whole code themselves or do this stuff to determine if claims are true and/or its worth to port something to this or start learning it. people spend a lot of time getting familiar with libraries in order to be able to use them properly.. If you help them a long that path more it will be more inviting to try your code. (that being said i think people talking about fixing C likely dont realise that people just quietly roll their own libs like this..not to fix C but because that is what C programming is.)
- exabrial 4mo agoCongrats! This is a feat! May I suggest producing a specification document that critically defines the desired behavior? (If this hasn’t been done)
- vetrom 4mo agoHas anyone gone and implemented a 'real' (production not necessary) piece of software this this yet?