48 ms·
Catch-23: The New C Standard Sets the World on Fire
- __s 4y agotl;dr `realloc(p, 0)` is slated to be undefined behavior in C23, whereas it's been somewhat implementation defined until now, with recommendation being realloc(p, 0) is equivalent to free(p) Seems a bit tone deaf to create new undefined behavior in memory handling, especially when a sane default behavior seems to be de facto I've used that free-on-0 behavior myself. Unfortunately the code that uses this will often have 0 be a length variable, so hard to grep for this. Ideally musl/glibc will both stick to that undefined behavior being free & gcc/clang won't go about making this something to point their optimizations at Lest we have to stop using realloc outside of a safe_realloc wrapper static void *safe_realloc(void *p, size_t newlen) { if (newlen == 0) { free(p); return NULL; } return realloc(p, newlen); } What got this whole thing weird is that C doesn't like zero sized objects, but implementations were allowed to return a unique pointer for a zero sized allocation. Which then raises the matter that being portable there require freeing that reserved chunk for non-free implementations. In theory this reservation code could be more efficient when code frequently reallocates between 0 & some small value. & there was uncertainty because NULL is a way to say allocation failure, but then if one did a NULL check on realloc's return value they also had to check that the size was non-zero
- wahern 4y ago> Seems a bit tone deaf to create new undefined behavior in memory handling, It's only tone deaf to people who understand "undefined behavior" as an epithet or as synonymous with giving a license to compilers to screw you over. The term doesn't have either of those meaning to those on the C committee. In fact, one of the explicit rationales for the proposal is that, "Classifying a call to realloc with a size of 0 as undefined behavior would allow POSIX to define the otherwise undefined behavior however they please." https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2464.pdf https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2464.pdf > especially when a sane default behavior seems to be de facto The above proposal, N2464, gives the behavior for AIX, zOS, BSD (unspecified), MSVC (crt unspecified), and glibc. They each have different behaviors. Why they chose to finally make it undefined (it was marked as obsolescent for a long time) rather than keep it as implementation-defined, I don't know. Perhaps because it 1) simplifies the standard, and 2) by making it undefined it suggests compilers should start warning about it--despite all this time neither has there arisen a consensus among implementations about the best behavior, nor are programmers aware that the behavior actually varies widely. EDIT: The draft SUSv5/POSIX-202x standard has indeed directly addressed this issue. See, e.g., https://www.austingroupbugs.net/view.php?id=374 https://www.austingroupbugs.net/view.php?id=374 The most recent draft included the following addition to RETURN VALUE: OB If size is 0, OB CX or either nelem or elsize is 0, OB either: OB * A null pointer shall be returned OB CX and, if ptr is not a null pointer, errno shall be set to [EINVAL]. OB * A pointer to the allocated space shall be returned, and the memory object pointed to by ptr shall be freed. The application shall ensure that the pointer is not used to access an object. CX marks points of divergence with C17. The first CX is because of the addition of reallocarray, absent from C17. The second is because POSIX will mandate the setting of EINVAL if NULL is returned.
- adgjlsfhk1 4y ago> It's only tone deaf to people who understand "undefined behavior" as an epithet or as synonymous with giving a license to compilers to screw you over. Unfortunately, this is the correct understanding of UB.
- peppermint_gum 4y ago>It's only tone deaf to people who understand "undefined behavior" as an epithet or as synonymous with giving a license to compilers to screw you over. The term doesn't have either of those meaning to those on the C committee. It's unfortunate but not surprising that the C committee isn't aware of the problems with the undefined behavior. In fact, after I started reading WG14 meetings minutes, I completely lost faith that any of the serious problems with the standard will ever get fixed.
- coliveira 4y agoThis is not a problem with the committee and is not a problem with compiler writers. The committee is only marking certain behaviors as UB. Compilers can do what they think is more sensible in these situations. And compiler writers are not forcing you to accept these extreme optimizations. You always have the option of disabling optimizations and accept that your code has bugs (UB). You just need to test the code you write under different compiler settings, similarly to how you test code in different environments.
- __s 4y ago"just disable optimizations" is not a solution unless the compiler allows enough fine grained control where that solution is `-ffree-zero-sized-realloc`
- moremetadata 4y ago> What got this whole thing weird is that C doesn't like zero sized objects, but implementations were allowed to return a unique pointer for a zero sized allocation. Some of the windows API's work like this, so how much is pressure from MS? Same discussion from 7 months ago. https://news.ycombinator.com/item?id=32352965 https://news.ycombinator.com/item?id=32352965 https://thephd.dev/c23-is-coming-here-is-what-is-on-the-menu#n2897---memset_explicit https://thephd.dev/c23-is-coming-here-is-what-is-on-the-menu... https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2897.htm https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2897.htm Pattern matching ram for variables/objects whilst they exist even if zero'ed or prefilled with a value doesnt give perfect security. Random values would make it harder to work out the variable/object.
- JoshTriplett 4y agorealloc to 0 size being free is useful in particular because it means a function pointer to realloc is a complete memory allocator: call realloc with pointer NULL to get malloc, and call realloc with size 0 to get free.
- i-use-nixos-btw 4y agoThis is written with quite a lot of hyperbole. The predominant focus is realloc(pre,0) becoming UB instead of what the author misleadingly describes as useful, consistent behaviour. It is far from that, and that’s the entire reason that it was declared UB in the first place: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2464.pdf https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2464.pdf. Note that this wasn’t a proposal to change something, it’s a defect report: the original wording was never suitable. The second part is the misconception about the impact of UB. Making something UB does not dictate that its usage will initiate the rise of zombie velociraptors. It grants the implementation the power to decide the best course of action. That is, after all, what they’ve been doing all this time anyway. Note that this deviates from implementation-defined behaviour, because an implementation-defined behaviour has to be consistent. Where implementations choose to let realloc(ptr,0) summon the zombie raptors, they are free to do so. Don’t like it? Don’t target their implementation. Again, this isn’t a change from the POV of implementers - it’s a defect in the existing wording. In this case, the course of action that any implementation will choose is to stick with the status quo. It is clearly not a deciding factor in whether or not you embrace the new standard, and to suggest otherwise is dishonest, sensationalist nonsense. The feature was broken, and it’s just being named as such.
- Arch-TK 4y agoI agree that realloc was poorly defined for the 0 size case, I think UB or IDB both would have worked in this case to really drive that point home, the WG chose UB. That being said, you're completely wrong about what UB means. Making use of UB may as well initiate the rise of zombie velociraptors. Except for the situation where your implementation explicitly specifies that it provides a predictable behaviour for a specific case of UB, there's literally no guarantee of what will happen. Assuming that the implementation will stick with some status quo and your code won't exhibit absolutely unusual behaviour is just naiive. Please don't mislead people into thinking that it's ever a good idea to assume that undefined behaviour will be handled sensibly, this kind of mislead assumption is one of the major sources of bugs in C code.
- astrange 4y ago
- ChancyChance 4y agoIs the world finally realizing that "a + b" actually returns two values: pass/fail and the value if pass? "a + b = c;" is a fundamentally flawed operation from a computer architecture perspective.
- Arch-TK 4y agoThere is actually another option. A more sophisticated type system. Let's say you had some pseudocode like this: let a = 5 let b = 12 let c = a + b The type of a would be Integer[5..5], the type of b would be Integer[12..12], the type of c would therefore be Integer[17..17]. In a more complex example: def foo(a: Integer[0..10], b: Integer[0..10]): return a + b The return type of this function would be Integer[0..20]. This kind of type system can solve a number of issues, all but division by zero (which would probably still have to be solved with some kind of optional type). If type inference dictates that the upper range of an integer would be too large to physically store in a machine data type, then you either resort to bignums or you make it a compilation error. By adding modular and saturating integer types you can handle situations where you want special integer behaviours. By explicitly casting (with the operation returning an optional) you can handle situations where you want to bound the range. This drastically simplifies a lot of code by removing explicit bounds checks in all places except where they are absolutely necessary. If for some reason you care about the space or computational efficiency of the underlying machine type, you can have additional annotations (like C's u?int_(least|fast)[0-9]+_t). If you absolutely must map to a machine type (this is usually misguided, unless you are dealing with existing C interfaces, for which such a language can provide special types) you can have more annotations. Ada has something resembling this. I believe there are some other languages that implement similar features. I believe this sort of thing has a name, but I am not great with remembering the names of things. Hopefully this is some food for thought.
- im3w1l 4y agoI think the issue with this is that the worst-case bounds normally grow much faster than the actual values. And it can be easy to see for the programmer that the values can't actually grow that much because a is only big when b is small or some property like that, but then you have to convince the compiler of the same. I might be misremembering though.
- RustyRussell 4y agoFrankly, the C standards ctte went off the deep end when they effectively banned NULL to memset etc (obv with zero length). Not because these functions couldn't handle it, but because this assertion simplifies optimizations elsewhere. This has required adding extra checks in my code, found mainly by trial and error, and has made it less readable and less optimal. Finally, the checked arithmetic operations returning false on success is a horror show. Fortunately it will be found on the first time the code is run, but that's a damnably low bar :(
- ericpauley 4y ago> Finally, the checked arithmetic operations returning false on success is a horror show. This seems in line with C conventions? Generally a 0 return code means success.
- wruza 4y agoWith int statuses, not with bools. It’s just a twisted logic in return value you have to deal with in your head. “If checked operation has a status, then it failed.” - ok “If checked operation [is true], then it failed.” - wat
- SAI_Peregrinus 4y agoThe checked operations ask "did an error occur?". If it's false, then the check passed and no error occurred. If it's true, then the check indicated an error.
- masklinn 4y ago> With int statuses, not with bools Which C historically did not have, so int played that role. The function is the same, and the existing idioms remain.
- wruza 4y agoI find it strange to introduce real bools (which these macros return according to their official signatures) and then to assign them a meaning of a still-nonexistent but widely used C type. At least my C intuition stumbles upon that immediately, no matter how long I think about it. Ah, anyway, standard C/libc is basically a lost cause. It can’t get any worse, since you have to refer to a manual at every call to not step on a landmine.
- solidsnack9000 4y ago"Looking forward, marijuana legalization will surely beget notions such as fractional-, imaginary-, and negative-length objects, each with as much potential for mayhem as zero-length objects." It's a funny thing to say.
- firstlink 4y agoRust seems to do fine with ZSTs somehow.
- kibwen 4y agoZSTs work splendidly in Safe Rust, but you do need to consider them if you're writing unsafe generic code. Here's the relevant section of the Rustonomicon: https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-siz... .
- garbagecoder 4y ago>negative-length nervous Minkowski laughter
- firstlink 4y ago> and that such changes may impose themselves on old code without recompilation when dynamically linked libraries are upgraded. All I can do is laugh. This is what the dynamic linker fanatics wanted. This is what they explicitly advocate for to this day. Share and enjoy!!
- bayindirh 4y agoI’d rather have small binaries and memory efficient systems instead of huge blobs having their own complete disconnected environments with non-coherent behavior on the same situation. Also, wasting tons of memory while at it. If I have something that critical, I can always statically compile.
- AshamedCaptain 4y agoI really don't think anyone could possibly want the _specified behavior_ of a function changing below their feet. However, the author is unlikely to be correct here. E.g., to this day, glibc contains _multiple implementations of memcpy_ just to satisfy those executables that depend on the older, memmove-like behavior that was once part of the unspecified behavior of glibc. The only way to get the dynamic linker to choose one of the newer versions is to, well, rebuild the executable. It is inconceivable that glibc would not use symbol versioning with an actual specification change. The behavior is practically the same as with static linking, and you still get the benefits of dynamic linking.
- throwaway892238 4y agoPeople who don't understand dynamic linking are doomed to re-implement it, poorly.
- coliveira 4y agoExactly! Shared libraries mean that new code with modified behavior can and will be called when made available, independent of how the original code was compiled. It is interesting that people come out to complain about this obvious behavior.
- Dwedit 4y agoDid we ever legalize type punning?
- cryptonector 4y agoAsking the real questions. Without looking I'm willing to bet the answer is "no, and stop asking".
- JonChesterfield 4y agoWe have "pointer provenance" which allows license to track type punning across more of your program than ever before in order to delete more parts of it with no diagnostic required. For bonus marks, int and atomic_int are unrelated types, and simd vector types aren't a thing, so enjoy the unfixable performance cost of choosing C.
- cryptonector 4y agocry sob But this will speed the transition to Rust.
- kzrdude 4y agoThrough union yes, I think
- GianFabien 4y agoMaybe I'm being dense. To me it appears that the standards are telling compiler writers what should be done. In doing so the compilers will become ever more complex and thus bug-prone. I learnt C back when K&R (first edition) was the reference. Ok, it was hardly much more than a universal assembler to make every computer look like a PDP-11. In my experience C is the language to use when you want to be close to the metal. For the rest I use which ever high-level language/environment is best suited. Admittedly some FFI are a pain to use, but once you get the boilerplate bedded down your much higher level language gets the coordination done.
- RobotToaster 4y ago>To me it appears that the standards are telling compiler writers what should be done. Isn't that what standards are supposed to do?
- JonChesterfield 4y agoTraditionally they recorded existing practice and gently encouraged diverging implementations to converge. The alternative approach is to invent things by committee, hopefully with some implementers watching, and hope for the best.
- eternalban 4y agoC is a very large language masquerading as a small language.
- MichaelZuo 4y agoWhat does that make C++?
- eternalban 4y agohttps://upload.wikimedia.org/wikipedia/commons/a/a7/Frankenstein%27s_monster_%28Boris_Karloff%29.jpg https://upload.wikimedia.org/wikipedia/commons/a/a7/Frankens... (don't get me wrong. love C. but in an innocent sort of way, like a teenager quite unaware of betrayals, heartbreak, love triangles, or UB, UsB, and IDB..)
- pjmlp 4y agoOnly because many keep worshiping K&R C, ignoring what is the actual C that modern compilers support.
- Dylan16807 4y ago> C23 furthermore gives the compiler license to use an unreachable annotation on one code path to justify removing, without notice or warning, an entirely different code path that is not marked unreachable: see the discussion of puts() in Example 1 on page 316 of N3054.9 I don't agree with that description at all. Here's the code: 1 if (argc <= 2) 2 unreachable(); 3 else 4 return printf("%s: we see %s", argv[0], argv[1]); 5 return puts("this should never be reached"); The only code path that's "entirely different" is lines 1,4,5 and in that case of course you remove a return that's after a return. And the other valid code path is 1,2,5, which has `puts` after `unreachable`. To need `puts` you have to imagine a code path that gets past the "if" without taking either branch? Maybe the author means something by "code path" that's very different from how I interpret it? I would be pretty surprised if the above code means something different from: if (argc <= 2) { unreachable(); return puts("this should never be reached"); } else { return printf("%s: we see %s", argv[0], argv[1]); return puts("this should never be reached"); }
- wahern 4y agoI think the point is that if the `argc <= 2` path is unreachable, then that means argc is always greater than 2, permitting the compiler to optimize the entire block to just: return printf("%s: we see %s", argv[0], argv[1]); IOW, the conditional has been elided. But you're right in that the wording of the complaint doesn't match the example. The author presumably had in mind some of the more infamous NULL pointer-related optimizations, without spending the time to put together a properly analogous example.
- dtolnay 4y agoI interpreted the author's characterization to be about something like: 1 if (argc <= 2) 2 puts("A"); 3 puts("B"); 4 if (argc <= 2) 5 unreachable(); 6 else 7 return puts("C"); 8 return puts("D"); in which not just lines 4-6,8 go away (as you said) but also lines 1-2. It makes sense to me but I can see why the author would characterize this situation as "license to use an unreachable annotation on one code path to justify removing an entirely different code path that is not marked unreachable". In a different world one might expect A to be printed "before the UB happens".
- juunpp 4y ago> The ckd_* macros steer a refreshingly sane path around arithmetic pitfalls including C's "usual arithmetic conversions." A 7 letter function to add two numbers and that returns a boolean... not entirely sure I'd call that 'sane'.
- ludocode 4y agoI'd prefer if it were more letters. It bothers me when API designers omit random letters just to save a few keystrokes. These are particularly egregious because I keep forgetting which letters they kept. Is it "chk"? or "ckd"? or "chd"? or something else? I wrote a portability library that wraps these with compiler intrinsic and standard C fallbacks. I chose to spell out the full word in addition to making the type explicit. It's a lot more verbose of course but a lot clearer to read: https://github.com/ludocode/ghost/blob/develop/include/ghost/math/checked_add/ghost_checked_add_i32.h https://github.com/ludocode/ghost/blob/develop/include/ghost...
- goatlover 4y agoA saner language would handle the conversion for you so it would work with just the normal math operators.
- tzs 4y ago> Pointers to free'd memory are akin to uninitialized pointers, so free(p) followed by if (p==q) is an instrument of arson What's the reason for this?
- coliveira 4y agoUsing a freed pointer is incorrect behavior, a bug in shorter terms. If you do anything with a freed pointer (other than assigning new memory), you're inviting all kinds of bugs (independent of what the compiler might be doing with your code).
- xigoi 4y agoObviously dereferencing a freed pointer is incorrect behavior, but what harm is there in using its numerical value?
- Dylan16807 4y agoI can't tell you exactly why but it's consistent with just about everything else involving p being undefined, and the result of the comparison would be useless anyway.
- tzs 4y agoWhy would the comparison be useless? I can imagine situations where a pointer q might sometimes be a copy of pointer p and sometimes might point to something else, and the code wants to free q if and only if it is not a copy of p (because p has been free'd earlier).
- Dylan16807 4y agoBecause a new object can have the same address as p, so comparing to p isn't enough to tell you if you have a copy of p or a live pointer to something else.
- jcranmer 4y agoGiven the following code: void *p = malloc(N); do_random_stuff(p); void *q = malloc(N); With this rule, the compiler can conclude that p and q cannot alias, even if it doesn't have body of do_random_stuff. Without it, it would first have to prove that p is never freed before calling q, which is basically impossible (moving the body of intervening code into a different file, for example, would do the trick).
- MatmaRex 4y ago> As C89 was taking shape, the neurodivergent notion of a "zero-length object" was making the rounds I'm surprised that the authors decided to, and were able to, slip in this little euphemism.
- bee_rider 4y agoI wonder if somewhere along the chain there was an automated tool to convert frequently abused mental-health related terms like “insane” into something leas hurtful, or something along those lines? I haven’t seen widespread use of the word “neurodivergent” as a kind of… whatever this is, weirdly euphemistic slur, almost?
- peterashford 4y agoYeah, that's pretty gross, tbh
- wizzwizz4 4y ago> I wonder if somewhere along the chain there was an automated tool to convert frequently abused mental-health related terms like “insane” into something leas hurtful, or something along those lines? And yet again, these Lincoln systems mess up. While giving advice to the author can avoid Great Grimsby mistakes, making the replacements automatically is an utterly Scunthorpe decision, with failures as Slough as they are foreseeable. If the intent is to be unhurtful, it should need to choose a different word to if the intent is to be hurtful! Even our most sophisticated automated systems are Milton Keynes at determining that kind of thing.
- shagie 4y agoAs an aside, this is one of the spots where GPT does a really good job of fixing things. Reword the following passage. Change euphemisms to wording that has similar meaning though no negative conotations. Indicate changed words by putting them in "{{word}}" ### Standards are supposed to lead ... Why are such requests made? Often because of arithmetic bugs. And what is a non-null pointer from malloc(0) good for? Absolutely nothing, except shooting yourself in the foot. ### To which it returned: Standards are meant to provide the groundwork for a better world by enabling code portability. Real standardization necessitates {{managing}} a variety of compiler and library implementations while maintaining sensible rules. The saga of the realloc story demonstrates that C standardization does not operate in this fashion any longer. As C89 was being crafted, there was a {{unconventional}} thought of a "zero-length object": Supporters proposed that a non-null pointer to such an object should be given for requests for zero-byte allocation. Why do such requests come about? Frequently due to miscalculations. And what is a non-null pointer from malloc(0) useful for? Nothing, apart from {{setting oneself up for failure}}. It changed (along with some wording around to make the changes fit): heading cats -> managing neurodivergent -> unconventional shooting yourself in the foot -> setting oneself up for failure
- antiquark 4y agoC reached its zenith in C90, and saw a few good ideas in C99. Everything since has been wankery from people who either are bored, or have a severe case of C++-envy.
- pjmlp 4y agoEven then it was already outdated when compared against languages like Modula-2 and Object Pascal, it got lucky to ride into the waves of UNIX adoption.
- GuB-42 4y agoI actually like unreachable() a lot. What it does is that it invokes undefined behavior, that's all. It does nothing trickier than any other kind of UB. In fact, I could implement unreachable() like this: void unreachable() { (char *)0 = 1; }. Standardizing it however gives interesting options for compilers and tool writers. The best use I can find is to bound the values of the argument of a function. For example, if we have "void foo(int a) { if (a <= 0) unreachable(); }, it tells the compiler that a will always be >0 and it will optimize accordingly, but it can also be used in debug builds to trigger a crash, and static analyzers can use that to issue warnings if, for example, we call foo(0). The advantage of using unreachable() instead of any other UB is that the intention is clear.
- lionkor 4y agoRespectfully, you would already be doing this in any C codebase, with `assert()`, right? We are all checking our preconditions with assert... right?
- pornel 4y agoNDEBUG makes these checks disappear, so that's not an option for checks that are supposed to stay in the program.
- GuB-42 4y agoAFAIK, assert() is not undefined behavior, so it can't be used for optimization. It is either implementation-defined in debug mode, or does nothing in release mode. For example: assert(a >= 0); if (a < 0) printf("a is negative"); In release mode, assert() will be gone, so the if/printf() will stay. If we used "if (a < 0) unreachable();" instead of assert(), it would optimize away both lines.
- lprib 4y agoUsing `unreachable()` instead of `assert()` for your preconditions without profiling first is just pre-loading the gun to shoot yourself in the foot in the future. When those preconditions are inevitably violated at some point, you will get random UB corruption rather than simply aborting as is the case for assert.
- GuB-42 4y ago> C178 purports to be a bug-fix revision of C11. Does the word "toto" on page 1 indicate (a) the editor's musical tastes; (b) that nobody bothered to spell-check the document; (c) that we're not in Kansas anymore; or (d) none of the above? As a french guy I'd go with (d). I've often seen "toto" used as a placeholder name, sometimes followed by "titi", "tata", "tutu", I have even used it myself. It is similar to "foo", "bar", "baz". I don't know if it is specific to France, of French speaking countries, but it is definitely a thing here.
- rahen 4y agoMost likely toto as the French for foobar. Jens Gustedt is part of the C comity and participated to C23. He also works for INRIA in France: https://en.wikipedia.org/wiki/French_Institute_for_Research_in_Computer_Science_and_Automation https://en.wikipedia.org/wiki/French_Institute_for_Research_...
- cryptonector 4y agoThe `realloc()` change calls for pitchforks.
- a-bit-of-code 4y agoIs it just me that thinks that the article is a [skilfully drafted] joke (or parody or whatever the correct word is)? The fact that it has been published close to April 1st raises more suspicions.
- brxaf 4y agoI thought the same initially, but the realloc() parts are definitely true.
- still_grokking 4y agoMy interpretation would be rather that the C language is a carefully drafted joke or parody.
- otabdeveloper4 4y agoHopefully not literally. (But C23 is exactly the kind of programming language you expect to do that.)
- kgbcia 4y agoI just need built-in string handling
- cryptonector 4y ago> No -the C committee
- JonChesterfield 4y agoAuthor is angry but not wrong. Lifting the most damning quote from the article as I haven't seen it for a while. C inventor Dennis Ritchie pointed to several flaws in [ANSI C] ... which he said is a licence for the compiler to undertake agressive opimisations that are completely legal by the committee's rules, but make hash of apparently safe programs; the confused attempt to improve optimisation ... spoils the language. —Dennis Ritchie on the first C standard
- layer8 4y agoWhile the situation with realloc() is unfortunate, it is also not difficult to write a wrapper that does what the author wants. I’ve done that before, because it has long been known that not all realloc() implementations conform to the (prior) C standard. One can furthermore assume that existing implementations won’t change their behavior just because C23 made it UB.
- p0nce 4y agoHonestly I'm happy the C standard now address how realloc behaves in detail. It was already hard before, and now it's documented.
- pjmlp 4y agoAnd zero focus on improving the root causes of memory corruption due to strings and array indexing errors. The security world will keep burning it seems.
- heywhatupboys 4y ago> The security world will keep burning it seems. There is no alternative to network protocols and IPC that the stringtypes C has. You get a length and a byte array. If you trust the user, you can assume length is correct. Otherwise no.
- pjmlp 4y agoSure there are, as proven by distributed networking stacks not written in C. In fact Ethernet early days goes back to Mesa not C. UNIX did not invent networking, networking predates UNIX for at least a decade.
- heywhatupboys 4y ago> Sure there are, as proven by distributed networking stacks not written in C. this has nothing to do with the C language, but the structure of information. If the datatype contains a length, it has to be serialized anyway. There is no way of fixing this.
- quintussss 4y agoI always wonder how much these new C standards use, as C is now mostly used in areas where one is severely limited when it comes to compiler choice. Where I work, we use GCC 6.2 and iso9899:1990 (C90). If we were able to use a modern compiler, we would probably just use C++.
- andrepd 4y ago> All C standards from C89 onward have permitted compilers to delete code paths containing undefined operations—which compilers merrily do, much to the surprise and outrage of coders.16 C23 introduces a new mechanism for astonishing elision: By marking a code path with the new unreachable annotation,12 the programmer assures the compiler that control will never reach it and thereby explicitly invites the compiler to elide the marked path. I don't agree with this in the slightest. I'm not "outraged" by undefined behaviour, it's a fundamental tool for writing performant code. Ensuring that dereferencing a null pointer or accessing outside the bounds of an array is undefined behaviour is what lets the compiler not emit a branch on every array access and pointer dereference. Furthermore, I really don't understand the outrage that there is another explicit tool to achieve behaviour the author may or may not consider harmful. If it's an explicit macro, it's not a tarpit!
- PointyFluff 4y ago[dead]
- blippage 4y ago#embed is what I really want. And separators. > Standard C advances slowly They're not joking, either. C is conservative to a fault, I think.
- AlbertoGP 4y ago> #embed is what I really want. And separators. If you want to try out those features now, I made a pre-processor that translates that into standard C99: https://sentido-labs.com/en/library/cedro/202106171400/use-embed-c23-today.html https://sentido-labs.com/en/library/cedro/202106171400/use-e... https://sentido-labs.com/en/library/cedro/202106171400/#number-literals https://sentido-labs.com/en/library/cedro/202106171400/#numb... It includes a cc wrapper called cedrocc that you can use as a drop-in replacement: https://sentido-labs.com/en/library/cedro/202106171400/#cedrocc https://sentido-labs.com/en/library/cedro/202106171400/#cedr...