6 ms·
What surprises me in C developers is that C exists for probably 40 years but they still don't have proper strings (not just pointers). In many cases there is no
by codedokode 7y ago
What surprises me in C developers is that C exists for probably 40 years but they still don't have proper strings (not just pointers). In many cases there is no large performance penalty for storing string length, and checking it, but they still use pointers or a separate pair of variables for pointer and buffer size instead of single object.
- zxcvbn4038 7y agoThere are countless libraries that add higher level string functions and no end to higher level languages. C fills the niche where you want something higher level then assembly but lower level then Perl, ruby, python, etc. Sometimes you want or need to manage your own memory. Arduino is a good contemporary example.
- stjohnswarts 7y agoExactly. C philosophy is to use libraries and not put things like a better string library in the core functions of the language. It keeps the language relatively clean and easy to understand, unlike c++
- unscaled 7y agoSo the C philosophy is to provide a bad standard string library that is not thread-safe and makes it impossible to write programs without remote code execution vulnerabilities, rather than have a better library with exactly the same functionality but with more security and safety "bloat"? /snark Yes, C used have a cavalier approach towards security in the past. But if you're asking why the standard library is not fixed yet, I think that instead of pinning it to some lofty philosophy, it's safer to say that good C developers realized long ago that the original C strings are a mistake. Most big C projects define their own string functions and often their own length-prefixed string types. The C standard committee just gave up on fixing this issue in the standard library, but this is not due to philosophy, but because of the impracticality to force a standard solution on this stage.
- deleted 7y ago[deleted]
- pjmlp 7y agoBonus points when the libraries are so incompatible among themselves that require extra conversation steps, and then just get dropped 'cause "mind the performance".
- jstimpfle 7y agoWhen compatibility is needed, APIs should consume pointer+length pairs. It doesn't get better than that, in ANY language, in terms of simplicity and modularity. Libraries like Qt with extreme lock-in are at the other end of the spectrum. If it works for them, that's nice. Doesn't work for me. I don't think using a string library is in the spirit of C programming.
- pjmlp 7y agoWhich means either pointer+length get packed into their own structure to avoid mix up errors, thus requiring conversion function calls across libraries, or they are given separately manually, thus opening the door to the copy-paste mistakes from pointer+bad length that they are supposed to protect against. Qt is as locked-in as any LPGL 3 FOSS project is.
- jstimpfle 7y ago> Which means either pointer+length get packed into their own structure to avoid mix up errors, thus requiring conversion function calls across libraries, or they are given separately manually, thus opening the door to the copy-paste mistakes from pointer+bad length that they are supposed to protect against. No, we were talking about compatibility/modularity. You're shifting the topic. > Qt is as locked-in as any LPGL 3 FOSS project is. I'm not speaking about licenses lock-in, but about lock-in from an engineering point of view. Are you aware of any significant Qt projects that don't have "Q" all over their codebase? (And yes, by contrast to GPL, I believe you can use LGPL libraries without suffering a terrible amount of (license) lock-in)
- pjmlp 7y agoHow am I shifting the topic? Compatibility/modularity doesn't happen in the air, rather in written code. So either one passes structs around, and somehow they need to be compatible. Or one passes pointer + lenght as two separated variables, with the consequences to keep in sync two unrelated variables, from the compiler point of view.
- pjmlp 7y agoArduino uses C++.
- jbboehr 7y agoI've used talloc [1] where appropriate to greatly simplify memory allocation and string handling. [1] https://talloc.samba.org/talloc/doc/html/index.html https://talloc.samba.org/talloc/doc/html/index.html
- emmelaich 7y agoC has _only_ pointers for variable size things, not just strings. Roughly speaking C vars are either known fixed length, or accessed via pointer. There is nothing else. (except arrays -- which are mostly pointers)
- doboyy 7y agoThe thing you are pointing to could have its length prefixed. I've always assumed that this isn't the case because nobody could commit to the size of the length prefix. Is it string8, string16, string32, or string64? Using a sentinel value to denote length is less opinionated and more portable.
- jstimpfle 7y agoAnd also unbeatable in memory efficiency.
- doboyy 7y agoUnfortunately, it's often algorithmically less efficient and more error prone, so everybody ends up replicating what git is doing with 'strbuf' but in slightly incompatible ways. The effect makes dealing with strings in C unnecessarily unpleasant.
- pjmlp 7y agoBecause they have a security culture that you only get errors due to "holding it wrong" or "every good programmer does it right", despite evidence on the contrary. Plus added the fact that early C compilers generated quite lousy code on 8 and 16 bit computers, there is this idea to micro-optimize each line of code as it is being written, without any profiling feedback of it actually matters, rather cargo cult how writting code like X is faster than Y. For example, outside 3D rendering and audio software processing, I never saw a visible impact (to the end user) of bounds checking.
- jstimpfle 7y ago> For example, outside 3D rendering and audio software processing, I never saw a visible impact (to the end user) of bounds checking. Indeed the computation overhead on bounds checking is irrelevant for "cold" code, but consider this 1) Pretty sure you can get bounds checking when compilers detect that you're accessing a static array. 2) Otherwise, it's unclear how to devise a system that integrates bounds checking with C semantics. (Yes, that's unfortunate!) 3) Bounds checking does at least increase code size.
- pjmlp 7y ago1) Totally optional from ISO C point of view, not all C compilers do do it, usually requires static analysis or specific compiler warnings to be enabled. Which not everyone does. 2) Solaris does it perfectly fine on SPARC thanks to tagged memory (ADI). Which Google in collaboration with ARM will make mandatory on future Android releases as well. [0] 3) It hardly mattered in MS-DOS and Amiga LOB applications developed in across Turbo Basic, Quick Basic, GFA Basic, Turbo Pascal, Clipper, so it matters even less nowadays unless we are speaking about PIC like hardware. Regarding bounds checking I usually refer to Hoare's turing award speech, back in 1981: "Many years later we asked our customers whether they wished us to provide an option to switch off these checks in the interests of efficiency on production runs. Unanimously, they urged us not to--they already knew how frequently subscript errors occur on production runs where failure to detect them could be disastrous. I note with fear and horror that even in 1980, language designers and users have not learned this lesson. In any respectable branch of engineering, failure to observe such elementary precautions would have long been against the law." Or for that matter, the DoD Multics's B2 security evaluation[1], with several remarks how PL/I made the system safer with its string handling, pointer integrity validation and bounds checking. As noted, yes there are niche cases where bounds checking does have an impact, but for a large spectrum of code that gets daily written it isn't the case. [0] - https://security.googleblog.com/2019/08/adopting-arm-memory-tagging-extension.html https://security.googleblog.com/2019/08/adopting-arm-memory-... [1] - https://multicians.org/multics-fer.pdf https://multicians.org/multics-fer.pdf