[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)