Live data from Hacker News

Modern C++ Won't Save Us (2019)

alexgaynor.net

181–190 of 266 posts

Re: Modern C++ Won't Save Us (2019)

#181
post #129

Here's the point of view from someone who has only written 1 piece of production software with both C++ and Rust. Trying to write C++ I was constantly fighting accidental memory copies. With Rust all of this was trivial and everything works as I expect. This is pretty much the reason I chose Rust over C++. As a beginner I have no idea how I would begin to elegantly write immutable data, parallel code. With Rust it's…

While I agree with most of what you wrote, CMake feels supercharged compared to the build system part of Cargo. Cargo is failing hard on the integration front, both on integrating things, and being integrated. build.rs is a minimal substitute of a build system: "deal with it yourself". The way Cargo wants to have total control, on the other hand, makes it hard to integrate with existing projects: those which don't us…

I was a C++ developer in a past life and Cmake was a big reason I moved on to greener pastures. It’s the only language that is more toilsome to use than C++ itself, and that by an enormous margin. It’s stringly typed (no, that’s not a typo, everything is a string), it’s syntax is obscure, it extends so poorly that it just bakes-in support for building popular libraries (e.g., Google’s test framework, Qt, etc iirc), imports are implicit so it’s tedious to track down the definition for a particular symbol, it completely punts on package management—not only were builds not reproducible but you couldn’t even get it to download and install dependencies for you from a declarative list. Cmake isn’t a build system, it’s a toolkit for scripting your own bespoke build system (and a crumby one at that) which basically means that every project is a unique snowflake with its own distinct quirks which are tedious to learn and maintain—even though 99% of projects would be covered by something like cargo. Those are some of the things I remember off the top of my head ten years later (it was also doggedly slow and things would break across minor releases, but I’m told those things have improved).

Cargo is imperfect, but it’s the right tool for the job 99% of the time.

Re: Modern C++ Won't Save Us (2019)

#182
post #178
post #160

Earlier quoted context omitted.

I don't know Modula-3 and Eiffel, but I do know some Ada. From my experience Rust, with the borrow checker, still brings a lot to the table compared to Ada. Although Ada has things that Rust doesn't have, too, like delta types, which are immensely useful in embedded programming, and SPARK. Ideally Rust would adopt some of these, or Ada in the next standard.

Ada is adding borrow checker like capabilities to SPARK. In fact this is what I consider Rust's biggest contribution to the computing world. Even if Rust dies tomorrow and eventually fades away, it has brought Cyclone and ATS ideas to the masses, to the point that many languages have done, are in the process of doing, design decisions to integrate affine or linear types to some extent with their type systems.

I would rather see more mainstreaming of sum types, although affine types are nice as well.

Re: Modern C++ Won't Save Us (2019)

#183

Earlier quoted context omitted.

The poster child for C++ being faster than C is std::sort() vs qsort(). The latter requires a function pointer dereference for each call to the user-supplied ordering function - the former does not. There are many similar opportunities for C++ to be faster than C.

The solution for C would be to "stamp out" a specialization of qsort() for a specific data structure either manually or with code generation. The C++ template system really isn't some "magic performance pixie dust", it just saves some typing ;) ...or alternatively, with global optimization (LTO/LTCG) there's actually a good chance that the comparision function calls of a C qsort() implementation can be "dissolved" vi…

Much of what you say is true, but I'm not sure that this is:

> (on the other hand, C++'s "zero cost abstraction" philosophy requires the same level of trust).

The C++ Standard _requires_ that a Standard Library implementation implements certain performance guarantees - I don't think the C Standard has such requirements. This means that certain implementations are effectively required - for instance that std::map is implemented (for better or worse) as a red-black tree.

Re: Modern C++ Won't Save Us (2019)

#184
post #31

> There are significant challenges to migrating existing, large, C and C++ codebases to a different language – no one can deny this. Nonetheless, the question simply must be how we can accomplish it, rather than if we should try. Um... no. Not every (or even most ) existing large C/C++ codebase should be migrated to another language. "But security vulnerabilities! And crashes!" I admit all that. But a program can be…

This amounts to saying that we should accept codebases continuing to contain exploitable vulnerabilities indefinitely. Perhaps for codebases that have a finite expiry date that's tolerable, but for a codebase that's expected to be maintained indefinitely I don't see how it can possibly be worthwhile - a rewrite will be a one-time cost, whereas exploitation is an ongoing cost that will surely exceed the one-time cost…

A program can fail in exceedingly many ways. It is basically impossible to formally verify a program. It’s great to start a new project in a “safer” language, but porting to another language is a different thing.

So for example, let’s take SQLite. It is written in C, but it has an insane amount of tests. Would it benefit anyone to rewrite it in Rust? It will definitely be much more buggy for a long time.

Re: Modern C++ Won't Save Us (2019)

#185

Earlier quoted context omitted.

The only explanation I can think of is that this is old terminology that has stuck around in course material based off older textbooks that aren't bothering with any sort of interprocedural anything. Function boundaries do make things fundamentally more difficult than basic block boundaries, for a large number of reasons. You can no longer have single definitions of values and updates to those values are not global u…

Interesting... now I'm thinking maybe I was confusing it with interprocedural analysis? I've definitely seen the distinction made between them before, though I'm not sure if I've seen them mentioned alongside local analysis in the same text. I guess if you want to have fun this week, go ask your colleagues what the difference between local, interprocedural, and global analysis is. See if they say the last two are syn…

As a preface, it is difficult to speak about true fundamental limitations of things like abstract interpretation because "print Top" is a valid algorithm that will work for all programs. It is just completely useless. So you can model function calls in trivial ways (just treat calls and returns as giant phi nodes and widen whenever you hit mutual recursion). But this tends to produce pretty poor results for real programs and your fixed point computation tends to take longer due to the shape of real program call graphs. Add in dynamic dispatch and you've got all sorts of fun (watch all your pointers in a java program get merged through the receiver to Object.equals(), for example).

In practice, these structural differences require new approaches. The field has done a really good job at intraprocedural analysis, solving a lot of really important problems many decades ago. How to do fixed point computation over SSAed CFGs is well understood, even when you've got heap relationships to think about. Interprocedural analysis still largely sucks. Even modern approaches like CFL-reachability for dataflow analysis produce a ton of garbage. This is one reason why I say it is just harder.

As you mention, recursion prevents you from inlining everything into one giant function. You do get "the rest of the way there" by inlining to some depth limit in the sense that inlining is a way of achieving context sensitive analysis (though it is generally not preferred). But you've still got big problems at the points of mutual recursion (either you need to widen badly or you need to actually do interprocedural analysis) and your program is also exponentially larger in pathological cases.

Re: Modern C++ Won't Save Us (2019)

#186
post #83

Earlier quoted context omitted.

An additional issue is that some sophisticated C++ doesn’t always translate easily into other languages. It isn’t just a fairly direct reimplementation but a legit redesign. That will be a bug factory, especially for the kinds of codes that tend to be difficult to translate, as proving equivalence won’t be trivial.

I'd submit that the kind of code that's difficult to translate - that is, code where it's not clear where the responsibility for the lifecycle of a given piece of memory lies - is already a bug factory.

Not every program has such a well-defined life cycle that fits into Rust’s memory model. There was a great post on why the wayland library’s rust implementation was abandoned. There was basically no point of Rust’s memory model there over C.

Re: Modern C++ Won't Save Us (2019)

#187

Earlier quoted context omitted.

Interesting... now I'm thinking maybe I was confusing it with interprocedural analysis? I've definitely seen the distinction made between them before, though I'm not sure if I've seen them mentioned alongside local analysis in the same text. I guess if you want to have fun this week, go ask your colleagues what the difference between local, interprocedural, and global analysis is. See if they say the last two are syn…

As a preface, it is difficult to speak about true fundamental limitations of things like abstract interpretation because "print Top" is a valid algorithm that will work for all programs. It is just completely useless. So you can model function calls in trivial ways (just treat calls and returns as giant phi nodes and widen whenever you hit mutual recursion). But this tends to produce pretty poor results for real prog…

Ahh I see! Thanks for the explanation.

Re: Modern C++ Won't Save Us (2019)

#188
post #152

Earlier quoted context omitted.

Not at all. Modern C++ can express some memory safety and lifetime models simply and elegantly that are difficult to express in other systems languages. It doesn’t define one for you by default but it also doesn’t limit you to a single model that is clearly inappropriate for some important systems code. The bug factory, in many cases, is a consequence of having no way to properly express lifetimes in languages that o…

Yet Microsoft and Google, despite their C++ investment into compilers and ISO seats, are also investing into hardware memory tagging, forcing static analysers down developer throats no matter what, while slowly adopting other AOT compiled languages on their products. Because while Modern C++ does indeed improve the memory safety and lifetime models, a large majority of the C++ community doesn't care about modern C++…

Static analysis can benefit every sort of language, Rust included.

Re: Modern C++ Won't Save Us (2019)

#189
post #129

Here's the point of view from someone who has only written 1 piece of production software with both C++ and Rust. Trying to write C++ I was constantly fighting accidental memory copies. With Rust all of this was trivial and everything works as I expect. This is pretty much the reason I chose Rust over C++. As a beginner I have no idea how I would begin to elegantly write immutable data, parallel code. With Rust it's…

C++ is a garbage language. There's literally nothing worse. Not PHP, not Perl, not Bash nor VBScript. C++ is literally the worst language. You have to be an arcane wizard to write safe C++. Your code reviewers have to be all-seeing oracles. You're asked to follow this pattern called RAII, but the language does nothing to tell you this or enforce it. Creating declarations and header files is so ceremonious and tiring…

One good thing about C++ is that it scares off dumb people. :-)

Re: Modern C++ Won't Save Us (2019)

#190
post #116

Earlier quoted context omitted.

That is the agenda usually pushed by anti-GC crowd, others think differently. https://www.f-secure.com/en/consulting/foundry/usb-armory https://www.astrobe.com/ https://dlang.org/ https://www.ptc.com/en/products/developer-tools/perc https://www.aicas.com/wp/products-services/jamaicavm http://joeduffyblog.com/2015/11/03/blogging-about-midori/

It isn’t an “anti-GC crowd”, it is based in pretty solid theoretical computer science with large amounts of empirical evidence behind it. GC-based environments are incompatible with schedule-based safety, optimization, etc which are major optimizations and design elements in modern systems. No one has ever demonstrated a systems architecture that can outperform a state-of-the-art schedule-optimized design. This resul…

I agree with you that a GCd language, almost by definition can’t be a low-level language.

I’m not familiar with schedule-optimized design though, could you expand a bit on it?

But I assume it can’t easily be used with routinely changing design requirements, with non-obvious object life-times, like most business applications, CRUD apps —- which is the primary use-case of high-level languages.

Post reply on HN