[HN Gopher] The initial proposal for a C++ Ecosystem Internation...
       ___________________________________________________________________
        
       The initial proposal for a C++ Ecosystem International Standard
        
       Author : pjmlp
       Score  : 45 points
       Date   : 2022-10-17 08:05 UTC (1 days ago)
        
 (HTM) web link (www.open-std.org)
 (TXT) w3m dump (www.open-std.org)
        
       | gavinray wrote:
       | Really hope this happens
       | 
       | Using vcpkg with CMake/Meson/Xmake mostly solves the package
       | management+ build system problem but God help you if the lib you
       | want doesn't have a vcpkg definition or CMake file
        
       | PointyFluff wrote:
       | That'll fix C++.
       | 
       | More standards.
       | 
       | Nothing better than a language designed by a committee of middle-
       | managers with a half-warmed-over-IQ.
        
         | jhoechtl wrote:
         | Just came here to tell you that I upvoted you and my initial
         | sentiment resonates with your wording.
        
         | en4bz wrote:
         | It's mostly run by code-golfers which is much worse.
        
       | jobs_throwaway wrote:
       | noob question: why is there still this sort of energy/effort put
       | towards C++ when Rust is available?
       | 
       | edit: thanks for downvoting a genuine question!
        
         | Mikeb85 wrote:
         | C++ can be more pleasant to write than Rust, especially if you
         | limit yourself to modern features, OO-style, etc... It's also
         | extremely mature, has a library for everything, is on every
         | platform known to mankind, etc...
         | 
         | C++ has a lot of baggage and if you maintain old C++ software
         | I'm sure it's a massive PITA but starting fresh in C++ isn't a
         | bad experience.
        
         | gp wrote:
         | Not all organizations are in a position to make the switch or
         | even want to. I personally like Rust and find it interesting,
         | but that doesn't mean I would throw away my C++ codebase.
         | 
         | I'm sure other people will be able to share reasons their
         | organizations use C++
        
           | chad1n wrote:
           | I'm not a Rust apologetic, but even if the standard tooling
           | committee appears, most big projects won't migrate to these
           | tools, considering that they've been using some building
           | scripts for 10-20 years and maintaining dependencies in hacky
           | ways. These standard tools will mostly help new projects in
           | C++ which can start from scratch and use vcpkg and whatever
           | building tool will be selected (probably cmake or meson).
        
             | jcranmer wrote:
             | There are a few things to note here.
             | 
             | First, the hacky build systems of old are increasingly
             | unsustainable; I've seen quite a few projects migrate to
             | things like cmake in part because not having that kind of
             | build system just doesn't work anymore. (And you get people
             | like Mozilla or Google who write their own build system
             | just for their software, but the end result is the same--
             | you've got some sort of modern-ish build system being
             | integrated). Even at $WORK, some of our old build system
             | stuff with confusing make rules and the like is being
             | shifted to a (hopefully) cleaner cmake stuff, albeit far
             | more slowly than I'd like.
             | 
             | Second, it's worth noting that tooling improvements can
             | motivate change. The ur-example here is the compilation
             | database idea Clang introduced. From what I've seen, every
             | build system that can support it (sorry, autotools) has
             | added information to extract this useful tool. If you can
             | come up with similarly useful build system summary
             | information that is useful for tooling, you're likely to
             | see relatively swift adoption of it.
             | 
             | Third, C++ is already undergoing changes that will
             | introduce build system breakages. Most notably and
             | obviously, modules. Build systems need to adapt to support
             | this, and if people are already making the switch to get
             | new features, incorporating other useful tooling additions
             | at the same time would see adoption.
        
             | bluGill wrote:
             | Projects will slowly migrate, as things are updated ' when
             | a third party library release a version with this they will
             | add support. When they need new features in their build
             | system they will add them in this format, creating a weird
             | hybrid until one day they turn the old stuff off.
        
           | thesuperbigfrog wrote:
           | >> I'm sure other people will be able to share reasons their
           | organizations use C++
           | 
           | Rust is great and offers a great path forward, but it was not
           | around 20+ years ago when $BIG_PROJECT was written. C++ was
           | around, popular, and useful so $BIG_PROJECT was written in
           | C++. $BIG_PROJECT made $BIG_COMPANY millions and is still in
           | use today.
           | 
           | $BIG_PROJECT engineers are looking into migrating parts of
           | $BIG_PROJECT to Rust, but the work is still early and the
           | $BIG_PROJECT's millions of lines of C++ won't be replaced
           | overnight. Improved, more uniform tooling for C++ would
           | simplify maintenance for $BIG_PROJECT and make it easier to
           | move $BIG_PROJECT to newer C++ toolchains and even other C++
           | toolchain vendors.
           | 
           | Maybe one day $BIG_PROJECT will migrate fully to Rust, or
           | perhaps $BIG_PROJECT will be re-written from the ground up in
           | Rust, but for now $BIG_PROJECT has to work.
        
         | FpUser wrote:
         | The simples answer is that many orgs have accumulated megatons
         | of high quality production code that cost them unknown billions
         | in total to create and that runs half of the world. Throwing it
         | away is insanity. Hence need to improve on what is already
         | available.
         | 
         | Also not everyone believes in silver bullets and modern C++ is
         | fairly god and easy enough to use. Just do not try to know
         | _ALL_ of the C++. This kind of expertise is needed by whole 2.5
         | people. Partially true for any complex enough language.
         | 
         | You are still more than welcome to start new projects in
         | whatever language warms up your heart or rewrite already
         | existing stuff.
         | 
         | P.S. I do not ever downvote post no matter what does it say.
        
         | otabdeveloper4 wrote:
         | Rust doesn't solve any real problem.
         | 
         | It's a meme language that is only used for writing blog posts
         | and internet commentary.
        
           | hoten wrote:
           | I suppose Figma is a meme company sold for meme dollars?
           | 
           | https://twitter.com/figma/status/991697942070333447?lang=en
        
             | pjmlp wrote:
             | The money maker WebAssembly part on the browser is still
             | C++.
        
             | otabdeveloper4 wrote:
             | Unironically yes.
        
           | jobs_throwaway wrote:
           | is memory safety not a real problem?
        
           | Karellen wrote:
           | So, Linus Torvalds, who rejected calls for code written in
           | C++ to be accepted into the Linux kernel for _decades_
           | because he thought that the extra features it provides were
           | not worth the added complexity it would bring, has decided to
           | allow Rust support in Linux because... he suddenly got
           | infected with brain worms that made him want to be a crowd-
           | following blogger writing commentary for internet upvotes?
           | 
           | And not because he thinks Rust might be able to solve actual
           | problems in kernel development?
           | 
           | I want whatever drugs you're taking.
        
             | otabdeveloper4 wrote:
             | Wake me up when some real kernel module actually gets
             | written in Rust.
             | 
             | (Actually, no, strike that, I don't want to sleep forever.)
        
             | fluoridation wrote:
             | To be completely honest, I would wager it was more a matter
             | of ego than anything rational. C++ kept improving over time
             | and he knew that, but rather than revise his position and
             | admit to an error, he stubbornly persisted until Rust came
             | along, and that gave him an out. "Well, C++ is too shitty;
             | but Rust, a language that has not been around for even a
             | decade, _that 's_ was I want to add support for in the
             | kernel". Rust has pretty much all the failings he accused
             | C++ of having, it just has memory safety as an additional
             | benefit.
        
               | tsimionescu wrote:
               | > Rust has pretty much all the failings he accused C++ of
               | having, it just has memory safety as an additional
               | benefit.
               | 
               | Memory safety is one hell of a benefit. In contrast, if
               | you look at Linux' coding style, C++ really doesn't have
               | any benefit over C.
               | 
               | Not to mention, many of C++'s advantages come from the
               | STL, which wouldn't work without extra work in
               | kernelspace. Rust has been designed for running on bare
               | metal from day 1.
        
               | fluoridation wrote:
               | You're talking about migrating kernel code to C++, but
               | I'm talking about _supporting_ C++ code in the kernel.
               | That is, if third parties wanted to write Linux drivers,
               | the only supported way was to do it in C.
               | 
               | That aside, the kernel does do polymorphism the hard way
               | (with unions and arrays of function pointers) in a few
               | places; the example I saw was some filesystem code, I
               | think. C++ is also much more type-safe than C, mostly by
               | refusing to implicitly convert between unrelated
               | pointer/reference types and preventing you from
               | inadvertently doing something absurd. References also
               | make null checks unnecessary and convey to the caller
               | that they're supposed to pass something valid, and RAII
               | simplifies a lot of resource management. Templates also
               | reduce boilerplate and are type-safe, although they're
               | also a harder sell and not everyone's cup of tea.
               | 
               | I agree that memory safety is a huge advantage (although
               | on the other hand, a double linked list in Rust is
               | currently impossible without unsafe blocks), but I refuse
               | to believe this decision has nothing to do with
               | stubbornness.
        
               | tsimionescu wrote:
               | > the kernel does do polymorphism the hard way (with
               | unions and arrays of function pointers) in a few places
               | 
               | Using C++ classes has some disadvantages compared to
               | C-style polymorphism - especially related to memory
               | layout and allocation - in C++, memory is allocated by
               | the code instantiating the object, not by the object's
               | code, so you have to know the size of the type (including
               | private fields) in any place where you are instantiating
               | it. Not sure how relevant this is for kernel code.
               | 
               | > C++ is also much more type-safe than C, mostly by
               | refusing to implicitly convert between unrelated
               | pointer/reference types and preventing you from
               | inadvertently doing something absurd
               | 
               | This part I agree with.
               | 
               | > References also make null checks unnecessary and convey
               | to the caller that they're supposed to pass something
               | valid
               | 
               | I think the distinction between references and pointers
               | is one of C++'s worse ideas. You can't generally replace
               | pointers with references either.
               | 
               | > RAII simplifies a lot of resource management
               | 
               | RAII doesn't work without bringing in a whole lot of
               | other heavy-duty features: mainly exceptions, but also
               | constructors and destructors.
               | 
               | > Templates also reduce boilerplate and are type-safe
               | 
               | Templates are more type-safe than macros, but not that
               | much more (since the template language is essentially a
               | dynamically-typed program, even though its output is a
               | C++ AST that will be further type-checked). Like RAII,
               | they also require you to use other features of C++,
               | especially operator overloading, and likely also copy
               | (and more recently, move) constructors.
               | 
               | > I agree that memory safety is a huge advantage
               | (although on the other hand, a double linked list in Rust
               | is currently impossible without unsafe blocks), but I
               | refuse to believe this decision has nothing to do with
               | stubbornness.
               | 
               | I do agree that stubbornness may well be a component.
               | However, I believe that there is a coherent argument that
               | can be made that supporting C++ for kernel modules is not
               | worth it, while supporting Rust for kernel modules is.
               | I'm not saying that this is the argument that Linus is
               | making, but I do believe it can be made.
               | 
               | Especially since we also need to remember that all kernel
               | modules are part of the kernel source tree. Supporting an
               | additional language has a significant cost for everyone
               | who is maintaining the kernel, since they need to add
               | tooling to handle that extra language for all targeted
               | platforms.
               | 
               | It should also be remembered that C++ compilers are even
               | worse than C compilers at mis-using instances of
               | undefined behavior to mis-optimize code, especially since
               | they typically rely even more on optimization steps to
               | have half-decent performance.
        
               | jcranmer wrote:
               | > RAII doesn't work without bringing in a whole lot of
               | other heavy-duty features: mainly exceptions, but also
               | constructors and destructors.
               | 
               | You don't need exceptions to make RAII work. It does make
               | fallible resource allocation a little bit trickier (the
               | RAII object needs to be prepared to be in a live-but-
               | failed-allocation state), but it's very doable.
               | Constructors and destructors are absolutely _not_ heavy-
               | duty features.
        
               | tsimionescu wrote:
               | They are heavy duty precisely because they rely on
               | exceptions to signal error conditions (or, in the case of
               | destructors, are completely unable to signal errors
               | safely at all), at least in combination with RAII.
               | 
               | Without exceptions, RAII is quite cumbersome - especially
               | in kernel mode, where you can't assume that memory
               | allocation is always successful, so even memory
               | allocation is a fallible resource allocation. Not to
               | mention, RAII makes it impossible to check whether you
               | successfully released the resource, which is a concern
               | that the kernel can't always ignore the way user-space
               | C++ code usually can.
        
               | jcranmer wrote:
               | If you're relying on exceptions to make destructors
               | fallible, you are going to have a very bad time. The
               | protocol of throwing an exception is to destroy all
               | objects in scope, and if doing so causes more exceptions
               | to need to be thrown, you're going to end up either with
               | a hard crash or one of the exceptions being destroyed. If
               | the fallibility of resource deallocation is really
               | important, then RAII isn't a good model to use (I prefer
               | something like a
               | connection.with_transaction([](Transaction &T) -> Result)
               | model myself for this).
               | 
               | Given that fallible destructors aren't an issue,
               | exceptions are only an issue for RAII if constructors can
               | only fail with exceptions. Note that Rust has fallible
               | constructors without exceptions, and C++ could implement
               | that too, though it is definitely less ergonomic than
               | exceptions.
        
               | fluoridation wrote:
               | The key to RAII is not so much constructors as _de_
               | structors. If you want to be able to signal construction
               | failure you just have an init() member function that
               | returns a bool or some integer. As for dynamic
               | allocation, when I worked on driver development for
               | Windows, I just had an allocate<T>() function that
               | returned a properly constructed std::unique_ptr<T> with
               | the deallocation function properly set and with the T
               | fully constructed (you may need more than one allocation
               | function if you need to allocate from multiple contexts
               | that require allocation in slightly different ways).
               | 
               | >Not to mention, RAII makes it impossible to check
               | whether you successfully released the resource
               | 
               | Actually, RAII makes it much easier by encoding that
               | knowledge into the owning object. Using the example
               | above, you could call allocate<T,
               | do_something_special_on_deallocation_failure>(). Then
               | whenever the pointer goes out of scope you'll do the
               | special thing without the user of the object having to
               | know what that special thing is.
        
               | tsimionescu wrote:
               | All of this complicates the program significantly, and
               | greatly reduces the advantages of RAII. If you're not
               | using the constructors for initialization, than your
               | desturctors also have to handle the case where the
               | objects didn't even attempt to acquire the resource they
               | may represent, for example.
               | 
               | Also, how to handle a failure to release a resource is
               | context dependent, you can't encode it in the type of the
               | resource unless you create a different type for each call
               | site.
        
               | fluoridation wrote:
               | If you really need to do something different at each
               | release point then you can have
               | do_something_special_on_deallocation_failure() notify the
               | error to the release point by a number of different
               | mechanisms.
               | 
               | Yes, all of this makes the code more complicated. The
               | point of these features is not to make the code simpler,
               | but to make it more robust. Rust is also more complicated
               | than C.
        
               | fluoridation wrote:
               | >It should also be remembered that C++ compilers are even
               | worse than C compilers at mis-using instances of
               | undefined behavior to mis-optimize code, especially since
               | they typically rely even more on optimization steps to
               | have half-decent performance.
               | 
               | Nonsense. Modern toolchains treat C and C++ as almost
               | interchangeable. For example, Clang compiles both naively
               | to a machine-independent IR and then performs all its
               | optimizations on that. "C is portable Assembly" has been
               | a myth for a long, long time. Nowadays C is effectively
               | as high level as C++, just with fewer features.
        
               | usefulcat wrote:
               | > You can't generally replace pointers with references
               | either.
               | 
               | If this were generally true, I would expect to see a lot
               | more use of pointers than references in c++ code, but in
               | practice it's the exact opposite--it's rare that one
               | needs to use a pointer rather than reference. Basically
               | only if it needs to be able to be null or if it needs to
               | be able to be modified.
        
               | tsimionescu wrote:
               | In C code, you'll find many uses of pointers for
               | iteration, which can't be replaced with C++ references.
               | C++ typically also uses pointers in these cases, but
               | wraps them in a layer of iterator templates (that is,
               | hopefully, optimized out into a raw pointer access).
               | 
               | Not to mention, references obscure the difference between
               | copying an object and sending its address at the call
               | site, and obscure the difference between accessing a
               | local object and a pointed-to object at the access site -
               | a major disadvantage compared to pointers. Especially for
               | a project which heavily uses email patches for code
               | review and discussion.
               | 
               | Also, there are programming errors that can lead to a
               | NULL reference, and there is no way to guard against that
               | in code using the reference (well, none that doesn't
               | generate Warnings, and/or is liable to be optimized out)
               | - whereas at least with pointers you can always check in
               | your own code.
        
               | fluoridation wrote:
               | Note that I was talking about using pointers to pass a
               | _single_ object by reference. In such cases references
               | are 100% better than pointers, if the pointer is never
               | supposed to be null.
               | 
               | >Also, there are programming errors that can lead to a
               | NULL reference, and there is no way to guard against that
               | in code using the reference (well, none that doesn't
               | generate Warnings, and/or is liable to be optimized out)
               | - whereas at least with pointers you can always check in
               | your own code.
               | 
               | On the other hand, if you find you've received a null
               | reference as a parameter then you know that something has
               | definitely gone wrong, because unlike with pointers null
               | references are impossible in the absence of UB. If all
               | you know is that the function has received a null pointer
               | then you could waste a lot of time trying to figure out
               | how the program reached that state, when in actuality the
               | problem is that someone else wrote out of bounds.
        
               | bluGill wrote:
               | Linux would benefit from a compiler to build a vtable
               | where plugins are needed. Linux would benefit from a STL
               | like library that might be home grown but will support
               | more types than whatever they are doing now .
        
         | jimbob45 wrote:
         | There exist codebases that are too large and too old to ever
         | adequately rewrite. Joel Spolsky wrote an entertaining article
         | some time ago on why rewriting software isn't always the
         | panacea it's made out to be[0].
         | 
         | [0] https://www.joelonsoftware.com/2000/04/06/things-you-
         | should-...
        
         | jcelerier wrote:
         | Rust doesn't have Qt
        
           | gavinray wrote:
           | https://github.com/rust-qt
        
             | rvz wrote:
             | Not only those are rudimentary unofficial bindings but that
             | looks unmaintained and is already out of date. Last updated
             | 2021.
             | 
             | So no. Rust does not have official Qt support.
        
               | juunpp wrote:
               | It's surprising to me that this was downvoted. Many a
               | Rust project pulls several hundred Cargo dependencies
               | that the developer probably hasn't even checked against
               | basic things like outstanding bugs. The lack of standard
               | package management in C++ sometimes is for the best.
        
             | jcelerier wrote:
             | > https://github.com/rust-
             | qt/examples/blob/master/widgets/basi...
             | 
             | this is ridiculous. rust does not have overloading ?
        
               | tialaramex wrote:
               | Rust doesn't have any sort of ad hoc polymorphism. Of
               | course, you would usually have a sensible name for these
               | functions (maybe new_0a is a sensible name, I'm not a Qt
               | programmer but I rather doubt it).
               | 
               | Rust's "constructors" aren't magic, whereas the C++
               | constructors are magic, so they need ad hoc polymorphism
               | or you could only have one constructor for each type.
               | 
               | Let's compare familiar types which weren't built using
               | some sort of FFI magic, C++ std::vector and Rust's
               | alloc::vec::Vec.
               | 
               | std::vector has 10 constructors, they can't have
               | different names, so they're distinguished by their
               | parameters, perhaps your IDE will prompt you with a list
               | of options or you'll remember the parameters you need to
               | do what you intended.
               | 
               | Vec::new() makes a Vec, Vec::new_in(allocator) makes a
               | Vec using a specific allocator, Vec::with_capacity(4)
               | makes a Vec with capacity for 4 things and so on.
               | 
               | Somebody else mentioned operators, note that Rust doesn't
               | really _overload_ operators either. In Rust the operators
               | are getting _implemented_. If you don 't implement an
               | operator, then it doesn't exist, whereas in C++ the
               | operators often have some pre-defined behaviour and you
               | can change that using overloading.
               | 
               | For example if your type Doodad should like to be able to
               | use the + operator on other Doodads, you can implement
               | core::ops::Add<Doodad> for Doodad - now the + operator
               | works when both sides are Doodads. If you'd like a += b;
               | to work, you'd implement core::ops::AddAssign<Doodad> for
               | Doodad. These traits require methods with the appropriate
               | signature e.g. AddAssign::add_assign(&mut self, rhs:
               | Doodad) saying this function needs a mutable reference to
               | a but consumes b.
               | 
               | Oh, before I forget:
               | 
               |  _Because_ Rust doesn 't have ad hoc polymorphism often
               | people realise they wanted _parametric_ polymorphism
               | here. For example C++ 23 can almost do
               | "bananas".contains("nanas") finally, but it uses a bunch
               | of overloading to pull that off, since Rust doesn't
               | _have_ this, it chose to reify the idea that 's filling
               | out that slot in the C++ functions as a Trait, and it
               | calls this the trait _Pattern_. So, all the places where
               | you mean  "You know, for matching strings" you can use
               | _any_ of the ways of matching strings because they
               | implement the Pattern trait
               | "bananas".contains('b')
               | "bananas".contains("nanas")
               | "bananas".contains(char::is_whitespace)
               | "bananas".contains(MyCustomThing { "is it fruit?" })
        
               | josephg wrote:
               | Nope! Rust doesn't have function overloading like C++.
               | What would that code look like in C++?
               | 
               | (Rust has operator overloading - but that's not the same
               | thing).
        
           | steveklabnik wrote:
           | It's not exactly Qt, but some former Qt folks are making
           | https://slint-ui.com/
        
         | adamdusty wrote:
         | You're getting lots of explanations for why people don't switch
         | to rust, mostly existing projects, but I'd like to point out
         | that plenty of people still start new projects in C++ as well.
         | Most game dev has to be c/c++ if you want to release on
         | consoles. This isn't technically true, but in practice it is
         | most of the time. Not everybody wants to program in rust's
         | pseudo-functional style. Some people like C because if you can
         | generally map nice C code to its assembly in your head.
         | 
         | In my opinion, memory safety also gets a little overblown. Most
         | applications don't really need memory safety, and for the ones
         | that do, C++ smart pointers are good enough. I'm sure plenty of
         | people will have strong opinions against that.
         | 
         | Ultimately there is this sort of energy towards c++ because
         | there are orders of magnitude more projects and developers that
         | use C++, and it would be silly to stop work on C++ every time a
         | C++ killer came along.
        
           | TillE wrote:
           | > Most game dev has to be c/c++
           | 
           | There are certainly a number of high-quality C libraries
           | hanging around (SQLite, libcurl, etc) that might be used, but
           | I don't think anyone's doing serious game dev in C these
           | days. It really is all about C++, and C# for Unity.
        
             | Mikeb85 wrote:
             | > C# for Unity
             | 
             | Scripting doesn't count for this comparison. Unity is still
             | a C++ engine.
        
         | [deleted]
        
         | PointyFluff wrote:
         | For all it's faults. C++ (along with other languages) already
         | has an international standards body.
         | 
         | While a language made by committee is invariably garbage
         | (citation: JavaScript), there is something to be said for
         | stabilizing the standard for safety-sensitive systems like
         | flight, space, medicine, automotive, and the ilk. Not a grate
         | look if your space-balloon goes over like a lead-balloon.
         | 
         | Also, Rust is not something you can just "switch" to; it's not
         | javascript or python. You have to UNLEARN a lot of bad nuns
         | before you can truly be productive in Rust. Learning rust is a
         | steep climb, coming from languages like C & C++; if you are
         | coming from a language like python or lisp, it's a damn near
         | smooth-vertical-shaft.
         | 
         | Frustratingly, a lot of the books for newbs are like: "So you
         | wanna do this cool thing in Rust? Then do this tutorial project
         | for this crate!", and they don't actually go over idiomatic
         | rust algorithms. The way rust handles code and data, lends to
         | "different" ways of solving problems. The best way to learn
         | rust, is to read rust, but that can get confusing with the
         | traits and typing bounds and lifetimes and unwraps. On the
         | other hand you get to say "turbofish" a lot; so there's that,
         | which is nice.
         | 
         | And so the issue becomes one of monkey-power. I can find
         | bucket-fulls of hairless apes to bludgeon in C or C++ code, but
         | it takes a more sophisticated `Ook<T>` to see the Octarine that
         | is Rust.
        
           | tialaramex wrote:
           | > For all it's faults. C++ (along with other languages)
           | already has an international standards body.
           | 
           | Not everybody in the C++ community is convinced this is a
           | benefit.
        
       ___________________________________________________________________
       (page generated 2022-10-18 23:02 UTC)