[HN Gopher] The C++ Killers (Not You, Rust)
___________________________________________________________________
The C++ Killers (Not You, Rust)
Author : todsacerdoti
Score : 67 points
Date : 2024-03-20 18:44 UTC (4 hours ago)
(HTM) web link (wordsandbuttons.online)
(TXT) w3m dump (wordsandbuttons.online)
| sylware wrote:
| rv64 assembly is the new C.
| bfrog wrote:
| C++ itself seems to be working pretty hard year after year on
| this task of killing C++ with endless half baked features that
| fail to address real problems
| zabzonk wrote:
| they do address real problems - specifically those of people
| trying to write very efficient libraries. if you are not in
| that group, simply don't use those features.
| UncleMeat wrote:
| And yet they can't update the standard library types to not
| be slow as hell because of ABI concerns.
|
| If C++ was really all about speed then we'd have destructive
| move letting you pass unique_ptr in a register without
| compiler trickery. The fundamental number one constraint on
| new C++ behaviors is ABI compatibility. The rest is
| secondary.
| zabzonk wrote:
| the c++ standard does not specify an ABI.
| UncleMeat wrote:
| The c++ standard absolutely cares deeply about abi
| compatibility. The committee can't even update intmax_t
| because it is an abi break. "Code compiled today and
| linked against code compiled years and years ago must
| behave correctly" is an absolutely premier design
| constraint when it comes to papers and it has prevented
| oodles of low hanging performance opportunities.
| zabzonk wrote:
| quote from standard where it says that?
| Const-me wrote:
| Sadly, the C++ standard bodies are actually breaking old code
| in new versions of the language.
|
| For example, C++/11 introduced UTF8 string literals. Great
| feature which does what you'd expect - declare a string
| literal in source code, get a const pointer to null-
| terminated array of utf-8 bytes.
|
| Then a decade later, in C++/20 they refactored these UTF8
| literals to evaluate into const pointers to the new
| incompatible data type, char8_t.
|
| It's so bad that compiler developers had to implement
| switches to disable the new BS. Unfortunately, these switches
| are incompatible across compilers, -fno-char8_t in gcc,
| /Zc:char8_t- in msvc.
| ilovefood wrote:
| Beautiful and well written article. Unfortunately I made a small
| mistake in the second quizz :P
| felipellrocha wrote:
| > The matter is, none of the languages, especially the so-called
| "C++ killers" give any real advantage over C++ in the modern
| world.
|
| To you. There are pleeenty of people who want to write performant
| code in a safe manner.
| pipeline_peak wrote:
| > None of these questions have a definite answer without context.
|
| This is a pretty annoying thing to do considering someone took
| the time to read through all this.
|
| Also not original, I've seen posts in here like this 3 times
| already
| arcticbull wrote:
| > But why can't I just quit then? What's the matter? The matter
| is, none of the languages, especially the so-called "C++ killers"
| give any real advantage over C++ in the modern world. All those
| new languages are mostly focused on holding a programmer on a
| leash for their own good.
|
| This, very specifically, is the advantage these languages have
| over C++.
|
| The benefit isn't the universe of things you can do (they're all
| Turing complete, you can do anything) - it's what the language
| stops you from doing. This is the thing the C++ committee never
| understood or at the very least never appreciated.
| zabzonk wrote:
| why do you think the designers of those new languages know what
| is good for you?
| kstrauser wrote:
| Because they tell me to stop managing memory by hand, as we
| have mountains of experiment proof that no one[0] is good at
| it.
|
| [0] I meant what I said.
| zabzonk wrote:
| um, modern c++ has for at least the past 10 years advised
| people not to manually manage memory.
| dekken_ wrote:
| not really, RAII/shared_ptrs is still manual memory
| management, just less footguns
| zabzonk wrote:
| well, i would not recommend shared_ptr except under rare
| circumstances, but i don't see what can be wrong with
| RAII. in fact, it is the languages thar don't have RAII
| that have the problems, IMHO.
| andyferris wrote:
| One thing I love about C++ is it (mostly) stops me making
| type errors, compared to dynamic languages - "compile and it
| works". Adding type constraints makes programming safer,
| easier, and results in better compilation.
|
| You can add other constraints (e.g. temporal constraints) and
| get similar benefits, on top of the above.
| dale_glass wrote:
| Because I believe safety critical places like aviation are
| the ones that actually get things right. You can't pile on
| every demand on the human in charge and expect improvement.
| We're just not great at taking every possible detail into
| account. Doing lots of grunt work all the time reliably is
| what we have computers for.
|
| In my old age, I find the more permissive a language is, the
| more painful it is to code in long term. Perl is great for
| simple things, but C++ was a vast improvement because it
| catches a lot of nonsense that Perl will compile just fine.
|
| And debugging is so expensive that eventually writing code
| fast is near worthless. Whatever you gain you more than pay
| for in debugging afterwards.
|
| C++ unfortunately doesn't go far enough.
| zabzonk wrote:
| yes - i switched from C to C++ a long, long time ago (late
| 1980s) because C++ was so much more strongly typed (i still
| don't understand why other C programmers have stuck with
| C). i'm less than convinced with the promises of rust (for
| e.g.), but have only written trivial programs in it.
| steveklabnik wrote:
| They don't. What they do is create a system where the system
| protects itself from human error. They don't know better than
| me: I agree with what they're doing. Automatic enforcement of
| good things, plus an escape hatch for emergencies, is better
| than no restrictions ever.
| wk_end wrote:
| I assume you program in assembly language, then? Can't trust
| those structured programming types to know best how to manage
| your instruction pointer after all. "Functions", "loops",
| "conditionals", all just fancy words for straitjackets.
| vundercind wrote:
| I'd love a demographic study of folks who are really
| unhappy about languages like Rust and Go specifically
| because they believe they're crushing their creative
| spirit. The "I need MAXIMAL EXPRESSIVENESS at all times!
| Don't tell me how to do things!" sort
|
| I hesitate to even guess what the findings would look like,
| but I bet it'd be interesting.
| tmtvl wrote:
| But when programming in assembly you're still beholden to
| the CPU designers in regards to out of order execution and
| branch prediction and all those fancy layers taking runtime
| control away from you. Better to just print your own
| silicon.
| keybored wrote:
| Language implementers _ought to_ know better than me (the
| user) about programming language semantics, in this case
| specifically things like memory safety.
| mgaunard wrote:
| Memory safety is a very small fraction of the problems a
| computer program can have, and replacing them by an
| immediate shutdown is hardly a very useful improvement on
| program quality.
| sophacles wrote:
| > Memory safety is a very small fraction of the problems
| a computer program can have
|
| And a large fraction of the problems that lead to
| security situations. Worse, they are often so subtle that
| they stay in a codebase for decades.
|
| > and replacing them by an immediate shutdown is hardly a
| very useful improvement on program quality.
|
| That's a pretty absolutist statement about something
| that's very context dependent.
| stavros wrote:
| This is a bit of a misnomer, languages don't generally _stop_
| you from doing things. They just make really damn sure that
| you aren 't doing it by accident.
| Brian_K_White wrote:
| what do you think those new languages prevent you from doing?
| UncleMeat wrote:
| Is a bounds check on every container access good for me? Not
| always. Sometimes my code is correct. But security
| vulnerabilities are observably a huge problem. And you only
| need one vuln in iMessage or whatever to get a dissident
| journalist's phone hacked and then get them murdered by the
| Saudi government. Is "I know what I'm doing, I promise" good
| enough for you in that case?
|
| I find it interesting because until about three years ago,
| C++ was always on the other side of this argument. We fight
| about static type systems. You could shout at the compiler
| that you know that your code is correct even though the type
| system doesn't pass. Why does the committee think it knows
| better than me! Everything is just bits after all!
|
| Now we are on the other side. C++ people saying "bro I
| totally promise I'll initialize this data member before it is
| used, stop making me initialize it in my constructor"
| zabzonk wrote:
| > Now we are on the other side. C++ people saying "bro I
| totally promise I'll initialize this data member before it
| is used, stop making me initialize it in my constructor"
|
| C++ has never said this - if a type has a constructor, that
| constructor will always be used in a data member (or
| elsewhere).
| UncleMeat wrote:
| ???
|
| You can absolutely write a type like this.
| class Foo { public: Foo() {} // never
| initialized x int x; }
|
| And then using it like this Foo f;
| bar(foo.x); // oops
|
| "But my types are well designed" is the usual response to
| "why the heck does the language allow you to quietly
| expose yourself to UB in this way?"
| munificent wrote:
| zabzonk said "if a type has a constructor", but I don't
| think the int type does, which is why you get
| uninitialized memory here.
|
| Any instance of Foo will run Foo's constructor because
| Foo has one. The problem is that that instance of Foo
| won't definitely have x initialized, because int doesn't.
| zabzonk wrote:
| i said "if a type has a constructor". but if you are
| fiddling around with ints and chars and the like, then
| you will need to initialise them. i have been writing c++
| since the mid80s and have never found this to be a
| problem, or at least no more than it would be to use an
| uninitialised int variable in C.
| arcticbull wrote:
| The fact this is even a distinction anyone has to keep in
| mind is again and example of the problem. People are
| _awful_ at remembering these weird little details. We
| shouldn 't make expect people do things they're bad at,
| all the time, and well. And I'll go a step further and
| say we shouldn't _let_ them by default. They should have
| to make it super explicit they want to opt into the weird
| behavior nobody expects.
|
| You can do this in Rust if you want! You just have to use
| unsafe { mem::uninitialized() } or even better, the newer
| unsafe { mem::MaybeUninit::uninit() }
|
| The whole point is that you _probably_ don 't ever want
| to have an uninitialized variable you can access willy-
| nilly, and if you do, you should be very explicit.
|
| Even your statement about C (and C++) isn't quite
| accurate, right, because anything static is guaranteed to
| be initialized to zero on creation. So while `int x` is a
| free for all, `static int x` is gonna be zero. Another
| thing people shouldn't have to think about!
|
| Principle of least surprise.
| munificent wrote:
| This is such a silly send-up. They don't know what's good for
| me. They tell me what their language is good for. I decide if
| what the language is good for is good for me.
| vundercind wrote:
| How could they know that?
|
| They might know how to design a language such that it tends
| to produce exceptionally readable codebases, good
| performance, and improved safety, though. Maybe not all three
| at once, but some mix of those that's better than existing
| languages, perhaps.
| scrubs wrote:
| If Austin Powers was a programmer:
|
| On a leash? What? ... [if only I could work in a] consequence-
| free environment, I'll be sound as a pound!
| spease wrote:
| In other words, the "feature" those languages have is reducing
| the cognitive complexity and more tightly bounding the risk.
|
| Newer languages are adding friction or dropping altogether
| things that you rarely or never want to do, to more tightly
| constrain the space of possible actions to the set of desired
| actions.
| wslh wrote:
| Great article more about different approaches to building
| software that languages themselves.
|
| My two cents: it is improbable that C++ will be ever replaced
| because it is a mastodon as a programming language: super
| complex, where complex includes complexity as difficulties and
| also its vastness. This doesn't mean that it will increase its
| usage since it is common nowadays to use specific programming
| languages (e.g. Python) for specific purposes and rely on C++ and
| others for very specific areas. Personally, I really liked SWIG
| [1] as a wrapper and interface generator. Don't know how much it
| is used today.
|
| Other experience but similar conclusion than the article.
| pornel wrote:
| Looks like the author is very focused on maximally optimizing
| some very compute-heavy signal-processing code, and doesn't care
| much what is used outside of the compute kernel.
|
| So it may be very true that for their work it's all the same
| whether they use C++, or Python with numeric libraries, or some
| niche DSL, or a macroassembler.
|
| But use of C++ is much broader than pure compute, so this
| perspective does not generalize to C++ or Rust as a whole.
| bun_terminator wrote:
| > Do you know that in MSVC uint16_t(50000) + uin16_t(50000) ==
| -1794967296?
|
| Not only is that insane code and both my compiler and static
| analysis go for my throat, it's also not true. I think the
| argument is supposed to be about unsigned integer overflow, but
| the numbers don't add up. The big negative number wraps to 63744.
| And the sum (100K) wraps to 34464.
| dzaima wrote:
| It seems the intent was for "*" to be used instead of "+". At
| which point it's actually undefined behavior even though the
| operands are unsigned!
| bun_terminator wrote:
| that makes more sense!
| lookitsnicholas wrote:
| may be slightly off-topic, but that website favicon is
| suspiciously reminiscent of the logo that Ableton currently use
| hahah
| omoikane wrote:
| > Do you know that in MSVC uint16_t(50000) + uin16_t(50000) ==
| -1794967296?
|
| There are two typos in this statement, one is "uin16_t" should
| have been "uint16_t", the other is that the "+" should have been
| "*". Searching for 1794967296 yields this answer:
|
| https://stackoverflow.com/questions/18161443/type-casting-wh...
| tomcam wrote:
| > I made a simple Lisp-style interpreter to help game designers
| automate resource loading, and went on a vacation. When I was
| back, they were writing the whole game scenes in this interpreter
| so we had to support it for a while.
|
| I very much want to hear that story
| mgaunard wrote:
| Of course I know that uint16_t+uint16_t gives an int. If you're
| gonna be programming in C or C++, you need to know these things.
|
| And yes, I do agree the fact that I know so much minutiae about
| those languages is part of the reason why I'm reluctant to go for
| something else I have a more shallow knowledge of. But that level
| of attention to detail is also what allows me to deliver high-
| quality code that does exactly what I intend it to do.
| imadj wrote:
| Related discussion:
|
| The C++ Killers (Not You, Rust) - Feb 2023 (59 comments) :
| https://news.ycombinator.com/item?id=34792932
|
| It seems author has published the article last year but moved it
| to his blog now
| npongratz wrote:
| > Just as Latin never actually died, just like COBOL, Algol 68,
| and Ada, - C++ is doomed to eternal half-existence between life
| and death.
|
| I'm almost afraid to ask, but I'd love to know: are there any
| Algol 68 projects in active use? Anyone have war stories of
| maintaining them (bug fixes, new features, improvements to
| interface with more modern systems) in the last couple decades?
| zabzonk wrote:
| certainly not active, but back in the 1980s i got dumped on a
| program that used algol, bcpl, fortran and cobol to drive a
| phototypesetter to do ... something. this took advantage of the
| fact that the dec10 allowed you to mix & match languages, much
| like the vax. i suppose i was lucky the idiot that originally
| wrote it didn't throw lisp into the pot.
|
| anyway, as i was hired as a microcomputer specialist, and as
| two dec10 systems programmers had ducked it, i simply said "no
| can do" - a valuable lesson.
|
| this is what i like about HN - recalling things i had
| completely forgotten!
| mgaunard wrote:
| The sine polynomial is bad because it's not written in a way that
| removes redundant multiplications.
|
| Those redundant multiplications cannot be removed without fast
| math because floating-point operations are not associative.
|
| There are well-known optimal ways to evaluate a polynomial,
| namely Horner's and Estrin's schemes.
| marmaduke wrote:
| Numba is great but missing explicit simd, stack allocated arrays,
| and user defined types, to name a few things. I tried to keep my
| colleagues in Jax these days.
| xiaodai wrote:
| Nicely written. I learned a lot
___________________________________________________________________
(page generated 2024-03-20 23:01 UTC)