7 ms·
Some __nonstring__ Turbulence
- jey 1y agoThat the annotation applies to variables and not types is surely an oversight or mistake right? Seems like it could have been easier to initially implement that way but it just doesn’t seem to fit with how C type system works. (Yes it will make declarations uglier to do it on types but that ship has sailed long ago; see cdecl.org)
- leni536 1y agoI either don't understand how the annotation would work on types, or what would be gained by it. What type would be annotated? A typedef to char[]? edit: Unless what they actually mean is annotating struct members, that would actually make sense.
- _nalply 1y agoI do understand. I imagine that it could work a little bit like unsigned: a modifier to integer types that tells that an integer's MSB is not to be used as a sign bit. __nonstring__ tells that the last byte of a byte sequence doesn't need to be NUL. I would find it sensible allowing putting the attribute to a type, but whatever.
- rurban 1y agoAnd how would you type a string vs byte array then? C doesn't even have proper string support yet, ie unicode strings. Most wchar functions don't care at all about unicode rules. Zero-terminated byte buffers are certainly not strings, just garbage. C will never get proper string support, so you'll never be able to seperate them from zero-terminated byte buffers vs byte-buffers in the type system. So annotating vars is perfectly fine. The problem was that the PM and Release manager was completely unaware of the state of the next branch, of its upcoming problems and fixes, and just hacked around in his usual cowboy manner. Entirely unprofessional. A release manager should have been aware of Kees' gcc15 fixes. But they have not tooling support, no oversight, just endless blurbs on their main mailinglist. No CI for a release candidate? Reminds us of typical cowboys in other places.
- iforgotpassword 1y agoI think the idea is simply to typedef __nostring__ char* bytes; And then use that type instead of annotating every single variable declaration.
- OskarS 1y agoBut you would still need to change it everywhere, right? Like, instead of changing the annotation everywhere you have to change the type everywhere. Doesn't seem like a huge difference to me.
- deleted 1y ago[deleted]
- dataflow 1y ago> That the annotation applies to variables and not types is surely an oversight or mistake right? I don't think so. It doesn't make sense on the type. Otherwise, what should happen here? char s[1]; char (__nonstring ns)[1]; // (I guess this would be the syntax?) s[0] = '1'; ns[0] = '\0'; char* p1 = s; // Should this be legal? char* p2 = ns; // Should this be legal? char* __nonstring p3 = s; // Should this be legal? char* __nonstring p4 = ns; // Should this be legal? foo(s, ns, p1, p2, p3, p4); // Which ones can foo() assume to be NUL-terminated? // Which ones can foo() assume to NOT be NUL-terminated?? By putting it in the type you're not just affecting the initialization, you're establishing an invariant throughout the lifetime of the object... which you cannot enforce in any desirable way here. That would be equivalent to laying a minefield throughout your code.
- dwattttt 1y agoDo you mean s & ns to be swapped? ns starts with a NUL terminator and s does not.
- dataflow 1y agoNo actually, that was the point. I was asking, what do you think should happen if you store a NUL when you're claiming you're not. Or if you don't store a NUL, when you claim it's there.
- dwattttt 1y agoWell, as a human compiler, I said "Hey, you've non-NUL terminated a NUL terminated string". If that was what you intended you should use the type annotation for that, so I think that case worked as intended. EDIT: > what do you think should happen if you store a NUL when you're claiming you're not I don't believe nonstring implies it doesn't end with a NUL, just that it isn't required to.
- dataflow 1y agoBut char[] already isn't required to be NUL-terminated to begin with. char a[1] = {'a'} is perfectly fine, as is a[0] = '1'. If all you want to do is to document the fact that a type can do exactly what it already can... changing the type to something new doesn't make sense. Note that "works as intended" isn't sole the criterion for "does it make sense" or "should we do this." You can kill a fly with a cannon too, and it achieves the intended outcome, but that doesn't mean you should.
- deleted 1y ago[deleted]
- AceJohnny2 1y agoFedora stupidly uses beta compiler in new release, Torvalds blindly upgrades, makes breaking, unreviewed changes in kernel, then flames the maintainer who was working on cleanly updating the kernel for the not-yet-released compiler? I admire Kees Cook's patience.
- eb0la 1y agoIMHO Cook is following good development practices. You need to know what you support. If you are going to change, it must be planned somehow. I find Torwalds reckless by changing his development environment before release. If he really needs that computer to release the kernel, it must be stable one. Even better: it should be a VM (hosted somewhere) or part of a CI-CD pipeline.
- evgpbfhnr 1y agoHe releases rc every single week (ok, except before rc1 there's two weeks for merge window), there's no "off" time to upgrade anywhere. Not that I approve the untested changes, I'd have used a different gcc temporarily (container or whatever), but, yeah, well...
- jaapz 1y agoI find it surprising that linus bases his development and release tools based on whatever's in the repositories at that time. Surely it is best practice to pin to a specified, fixed version and upgrade as necessary, so everyone is working with the same tools? This is common best practice in many environments... Linus surely knows this, but here he's just being hard headed.
- IsTom 1y agoPeople downloading and compiling the kernel will not be using a fixed version of GCC.
- charcircuit 1y ago
- jaapz 1y agoTorvalds is known for being flamey towards kernel maintainers, but most of the time that is for good reason. Here however, he should just admit he made a mistake instead of doubling down. Admitting your own mistakes is a mark of a great maintainer as well.
- bonzini 1y agoYeah, admitting he's wrong is certainly not his strong suit. He will do so years down the road but not in the heat of the argument.
- bastawhiz 1y agoTorvalds is exactly the sort of person I'd leave a company to be as far away from as possible. He's brilliant but absolutely insufferable whether it's deserved or not. Anyone with admin access who leans into a pissing contest after breaking the build because they upgraded their operating system just before a release rather than taking the hour to fix the mess they made is going to make you hate your job. God bless the well-mannered kernel maintainers who grind past it.
- ndesaulniers 1y agoI don't miss working on the kernel, tbf. Constant arguments.
- conradfr 1y agoMaybe that's the sign that someone has been doing this job for too long and need to be replaced by someone not tired of it.
- Ukv 1y agoFrom the comments: > C "strings" work the way they do because C is a low level language, where you want to be able to do low-level things when necessary. It's a feature, not a deficiency. Are NUL-terminated strings really considered preferable, even for low-level work? I always just considered them an unfortunate design choice C was stuck with. Many O(1) operations/checks become O(n) because you have to linearly traverse the entire string (or keep a second pointer) to know where it ends/how long it is; you can't take a substring within another string without reallocating and copying that part over with a new NUL appended at the end; you can't store data that may contain a NUL (which text shouldn't, in theory, but then you need a separate approach for binary data); and plenty of security issues arise from missing or extra NULs.
- formerly_proven 1y agoC's design is probably the most post-hoc rationalized thing in the world directly after Abrahamic scripture. "Of course the null-terminated strings of C are more low-level than the length-prefixed strings of Pascal, because the elders of C wisely designed them to be so." Alternatively, something is low-level because it works like C because C semantics have simply become the universal definition of what is thought of as low-level, regardless of machine mismatch. Likewise, maybe it's not such a good idea that UNIXv6 or other educational unix-likes are used in operating system classes in universities. It's well-applicable, sure, but that's not the point of that education. Maybe we should use a Japanese or German clone of some IBM mainframe system instead, so that people actually get exposed to different ideas, instead of slightly simpler and less sophisticated versions of the ideas they are already familiar with. Too much unix-inbreeding in CS education isn't good.
- pjmlp 1y agoEspecially when C advocates tend to ignore the history of systems programming languages predating the language by a decade, because the authors decided it was cooler to do their own thing, notice a similar pattern to other languages? > Although we entertained occasional thoughts about implementing one of the major languages of the time like Fortran, PL/I, or Algol 68, such a project seemed hopelessly large for our resources: much simpler and smaller tools were called for. All these languages influenced our work, but it was more fun to do things on our own. -- https://www.nokia.com/bell-labs/about/dennis-m-ritchie/chist.html https://www.nokia.com/bell-labs/about/dennis-m-ritchie/chist... And using Pascal as counter example gets tiresome, not only it wasn't designed for systems programming, most of its dialects did fix those issues including its revised report (ISO Extended Pascal), by 1978 Niklaus Wirth had created Modula-2, based on Mesa (Xerox PARC replacement for their use of BCPL), both of which never had problem with string lengths.
- Philpax 1y agoLinus was a hypocritical asshole here, but more to the point, why are they using strings for this anyway? No byte arrays / literals in their C dialect?
- xnorswap 1y agoMy layman understanding is that it's the other way around, C doesn't have a string type. Since C doesn't have a string type, "quoted strings" are actually char[] but with '\0' as an extra last character. People have therefore made warnings happen when defining a char[] which silently truncates the '\0', because that's a common source of bugs. They've then had to develop a way of easily disabling that warning from being generated, because it's also common enough to want to avoid the warning. All of this seems insane coming from a modern language. But look at the complete disaster that was the Python 2 -> 3 migration, a large motivator for which was "fixing" strings from a non-unicode to unicode compatible type. A decade or more of lost productivity as people struggled to migrate. There's no way to actually fix C. Just keep recommending that people don't use it.
- Philpax 1y agoYep, agreed on all accounts; I'm an advocate for Rust for Linux for these reasons, among others. My thinking was that the Linux kernel already uses a custom dialect of C with specific features that benefit their workflow; I'm surprised that one of those features wasn't a char[] charset = b"abcdefghijklmnopqrstuvwxyz"; that would allow for intent to be signalled to the compiler.
- surajrmal 1y agoRust for Linux still uses null terminated strings for comparability.
- Incipient 1y agoThis is definitely unexpected for me - I'd have thought something like an RC for a kernel would have to be 'approved' for release only after passing all tests, which should include building with all official compilers (and all official architectures, etc). Unless either the older GCC or the beta GCC isn't "official"? In which case that's not necessarily expected to be picked up in an RC?
- bonzini 1y agoRelease candidates are just time-based for many projects. For Linux, in addition, the rhythm of stabilization can be different for various subsystems.
- Philpax 1y agoMy understanding is that Linux has no form of CI [0], so they don't actually have an automated way to check for compilation across all platforms and compilers. [0]: https://lwn.net/Articles/1018802/ https://lwn.net/Articles/1018802/
- bjourne 1y agoErr... we teach C neophytes that you should never write values to variables that are larger than what the variables can hold. Don't write an int to a short, don't write a short to a char, and don't initialize five bytes to an array storing four bytes. Am I missing something here? char foo[4] = "ABCD" is always incorrect, no ifs and buts. If you want "readable" bytes, use character literals. You should never discount the null terminator.
- SonOfLilit 1y agoYes, you're missing something. Sometimes I'll need an array of 4 ints, so I'll define one: int a[4] = {1,2,3,4}; other times I'll want 4 bytes. So sure, I can write: char a[4] = {'A','B','C','D'}; However, (I hope) I'll get the exact same compiler warning as the more readable: char a[4] = "ABCD"; that does the exact same. So I'll need the __nonstring__ anyway. And then why not use the more readable syntax, since I'm telling the compiler and reader explicitly that I don't want a null terminator? The core issue is C's habit of using the exact same language construct for different purposes, here char[] for both uint8_array and null_terminated_str.
- bjourne 1y agoYour char a[4] is not more readable and sooner or later you'll get screwed by strlen(a) or some such. It's quite telling that the construct is not legal in c++.
- SonOfLilit 1y agoWhy would I run strlen() on the second one but not on the first one? Presumably I know that I defined an array of chars and not a cstring? Or if I forget, couldn't I forget in the first case too? Once I defined it, they're both just char[4]s.
- nofriend 1y ago> However, (I hope) I'll get the exact same compiler warning as the more readable: The latter is a null terminated string, the former is not. Compiler warnings are principally a set of heuristics for bad code. Heuristically the first example is more likely to be intentional than the latter.
- mastax 1y agoIt’s still shocking to me that there’s no official kernel CI.
- quink 1y agoWouldn’t mind if Torvalds could do to CI/CD what he did to VCS with git.