Seems rather like an very incomplete view of a C++ programmer, wanting to raise it to "systems programmer".
Seems rather like an very incomplete view of a C++ programmer, wanting to raise it to "systems programmer".
Immutable is kind of irrelevant in a discussion of multi-threading because immutable data has no problems in this regard. Which, of course, in a way also makes it relevant because one prevents issues. Ultimately one cannot have just immutable data because the computer would not be allowed to do anything. This document would be about data that cannot be immutable.
But the complaint sounds a bit like an article about assembly language getting the complaint that it does not explain how to implement a word processor.
You need mutation or garbage collection (and systems programming is the kind of environment where that's not just "someone else's problem").
The point of this article is to detail needs for those monads to interact in a concurrent manner.
To push back on this, no data is completely immutable, it is mutable on initialization, treating it as immutable between threads is ok after this stage, but if you disregard issues with timing and mutation you will run into problems between threads on initialization.
I'm not sure I understand this comment. C++ is one of the very few languages that can be used for programming everything from a web server to a garbage collector to firmware. There's no "raising" going on here.
Presumably, you're thinking of systems in the more abstract sense: systems of more or less pure software components that model some domain. That's just not what this article is about.
You could absolutely get a job as a system programmer not knowing and never touching C++, but not knowing Shell will not get you anywhere in that field.
It doesn't really have to be direct or tight (not even sure what that might mean). I'm guessing you were trying to say that it has to have minimal overhead compared to theoretically possible performance, in which case that's not true at all (a lot of Linux services and management tools are written in Shell, which just isn't known for great performance at all).
C was the overwhelming language of choice for a very long time, but C++ made steady and verysignificant inroads in the last 20 years. Objective-C and Java had/have niches. Rust and Go have traction and continue to gain more. Swift is working towards it.
Actors and immutable types, which the GP mentioned, have less signifance here because they largely trade transparent resource management (which is critically important in many of these projects) for correctness guarantees and sophisticated domain modeling. That said, we can expect there to be more room for them, especially where implementations of those features are zero/low-overhead.
C++ has very little (basically nothing) to do with what Python or Shell call. When I mention these languages in the context of system programming, I mean programs like, eg. ifup / ifdown or GRUB configuration, LDAP client utilities and so on.
C++ was and still is an unwelcome guest in this area. It's not minimalist enough to be easy to use in constrained environments, but when resources allow it, there are better languages for any task you can think of. In my experience, the only people who insist on using C++ are the Visual C++ Windows programmers. But, overwhelming majority of system jobs aren't for MS Windows, so, the Visual C++ people can be safely ignored. In the same way how you can safely ignore Objective-C, when it comes to system programming. You can work in the field of system programming whole your life, switch dozens of companies and products, and never hit C++ or Objective-C requirement. They are too niche and unimportant in the large scheme of things.
If, on the other hand, you were looking for a field where C++ is the most common language, then video games come to mind. Enterprise applications, especially targeting MS Windows, usually with a significant GUI component. It's really not meant, and doesn't work well as a system programming language. It's OK for application development (but there are better alternatives today). It survives due to the existing libraries and compilers, and, of course, expertise accumulated in programming community. But, that expertise and libraries are mostly in the fields mentioned above.
I don’t particular like how torch is designed and written, but that’s a different story. TensorFlow is c++ as well, in case you wondered.
But maybe that all does not match your requirements for system programming? Try Haiku, at least back when it was BeOS I really liked that the whole OS was written in C++. I have a colleague who wrote some microcontroller code in C++ because he likes it so much and I don’t think there’s anything wrong with that either.
The whole OS was written in many languages. It's hard to think about a mainstream language that wasn't used to write an OS. I think, you can even find OS written in PDF, if you persist at your search. This doesn't mean that PDF is a good system programming language, or that it's worth considering in this domain...
PDFs are if I’m not mistake not turing complete, they omitted those PS features from the standard for various reasons, so you probably can’t write anything reasonable in “PDF” (unless you use embedded JS etc)
As far as mentioning shell and Python, I don't consider those primary system programmer tools. You might need to know them to be a good generalist *nix system programmer, but it's really tangential to whether C++ has a place in systems programming. Python and shell are in competition with Perl and Tcl, not with C++. To say that they are is like saying a carpenter is in competition with a welder because they both build stuff.
Those are all gimmicks. They aren't really worth considering if talking about system programming. Again, if you want to be a system programmer, and you want to know what languages will get you there, then C++ isn't in that list. It's unimportant. Can you use it for system programming? -- Yes, if you don't have better things to do with your life. Will it be a good choice? -- No, for virtually any problem that exists in that domain there will be a better pick.
> Microsoft Windows is the most popular operating system in the world
No it's not. It's a very niche operating system. It's the most popular operating system in the world of desktops. But, if we are selecting arbitrary electronics form-factor, then any operating system can be made the most popular in the world. Pretty sure FreeBSD is the most popular operating system in the world, if you choose that the only computers that matter are those that run FreeNAS.
> C++ can be easily integrated anywhere C is used
And so are Python, JavaScript, Rust, Ada, PostScript, Awk, Forth and many, many other languages. What's your point?
> System programmers are more likely to know C and C++ than Java
Tell me you've never worked in the field of system programming without telling me you've never worked in the field of system programming. Java is a very popular pick for writing management components for enterprise-grade system products. I've seen multiple storage products where the part of the product that did the storage part was written in C, but the management was written in Java. I've seen this more often than I've seen any C++ used in system programming. The problem is more cultural, probably. The Visual C++ programmers usually don't have a good grasp of what good system programming tools / practices would be. Just the very mention of C++ in one's resume would often be enough for that person not being invited to an interview.
> I don't consider those primary system programmer tools.
Why should anyone care about what you consider? Are you an expert in this field? So far you've shown complete lack of expertise...
It's the most popular operating system except for on phones and it has been for decades.
>Why should anyone care about what you consider? Are you an expert in this field? So far you've shown complete lack of expertise...
I have over 20 years of experience writing C++ and I know it is used widely. Your characterization of it as niche in embedded or OS is completely wrong. I'm not going to say where I work but you've heard of it.
> The Visual C++ programmers usually don't have a good grasp of what good system programming tools / practices would be. Just the very mention of C++ in one's resume would often be enough for that person not being invited to an interview.
The fact you keep referring to "Visual C++" and make sweeping generalizations about C++, especially in a systems context, tells me you are severely lacking in expertise.
> Pretty sure FreeBSD is the most popular operating system in the world, if you choose that the only computers that matter are those that run FreeNAS.
This is such a mischaracterization that you should know better. Windows is on literally billions of computers and embedded things. FreeBSD is not even on most NAS devices.
>And so are Python, JavaScript, Rust, Ada, PostScript, Awk, Forth and many, many other languages. What's your point?
If you think any of those is as easy to integrate with a C operating system as C++, you're dangerously uneducated and have no place lecturing anybody about anything programming-related, especially systems programming. I don't enjoy being so blunt but you're wasting my time and yours and spreading silly anti-C++ propaganda.
[1] Which is not to say "best". My standard complaint in these threads is that the C++ ordering semantics are a mess designed to make things easier for compiler writers to target architectures with variant ordering guarantees and not for algorithm developers to create correct code. But lockless code is much harder to write than compilers! It's a bad trade. ARM had this right decades ago with simple read/write barriers, which are vastly easier to understand when reading code.
The acquire/release semantics make perfect sense for locks, because that's what it was designed for. Designing anything else with them is extremely difficult, and in practice such work tends to lean heavily on the full-barrier "sequentially consistent" primitive instead. The older read/write barrier instructions were much simpler. (And x86 is simpler still, with just one reordering rule to worry about and a single idea of serializing instructions to regulate it).
C++ memory model is there to make life of a programmer easier across different micro-architectures because memory model of the micro-architecture is what differs.
After all, if the software most people execute rewards CPUs which do X and punishes CPUs which do Y instead, it's a tough sell to design your CPU to do Y, that means ordinary users will get the idea it's worse than it really is, and your sales people don't like that, it seems reasonable to argue that the reason modern x86-64 CPUs ignore the weird x87 FPU features is that nobody's programs want those weird features.
I remember in the mid-1990s there was a lot of hype for high clock frequency 80486 and clones because they had very good integer performance. However, Intel's Pentium had excellent FP performance at similar or lower clocks. The video game Quake needed floating point, and so Quake on my 100 MHz Pentium was very quick, while on a friend's 100MHz 486 it was pretty nasty. Increased sales of the Pentium were I believe widely attributed to the game Quake showing off the FP performance (it's nothing to look at in today's terms, we did not have GPUs back then).
I have never worked for a CPU design firm or CPU manufacturer, so I can't speak to whether this is in practice a meaningful influence.
I never heard that argument (source would be good?) but this is very different to what the parent comment said. Code does not run in vacuum - it runs on the CPU. And CPU does not exist vacuum - it's there to run that very code so they're both very inter-dependent and intertwined. As much as CPU designs are changing to accommodate new algorithmic requirements so does the code but vice-versa - to make a utility of new CPU designs.
So, of course, CPU vendors will do everything that is in their control to make the new chip design appealing to their customers. This has been done forever. If that means spending extra transistors to run some C++ heavy data center code faster by 10% of course they will do it - there's a very large incentive in doing so.
But that doesn't mean that CPU vendors are designing their chips to accommodate abstract programming language models. In this case, memory models.
Probably one of the most easiest examples of such practices to understand, and that I could think of right now, is Jazelle - an ARM CPU circuitry designed to execute the Java bytecode directly in the CPU itself.
It's basically exactly what the parent comment said, FWIW. :)
I don't think I agree that this doesn't mean the memory model infects the CPU design. Actually I don't think I agree more generally either. For example I would say that the Rust strings are fast despite the fact that modern CPUs have gone out of their way to privilege the C-style zero terminated string. There are often several opcodes explicitly for doing stuff you'd never want except that C-style strings exist. They would love to be faster but it's just not a very fast type, so there's not much to be done.
Contrast this with say, bit count, which is a good idea despite the fact it's tricky to express in C or a C-like language. In a language like C++ or Rust you provide this as an intrinsic, but long before that happened the CPU vendor included the instruction because this is fundamentally a good idea - you should do this, it's cheap for the CPU and it's useful for the programmer, the C language is in the way here. "Idiom recognition" was used in compilers to detect OK, this function named "count_pop" is actually the bit count instruction, so, just use that instruction if our target architecture has it. More fragile than intrinsics (because it's a compiler optimisation) but effective.
At an even higher level, from the point of view of a CPU designer, it would be great to do away with cache coherence. You can go real fast with less transistors if only the stupid end users can accept that there's no good reason why cache A over here, near CPU core #0 should be consistent with cache D, way over on another physical CPU, near CPU core #127. Alas, turns out that writing software for a non-coherent system hurts people's brains too much so we've been resolutely not doing that. But that's exactly a model choice - we reject the model where the cache might not be coherent. Products which lack cache coherence struggle to sell.
Acquire/release happened to be a good fit, easy enough to program for, and relaxed enough to map relatively closely existing architectures. So C++11 embracing it was just moving with the zeitgeist.
For example Itanium got acquire/release operations well before the work on the C++11MM even started.
The x86 is the weird architecture that tried to keep existing programs working when they moved to multicore. Most other architectures implemented whatever is easier to implement in hardware, and compilers have to target that. And the compiler can't simulate a strong memory model on top of a weak one, because that means lots of overhead for every memory operation and that's not what C does.
One of the interesting problems for Rust-for-Linux is what to do about that, Rust has all of the C++ 11 memory ordering except the problematic (and in practice abandoned) Consume ordering, but it doesn't have a convenient way to admit a different model, yet Linus isn't exactly likely to wake up one day and declare now Linux has the C++ 11 ordering model.
As to your concern, of course the compiler vendors have to worry about portability. It's all very well to say this works on ARM, but the expectation from a person writing Rust or even C++ is that a correct program should work on all of an ARM, an x86, archaic PowerPC and somebody's cheap in-order embedded CPU.
If the vendor only really cares about one architecture (cough, Microsoft) then they might invent weird rules that only really make sense for that architecture and your "correct" programs either don't work, don't compile, or are very slow on every other CPU. But that's hardly a reliable way forward into the future.
Yes, but the point was that "defining a language that doesn't suck" is a competing requirement. Again, C++ just dropped the ball here and solved the wrong problem. And we all suffer for it with repeated blog posts like this one trying desperately to explain exactly what "acquire" means and not how hardware actually works.
And yes: Linux has clean and easy (or as easy as these things get) read/write barriers, the implementation of which has now been terribly polluted by the toolchain's incompatible choice of semantics.
The term "systems programmer" is right there in the title. They are also the very first words in the article. The examples are in C++, but the whole document focuses on both C and C++. The article clearly focuses on the primitives, as it should.
It's undoubtedly a great article on the subject, but nitpickers have to nitpick, and one-uppers have to one-up.
I look forward to read your article on the topic.