I’m not usually one to comment on these sorts of issues but it ticked me off how the author of this article consistently decided to refer to leah2 by her deadname and to use the wrong pronouns. Kinda took me out of the article, oh well.
I don’t intend to speak for Leah but according to her comment I was replying to, she’s clearly not stoked about it. I think that’s a good enough indication that this wasn’t really the way the author should have approached mentioning her if the intent was to respect her. I’m not trying to frame the blog post as an “attack” either, but yeah. I don’t think there’s really a discussion to be had here.
n.b.: I do not know Leah nor have I have ever talked to her.
yeah, that struck me too. i wish there was a flag like, “this is ok except i would rather not have to endure ambient transphobia with my os/compiler blog post”
I don’t enjoy writing Rust and I don’t like that it cannot be bootstrapped from C. But, it is really ill-informed to call Rust security theater. Rust solves real issues!
Thanks, I was not aware of this and it’s interesting so see their way of keeping complexity under control in their system.
It mentions how “Before that, sabotage was strictly C-only”, and only afterwards did they include C++ code. I’ve been using C more again, because for certain programs it’s refreshing to keep things simple. For others, it is worth it to use Rust and C++. The only way to keep unnecessary complexity at bay is to push constantly against it as these guys are doing.
I use a different Linux distribution, but I benefit indirectly from their work.
I’ve recently been writing some C again and it requires me to write more code than I would in C++ to generate equivalent machine code. Pushing for complexity at one level doesn’t necessarily give lower complexity overall. For example, we wrote snmalloc in C++. It compiles to about half as much object code as jemalloc (written in C) and performs better. Our platform abstractions are classes (where, for example, both Linux and *BSD inherit from a generic POSIX implementation and replace methods with non-portable bits) and so the only things platform-specific are isolated in a separate class and pulled in as template parameters elsewhere, compared to the large number of platform #ifdefs in jemalloc.
You are right, there are different forms of complexity, and as Stroustrup mentioned in his interview with Lex Fridman, good abstractions allow an optimizing compiler to do a better job:
I used to mention C but these days going low-level is not actually what gives you the performance. It is to express your ideas so cleanly that you can think about it and the optimizer can understand what you’re up to.
My favorite way of optimizing these days is to throw out the clever bits, and see if it still runs fast. And sometimes it runs faster. So I need the abstraction mechanisms of something like C++ to write compact high-performance code.
There was a beautiful keynote by Jason Turner at the CppCon a couple of years ago, where he decided he was going to program Pong on a Motorola 6800 I think it was ¹ […]
So he shows in real time how he writes Pong, starting with fairly straightforward low-level stuff, improving his abstractions, and what he’s doing, he’s writing C++ and it translates into […] assembler […] and you can see it in real-time […]
So he types and you can see it in real time, and even if you can’t read the assembly code you can just see it, his code gets better, the assembler gets smaller.
He increases the abstraction level, uses C++ 11 as it works better, this code gets cleaner, gets easier to maintain, the code shrinks and it keeps shrinking, and I could not in any reasonable amount of time write that assembler as good as the compiler, generated from really quite nice modern C++, and I’ll go as far as to say the the thing that looked like C was significantly uglier and larger when it became machine code.
¹. Jason Turner’s presentation was about writing a game for the Commodore 64, thus a Mostek 6510/6502 which indeed was initially designed as an improved version of the Motorola 6800. The shrinking-assembly action starts at 12:12″:
https://www.youtube.com/watch?v=zBkNBP00wJE&t=732s
I’d not see Jason Turner’s talk, but it was amazing. Nothing that should surprise a C++ programmer but a great example of how many of the abstractions are zero cost. Even including the embedded data, he ends up with less than one 6502 instruction per line of code (including blank lines and comments) and the C++ source is incredibly clean, readable, and easy to maintain. I’d love to see a follow on where he ports it to a Z80-based system with different joystick hardware and a different sprite acceleration. It would need some code changes but I bet you could reuse most of the code and also keep the generated 6502 output the same size.
The C++ code that I’m happiest with in this regard is this signal handler, which is reached when a seccomp-bpf (Linux) or capsicum (FreeBSD) sandboxing policy is violated. The OS-enforced policy in both cases is slightly over-restrictive and I want the running code to invoke an RPC to a more-privileged process in some cases. For each OS/architecture pair, there’s a helper class that knows how to pull an argument of a specific type and at a specific index out of the ucontext_t, how to get the syscall number from the siginfo_t and how to inject the return value back into the ucontext_t. This is a very small bit of code (syscall arguments on x86-64 are all sign or zero extended values in registers, so it’s trivial to just grab the arg from the right register and truncate as required. For x86-32 it would be a bit more complex because the arguments are on the stack, but even that would be pretty simple).
For each system call that you want to handle, you provide the system call number and the function that does the RPC. The arguments that need to be extracted are inferred, extracted, and forwarded by some completely generic logic. Doing this in C would be a mess.
I’m not usually one to comment on these sorts of issues but it ticked me off how the author of this article consistently decided to refer to leah2 by her deadname and to use the wrong pronouns. Kinda took me out of the article, oh well.
Not only me, but also other people involved. :(
That’s awful, there’s no justification why the author would do that. I’m sorry for you and everyone else involved. :(
I wouldn’t treat this as an attack. It’s a historical account of the past years where people went by different names in the past 10 years.
I suggest you read https://leahneukirchen.org/faq.html
Ok.
Leah’s name has not been updated in the referenced git repository.
Anyway, I do not think it was an intentional attack.
I don’t intend to speak for Leah but according to her comment I was replying to, she’s clearly not stoked about it. I think that’s a good enough indication that this wasn’t really the way the author should have approached mentioning her if the intent was to respect her. I’m not trying to frame the blog post as an “attack” either, but yeah. I don’t think there’s really a discussion to be had here.
n.b.: I do not know Leah nor have I have ever talked to her.
From the article:
It seems pretty clear that her new name is known and clarified.
Same, plus the Rust as a Microsoft + Mozilla + Google conspiracy against open source.
yeah, that struck me too. i wish there was a flag like, “this is ok except i would rather not have to endure ambient transphobia with my os/compiler blog post”
Void Linux offered musl in 2014 too.
I don’t enjoy writing Rust and I don’t like that it cannot be bootstrapped from C. But, it is really ill-informed to call Rust security theater. Rust solves real issues!
Thanks, I was not aware of this and it’s interesting so see their way of keeping complexity under control in their system. It mentions how “Before that, sabotage was strictly C-only”, and only afterwards did they include C++ code. I’ve been using C more again, because for certain programs it’s refreshing to keep things simple. For others, it is worth it to use Rust and C++. The only way to keep unnecessary complexity at bay is to push constantly against it as these guys are doing. I use a different Linux distribution, but I benefit indirectly from their work.
I’ve recently been writing some C again and it requires me to write more code than I would in C++ to generate equivalent machine code. Pushing for complexity at one level doesn’t necessarily give lower complexity overall. For example, we wrote snmalloc in C++. It compiles to about half as much object code as jemalloc (written in C) and performs better. Our platform abstractions are classes (where, for example, both Linux and *BSD inherit from a generic POSIX implementation and replace methods with non-portable bits) and so the only things platform-specific are isolated in a separate class and pulled in as template parameters elsewhere, compared to the large number of platform
#ifdef
s in jemalloc.You are right, there are different forms of complexity, and as Stroustrup mentioned in his interview with Lex Fridman, good abstractions allow an optimizing compiler to do a better job:
https://www.youtube.com/watch?v=uTxRF5ag27A&t=1186s
¹. Jason Turner’s presentation was about writing a game for the Commodore 64, thus a Mostek 6510/6502 which indeed was initially designed as an improved version of the Motorola 6800. The shrinking-assembly action starts at 12:12″: https://www.youtube.com/watch?v=zBkNBP00wJE&t=732s
I’d not see Jason Turner’s talk, but it was amazing. Nothing that should surprise a C++ programmer but a great example of how many of the abstractions are zero cost. Even including the embedded data, he ends up with less than one 6502 instruction per line of code (including blank lines and comments) and the C++ source is incredibly clean, readable, and easy to maintain. I’d love to see a follow on where he ports it to a Z80-based system with different joystick hardware and a different sprite acceleration. It would need some code changes but I bet you could reuse most of the code and also keep the generated 6502 output the same size.
The C++ code that I’m happiest with in this regard is this signal handler, which is reached when a seccomp-bpf (Linux) or capsicum (FreeBSD) sandboxing policy is violated. The OS-enforced policy in both cases is slightly over-restrictive and I want the running code to invoke an RPC to a more-privileged process in some cases. For each OS/architecture pair, there’s a helper class that knows how to pull an argument of a specific type and at a specific index out of the
ucontext_t
, how to get the syscall number from thesiginfo_t
and how to inject the return value back into theucontext_t
. This is a very small bit of code (syscall arguments on x86-64 are all sign or zero extended values in registers, so it’s trivial to just grab the arg from the right register and truncate as required. For x86-32 it would be a bit more complex because the arguments are on the stack, but even that would be pretty simple).For each system call that you want to handle, you provide the system call number and the function that does the RPC. The arguments that need to be extracted are inferred, extracted, and forwarded by some completely generic logic. Doing this in C would be a mess.