[HN Gopher] C++ is an absolute blast
       ___________________________________________________________________
        
       C++ is an absolute blast
        
       Author : ok123456
       Score  : 270 points
       Date   : 2024-12-23 15:37 UTC (1 days ago)
        
 (HTM) web link (learncodethehardway.com)
 (TXT) w3m dump (learncodethehardway.com)
        
       | pjmlp wrote:
       | While it is a great language, ir would profit from less "lets
       | code C with C++ compiler" attitude.
       | 
       | Basically it is like renaming those JavaScript files from .js to
       | .ts, and keep coding as if nothing else is available as
       | productivity and safety improvements.
        
         | ablob wrote:
         | Having read the article, nothing really stands out to me as "C
         | with C++ compiler".
         | 
         | It talks about ranges, shared/unique pointers, lambdas...
         | Essentially a lot of things C is lacking. I don't know where
         | exacly the overlap you're insinuating comes from.
        
           | pjmlp wrote:
           | Where did I mentioned the article?
        
             | rickmode wrote:
             | Pronoun confusion. The second pronoun is ambiguous.
             | 
             | Since we are all "hackers" here, I'll be pedantic...
             | 
             | "While it is a great language..."
             | 
             | The "it" pronoun clearly refers to the C++ language, as I'm
             | sure you intended.
             | 
             | "...ir would profit from less 'lets code C with C++
             | compiler ' attitude."
             | 
             | The "ir" -- presumably a typo for "it" -- can refer to the
             | article or C++. Given that this thread is about an article,
             | the second "it" referring to the article is a natural
             | assumption.
        
               | pjmlp wrote:
               | It with typo refers to C++.
        
         | thefourthchime wrote:
         | I feel like an abused spouse after C++. I now avoid:
         | 
         | - Inheritance - Reference counting - Threading - Templates -
         | Classes if possible - Hidden memory allocation - Anything that
         | looks clever
         | 
         | Anytime I use them I get flashbacks to some mangled mess of
         | templated threaded classes with some memory leak that shows up
         | after 3 days.
         | 
         | I remember writing C++ and trying to figure out how the design
         | would work between these classes, I would end up with something
         | complicated and not entirely correct. Eventually, I thought,
         | what if I did this in C? What would it look like, 90% it turns
         | out with 90% less design and code (and bugs).
        
           | pjmlp wrote:
           | There is no rule that requires "programming in C++ proper"
           | being equal with using 100% of the language standard.
           | 
           | There is a middle layer, without having to keep repeating all
           | the security flaws of coding in plain C.
        
           | unclad5968 wrote:
           | You don't have to use any of that and you still get lots of
           | nice things like range based for loops, STL containers,
           | algorithms, namespaces, and constexpr.
        
       | xorvoid wrote:
       | I'm glad someone is having fun in C++. Personally, after >20
       | years, I have to be done with C++. It's just a mess.
       | 
       | If I really need the low-level control, I can wrangle C (warts
       | and all), otherwise Rust, Python, etc just make me happier.
        
         | pjmlp wrote:
         | Beware of C23 and later.
         | 
         | C is basically going into "we want C++ but without OOP and with
         | templates done via _Generic".
         | 
         | Also LLVM and GCC aren't going to be rewritten from C++ into
         | Rust anytime soon.
        
           | bilekas wrote:
           | > Also LLVM and GCC aren't going to be rewritten from C++
           | into Rust anytime soon.
           | 
           | I'm afraid you underestimate the will power of rustaceans to
           | find literally anything to rewrite.
        
             | pjmlp wrote:
             | I doubt Cranelift will ever match the only project that has
             | beaten the contribution level of Linux kernel.
        
           | cornstalks wrote:
           | > _Beware of C23 and later._
           | 
           | Beware of what? C23 fixed a number of issues. Sure, there are
           | some oddballs (QChar and auto, mostly), but overall I think
           | C23 is an improvement.
        
             | pjmlp wrote:
             | Those C89 hardliners have a different point of view.
             | 
             | Also there is the whole point Objective-C and C++ are much
             | better than those improvements will ever be.
        
               | motorest wrote:
               | > Those C89 hardliners have a different point of view.
               | 
               | C89 was only a thing because Microsoft somehow decided to
               | drag it's feet and prevented msvc from supporting
               | anything beyond c89 for a long, long time. Only in 2020
               | did they manage to finally do something about it.
               | 
               | https://devblogs.microsoft.com/cppblog/c11-and-c17-standa
               | rd-...
        
               | pjmlp wrote:
               | Because for Microsoft C belonged into the past, it was
               | about time to move into C++.
               | 
               | https://herbsutter.com/2012/05/03/reader-qa-what-about-
               | vc-an...
               | 
               | They only changed of point of view after Satya, and the
               | whole Microsoft <3 Linux and Microsoft <3 FOSS pivot.
               | 
               | And in any case, blaming Microsoft doesn't really work
               | out, as many of those folks don't even care Windows
               | exists, only UNIX/POSIX platforms.
        
           | janice1999 wrote:
           | I imagine most C programmers are still using C99 or older
           | anyway, particularly in the embedded space.
        
             | ericbarrett wrote:
             | I'm not sure this is still true. I'm just a hobbyist but
             | esp-idf, for example, supports C++23.
        
               | TJSomething wrote:
               | esp-idf is still on GCC 11, but most of the features of
               | C23 are in GCC 13.
        
             | phkahler wrote:
             | C99 or _newer_. You gotta have standard fixed size types
             | like int16_t.
        
               | bcrl wrote:
               | Not in the embedded space. When you've worked on embedded
               | systems long enough, you learn that you have to accept
               | the compiler that the vendor provided you with, and you
               | adapt your codebase to the limitations of that compiler.
               | This means working around code generation bugs, adding
               | #ifdefs to define typedefs for things like int16_t if
               | they don't exist.
               | 
               | That said, things are a lot better than they were 15
               | years ago, and the mainstream ARM compilers used today
               | are leagues better than the barely functional cobbled
               | together ports from the early '00s. ARM64 is a tier 1
               | platform, and there are enough users of the platform that
               | the extended QA team that embedded developers were
               | unintentionally part of in the past is no longer really
               | the case (at least when it comes to the compiler).
               | 
               | However, there are still truly obscure architectures
               | (mostly 8 bit and 16 bit) that continue to have oddball
               | compilers. And you accept and deal with that insanity
               | because it means you're only paying $0.01 for that
               | microcontroller to blink an LED when some kind of an
               | event occurs.
        
           | uecker wrote:
           | What part of C23 makes you believe this?
        
             | pjmlp wrote:
             | Everything that was taken from C++, and _Generic.
             | 
             | And the ongoing discussion for lambdas that didn't make it
             | into C23, but still on the table for C2y.
             | 
             | Meanwhile, zero progress in what actually matters, proper
             | strings and arrays, that aren't a continuous source of
             | memory corruption bugs.
        
         | yodsanklai wrote:
         | Agree. C++ is here to stay though. Too much code written in
         | that language. It's certainly a great skill to have, and there
         | are super lucrative jobs too.
         | 
         | For me, I feel the language just go in the way and is way too
         | complex. Sure, I know the discourse: "modern C++" is great, you
         | don't need to learn about older. versions of C++, things are
         | getting simpler with each new version.
         | 
         | The problem is that the codebase you get to work on aren't
         | modern C++. They use every possible feature ever released and
         | it's just hard and full of pitfalls.
         | 
         | I suppose people who have only work on C++ in their projects
         | for years can develop some level of expertise and are immune to
         | the complexity. But really, not a great language...
        
         | jandrewrogers wrote:
         | One of the things that has made C++ more tolerable over time is
         | that it became easy to seamlessly replace most of it with an
         | implementation that works the way you think it should and with
         | most behaviors being fully defined -- the core data types,
         | standard library, etc. Particularly with C++20 and later,
         | alternative foundations feel quite native and expressive.
         | 
         | Most new C++ projects I see lean into this quite heavily. The
         | ease with which you can build a systems-level DSL for your
         | application is a strength of C++.
        
           | mst wrote:
           | There's a parallel here with modern applications perl as
           | compared to the crawling horrors people perpetrated in CGI
           | scripts during the dot com boom.
           | 
           | Also present day javascript (the language; the ecosystem is
           | another matter ;) compared to the 'var' and IIFEs-for-scoping
           | era.
        
         | motorest wrote:
         | > I'm glad someone is having fun in C++. Personally, after >20
         | years, I have to be done with C++. It's just a mess.
         | 
         | I've spent a couple of decades working with C++, and the truth
         | of the matter is that, as much as it pains the bandwagony
         | types, C++ became great to work with once C++11 was rolled out.
         | The problem is that teams need to port their projects to >C++11
         | and that takes an awful lot of work (replace raw pointers with
         | smart ones, rearchitect projects to shed away C-style
         | constructs, etc) which some product managers are not eager to
         | take.
         | 
         | I firmly believe that the bulk of this irrational hatred
         | towards C++ comes from naive developers who try to rationalize
         | away their lack of experience by blaming everything on the
         | tool. On top of this, cargo-cult mentality also plays a role.
         | 
         | What makes this quite obvious is the fact that the solution
         | presented to all problems always comes in the form of major
         | rewrites, even with experimental and unproven features and
         | technologies. Writing everything again is always the solution
         | to everything. Everyone before them knows nothing whereas these
         | messiah, cursed with being the only ones who see the one true
         | answer, always have a quick and easy answer to everything which
         | always boils down to rewriting everything from scratch with the
         | flavor of the month. Always.
         | 
         | Weird, huh?
        
           | ModernMech wrote:
           | > C++ became great to work with once C++11 was rolled out.
           | The problem is that teams need to port their projects to
           | >C++11
           | 
           | The problem is the C++ that's not great to work with is still
           | there, and there's nothing preventing the rest of the world
           | from using it; there are always going to be naive developers
           | with a lack of experience who don't know how to use the tool.
           | For this reason, all the code that's possible to write in C++
           | will be written, that includes the unsafe code.
           | 
           | It's not enough to have a safe, nice, modern, subset of C++
           | that everyone "should" use. If developers have the option to
           | use the warty, sharp, foot-gun infested version of C++ they
           | will, and they will gift that code to the rest of us in the
           | form of readily exploitable software.
           | 
           | This is why organizations like CISA are suggesting developers
           | move to other languages that take a stricter posture on
           | memory safety: https://www.cisa.gov/news-events/news/urgent-
           | need-memory-saf...
           | 
           | > companies should investigate memory safe programming
           | languages. Most modern programming languages other than C/C++
           | are already memory safe. Memory safe programming languages
           | manage the computer's memory so the programmer cannot
           | introduce memory safety vulnerabilities. Compared to other
           | available mitigations that require constant upkeep - either
           | in the form of developing new defenses, sifting through
           | vulnerability scans, or human labor - no work has to be done
           | once code is written in a memory safe programming language to
           | keep it memory safe.
        
             | motorest wrote:
             | > The problem is the C++ that's not great to work with is
             | still there, and there's nothing preventing the rest of the
             | world from using it;
             | 
             | That's precisely why all this criticism is actually thinly
             | veiled naive inexperient developers blaming the tools.
             | Selling full rewrites as solutions to the problems they
             | created is a telltale sign. As they are lacking the
             | experience and know-how to fix the mess, they succumb to
             | the junior dev disease of believing deleting everything and
             | starting from scratch is a solution to all of life's
             | problems and inconveniences.
        
               | grumpyprole wrote:
               | > naive inexperient developers blaming the tools
               | 
               | That's not the problem. It's naive inexperienced
               | developers _using_ the tools. Most developers have to
               | maintain code they didn 't write themselves. One can
               | learn all the C++ best practices in the world, but it
               | won't protect you from _other people_. That 's why
               | languages with strong restrictions and constraints that
               | force safety and correctness are needed. With such
               | languages, naive inexperienced developers won't be able
               | get anything to compile. We won't have to deal with their
               | mistakes as they'll never be able to ship them. Any
               | experienced developer would surely want this.
               | 
               | A rewrite is not pointless if you are rewriting into a
               | language with additional guarantees. You are checking for
               | and proving the absence of certain classes of software
               | flaws by doing so.
        
               | lll-o-lll wrote:
               | > With such languages, naive inexperienced developers
               | won't be able get anything to compile.
               | 
               | Hey dude, I can't get this thing to compile?
               | 
               | Just wrap all your variables in Arc; that's what I always
               | do.
        
               | wiseowise wrote:
               | I don't see how juniors, who want to rewrite things, are
               | the reason why C++ has 3 freaking ways to initialize a
               | variable.
        
               | davisp wrote:
               | There's a few more than three.
               | 
               | https://leanpub.com/cppinitbook
               | 
               | https://www.reddit.com/r/ProgrammerHumor/comments/8nn4fw/
               | for...
        
           | zahlman wrote:
           | > C++ became great to work with once C++11 was rolled out.
           | 
           | Have Yossi Kreinin's objections
           | (https://yosefk.com/c++fqa/defective.html) been addressed
           | yet? In particular, can I reuse source code from another file
           | without a text preprocessor yet? Can I change a class'
           | private members without recompilation, or am I still stuck
           | with indirecting that behind a "pImpl" pointer in the class
           | declaration in the header file? (Being able to use a smart
           | pointer for that is not addressing the problem.) Are compiler
           | error messages resulting from type mismatches reasonably
           | short (without third-party tools like STLFilt) yet (never
           | mind whether they're informative or pleasant to decipher)?
           | 
           | I know that "some parts of the FQA are not up to date with
           | C++11 [and onward]", but I haven't heard of these problems
           | being fixed.
        
             | motorest wrote:
             | > Have Yossi Kreinin's objections
             | (https://yosefk.com/c++fqa/defective.html) been addressed
             | yet?
             | 
             | A cursory read of that list is enough to see it's a list of
             | complaints fueled by a mix of ignorance and disingenuity.
             | 
             | For example, the first entry complaining about "no compile
             | time encapsulation" is somehow completely ignorant and
             | oblivious to very basic things such as the pimpl idiom. I
             | mean, this thing is notorious in the way it allows Qt to
             | remain binary compatible across even major version bumps.
             | And yet, "This makes C++ interfaces very unstable"?
             | 
             | The list reads like pure nonsense, to be quite honest. At
             | some point the author gripes over the lack of garbage
             | collection. Which language lawyers know very well that
             | until somewhat recently C++ standards actually had
             | provisions to explicitly support it, but whose support was
             | removed because no one bothered with it.
             | 
             | Is this your best reference?
        
               | zahlman wrote:
               | Yossi is aware of the pImpl idiom and refers to it
               | explicitly in section 16.21 of the FQA. It adds the
               | overhead of indirection; in particular, it means that
               | even when you don't use polymorphism and were able to
               | avoid the cost of a vtable, you still don't get to have
               | an array of instance data contiguously in memory. And
               | it's still something you have to do manually; you don't
               | get it by default. It seems clear to me that this simply
               | doesn't meet Yossi's standard for "compile time
               | encapsulation".
               | 
               | >At some point the author gripes over the lack of garbage
               | collection. Which language lawyers know very well that
               | until somewhat recently C++ standards actually had
               | provisions to explicitly support it, but whose support
               | was removed because no one bothered with it.
               | 
               | Other people not caring about garbage collection doesn't
               | mean it's a missing feature. It's clear why operator
               | overloading in particular would benefit from the ability
               | to make temporaries without worrying about the memory
               | they allocate. (Of course, this was written in an era
               | with a much poorer ecosystem of "smart pointers".)
               | 
               | >Is this your best reference?
               | 
               | It's not as good of a reference as I remember it being, I
               | suppose. It _has_ been a long time. But what I 've seen
               | of C++ in the interim, bit by bit, has generally made me
               | less inclined to pick it up again, not more. The
               | complexity just doesn't seem justified.
        
         | markus_zhang wrote:
         | I take a few features from C++ in my C++/SDL2 Ultima spinoff
         | project -- never completed sadly. Class, std::function,
         | std::unordered_map, std::string, std::unique_ptr<type> are the
         | only ones that I could recall.
         | 
         | I can't imagine reading other people's code though, unless it's
         | in a similar style. I did find that the most difficult part is
         | to get past the programming patterns (such as Visitor pattern)
         | as I don't write large programs professionally.
         | 
         | I wish C++ stopped at C++/11. The committee seems to want to
         | include everything into it at the moment. Maybe C++ is sort of
         | ULTRA programming language that supports every niche
         | programming style.
        
           | jandrewrogers wrote:
           | FWIW, C++20 is a _much_ tidier and more usable language than
           | C++11. The difference between C++11 and C++20 is almost as
           | large as C++11 and legacy C++.
        
           | tcbawo wrote:
           | What is your Ultima spinoff project?
        
             | markus_zhang wrote:
             | Ah that was my pet project to create an engine that runs a
             | game similar to Ultima 1-3. I even used the Ultima 4 sprite
             | sheet. Never completed it though.
        
         | mort96 wrote:
         | C++ is an absolute mess.
         | 
         | But it's a fun mess, and I like writing in it :) Sometimes,
         | that's important.
         | 
         | My relationship with, say, Rust is much colder: I respect Rust,
         | I use Rust where I think it makes sense (especially in e.g
         | professional contexts where I often can't defend the use of
         | C++), and I think what it's doing is important. But I find it
         | tedious to write, despite having a fair amount of Rust projects
         | under my belt at this point. It's better in key ways, but not
         | as _enjoyable_ , for me.
        
           | scotty79 wrote:
           | Rust is fun for me but I keep it high level with Rc and
           | built-in data structures. It's fun thinking about variables
           | as little boxes of fixed size that values get moved into or
           | out of. It's so different than almost any other language
           | where stuff lies often god knows where and is referenced ad
           | nauseam. Although that can be fun too if the language treats
           | mutability as exception rather than a rule.
        
         | amelius wrote:
         | Same. I wish someone made a better C++ from a blank slate. And
         | no it's not Rust.
        
         | zahlman wrote:
         | Is Rust not meant to offer the same kind of control and "low-
         | level-ness" as C? Like, can't you cast integers to pointer
         | explicitly if you break the `unsafe` seal (and thereby e.g. do
         | memory-mapped IO to control hardware)?
        
       | NotGMan wrote:
       | The problem with any language trying to replace C++ for larger
       | codebases is that it's not half as powerful as C++.
       | 
       | I've often cursed in C# because something that could be done
       | trivially in C++ if impossible and causes the dev to create
       | convuluted C# while it could be trivialy done in C++ due to its
       | very expressive language features.
       | 
       | Those 0.1% of the time that you need those extreme features are
       | what makes or breaks the language in PRODUCTION.
        
         | sidpatil wrote:
         | What are some examples of these C++ features you've missed in
         | other languages?
        
           | pixelpoet wrote:
           | Zig not having operator overloading makes it suck horribly
           | for writing any kind of vector code. If everyone had to write
           | int a = int_add(int_mul(3, 7), 2) etc there would rightly be
           | a riot, but since they're not 3D coders they just don't give
           | a shit. Too bad, Zig looks great.
        
             | pixelpoet wrote:
             | Sorry, one more thing to add to this: Andrew Kelley is
             | obviously a genius, and his talk introducing Zig[0] is in
             | my top 10 of all time technical presentations, for many
             | reasons. But I really do wish someone close to him with a
             | passion for how coding is in many ways applied mathematics,
             | would ask him to please have broader algebraic support for
             | basic operations like +, -, * and maybe divide, with their
             | basic dataflow characteristics. Optimal speed for complex
             | numbers vs std::complex out of the box would be attractive.
             | 
             | I understand his point about not wanting to allow every
             | random C++ feature, but in these cases, it isn't a C++
             | feature, it's language-level basic algebra.
             | 
             | In C++ land, ISPC[1] is often what you use when you want
             | top speed rendering perf on SIMD CPUs, e.g. Moonray
             | project[2]
             | 
             | Please, just go ahead and define a nice clean API for
             | vectors and scalars like OpenCL provides on its beautiful
             | reference cards:
             | https://www.khronos.org/files/opencl-1-2-quick-reference-
             | car...
             | 
             | [0] https://www.youtube.com/watch?v=Gv2I7qTux7g
             | 
             | [1] https://ispc.github.io/
             | 
             | [2] https://openmoonray.org/
             | 
             | Final edit sorry: in the end I love C++ and have been
             | learning Rust mainly out of curiosity. Avoiding C++ quirks
             | one can have few problems and a great time.
        
           | uzerfcwn wrote:
           | Once, I wanted to write a C# function roughly like this:
           | (T1, ..., Tn) Apply<T1, ..., Tn>((Func<P, T1>, ..., Func<P,
           | Tn>) args)
           | 
           | This is not possible in C# because the language doesn't have
           | variadic generics. Instead, I used runtime reflection and
           | wrote something like this:                 object[]
           | Apply(Func<P, object>[] args)
           | 
           | Although it worked, the downside is that the types T1, ...,
           | Tn are no longer statically known, which means that the
           | function's contract has to be written in comments and the
           | caller has to check them manually. In contrast, C++ has
           | variadic templates, which would allow the compiler to check
           | the types automatically.
        
         | blharr wrote:
         | I've had the exact same experience, but opposite. Tons of
         | things that are trivial in C# take a ton of code in C++ to me.
         | Maybe it's just going from being an expert in one language to a
         | newer language?
        
           | neonsunset wrote:
           | This often comes from expecting C# to be _just_ like C++,
           | where-as more complex use cases are often expected to be done
           | in a (sometimes completely) different way there. It 's a good
           | idea to try not to fight the language and work _with_ the way
           | it exposes its features.
           | 
           | My experience was just like yours - easy to move between C
           | and C#, or Rust and C#. But attempting C++ implementation was
           | always far more difficult. It was never worth it over just
           | spending extra effort in either alternative.
           | 
           | If GP reply author has C#-specific questions I'd be happy to
           | answer or point him or her in the right direction. C# is a
           | language with strong systems programming capabilities but has
           | its own learning curve.
        
         | ykonstant wrote:
         | That claim certainly warrants a serious example. Perhaps you
         | mean "something ... requiring maximum performance ..."?
        
         | tester756 wrote:
         | >I've often cursed in C# because something that could be done
         | trivially in C++
         | 
         | e.g?
        
       | GlenTheMachine wrote:
       | OK, so I admit I also washed my hands of C++ sometime around 2009
       | and I am being forced back into for <reasons>, and I had no idea
       | what these auto and lambda keywords were.
       | 
       | Can anyone point me to a learning reference that will let me jump
       | the meta programming apocalypse and just get to the good stuff?
        
         | seanthemon wrote:
         | jump into learncpp and choose where to start from, goodluck
        
         | olvy0 wrote:
         | The "Back to Basics" videos from cppcon are pretty good, IMO.
         | 
         | For lambdas: Back to Basics: Lambdas - Nicolai Josuttis -
         | CppCon 2021
         | 
         | https://www.youtube.com/watch?v=IgNUBw3vcO4
         | 
         | Back To Basics: Lambda Expressions - Barbara Geller & Ansel
         | Sermersheim - CppCon 2020
         | 
         | https://www.youtube.com/watch?v=ZIPNFcw6V9o
         | 
         | For auto, this one is short and summarizes some of the gotachs:
         | 
         | C++ Weekly - Ep 287 - Understanding `auto`
         | 
         | https://www.youtube.com/watch?v=tn69TCMdYbQ
        
       | vitaut wrote:
       | > C++ has built-in regex now and they're pretty damn good too
       | 
       | Sadly, `std::regex` is anything but good (poor performance, lack
       | of Unicode support) and should be generally avoided.
        
         | yodsanklai wrote:
         | The linter used at my work insists on not using it....
        
         | fooker wrote:
         | Is there something wrong with the specification that causes
         | poor performance?
        
           | steveklabnik wrote:
           | It's ultimately a "won't break ABI" issue:
           | https://stackoverflow.com/a/70587711
        
           | johannes1234321 wrote:
           | The underlying issue is that for the matches the interface
           | relies a lot on heap allocations for the individual matches,
           | leading to a lot of allocations of small regions to copy from
           | the original input. Many other libraries provide a lot more
           | control there.
           | 
           | In benchmarks std::regexp often is a lot slower compared to
           | other implementations, independent from the standard library
           | implementation of choice.
           | 
           | The big upside compared to all others is that it's always
           | available. But if there is a choice alternatives are often
           | better.
        
       | sumuyuda wrote:
       | I'm not for sure auto is an improvement. I know it is required
       | for lambdas and it makes it easier to type out a very verbose
       | type, but it really does reduce code readability.
       | 
       | I've even seen developers use it instead of bool, which is pretty
       | laughable as the they are the same number of characters.
        
         | wk_end wrote:
         | A verbose enough type - and C++ has plenty of those - is
         | indistinguishable from line noise.
         | 
         | There are places where having an explicit type annotation can
         | improve readability, places where it harms readability, places
         | where it doesn't make much difference one way or another.
         | Giving us the option has been a blessing. All programming calls
         | for good taste, C++ programming calls for it more than most.
        
         | BeetleB wrote:
         | > but it really does reduce code readability.
         | 
         | How about not specifying the type, and letting the compiler
         | infer it correctly and error out when it cannot - like so many
         | other languages do? And those languages are much _stricter_
         | about types than C++.
         | 
         | And auto _reducing_ code readability? Having to figure out the
         | intricacies of a detailed type to write was a huge barrier, and
         | virtually anyone reading the code with a type involving several
         | nested angle brackets would not bother mentally parsing it
         | anyway.
        
           | Leherenn wrote:
           | I think it does reduce readability in some scenarios.
           | 
           | For instance: const auto& processes =
           | getCurrentlyRunningProcesses(); for (const auto& process:
           | processes) { // Ok, what do I do with process now? Is it a
           | pair from a map? A struct from a vector? // If it's a pair
           | from a map, is the key the pid, a unique id, something else?
           | }
           | 
           | std::unordered_map<Pid, ProcessData> is more readable than
           | auto here IMO: you don't need to open the definition (or hope
           | your IDE correctly display the type).
        
         | jamesfinlayson wrote:
         | I remember reading something here recently about auto causing
         | some painful and difficult to diagnose bug - I think string was
         | what they thought the type should be (and some implicit cast
         | would have made it a string if the type was specified)... but
         | instead it created a string_view which went on to be used
         | somewhere that accepted both string and string_view and then
         | something tried to use it later but whatever the string_view
         | was pointing to was gone (or something in that vein - I don't
         | recall exactly).
        
           | xonre wrote:
           | It's probably auto when you wanted auto&.
           | 
           | A copy was made instead of a reference. I've been bitten by
           | that.
        
         | ansgri wrote:
         | Auto is an improvement for C++ only because of its uniquely
         | unergonomic type system and standard library. I'd very much
         | prefer writing something like `iterator<auto>` instead of
         | `auto` or `std::map<lotsofchars>::iterator` and not be told by
         | every linter to change most explicit type declarations to
         | `auto`.
        
       | SloopJon wrote:
       | This is a long rant that covers a lot of ground, a lot of which
       | will inevitably be ignored because the letters "C++" trigger
       | people, myself included sometimes. (Skip ahead to "It's Not All
       | Puppies and Butterflies" for some of the complaints.) The author
       | is really impressed by C++11, as am I, after purposely ignoring
       | C++ for the better part of twenty years.
       | 
       | I appreciate the shout outs to some packages and libraries to
       | play with, although I still often find it a pain to incorporate
       | other libraries into my projects. (Single-file headers, anyone?)
       | I'm intrigued by FTXUI.
       | 
       | And boy, howdy, he's right: cppreference.com is amazing. Python's
       | documentation is pretty good, but I've never seen anything as
       | good as cppreference.com.
        
         | zahlman wrote:
         | cppreference.com is very, very good at being _reference_ , as
         | in the name.
         | 
         | Python's documentation is scattershot and incomplete in many
         | places, and lacks a consistent copy-editing style - but it
         | offers good coverage of all kinds of documentation (per the
         | Diataxis framework), not just reference. The people writing
         | that documentation explicitly take that framework into
         | consideration and use it to look for ways to improve. (But it's
         | still a volunteer effort that works basically the same way the
         | code development does, following open-source principles, so.)
        
         | tecoholic wrote:
         | The article filled me on a lot of things I didn't know about
         | C++ because I learnt it at school and college, but soon moved
         | to Python/JavaScript for day job. I have been itching to "get
         | closer to the system" for a while now, and learning Rust on the
         | side hasn't been easy. This article gave me hope that, I might
         | be able to do that if I refreshed C++. Hello CMake... or I
         | should probably say, Meson.
        
       | DidYaWipe wrote:
       | I've had some good times in C++. But for everything that's been
       | thrown into it, I can't believe we're still dealing with header
       | files. That was one of the greatest things about moving to Swift:
       | no more of that BS.
       | 
       | But with SwiftUI, Swift has also become "unfun." SwiftUI and
       | Apple's half-assed, broken observation and "reactive" paradigm
       | have made programming a joyless slog.
        
         | badpun wrote:
         | C++20 has modules, which replace header files completely
         | (unless you use old libraries which aren't available as modules
         | yet). Compiler support is there, but unfortunately IDEs are
         | lagging. If you use modules with Visual Studio, say goodbye to
         | IntelliSense. Maybe they'll iron out the bugs in a couple
         | years...
        
           | DidYaWipe wrote:
           | Wow, that's ridiculous.
           | 
           | I wonder if Xcode does any better with them. Now that would
           | be something.
        
           | ModernMech wrote:
           | C++ has modules for small values of "modules":
           | https://arewemodulesyet.org
           | 
           | It's a bit tongue in cheek but: "Are we modules yet? Nope.
           | ... Estimated finish by: Wed Sep 20 2541"
        
             | badpun wrote:
             | You can use modules to structure your own codebase. No more
             | need to write headers and think about how to structure your
             | code in terms of compilation units. But yeah, your link
             | shows that practically none of the popular libraries
             | (except STL) can be imported as modules today.
        
           | wiseowise wrote:
           | C++20 that is not complete in 2025. I don't know how C++
           | developers can work in this with a straight face.
        
             | metaltyphoon wrote:
             | You probably have to think this way: Anything added to C++
             | will only get to be used in for real for real in 10 years
             | minimum.
        
           | lyu07282 wrote:
           | They needed the most powerful, most flexible module system
           | ever, so it might take decades to really become useable.
           | Adoption has been painfully slow so far, it's insane
           | complexity really doesn't help.
        
         | sumuyuda wrote:
         | I did C and C++, then moved on to Objective-C and Swift. I
         | recently switched back to C++, after getting tired of Apple's
         | shit treatment of developers. I also have no interest in
         | learning SwiftUI.
         | 
         | Having to define header files in C++ is pretty annoying after
         | doing Swift for many years.
        
         | motorest wrote:
         | > I've had some good times in C++. But for everything that's
         | been thrown into it, I can't believe we're still dealing with
         | header files.
         | 
         | There is nothing wrong with header files. In fact, there is no
         | such thing as a header file specified in C++. There are only
         | forward declarations and definitions, and how those can be
         | managed by developers.
         | 
         | Meaning, any talk about header files is a discussion on
         | software engineering practices, and how developers create or
         | avoid their own problems.
        
           | DidYaWipe wrote:
           | "There are only forward declarations and definitions, and how
           | those can be managed by developers."
           | 
           | Why do we need to manage them?
        
             | motorest wrote:
             | > Why do we need to manage them?
             | 
             | Why do developers need to write code that makes sense and
             | does what they want it to do?
        
               | DidYaWipe wrote:
               | Enjoy your echo chamber.
        
               | motorest wrote:
               | > Enjoy your echo chamber.
               | 
               | Is that supposed to mean anything at all?
        
               | BeetleB wrote:
               | Why do developers in other languages not have to deal
               | with it?
        
               | motorest wrote:
               | > Why do developers in other languages not have to deal
               | with it?
               | 
               | They do, except they don't have the bandwagon effect
               | motivating them to complain about other solved problems.
        
             | amelius wrote:
             | Because nobody has figured out a way to automate the
             | process of generating declarations from definitions.
        
       | 01100011 wrote:
       | I periodically work on c++ instead of C and each time it follows
       | a similar pattern where I learn about some new c++ trick, think
       | it will make things better, write my code, hit a compiler error,
       | then spend the rest of the day learning why I can't do what I
       | want. Granted, I usually am stuck at c++14, and some of the
       | issues are fixed in future versions but still...
       | 
       | I really want to love C++. It gives me a more powerful C that
       | theoretically should improve my output but in the end it carries
       | so much cognitive baggage that I usually end up writing "C with
       | classes" and move on.
        
         | blastonico wrote:
         | chatgpt or copilot helps a lot with that. I usually copy the
         | text and let it decipher the thing for me.
        
           | mithametacs wrote:
           | they're still bad for generating any significant body of
           | code.
           | 
           | They're a little bit better about deciphering errors.
           | 
           | They'll still bullshit* you and send you on wild goose
           | chases.
           | 
           | *hallucinate if you prefer
        
             | matheusmoreira wrote:
             | > They'll still bullshit you and send you on wild goose
             | chases
             | 
             | And confidently at that. It can't seem to find the backbone
             | to say no to me either.
             | 
             | If I say something like "wait, X doesn't seem to make
             | sense, isn't it actually Y and Z?" it will agree and
             | reformulate the answer as if Y and Z were correct just to
             | placate me. I usually use the LLM to learn new things, I
             | don't don't actually know if Y and Z apply.
        
         | fooker wrote:
         | C++, like most technology, works better if you put in the work
         | to learn about it.
         | 
         | (Admittedly there are languages like python and ruby that buck
         | this trend.)
        
           | motorest wrote:
           | > C++, like most technology, works better if you put in the
           | work to learn about it.
           | 
           | There's also the impact of software entropy: if someone has
           | little to no experience developing software and has to grow
           | it by adding features and fixing bugs, over time their
           | contribution to the project invariably results in degrading
           | it beyond the point they can possibly salvage it.
           | 
           | At that point, they blame the tools.
        
           | Symmetry wrote:
           | Sure, but the effort/reward ratio bears some consideration.
           | I've put a lot more effort into learning C++ than any other
           | programming language but I'd still say it's just the language
           | I'm maybe 4th most proficient in.
        
           | 01100011 wrote:
           | Programming languages are a means to an end. I'd rather have
           | my cognition going towards solving the actual problem and not
           | worrying about implementation details.
        
           | zahlman wrote:
           | Python _does_ work better if you put in that kind of work.
           | Otherwise you 'll get bit by the way mutable default
           | arguments work[0] (or never learn to use it to your
           | advantage), or by late binding of closures[1] (and maybe
           | you'll pick up the awful habit of _exploiting the confusing
           | early binding of default arguments_ to make the `lambda`s
           | that you constructed in a loop work properly[2]). Or you won
           | 't get the big picture of the descriptor protocol[3] and how
           | method lookup[4] is related to the implementation of
           | properties[5]. Or you won't get the fancy metaclass[6] thing
           | that your favourite framework is expecting you to treat as an
           | opaque abstraction[7], or how and when you might use a class
           | decorator[8] instead of a metaclass to do that kind of
           | metaprogramming.
           | 
           | [0]: https://stackoverflow.com/questions/1132941
           | 
           | [1]: https://stackoverflow.com/questions/2295290
           | 
           | [2]: https://stackoverflow.com/questions/3431676
           | 
           | [3]: https://docs.python.org/3/howto/descriptor.html
           | 
           | [4]: https://eev.ee/blog/2013/03/03/the-controller-pattern-
           | is-awf... (yes, this was partly an excuse to get one of Zed
           | Shaw's critics [9] into the discussion)
           | 
           | [5]: https://stackoverflow.com/questions/3798835
           | 
           | [6]: https://stackoverflow.com/questions/100003
           | 
           | [7]: e.g. https://medium.com/@miguel.amezola/demystifying-
           | python-metac... - I didn't have a good link for this and
           | didn't spend a long time searching, but this seems okay
           | 
           | [8]: https://stackoverflow.com/questions/681953
           | 
           | [9]: https://eev.ee/blog/2016/11/23/a-rebuttal-for-python-3/
        
         | gopalv wrote:
         | > then spend the rest of the day learning why I can't do what I
         | want
         | 
         | There's a point when learning's fun, I think the OP is still
         | there.
         | 
         | I wrote a bunch of realtime C++ in 2003, hated it. But last
         | year, I wrote most of my code in C++ and liked it finally.
         | 
         | Lambda and auto was the tipping point where I stopped hating
         | it. Some templates thrown in, but mostly to avoid writing a lot
         | of branches for variants of the same function.
         | 
         | With lambdas I could now write the way I was initially taught
         | programming, mostly by Lispy teachers channeling SICP.
         | 
         | Didn't hate the allocations either with unique_ptr.
        
           | hashishen wrote:
           | "Lispy teachers channeling SICP" made new audibly laugh
        
           | cshokie wrote:
           | If you haven't already look up 'if constexpr' in cpp17 and
           | newer. It lets you have compile time branches in a single
           | function.
        
             | mst wrote:
             | Also requires, which initially looks batshit insane but is
             | in fact really quite cool: https://www.think-
             | cell.com/en/career/devblog/if-constexpr-re...
        
           | scotty79 wrote:
           | > There's a point when learning's fun, I think the OP is
           | still there.
           | 
           | What a horrible idea that one might no longer be there.
        
         | mystified5016 wrote:
         | This describes my C++ experience precisely. Initially I was a
         | C# programmer learning C for embedded projects and it went
         | exactly like this.
         | 
         | C++ has a lot of really neat features that sure look powerful
         | if your application aligns precisely. It seems like _every_
         | time I try a new feature, what I want to do is always an edge
         | case that doesn 't work in my situation. I try for a few
         | hours/days before I give up and just write it in C.
        
           | bcrl wrote:
           | My biggest disappointment with C++ is that the standard
           | libraries are completely unsuitable for use in embedded
           | systems where you have to control when, where and how many
           | memory allocations occur. This is particularly important when
           | the system level design choice is to perform all allocations
           | at system startup, which is a common design pattern for high
           | performance systems with real time characteristics. A high
           | speed messaging system I worked on ran into this all the
           | time. We couldn't use the standard implementations of things
           | like heaps, hashes or queues because they don't have a way of
           | making memory allocations occur at startup. It was quite
           | common to have to re-implement those data structures when
           | adding a new feature, as the stl or boost implementations
           | were not suitable for this design pattern.
        
             | swordzen wrote:
             | Have you tried override the allocators and destructors of
             | your classes so you can do all allocations at startup?
        
         | ahartmetz wrote:
         | I see a lot of bad code from people who have just learned about
         | some feature and want to use it. Don't do that. Think of how to
         | write your code, and then, if a feature solves a problem, use
         | it. Problem->Solution, not the other way around.
         | 
         | E.g. C++ templates are generally pretty awful, but sometimes,
         | compile-time duck typing, or automatically adding padding based
         | on sizeof(), etc, is very useful.
        
       | liendolucas wrote:
       | A bold statement from Ken Thompson on C++:
       | https://m.youtube.com/watch?v=c-P5R0aMylM
        
       | blastonico wrote:
       | The amount of high performance, production grade, massively
       | tested libraries written in C++ is unbeatable. I will be honest
       | here, it's easier to improve C++ security by implementing a
       | compiler that produces safer C++ (like Typescript to Javascript)
       | than rewriting everything in any other language (Rust, Zig, Odin,
       | whatever).
       | 
       | I mean, could you estimate the cost ($ and time) it would take to
       | rewrite the best audio framework in any other language?
       | (https://juce.com/).
        
         | devjab wrote:
         | Zig is great, it's not aiming to be a replacement for C++
         | though. One of the awesome things about Zig is its
         | interoperability with C. In that sense it's more of a
         | Typescript to C than Rust is to C++. I'm still not sure what I
         | think about Rust personally. In my region of the world I
         | suspect it'll continue to struggle to find any form of adoption
         | as the C++ people seem to have very little interest in trading
         | their decade long experience for Rust. Zig on the other hand is
         | winning the hearts and minds of most C programmers I know.
         | 
         | I hope Rust succeeds though. I say this more from a change
         | management perspective than anything else. It's extremely hard
         | for us to find developers who will primarily work with garbage
         | collected languages but occasionally have to work with either C
         | or C++ when bottle necks appear. Rust makes that much easier,
         | or perhaps less dangerous would be a better term. I'm not sure
         | any of the attempts at making C++ more safe to use is going to
         | really succeed in this regard. Maybe, but I nothing within the
         | C++ community seems to pull in that direction so I doubt it.
         | I'd like to mention that I'm aware that Zig isn't helpful in
         | this regard either as it's not memory safe.
        
         | zahlman wrote:
         | How many total lines of code do you imagine are in these
         | libraries, compared to _all their clients_? If rewriting the
         | libraries sounds like an unreasonable amount of work in a world
         | where all that client code exists, doesn 't that reflect
         | negatively on the readability of C++?
        
       | FpUser wrote:
       | Agree. Sure there are problems here and there but I think that
       | overall modern C++ is likely the most versatile tool in the
       | "compiled to native, can do anything" family
        
       | jonstewart wrote:
       | Every time I try to use Rust instead of C++, I'm left asking
       | "bruh, do you even functor?"
        
       | macawfish wrote:
       | Using c++ after learning rust feels like picking through moldy
       | bread
        
         | hypeatei wrote:
         | Using C++ after Rust made me appreciate the latter a lot more.
         | You quickly learn all the footguns that the compiler stops you
         | from doing and is generally a good learning experience.
        
           | ModernMech wrote:
           | This is what I feel as well. I liken it to using an aimbot in
           | Quake. Turn off the aimbot and you still win because the
           | aimbot trained you how to get headshots. There are many times
           | the Rust compiler told me I couldn't do something I had
           | insisted would be fine, only to ponder and realize in fact
           | what I was doing would cause subtle bugs in an edge case.
           | Rust catches it at compile time, C++ allows you to write the
           | code and sends you a segfault when the subtle edge case
           | occurs in production.
        
             | chowells wrote:
             | Segfaults in production are the _good_ case. They 're when
             | the system recognizes you've made a mistake and stops it
             | from propagating. The bad cases are when the program keeps
             | running but silently does the wrong things.
        
               | spacechild1 wrote:
               | Yes! This can be a real problem when your data structures
               | are allocated from a memory pool. Since the whole memory
               | region is owned by the program, out-of-bounds writes will
               | either do nothing or silently corrupt your program state.
        
               | ModernMech wrote:
               | The good case is that you catch the error in development
               | and it doesn't even get to production.
        
           | plandis wrote:
           | Plus the Rust compiler actually gives you helpful error
           | messages. C++ compiler errors might as well be in Klingon.
        
         | marcosdumay wrote:
         | Strings!
         | 
         | Strings in Rust aren't that great, because there are some
         | details you must keep track. But when I was first learning it,
         | I eventually had some desire to rewrite stuff in C++, and
         | always stopped at the first thought of dealing with strings.
        
       | aleden wrote:
       | For the love of God when will c++ compilers finally be able to
       | output template errors that aren't completely expanded and are
       | written in terms of the user's typedefs? Most of the time I spend
       | parsing template errors with boost is just to figure out what the
       | hell is being complained about.
        
         | ModernMech wrote:
         | I have found LLMs are a great tool for metaprogramming. I think
         | the template error problem has been wanting for a sufficiently
         | advanced compiler, and that's what I see LLMs as being. ChatGPT
         | has been a great help in debugging programs I've written in C++
         | templates, both in generating the template code and trying to
         | decipher errors generated, leading to suggestions for the
         | template code rather than the expanded syntax.
        
           | aleden wrote:
           | Yeah, totally. I find LLMs are very useful for doing stuff
           | with the preprocessor, too. ChatGPT taught me how to use
           | boost preprocessor (BOOST_PP_FOR_EACH_PRODUCT).
           | 
           | Still though, I want to see MyMapType::value_type in compiler
           | errors rather than... Well, you know. It's going to contain
           | the type of the key, the type of the value, the type of the
           | allocator, just when all you want to really know is that it's
           | a pair<key, value>, which I think most people know of as My
           | map type::value_type.
        
         | wk_end wrote:
         | Weren't concepts supposed to fix this? Apparently they made it
         | into the 2020 standard. I haven't touched the language in many
         | years - did they not help?
        
           | andrewflnr wrote:
           | Concepts did not actually make it into the standard. I
           | vaguely recall they were cut at the last minute or something.
        
             | suby wrote:
             | Concepts are in C++20. I don't know the specifics but it's
             | my understanding that the version we got is stripped down
             | in comparison to the original proposal.
        
               | andrewflnr wrote:
               | Oh, woops. Maybe they I only updated my belief before
               | 2020. OP is right about one thing, cppreference is great.
               | https://en.cppreference.com/w/cpp/language/constraints
        
       | ryao wrote:
       | > I want you to ask yourself an honest question. When was the
       | last time you actually had fun in programming?
       | 
       | Every time I write C code.
        
         | binary132 wrote:
         | For me, C is fun until I hit a certain level of abstraction
         | complexity involving fake homespun vtables and it starts
         | getting harder than it should be to chase down bugs.
        
         | NooneAtAll3 wrote:
         | every time I write C code, I don't want to remember how to
         | implement unordered map
        
           | kragen wrote:
           | You mean                   enum { nb = 1024 };         struct
           | { int k, v; } hash[nb];              // 0 is an invalid key
           | void incr(int k)         {           int i = k % nb, j = i;
           | do {             int k2 = hash[i].k;             if (k2 && k2
           | != k) {               i = (i+1) % nb;               continue;
           | }             hash[i].k = k;             hash[i].v++;
           | return;           } while (i != j);           abort();
           | }
           | 
           | Apologies for the telegraphic variable names and weird
           | control flow. I wrote this on my cellphone. Lacking these 15
           | lines are what keep you from writing C?
           | 
           | There's a nice tutorial on hash tables in K&R, and I can also
           | recommend learning about Chris Wellons's "MSI" hash table
           | design, described in C at
           | https://nullprogram.com/blog/2022/08/08/. He shows a more
           | full featured hash table in about 30 lines of code, depending
           | on what functionality you need. It's eminently practical, and
           | usually a lot faster than generic algorithms.
           | 
           | That's not an exceptionally simple hash table either. One
           | night I hurriedly wrote a rather long-winded implementation
           | also on my cellphone (strings, with separate chaining and a
           | djb-style hash function) and it also came to about 30 lines
           | of code: http://canonical.org/~kragen/sw/dev3/justhash.c
        
           | uecker wrote:
           | You can't use anyone else code and always delete your own
           | previous implementation?
        
         | spacechild1 wrote:
         | Everytime I need to write C, I wish I could use C++ instead.
         | The things I miss most are RAII, templates, lambdas, const-
         | correctness, and most importantly, a standard library with
         | container types and algorithms.
        
           | uecker wrote:
           | What is wrong with const-correctness in C?
           | 
           | I think container types and algorithms is a fair point, but
           | if you program C more you should have a go-to library or your
           | own implementation.
        
         | uecker wrote:
         | I agree, I switched from C++ to C and I found it relaxing to be
         | able to just forgot about a million language features and their
         | complicated interactions.
         | 
         | I also find you have some experience, know how to build good
         | abstractions and have a set of good data structures, there is
         | no issue with address complex problems in C.
        
       | 8f2ab37a-ed6c wrote:
       | Come write products on top of Unreal Engine, you will have the
       | opportunity to dive into 20+ MLoC of real time C++ goodness. Make
       | sure it's a multiplayer experience for bonus points, eventual
       | consistency makes everything extra exciting.
       | 
       | It gives you an appreciation of just how unlikely we're to ever
       | move away from the stuff, short of an LLM innovation that can
       | digest codebases of that size and do an automated port, which I
       | suppose is not outside of the realm of reality these days.
        
       | IshKebab wrote:
       | There's too much wrong in this rant to list...
        
         | ModernMech wrote:
         | I think we can start with "C++ is not popular enough to attract
         | the weirdos".
         | 
         | Presumes C++ is not popular and also popularity attracts
         | weirdos. If anything, weirdos are attracted to languages that
         | are not popular at all. I remember once I was on a small
         | language project and this guy on the mailing list wouldn't stop
         | going on about how our language had to support vorpal math.
        
       | nayuki wrote:
       | > C++ Is An Absolute Blast
       | 
       | No, it's one of the worst languages I ever used. Tons of footguns
       | and bad design choices everywhere. Too much cognitive load for
       | less benefit than other languages.
       | 
       | I'm surprised the article didn't mention <iostream>. The
       | f.fail(), f.eof(), f.flags() are confusing and verbose. Even
       | something as simple as f.read() doesn't return the number of
       | elements read, so you need to make a separate call to f.gcount().
       | And then there are all the opaque types like std::streamsize,
       | std::mbstate_t, etc., where you have no idea how their sizes
       | relate to language types like int/long/etc. or fixed-width types
       | like int32_t/uint64_t/etc.
       | https://en.cppreference.com/w/cpp/string/char_traits
       | 
       | And then there are the redundancies. int x = 0; int x(0); int
       | x{0}; all roughly do the same things but have subtle differences
       | in more advanced use cases. This recent thread (
       | https://codereview.stackexchange.com/questions/294784/c20-ro... )
       | reminded me that `typedef` got replaced by `using`. A while ago,
       | I came up with a long list of near-duplicate features:
       | https://www.nayuki.io/page/near-duplicate-features-of-cplusp...
       | 
       | > JavaScript still can't even figure out what a for-loop is
       | 
       | ECMAScript 6 added the for-of loop, which is the more useful
       | alternative to the for-in loop.
       | 
       | > C++ has lambda, and it's not bullshit like Python's lambda
       | 
       | C++ lambdas have a heavier syntax than any other lambda I know of
       | (e.g. Python, Java, JavaScript, Haskell, Rust), because it needs
       | to specify attributes and captures.
       | https://en.cppreference.com/w/cpp/language/lambda
       | 
       | > My thinking is C++ is now about as good as any other language
       | out there
       | 
       | Not by a longshot. Instead of C++, I reach for Java if I want
       | fast design time, safe operations, and a more limited set of
       | tools (e.g. not needing to decide how many layers of pointer
       | indirection I want). I reach for Rust if I want the power of C++
       | without its footguns.
       | 
       | Heck, my motto for Rust has always been, "C++ done right". Every
       | time I compare analogous features in C++ and Rust, I find that
       | the Rust version is much better designed. As the simplest
       | example, in Rust it's a compile-time error to use a variable
       | whose value is moved out, whereas in C++ the variable is still
       | usable but has an invalid value. Another example is that Rust has
       | traits but C++ relies on instantiating templates and then "duck-
       | typing" to see if the resulting code can actually compile. And
       | let's not forget nullptr, the trillion-dollar mistake - C++ makes
       | nullptr implicitly part of every pointer(*) type, but Rust bans
       | it by default unless you opt in with Option<T>. Rust has other
       | quality-of-life features such as easily declared tuple types, the
       | unit type instead of void (which makes functional programming
       | easier as you don't have to special-case void), pattern matching
       | and unpacking, methods on primitive types (e.g. 456u32.isqrt()
       | instead of sqrt(456)). I just can't look at C++ seriously when
       | Rust is miles ahead, being more expressive and safer.
       | 
       | > The Amazing Comeback of C++11
       | 
       | I will agree with this in a limited sense When I write C++ code
       | (because I'm a masochist), I will not tolerate anything less than
       | C++11, because C++03 and C++98 are much, much worse. I'm talking
       | about things like various types, standard library
       | classes/functions, unique_ptr, and move semantics.
        
         | motorest wrote:
         | > No, it's one of the worst languages I ever used.
         | 
         | That says more about you than the languages you've used.
         | 
         | C++ is one of the top 5 languages used in production. This is
         | true still today, with so many specialized languages to pick
         | and choose. No one had to hold a gun to anyone's head to get
         | them to adopt it. How do you rationalize that if your opinion
         | had any substance or merit?
         | 
         | For the sake of argument, I assert exactly the opposite: C++
         | post-C++11 is the absolute best language ever devised by
         | mankind, bar none. Am I wrong?
         | 
         | > Tons of footguns and bad design choices everywhere.
         | 
         | Please go ahead and point out the single most egregious "foot
         | gun" or bad design choice you can possibly imagine. The worst.
         | This will serve to show the world how well thought through your
         | opinion actually is.
        
           | whytevuhuni wrote:
           | I don't think C++ is one of the worst languages; there are
           | very few languages as powerful as C++, that alone makes it
           | one of the best.
           | 
           | But, much like love and hate, I also don't think that the
           | opposite of good is always necessarily bad, nor vice-versa. A
           | language can be both good and bad at the same time, in
           | different aspects.
           | 
           | C++ is really good (unrestrained freedom, performance,
           | ecosystem), and also really bad (tooling, templates, really
           | hard to debug memory issues).
           | 
           | Rust is somewhat less good (less free, slower, puny ecosystem
           | in comparison), but also a _lot_ less bad (powerful type
           | system, thread safety, fearless iterators /lambdas, etc).
           | 
           | Many of the warts C++ has to carry due to its commitment to
           | compatibility, are fixed in Rust with much better
           | alternatives. A lot of footguns are well encapsulated in
           | Rust's affine-ish types and algebraic data types, while still
           | providing unsafe hatches for when you need them. Defaults
           | really matter.
        
           | wiseowise wrote:
           | > No one had to hold a gun to anyone's head to get them to
           | adopt it. How do you rationalize that if your opinion had any
           | substance or merit?
           | 
           | We did. It was either C or C++ that were supported by our
           | hardware vendor.
           | 
           | > For the sake of argument, I assert exactly the opposite:
           | C++ post-C++11 is the absolute best language ever devised by
           | mankind, bar none. Am I wrong?
           | 
           | Absolutely. It is one of the most complex and error prone
           | languages out there.
        
           | sunshowers wrote:
           | Lambdas that can borrow from the stack and still return.
           | Absolutely unacceptable feature without a borrow checker.
        
         | jandrewrogers wrote:
         | > in Rust it's a compile-time error to use a variable whose
         | value is moved out, whereas in C++ the variable is still usable
         | but has an invalid value
         | 
         | C++ does it this way because there are common cases in systems
         | code where doing it the Rust way would literally be unsafe. Not
         | all memory references are visible at compile-time and may exist
         | outside the address space.
        
           | aw1621107 wrote:
           | Would you mind elaborating more on those common cases? I'm
           | not sure I've heard of destructive moves being less safe than
           | non-destructive moves and I'm not smart enough to figure out
           | what you're talking about in your second sentence.
        
             | jandrewrogers wrote:
             | Shared address space. Some other process or silicon can
             | read or write the object you just moved but doesn't know
             | you moved it. You need to keep the memory previously
             | occupied by the moved object valid long enough for those
             | references to realize you moved it to prevent corruption.
             | 
             | A typical case is high-performance I/O, which uses a lot of
             | DMA. DMA is oblivious to most programming language
             | semantics like lifetimes, ownership, etc and will happily
             | step all over your address space if you aren't careful.
        
               | sunshowers wrote:
               | This just means that affine types aren't the right tool
               | to model memory that you don't have full control over.
               | Which is true, but also represents a very small subset of
               | overall data. Rust provides you with other tools to
               | handle those kinds of situations.
               | 
               | There is a small wart here, which is that (with async
               | Rust) some of these use cases would benefit tremendously
               | from full-fledged linear types, or at least an easy way
               | to run code during async cancellation.
               | 
               | The difference between an affine and a linear type is
               | that the ways in which a linear type is consumed are
               | controllable through encapsulation -- for example,
               | imagine you have a type which represents a certain amount
               | of money, and you want to statically prevent the money
               | from being dropped on the floor. Affine types don't
               | prevent that statically, but linear types do. You can
               | still have runtime checks though.
        
               | the__alchemist wrote:
               | I'm curious to hear more about this use case. The DMA I
               | do in rust is generally static buffers, because I'm not
               | sure how to pass the borrow checker otherwise. (There are
               | ways). Generally, you set up a static [u8] buffer, and
               | pass its pointer to the hardware that's doing the DMAing.
               | Then magic, then the buffer gets read or written by the
               | hardware. In this scenario, the variables never go out of
               | scope. Am I cheating, and avoiding this issue by using
               | static buffers? If the buffer drops during a DMA
               | transfer, I believe UB happens.
               | 
               | I'm suspicious a similar principle happens with memory-
               | mapped flash memory as well, e.g. QSPI.
        
               | aw1621107 wrote:
               | Thanks for taking the time to elaborate!
               | 
               | > Some other process or silicon can read or write the
               | object you just moved but doesn't know you moved it.
               | 
               | That should primarily affect buffers that are inline with
               | the moved object, right? i.e., not static buffers or
               | stuff that's heap-allocated? How common is that scenario?
               | I admittedly generally thought DMA used static buffers,
               | though to be fair I'm not exactly highly experienced in
               | the space.
               | 
               | > You need to keep the memory previously occupied by the
               | moved object valid long enough for those references to
               | realize you moved it to prevent corruption.
               | 
               | How is this (reliably) handled in C++? I feel there's
               | gotta be more than just hoping the empty object hangs out
               | long enough for the rest of the system to catch on (e.g.,
               | moving things around near the end of a scope when the
               | empty object will be destroyed "soon").
        
         | zahlman wrote:
         | I'm mostly very much in agreement with what you've said here
         | but I want to pick on a few things:
         | 
         | > Instead of C++, I reach for Java if I want fast design time,
         | safe operations, and a more limited set of tools (e.g. not
         | needing to decide how many layers of pointer indirection I
         | want).
         | 
         | I don't think I've ever seen a good reason to prefer Java over
         | C# for anything.
         | 
         | > Another example is that Rust has traits but C++ relies on
         | instantiating templates and then "duck-typing" to see if the
         | resulting code can actually compile
         | 
         | Is the https://en.cppreference.com/w/cpp/header/type_traits
         | functionality not sufficient for what you have in mind?
         | 
         | >the unit type instead of void (which makes functional
         | programming easier as you don't have to special-case void)
         | 
         | Why would special-casing be necessary? You don't need to say
         | e.g. that mapping a void-returning function produces an empty
         | result; it could just be a compile error. I feel like void
         | returns _should be_ a special case and I don 't like all the
         | ways `None` is used in Python, because it's one of the few
         | things that blurs an otherwise very strong distinction between
         | statements and expressions, analogously between commands and
         | queries.
        
         | xonre wrote:
         | You are correct wrt to iostream, it's bad. I stick to studio.h.
        
       | halfcat wrote:
       | I recall not being very effective with C++ for years, and then
       | someone recommended the book Large Scale C++ Software Design, and
       | that was a big unlock.
       | 
       | I didn't use 80% of what's in the book, but just having a
       | comprehensive way of structuring the code was a massive
       | productivity boost. Looking back, I suspect it was less that it
       | was "the right way", but just that it was "a way" and most of the
       | benefit was it kept me from overthinking and got me to work.
       | 
       | Later with C++11, I kept having this thought, "in Python this
       | would be way less verbose", and I started writing C++ that looked
       | more like Python, creating whatever helper functions Python would
       | have (mostly simple stuff, string handling, etc).
       | 
       | That was one of the most productive seasons of programming I ever
       | had, and I still get tempted to write stuff in C++ that Python is
       | better suited for, just because the benefit of not overthinking
       | is that significant (at least for me).
        
       | andai wrote:
       | >But, C++ kept evolving, and the standards committee seemed to
       | realize that if they don't do something they'll become an obscure
       | language only used by a single 10 trillion dollar industry. How
       | pathetic!
       | 
       | Which industry is this referring to?
        
         | brabel wrote:
         | My guess is that it's the game industry, because it's probably
         | worth that much and is almost pure C++.
        
       | ajuc wrote:
       | The stuff you use for work is not fun. The stuff you use for fun
       | is fun. There, I solved the mystery for you.
       | 
       | If you choose technology for work by what is the most fun - you
       | enter a hedonist treadmill. Stop. JS framework insanity lies that
       | way. No cool technology will save you from burnout.
        
       | derriz wrote:
       | I was C++ dev for 5 or 6 years, up to the late 2000s.
       | 
       | I got another C++ job about 3 years ago but bailed after about a
       | year.
       | 
       | I could write a tome about what I dislike but to start with, any
       | language that lacks a working standard built-in string type, is
       | just a hard no for me at this stage in my life. Life is just too
       | short.
       | 
       | The tooling and IDE support is atrocious, no standard dependency
       | management for 3rd party libraries and CMake makes maven look
       | well designed.
       | 
       | I tried to pull my knowledge up to date. Hmmm, we used to have
       | lvalues and rvalues, what's this prvalue thing?
       | 
       | Surely cppreference can explain:
       | 
       | > _a prvalue ("pure" rvalue) is an expression whose evaluation_
       | 
       | > _- computes the value of an operand of a built-in operator
       | (such prvalue has no result object), or_
       | 
       | > _- initializes an object (such prvalue is said to have a result
       | object)._
       | 
       | > * The result object may be a variable, an object created by
       | new-expression, a temporary created by temporary materialization,
       | or a member thereof. Note that non-void discarded expressions
       | have a result object (the materialized temporary). Also, every
       | class and array prvalue has a result object except when it is the
       | operand of decltype;*
       | 
       | > _The following expressions are prvalue expressions:_
       | 
       | > _a literal (except for string literal), such as 42, true or
       | nullptr;_
       | 
       | > _a function call or an overloaded operator expression, whose
       | return type is non-reference, such as str.substr(1, 2), str1 +
       | str2, or it++;_
       | 
       | > _a++ and a--, the built-in post-increment and post-decrement
       | expressions;_
       | 
       | > _a + b, a % b, a & b, a << b, and all other built-in arithmetic
       | expressions;_
       | 
       | > _a && b, a || b, !a, the built-in logical expressions;_
       | 
       | > _a < b, a == b, a >= b, and all other built-in comparison
       | expressions;_
       | 
       | > _& a, the built-in address-of expression;_
       | 
       | > _a.m, the member of object expression, where m is a member
       | enumerator or a non-static member function[2];_
       | 
       | > _p- >m, the built-in member of pointer expression, where m is a
       | member enumerator or a non-static member function[2];_
       | 
       | > _a.*mp, the pointer to member of object expression, where mp is
       | a pointer to member function[2];_
       | 
       | > _p- >*mp, the built-in pointer to member of pointer expression,
       | where mp is a pointer to member function[2];_
       | 
       | > _a, b, the built-in comma expression, where b is an prvalue;_
       | 
       | > _a ? b : c, the ternary conditional expression for certain b
       | and c (see definition for detail);_
       | 
       | > _a cast expression to non-reference type, such as static_cast
       | <double>(x), std::string{}, or (int)42;_
       | 
       | > _the this pointer;_
       | 
       | > _an enumerator;_
       | 
       | > _a non-type template parameter of a scalar type;_
       | 
       | > _a lambda expression, such as [](int x){ return x * x; };_
       | 
       | > _(since C++11)_
       | 
       | > _a requires-expression, such as requires (T i) { typename
       | T::type; };_
       | 
       | > _a specialization of a concept, such as
       | std::equality_comparable <int>._
       | 
       | > _(since C++20)_
       | 
       | > _Properties:_
       | 
       | > _Same as rvalue (below)._
       | 
       | > _A prvalue cannot be polymorphic: the dynamic type of the
       | object it denotes is always the type of the expression._
       | 
       | > _A non-class non-array prvalue cannot be cv-qualified, unless
       | it is materialized in order to be bound to a reference to a cv-
       | qualified type(since C++17). (Note: a function call or cast
       | expression may result in a prvalue of non-class cv-qualified
       | type, but the cv-qualifier is generally immediately stripped
       | out.)_
       | 
       | > _A prvalue cannot have incomplete type (except for type void,
       | see below, or when used in decltype specifier)._
       | 
       | > _A prvalue cannot have abstract class type or an array
       | thereof._
       | 
       | Yeah, this language is loads of fun. I've worked on compilers,
       | interpreters, implemented extended Hindley-Milner type systems,
       | etc. so normally love reading formal language specs but this is
       | just insane.
        
         | AnimalMuppet wrote:
         | > any language that lacks a working standard built-in string
         | type, is just a hard no for me at this stage in my life.
         | 
         | Um, std::string is a thing...
        
       | TrianguloY wrote:
       | I've had a similar situation with Kotlin. I've always been a java
       | developer, and I enjoy using it, but even with the newer features
       | it's just...slow.
       | 
       | When I had to script things I chose JavaScript (native
       | JavaScript) since it's way faster to iterate, but I've always
       | missed the static typing (I also know python, but I honestly
       | prefer JavaScript)
       | 
       | Until I learned Kotlin. It's been a blast to use, incredible
       | common libraries, streams everywhere, nulls that you can use
       | without issues...I just love it (so much in fact that I'm in the
       | process of switching project from java to Kotlin).
       | 
       | When I need to do scripts, like for the advent-of-code, I choose
       | Kotlin.
        
         | adra wrote:
         | I also really enjoyed the jump into Kotlin as well! That said,
         | I'm also very happy with recent java versions trying very hard
         | to close the gap. It does feel like at least half of Java's
         | recent major lifts have been to emulate things done well in
         | other languages (a great attribute for a self-aware language
         | developer). I definitely never appreciated a lot of their newer
         | feature choises like records until I saw them working really
         | well in Kotlin data classes.
        
       | shmerl wrote:
       | C++ is fun, but "Rust weirdos" are right. Don't use C++, use
       | Rust. That's all.
        
       | wiseowise wrote:
       | > Need package management? Check out Conan, Meson's WrapDB, and
       | vcpkg.
       | 
       | No, just no. All of them are complete, utter crap that doesn't
       | hold a candle to languages that were designed with packages in
       | mind. We're using Conan at work, I've been using vcpkg at home
       | and I loathe both.
       | 
       | > I mean, do you really think Python's package management is top
       | notch? You do? Why are there like 10 package managers then?
       | 
       | Worst Python package manager runs circles around whatever C++
       | offers.
        
         | synergy20 wrote:
         | what's wrong with vcpkg? looks good to me
        
         | Philpax wrote:
         | I don't think we need to pretend Python package management is
         | good to contrast C++, they're both awful for different reasons.
         | 
         | At least there's maybe a way out for Python (uv / the various
         | PIPs); C++ doesn't appear to have any kind of plan whatsoever,
         | outside of gesturing in the direction of modules.
        
       | amelius wrote:
       | Is anyone still using the Boost libraries?
        
         | spacechild1 wrote:
         | Yes! Boost.Asio is still the go-to networking library. (It's
         | also available as a standalone, though.)
         | 
         | Some parts have been adopted by the C++ standard library and
         | can thus be considered obsolete, there a still quite a few
         | goodies!
        
         | nurumaik wrote:
         | Yes, it gives me free coffee breaks every time I compile my
         | code
        
       | ironman1478 wrote:
       | C++ really is a blast and I think the complaints people have
       | about it really depend on context. Lots of C++ devs hate that
       | language but imo misdirect their hate. They actually work on
       | legacy products built by people who were never that great at
       | writing software. This happened to me with Rust actually where I
       | was thrust into an existing rust project at the company I work
       | for. It's an "old" codebase with many different and conflicting
       | conventions within it (different error handling types that don't
       | compose well, bad class abstractions, lots of unsafe block when
       | not needed, etc). The project was the most miserable project I've
       | ever worked on and it's easy for me to blame Rust, but it's
       | really just bad software development. There are warts in C++, but
       | a lot of the pain people run into is just that they are working
       | on crap code and it would be crap in any language.
        
         | psyclobe wrote:
         | This 1000%, stop blaming the tools!
        
           | mrcsd wrote:
           | How can we make better tools if we don't blame tools?
        
           | zdragnar wrote:
           | Eh, I'm reminded of the old "programming languages as
           | weapons" comic, with the one that I still remember is
           | JavaScript was a sword without a hilt, with the blade being
           | the "good part" and in place of the hilt, another blade
           | labelled the "bad part".
           | 
           | You can blame devs instead of tools all day long, but you
           | can't deny that there are things about the tools that hold
           | the developers back.
        
         | nvarsj wrote:
         | True - but it's much easier to make an incomprehensible mess in
         | more complex languages. Whereas blub language projects are
         | pretty easy to decipher regardless of the state of the
         | codebase.
        
         | zahlman wrote:
         | I really can't resonate with this. The type system is obnoxious
         | (and you don't even get proper memory safety out of it), the
         | "most vexing parse" truly is vexatious, there's all the
         | weirdness inherited from C like pointer decay (and then
         | building new solutions like std::array on top while being
         | unable to get rid of old ways of doing things), and of course
         | the continued reliance on a preprocessor to simulate an actual
         | module import system (and the corresponding implications for
         | how code for a class is organized, having to hack around with
         | the pimpl idiom etc....)
         | 
         | Essentially, the warts are too large and numerous for me to
         | find any inner beauty in it any more.
        
           | ironman1478 wrote:
           | I mean, this is all anecdotal, but I've only ran into the
           | most vexing parse a few times, I rarely had to use the pimpl
           | idiom, and the header file stuff... okay that isn't great.
           | I've been a c++ dev for 10 years and I actually worked on an
           | extremely old codebase and was involved in modernizing it is
           | to C++11. Maybe I'm too C++ brained, but all those things
           | just aren't that bad? There is no wartless language and you
           | just deal with the warts of the language you're in and it's
           | your responsibility to learn the details of the language.
        
             | blep-arsh wrote:
             | I can deal with all the warts but I'm not really having a
             | blast.
        
             | cataphract wrote:
             | The header stuff is pretty bad. The rest are strange
             | choices of stuff to complain about. The vexing parse was
             | never a big deal and these days with bracket initialization
             | (which only rarely you can't use) even less. The pimpl
             | idiom: not sure why it's really a problem. Plus you have
             | many choices for type erasure in c++.
        
               | zahlman wrote:
               | >The vexing parse was never a big deal
               | 
               | I definitely got bit by it multiple times.
               | 
               | >The pimpl idiom: not sure why it's really a problem.
               | 
               | Because it's even more boilerplate and adds indirection
               | in a place where you might have been painstakingly trying
               | to avoid it (where the first indirection costs you all
               | your cache coherency). C++ lets you go out of your way to
               | avoid objects having to carry any overhead for virtual
               | dispatch if you aren't going to use it; but then you
               | might have to choose between rerouting everything through
               | a smart pointer _anyway_ or suffering inordinately long
               | compile times. Nothing to do with type erasure (if I 'm
               | thinking clearly, anyway).
        
           | delta_p_delta_x wrote:
           | > and of course the continued reliance on a preprocessor to
           | simulate an actual module import system
           | 
           | C++ modules are supposedly meant to save the day. Although
           | only recently have the big three compilers (GCC, Clang, MSVC)
           | reached some form of parity when compiling modules.
        
         | CJefferson wrote:
         | In every other language (except C), basically every time you
         | write v[x]=y you aren't inviting the possibility of arbitary
         | memory corruption. The C++ 'std::optional' type makes calling
         | '*v' undefined behaviour if 'v' is empty. The whole point of
         | optional is to store things that might be empty, so why put
         | undefined behaviour on the most common operation on an optional
         | when it's empty (which is going to be common in practice,
         | that's the point!)
         | 
         | The problem I have with C++ (and I've written a lot), is every
         | programmer involved in your project has to be 100% perfect,
         | 100% of the time.
         | 
         | I know you can run memory checkers, and STL debug modes, but
         | unless you are running these in release as well (is anyone
         | doing that?), then you are then counting on your testsuite
         | hitting every weird thing a silly, or malicious, user might do.
         | 
         | Given how important software is nowadays, and how Rust seems
         | close to the performance of C++, is it really worth using a
         | language where so many of the basic fundamental features are
         | incredibly hard to use safely? They keep making it worse,
         | calling an empty std::function threw an assert, the new
         | std::copyable_function has made this undefined behaviour
         | instead!
        
           | CyberDildonics wrote:
           | _The C++ 'std::optional' type makes calling '_v' undefined
           | behaviour if 'v' is empty*
           | 
           | Are you talking about dereferencing a null pointer? That is
           | going to case a low level exception in any language, it has
           | nothing to do with std::optional.
           | 
           |  _every time you write v[x]=y you aren 't inviting the
           | possibility of arbitary memory corruption_
           | 
           | That's how computers work. You either pay the penalty of
           | turning every memory check into a conditional boundary check
           | first or you avoid it all together and just iterate through
           | data structures, which is not difficult to do.
           | 
           | Also debug mode lets you turn on the bounds checking to debug
           | and be fast in release mode.
           | 
           | The reality is that with a tiny amount of experience this is
           | almost never a problem. Things like this are mostly relegated
           | to writing your own data structures.
        
             | CJefferson wrote:
             | No, I'm talking about std::optional<T>. It's a type
             | designed to store an object of type T, or nothing. You use
             | '*v' to get the value out (if one is present).
             | 
             | It was originally discussed as a way of avoid null
             | pointers, for the common case where they are representing
             | the possibility of having a value. However, it has exactly
             | the same UB problems as a null pointer, so isn't really any
             | safer.
             | 
             | I'm going to be honest, saying that memory corruption in
             | C++ is 'almost never a problem' just doesn't match with my
             | experience, of working on many large codebases, games, and
             | seeing remote security holes caused by buffer overflows and
             | memory corruption occurring in every OS and large software
             | program ever written.
             | 
             | Also, that 'penalty' really does seem to be tiny, as far as
             | I can tell. Rust pays it (you can use unsafe to disable it,
             | but most programs use unsafe very sparingly), and as far as
             | I've seen benchmarks, the introduced overhead is tiny, a
             | couple of percent at most.
        
               | CyberDildonics wrote:
               | _It was originally discussed as a way of avoid null
               | pointers,_
               | 
               | I don't think this is true. I don't think it has anything
               | to do with null pointers, it is a standard way to return
               | a type that might not be constructed/valid.
               | 
               | I think you might be confusing the fact that you can
               | convert std::optional to a bool and do if(opt){
               | opt.value(); }
               | 
               | You might also be confusing it for the technique of
               | passing an address into a function that takes a pointer
               | as an argument, where the function can check the pointer
               | for being null before it puts a value into the pointer's
               | address.
               | 
               |  _I 'm going to be honest, saying that memory corruption
               | in C++ is 'almost never a problem' just doesn't match
               | with my experience,_
               | 
               | In modern C++ it is easy to avoid putting yourself in
               | situations where you are calculating arbitrary indices
               | outside of data structures. Whether people do this is
               | another story. It would (or should) crash your program in
               | any other language anyway.
               | 
               |  _Also, that 'penalty' really does seem to be tiny_
               | 
               | The penalty is not tiny unless it is elided all together,
               | which would happen in the same iteration scenarios that
               | in C++ wouldn't be doing raw indexes anyway.
        
               | Maxatar wrote:
               | >I don't think this is true. I don't think it has
               | anything to do with null pointers
               | 
               | The paper that proposed std::optional literally uses
               | examples involving null pointers as one of the use cases
               | that std::optional is intended to replace:
               | 
               | https://isocpp.org/files/papers/N3672.html
               | 
               | Here is an updated paper which is intended to fix some
               | flaws with std::optional and literally mentions
               | additional use cases of nullptr that the original
               | proposal did not address but the extended proposal does:
               | 
               | https://www.open-
               | std.org/jtc1/sc22/wg21/docs/papers/2023/p29...
               | 
               | I am going to be somewhat blunt, but if you're not
               | familiar with how some of the use cases for std::optional
               | is as a replacement for using raw pointers, along with
               | some of your comments about how C++ treats undefined
               | behavior, as if it's just results in an exception,
               | suggests you may not have a rigorous enough understanding
               | of the language to speak so assertively about the topic.
        
               | CyberDildonics wrote:
               | _I am going to be somewhat blunt, but if you 're not
               | familiar with how some of the use cases for std::optional
               | is as a replacement for using raw pointers_
               | 
               | I never said there wasn't a use case, I said it wasn't
               | specifically about protecting you from them. If you put a
               | null pointer in and reference the value directly, it
               | doesn't save you.
               | 
               | If you don't understand the context of the thread start
               | arguments over other people's simplified examples. I'm
               | not going to write huge paragraphs to try to avoid
               | someone's off topic criticisms, I'm just telling someone
               | their problems can be avoided.
        
               | Maxatar wrote:
               | Yes you did and I literally quoted it, here it is, your
               | words:
               | 
               | "I don't think this is true. I don't think _it has
               | anything to do with null pointers_ , it is a standard way
               | to return a type that might not be constructed/valid."
               | 
               | This was in response to:
               | 
               | "It was originally discussed as a way of avoid null
               | pointers,"
               | 
               | I have provided you with the actual papers that proposed
               | std::optional<T> and they clearly specify that a use case
               | is to eliminate the use of null pointers as sentinel
               | values.
        
               | CyberDildonics wrote:
               | It's a template, you can put whatever you want in it
               | including a pointer. All your example shows is that you
               | can bind a pointer to a reference and it will wrap it but
               | won't access the pointer automatically.
               | 
               | I'm not sure what your point here is other than to try to
               | mince words and argue. It's a standard way to put two
               | values together and what people were probably already
               | doing with structs. You can put pointers into a vector
               | too, but that doesn't mean it's all about pointers.
        
               | Maxatar wrote:
               | It's okay to admit you were wrong.
        
               | CyberDildonics wrote:
               | I think if you had something real to say here you would
               | have done it already.
        
               | saghm wrote:
               | I'm pretty sure the issue that the parent commenter is
               | referring to isn't about wrapping a pointer type in an
               | optional, but wrapping a _non-pointer_ type in an
               | optional, and then trying to access the value inside.
               | std::optional literally provides a dereference operator
               | operator[1] which contains the following documentation:
               | 
               | > The behavior is undefined if _this does not contain a
               | value.
               | 
               | The equivalent to this in Rust isn't `Option::unwrap`,
               | which will (safely) panic if the value isn't present; the
               | equivalent is `Option::unwrap_unchecked`, which can't be
               | invoked without manually marking the code as unsafe. I've
               | been writing Rust professionally for a bit over five
               | years and personally for almost ten, and I can
               | definitively say that I've never used that method a
               | single time. I can't say with any amount of certainty
               | whether I've accidentally used the deference operator on
               | an optional type in C++ despite writing at least a couple
               | orders of magnitude less C++ code because it's not
               | something that's going to stick out; the deference
               | operator gets used quite often and wouldn't necessarily
               | be noticeable on a variable that wasn't declared nearby,
               | and the compiler isn't going to complain because it's
               | considered entirely valid to do that.
               | 
               | [1]: From https://en.cppreference.com/w/cpp/utility/optio
               | nal/operator_
        
               | jpc0 wrote:
               | Is your argument that rust with panic if you are a bad
               | programmer and C++ says its Ub of you are a bad
               | programmer?
               | 
               | That's just fundamental difference of opinion, Rust isn't
               | designed for efficiency, it's designed for safety first.
               | C++ unofficial motto is, don't pay for what you don't
               | use.
               | 
               | If I type *X why would I pay for a check if its empty, I
               | literally should have checked the value isn't empty.
               | 
               | If you work in a code base with people who don't check,
               | your codebase doesn't have static analysers, you do no
               | code review and dereferencing an uncheck optional get's
               | to production, do you think a .unwrap in rust wouldn't
               | have made it to production?
        
               | CJefferson wrote:
               | Your basis seems to be no-one is ever going to write bad
               | code, anywhere, ever, and invoke undefined behavior. That
               | doesn't seem reasonable.
               | 
               | Also, an unwrap isn't perfect, but it's much better than
               | UB. It asserts. No memory corruption, no leaking all your
               | user's data, no massive fines.
               | 
               | The equivalent to C++ would be an unchecked unwrap in an
               | unsafe code block, and that would throw up flags during
               | review in any Rust codebase.
        
               | jpc0 wrote:
               | An unchecked dereference should also throw up flags
               | during review in a C/C++ codebase. I didn't assume that
               | nobody would make mistakes. My argument has always been
               | that you use a language like C++ where needed. Most of
               | your code should be in a GC language. Going in with that
               | mentality, even if I wrote that code in Rust, I'm
               | exporting a C API, which means I may as well have written
               | the code in C++ and spend some more time in code review.
               | 
               | EDIT: an unwrap that crashes in a panic is a dos
               | condition. In severity this might be worse or better
               | depending where it happens.
               | 
               | Both are programmer error, both should be caught in
               | review, both aren't checked by the compiler.
        
               | jodrellblank wrote:
               | > " _Rust isn 't designed for efficiency"_
               | 
               | Citation needed, because Graydon Hoare the original Rust
               | creator (who has not been involved with Rust development
               | for quite a long time) wrote about how the Rust that
               | exists is not like the original one he was designing:
               | 
               | - "Tail calls [..] I got argued into not having them
               | because the project in general got argued into the
               | position of "compete to win with C++ on performance" and
               | so I wound up writing a sad post rejecting them which is
               | one of the saddest things ever written on the subject. It
               | remains true with Rust's priorities today"
               | 
               | - "Performance: A lot of people in the Rust community
               | think "zero cost abstraction" is a core promise of the
               | language. I would never have pitched this and still,
               | personally, don't think it's good. It's a C++ idea and
               | one that I think unnecessarily constrains the design
               | space. I think most abstractions come with costs and
               | tradeoffs, and I would have traded lots and lots of small
               | constant performancee costs for simpler or more robust
               | versions of many abstractions. The resulting language
               | would have been slower. It would have stayed in the
               | "compiled PLs with decent memory access patterns" niche
               | of the PL shootout, but probably be at best somewhere in
               | the band of the results holding Ada and Pascal."
               | 
               | https://graydon2.dreamwidth.org/307291.html
        
               | jpc0 wrote:
               | The fact that by default array access is bounds checked
               | in Rust and by default it isn't in C++ disproves that.
               | 
               | I think you would have a hard time convincing the C++
               | standards committee to put a checked container in the
               | standard, maybe now with the negative publicity maybe but
               | definitely not before.
               | 
               | I'm guessing it would be impossible to get an unchecked
               | container into the rust stdlib.
        
               | CJefferson wrote:
               | I just want to pick out one thing:
               | 
               |  _It would (or should) crash your program in any other
               | language anyway._
               | 
               | To me there is a massive difference between "there is a
               | way a malicious user can trigger an assert, which will
               | crash your server / webbrowser", and "there is a way a
               | malicious user can use memory corruption to take over
               | your server / webbrowser".
               | 
               | And bounds-checking penalties are small. I can tell they
               | are small, because Rust doesn't have any kind of clever
               | 'global way' of getting rid of them, and I've only
               | noticed the cost showing up in profiles twice. In those
               | cases I did very carefully verify my code, then turn off
               | the bounds checking -- but that's fine, I'm not saying we
               | should never bounds check, just we should do it by
               | default. Do you have any evidence the costs are
               | expensive?
        
               | CyberDildonics wrote:
               | If you profile looping through an array of pixels in
               | linear memory order vs bounds checking every access it
               | should be more expensive due to the branching.
               | 
               | As someone else mentioned you can boundary check access
               | if you want to in C++ anyway and it's built in to a
               | vector.
               | 
               | My point here is that it isn't really a big problem with
               | C++, you can get what you want.
        
               | Maxatar wrote:
               | Iterating over an array in Rust does not involve bounds
               | checking every access since Rust guarantees immutability
               | to the container over the course of the iteration. Hence
               | all that's needed is to access the size of the array at
               | the start of the iteration and then it is safe to iterate
               | over the entire array.
               | 
               | Note that this is not something C++ is able to do, and
               | C++ has notoriously subtle iterator invalidation rules as
               | a consequence.
        
               | CyberDildonics wrote:
               | They asked for evidence of bounds checks being expensive,
               | please try to keep the context in mind.
               | 
               |  _Note that this is not something C++ is able to do_
               | 
               | Or you could just not mutate the container.
        
               | Maxatar wrote:
               | It's the optimization that C++ is unable to perform, not
               | the immutability.
        
               | pptr wrote:
               | If you declare using an invalidated iterator as UB, the
               | compiler can optimize as if the container was effectively
               | immutable during the loop.
        
               | CyberDildonics wrote:
               | Are you talking about optimizing out bounds checking that
               | isn't happening in the first place?
        
               | jodrellblank wrote:
               | > " _They asked for evidence of bounds checks being
               | expensive_ "
               | 
               | They said "bounds-checking penalties are small" not that
               | it was free. You've described a situation where bounds
               | checking happens and declared that it "should be"
               | expensive because it happens. You haven't given evidence
               | that it's expensive.
        
               | carom wrote:
               | You have to do a very similar operation to has_value()
               | .value() with Rust's optional though... How is
               | opt.ok_or("Value not found.")?; so different from the C++
               | type?
        
               | Maxatar wrote:
               | One is undefined behavior which may manifest as entirely
               | unpredictable side-effects. The other has semantics that
               | are well specified and predictable. Also while what you
               | wrote is technically valid, it's not really idiomatic to
               | write it the way you did in Rust, you usually write it
               | as:                   if let Some(value) = some_optional
               | {         }
               | 
               | At which point value is the "dereferenced" value. Or you
               | can take it by reference if you don't want to consume the
               | value.
        
               | carom wrote:
               | I prefer ok_or for optionals and map_err for for results
               | in Rust. I believe the way you proposed ends up with very
               | deeply nested code which I try to avoid.
        
               | Kranar wrote:
               | It seems like people think dereferencing an unengaged
               | optional results in a crash or exception, but ironically
               | you are actually less likely to get a crash from an
               | optional than you would from dereferencing an invalid
               | pointer. This snippet of code, for example, is not going
               | to cause a crash in most cases, it will simply return a
               | garbage and unpredictable value:                   auto v
               | = std::optional<int>();         std::cout << *v <<
               | std::endl;
               | 
               | While both are undefined behavior, you are actually more
               | likely to get a predictable crash from the below code
               | than the above:                   int* v = nullptr;
               | std::cout << *v << std::endl;
               | 
               | I leave it to the reader to reflect on the absurdity of
               | this.
        
               | carom wrote:
               | I understand what undefined behavior is, I just don't
               | dereference pointers or optionals without first checking
               | them against nullptr or nullopt (respectively). In fact,
               | I generally use the .has_value() and .value() interface
               | on the optional which, to my point in the above comment,
               | is a very similar workflow to using an optional in Rust.
               | 
               | I think if you adopted a more defensive programming style
               | where you check your values before dereferencing them,
               | handle all your error cases, you might find C++ is not so
               | scary. I would also recommend not using auto as it makes
               | the types less clear.
               | std::optional<int> v = std::nullopt;         if (v ==
               | std::nullopt) {             return
               | std::unexpected("Optional is empty.");         }
               | std::println("{}", *v);
               | 
               | If you are dereferencing things without checking that
               | they can be dereferenced I don't know what to tell you.
        
               | d0mine wrote:
               | What is the desired behavior? I see at least 3 options:
               | panic (abort at runtime predictably), compiler error
               | (force handling both Some&Nothing cases [needs language
               | support otherwise annoying], exceptions (annoying to
               | handle properly). There is too much undefined behavior
               | already.
               | 
               | Perhaps, 3 types could exist for 3 options.
        
               | tangus wrote:
               | You can pay the penalty and get safe container access,
               | too. AFAIK, C++ standard containers provide both bounds
               | checked (.at()) and unchecked ([]) element retrieval.
        
               | CJefferson wrote:
               | Now we are getting down to a philosophical issue (but I
               | think an important one).
               | 
               | In Rust, they made the safe way of writing things easy
               | (just write v[x]), and the unsafe one hard (wrap your
               | code in 'unsafe'). C++ is the opposite, it's always more
               | code, and less standard (I don't think I've seen a single
               | C++ tutorial, or book, use .at() as standard rather than
               | []), to do bounds checked.
               | 
               | So, you can write safe code in both, and unsafe code in
               | both, but they clearly have a default they push you
               | towards. While I think C++'s was fine 20 years ago, I
               | feel nowadays languages should push developers to write
               | safer code wherever possible, and while sometimes you
               | need an escape hatch (I've used unsafe in a very hot
               | inner loop in Rust a couple of times), safer defaults are
               | better.
        
               | Gibbon1 wrote:
               | I've been wondering how much you'd pay if you just
               | required that out of bounds accesses be a no-op with an
               | option of calling an error handler. De-reference a null
               | or out of bounds pointer you get zero. Write out of
               | bounds, does nothing.                 int a = v[-100]; //
               | yolo a is set to 0
               | 
               | I really suspect that unlike the RISC mental model
               | compiler writers think in terms of a superscalar
               | processor would barely be slowed down. That is if the
               | compiler doesn't delete the checks because it can prove
               | they aren't needed.
        
       | wkyleg wrote:
       | I learned C++ and enjoyed it but never went too deep. I always
       | enjoyed C more. There's also so many S tier codebases to read to
       | learn C better like the original Dune game engine or Unix
       | utilities.
       | 
       | Having dabbled a bit with Rust recently I can't see any strong
       | reasons to use C++. The combination of strong functional
       | programing inspired type system with performance seems
       | unbeatable. Almost a perfect language.
       | 
       | I'm sure there must be some legacy reasons to use C++ though.
       | Maybe Game Engines, embedded programing, some kind of other
       | legacy tie in?
        
         | PartiallyTyped wrote:
         | HFT perhaps?
        
           | wkyleg wrote:
           | I can see that.
           | 
           | On most metrics I've seen Rust is comparable on general
           | speed.
           | 
           | Maybe if you're at the level where you've essentially writing
           | portable assembly and are okay with lack of safety. You need
           | to know exactly what is happening within the CPU, maybe on
           | custom hardware.
           | 
           | I bet some defense applications would be in this category
           | too, although for my own sense of self preservation I would
           | prefer the Rust type system.
        
             | gpderetta wrote:
             | Rust would probably be a good fit for HFT, but as the field
             | is so dominated by C++ is hard for another language to make
             | inroads. Java managed to some extent.
             | 
             | I would expect a lot of unsafe though.
        
               | cempaka wrote:
               | Ecosystem effects are definitely important to C++'s
               | dominance in HFT, but it's also a domain where a lot of
               | the guarantees Rust offers just aren't all that relevant.
               | From a security perspective most code always runs in
               | sandboxes accessible to only a select few whitelisted
               | IPs. True, you don't want a segfault while you're in the
               | middle of sending an order to an exchange, but most of
               | those are pretty easily smoked out in simulation testing.
        
         | fuzztester wrote:
         | _Huge_ amount of legacy across many dimensions, not just apps
         | written in it [1], like number of users, published and
         | available knowledge  / resources (books, courses, blogs,
         | articles, videos, software libraries, etc.), high compatibility
         | with another huge language (C), etc.
         | 
         | This is just software industry general knowledge, for those who
         | have been there for more than a few years in the field. I am
         | not even a proper beginner in it, because I have never used it
         | much, although I had bought, read and to some extent,
         | understood some classic C++ books, including by the language
         | creator (Bjarne Stroustrup [2]), Scott Meyers [3], and a few
         | others, earlier. I did have a lot of experience using C for
         | many years in production, though, including on a successful
         | commercial product.
         | 
         | [1] https://www.stroustrup.com/applications.html
         | 
         | [2]:
         | 
         | https://www.stroustrup.com
         | 
         | https://en.m.wikipedia.org/wiki/Bjarne_Stroustrup
         | 
         | [3] https://en.m.wikipedia.org/wiki/Scott_Meyers
        
         | nurumaik wrote:
         | C++ makes sense when you need low latency, but don't really
         | care about correctness
         | 
         | So I believe gamedev will stay on C++ the longest
         | 
         | Game crashes with segfaults for 0.001% users? So what?
        
       | indigoabstract wrote:
       | I really love how politically incorrect this post is. And how
       | honest and fresh it sounds, though quite a few have been quick to
       | say how wrong he is. They could be right, but I think it misses
       | the point.
       | 
       | Yes, it's way too easy to do dumb stuff in C++, when you're tired
       | or not sure what you're doing. Things like holding raw pointers
       | or references to things you shouldn't like std::vector::data(),
       | or questionable reinterpret casts and many other things. The
       | compiler won't stop you, only your experience.
       | 
       | But he's right about one thing at least: Programming should be
       | fun!
       | 
       | All these layers and rules and concerns about memory safety and
       | security don't offer only advantages. They also have tradeoffs.
       | And it's the same thing with those scrum agile ceremonies. It
       | serves its purposes. But it's also the best invention ever to
       | suck all the joy out of programming.
       | 
       | I think that both C and C++ still have that fun feeling going for
       | them. When you know what you want to work on and how to do it and
       | you just start doing it and get into the flow. And if you're
       | careful and do things right, it just works and it's a blast!
       | 
       | That's my takeaway from the article. That feeling like you're
       | talking directly to the machine, getting it to show you on screen
       | what you saw in your mind, without anything else getting in your
       | way. Now, that is fun!
        
         | zahlman wrote:
         | Programming should be fun. I don't think that's controversial
         | or politically incorrect. (Or if it is, I don't know why.)
         | 
         | A lot of people don't naturally have the kind of fun in C++
         | that Zed describes, and it seems most people here (including
         | myself) would rather talk about that.
        
           | indigoabstract wrote:
           | It's controversial because of how he makes fun about the
           | people using and promoting other languages, like Rust. I
           | thought it was hilarious.
           | 
           | And in case you haven't noticed, C++ isn't seen in a good
           | light anymore for some years now. There are a lot of loud
           | voices saying its time has past and calling for it to be
           | replaced with something newer and better.
           | 
           | It's all subjective anyway, but I resonate with the feeling
           | of fun he describes when doing projects in C++. Feeling
           | productive and being protected from whole classes of bugs
           | common in C++ is all well and good, but he was talking about
           | programming being fun and I do not get that same feeling when
           | programming in other languages.
           | 
           | It's perfectly understandable that you don't feel the same
           | way though. I hope you do when programming in your favourite
           | language. Otherwise it becomes just something you do to pay
           | the rent.
        
             | zahlman wrote:
             | Zed is definitely the sort of person who can make an
             | uncontroversial point sound controversial, yeah. I think
             | we're in violent agreement here.
        
             | tavavex wrote:
             | > It's controversial because of how he makes fun about the
             | people using and promoting other languages, like Rust. I
             | thought it was hilarious.
             | 
             | But doesn't that completely ruin the point of the post? I
             | agree with you that something feeling 'fun' is more
             | personal, and that the criteria of what constitutes fun are
             | up to the user. The author doesn't agree with that - you
             | can either adopt the former point or promote the Right Way
             | of having fun. Those snarky remarks made me put this blog
             | into the second category. When you're so invested in your
             | argument, even a fundamentally harmless post about having
             | fun will get that language wars hit piece subtext.
             | 
             | If anything, they seem more like desperate cheap shots than
             | arguments. Other people, the NSA etc dislike unsafe-by-
             | default code? Well, they're just authoritarian anti-fun
             | ideologues! Rust users bring up some of the same criticisms
             | I recall in the last paragraph? Well.. uh... that borrow
             | checker, am I right?
        
               | indigoabstract wrote:
               | I think he was just making fun of people who inflate the
               | importance of their language and their way too much and
               | it should be taken in that spirit. There are good reasons
               | why all these new languages like Rust and Zig popped up
               | in the last 10 years or so and started getting traction.
               | Obviously a lot of people were unhappy having C/C++ as
               | their only choice for performance focused or system level
               | programming. At least in the games business it still
               | seems to be doing well.
               | 
               | But to get back to the point of the article, for fun solo
               | projects, when the 'mood for coding' comes over, I may be
               | biased, but I think C++ is still the best. It's like when
               | building a prototype. You just want to test your idea and
               | see how it looks and play with it and just worry about
               | bugs and program correctness later. While coding it in
               | Rust you'd have to spend extra time determining the
               | correct memory ownership relations and that can break the
               | flow.
               | 
               | After programming for 20 years, it doesn't come nearly as
               | often as it used to, but I still get that feeling from
               | time to time.
        
       | avalys wrote:
       | If you're starting a new project with a talented team that knows
       | how to use modern C++ well, I agree that C++ is great! It's a
       | pleasant and powerful language, delivers great performance and
       | (while complicated) is straightforward to debug and optimize.
       | 
       | I had the privilege of working on a codebase that was about 5
       | years old, written to C++11 standards or later, and I thoroughly
       | enjoyed it, for many of the reasons expressed in the article.
       | 
       | If you are working on an older codebase that has evolved over
       | 20-30 years, or one that has not been maintained by talented
       | people, you will have a very different experience.
        
         | creato wrote:
         | > If you are working on an older codebase that has evolved over
         | 20-30 years, or one that has not been maintained by talented
         | people, you will have a very different experience.
         | 
         | I'm trying to think of any other language that could fit that
         | description and not also be a terrible experience. In fact, I'd
         | prefer C++ to many other possibilities I can think of (C, Java,
         | Fortran). The exception would be C#, but I'm not sure if it's
         | old enough to fit.
        
           | avalys wrote:
           | Fair point, although I think it's true that C++ gives you
           | more rope to hang yourself with, and if I had to choose, I'd
           | rather maintain a crusty old codebase written in Java than
           | one written in C++.
        
             | snovv_crash wrote:
             | The issue is that the JVM has started deprecating features
             | which old codebase rely on.
             | 
             | I don't work with it, but even I know about the JVM no
             | longer supporting sandboxing or being able to kill threads
             | programmatically.
             | 
             | C++ doesn't have this issue because you can still deploy
             | code from an old toolchain onto a modern OS.
        
               | adra wrote:
               | You can and always have been able to .destroy() threads
               | in java, but doing so breaks the memory model in ways
               | that make it clear that you should never do it. My guess
               | is that if you're kill heavy in c++, then you've also run
               | into bugs waiting on locks of threads you've now just
               | murdered. That's why there's a ton of great abstractions
               | for how to "kill work running somewhere else" that
               | doesn't leave your application in a potentially unstable
               | state.
               | 
               | Java 9+ sure did kill off a lot of things that weren't
               | particularly ideal. Most normal devs who don't write
               | libraries probably can't even name a single feature
               | removed (corba, script interpreters, some jmx cruft,
               | etc). Most of what was culled still exists in libraries
               | that could easily be added back with project imports.
               | Maybe Java applets are super dead now? I don't believe
               | any modern browsers still support native plugins, but
               | maybe there are some niche individuals bemoaning the loss
               | of java web start.
               | 
               | As for the "can still deploy code" comment, the same
               | applies to java. Look around, and sadly you see very old
               | releases of java still in use today. My guess is that if
               | I fired up a java 1.0 compiler and JVM today, it would
               | run on my PC (poorly).
               | 
               | Before criticising something, please consider being well
               | enough informed to warrant the comment.
        
           | jacoblambda wrote:
           | So that's a fun one. C# the language people know first
           | released in y2k and the 1.0 release was 2002.
           | 
           | So it definitely is old enough to fit and it certainly has
           | it's warts from age that show up in long lived projects.
        
             | golf1052 wrote:
             | I used to work on a codebase at Microsoft that was
             | classified as a microservice. Pretty much entirely written
             | in C# and it was about 12 years old.
        
         | LeftHandPath wrote:
         | I started my life as a dev with PHP, learning it on the job to
         | set up a custom Wordpress theme with plugins for special
         | datatypes (eg STCs).
         | 
         | When I was 21, they offered to pay for my tuition so I went
         | back for a CoE degree (later switching to CS). The moment I
         | touched C++ - on my very first day in their "intro to
         | programming" class - I fell in love. The type system,
         | debugging, and ecosystem was fantastic compared to PHP 7 that I
         | was using at the time. With my manager's permission, I went
         | back to some of our existing intranet apps and built a
         | C++-based API for them that our PHP would call over a web-
         | socket, so that I could leverage the type system (and
         | performance). Those systems are still in daily use, company
         | wide. Maintenance hasn't been a problem. And that's despite
         | running in a really weird environment (IBM Pase for i).
         | 
         | Now, after using Rust and Axum, I'd vastly prefer the Rust
         | ecosystem for creating that type of API. But C++ deserves
         | credit. It really is a great language, especially if you're
         | coming from web languages like (non-TS) JavaScript or PHP.
        
       | runjake wrote:
       | Can anyone recommend some good "modern" C++ books in this spirit
       | (writing software for fun, not large enterprises)?
       | 
       | Preferably for Linux and/or Windows.
        
         | rramadass wrote:
         | Not sure about what you mean by "fun" but Peter Gottschling's
         | _Discovering Modern C++ An Intensive Course for Scientists,
         | Engineers and Programmers_ is pretty good. For a catalog of
         | shiny new C++ features Marius Bancila 's _Modern C++
         | Programming Cookbook_ is comprehensive.
        
       | chubot wrote:
       | IMO the way to make C++ fun is to:                   1. Build and
       | run it with a shell script (because the build systems do suck)
       | Dependencies may complicate this, but you can still link with
       | them with a shell script            And use Unix - I started with
       | C++ on Windows, and that sucks (also mentioned in the article)
       | 2. Turn on address sanitizer in development, which makes it
       | memory safe - you get a Python-like            stack trace on
       | errors instead of undefined behavior
       | 
       | Example:                   $ echo 'int main() { return 42; }' >
       | foo.cc              $ c++ -fsanitize=address -o foo foo.c &&
       | ./foo; echo $?         42
       | 
       | I use an actual editor, and unit tests, but essentially shell is
       | my REPL for C++. It's easier to figure out that way.
       | 
       | Newer features like constexpr have subtle rules, so it's easier
       | to just try it (even though I've used C++ for many years). I run
       | all the tests with Clang too.
       | 
       | ---
       | 
       | Example with ASAN:                   $ echo 'int main() { char
       | buf[1]; buf[1] = 42; }' > error.cc
       | $ c++ -fsanitize=address -o error error.cc && ./error; echo $?
       | ==118199==ERROR: AddressSanitizer: stack-buffer-overflow on
       | address 0x7ffcd94eb431 at pc 0x56217647520f bp 0x7ffcd94eb400 sp
       | 0x7ffcd94eb3f8         WRITE of size 1 at 0x7ffcd94eb431 thread
       | T0             #0 0x56217647520e in main
       | (/home/andy/git/oilshell/oil/error+0x120e)             #1
       | 0x7f7928446249 in __libc_start_call_main
       | ../sysdeps/nptl/libc_start_call_main.h:58
       | 
       | It's not too hard to learn to read the output, and then basically
       | you can go nuts like C++ is Python. For a small program, the
       | edit/run cycle will be extremely fast, like Python.
       | 
       | The silent undefined behavior is a big barrier to learning, and
       | this removes most of it. (You can also pass -fsanitize=undefined
       | for UBSAN, which finds other bugs, but many fewer IME)
       | 
       | ASAN is built into compilers; you don't need to install anything.
       | A bare Debian or BSD system has all this good stuff :-)
       | 
       | (copy of lobste.rs comment)
        
       | epolanski wrote:
       | A well written blog post that makes many valid points but comes
       | with a wrong assumption: that making a language creativity-
       | friendly is an absolutely desirable trait.
       | 
       | It's a desirable trait for my personal projects, where I may use
       | Haskell, Ruby, Ocaml, Racket or something more exotic.
       | 
       | At work, I'd rather use languages that are boring, with well
       | defined and uncreative patterns and practices. Professionally I
       | expect to not be surprised often and I want the smallest group
       | cognitive load possible.
       | 
       | Languages that breed too much creativity tend to have a rather
       | short list of killer software (that kind of software that makes
       | it worth learn a specific programming language).
        
         | barbazoo wrote:
         | I feel that way with Ruby vs Python sometimes.
        
         | zahlman wrote:
         | I wonder if Zed started using, or went back to, Perl after
         | getting so worked up about the 2 -> 3 transition. (From what I
         | can tell, he's still complaining about it, and still wrong in
         | many of those complaints, and makes unsubstantiated claims in
         | others.)
        
       | bnolsen wrote:
       | I worked with c++ for many years and it has lots of warts. Slow
       | compilation, lack of decent build system (no cmake isn't that
       | great), mistakes made in the standard library (iostreams), weak
       | cross platform standard libraries were always a headache. But I
       | always loved the power that <algorithm> and the like provides,
       | although attaching allocators (and other template things) kind of
       | sucks.
       | 
       | When I looked at and test drove rust all I saw was heaps of
       | complexity stacked up yet again. Probably didn't help that I
       | smacked headlong into the Arc Mutex and lifetimes mess. I'm
       | really more inclined to go for something like 'zig' which does so
       | much with simple syntax (and awesome comptime) and still gets
       | excellent performance.
        
         | marssaxman wrote:
         | > no cmake isn't that great
         | 
         | Nor is cmake even really a standard: after thirty-odd years
         | writing C++, I've yet to work on a project which used it!
        
           | PittleyDunkin wrote:
           | That's pretty damn impressive! How did you manage to avoid
           | codebases with CMake? Or are you just saying you personally
           | chose not to use it for your own?
        
         | scotty79 wrote:
         | > lack of decent build system
         | 
         | At one point I was using gulp.js to build my small C++
         | experiment.
        
       | readyplayernull wrote:
       | I returned to C++ after 20 years to program ESP32
       | microcontrollers. The Arduino Framework is compiled with C++
       | 21... wait, what? Well that's the value of __cplusplus = 202100L
       | 
       | Glad to find the standard library progressed so much to make C++
       | more similar to modern languages, but sometimes I wish there was
       | a simpler way to access the std namespace. Any proposal to
       | replace "std::" with $
        
       | lairv wrote:
       | I just spent 3 days to statically link a third party dependency
       | to my C++ project, in a way that works with linux/windows/macos.
       | The package wasn't available on conan/vcpkg, it was just a github
       | repo with a weird combination of Makefile/cmake file. While I'm
       | far from a cmake/cpp expert, this is a non-issue with most modern
       | languages: you just pip install, cargo add, npm install, go get
       | etc. You can read front-to-cover books about every details of C++
       | semantics and it'll still be a PITA to work on real world
       | projects
        
         | 77pt77 wrote:
         | The javascript toolchain for dependencies and build is as
         | arcane as the sloppiest Makefile.
         | 
         | It's amazing that we ended up with the javascript equivalente
         | of autotools.
        
           | agumonkey wrote:
           | yeah, dealing with npm really made me feel like the best part
           | of autotools
        
           | dannymcgee wrote:
           | Created an account just to say: I am a 10-year JavaScript
           | veteran who knows the ecosystem at least as well as any sane
           | person could possibly be expected to, and this is 100%
           | correct. When I tell people that JS build tooling is the
           | second-worst headache to C/C++ build tooling, they laugh, but
           | stick a toe outside the happy path of `npm create <some-
           | framework-project> && npm start` and you will know what pain
           | feels like.
           | 
           | I did get some similar vibes trying to work with Gradle and
           | Maven for a project a while back, but I don't really live in
           | that world so it's hard to say whether my experience was
           | typical or just symptomatic of my inexperience.
        
             | smarkov wrote:
             | And it'll continue to get worse because JS devs love coming
             | up with their own abstractions over everything and piling
             | complexity. You don't write JS, you write TS. You don't
             | write HTML, you write JSX. You don't write CSS, you write
             | Tailwind. And of course, React has its own compiler as of
             | recently. Now you have to figure out in what order to run
             | these parsers, bundle everything together including your
             | hundreds of dependencies, minimize, obfuscate, tree shake,
             | and whatever else fairy dust magic you want to sprinkle on
             | top. Meanwhile, the default build tool of choice changes
             | about once every 2 years, and now you also have a choice of
             | runtime - node vs bun vs deno. Can't wait to see what the
             | next revolutionary idea would be to contribute to this
             | madness.
        
               | claytongulick wrote:
               | There are those of us out there that have a beautiful
               | experience with JavaScript. Vanilla JS, web components, a
               | lightweight rendering library like lit-html, class props
               | as reactive state...
               | 
               | NodeJS + express + vanilla web components is the most
               | graceful and productive stack I've ever used in 30+ years
               | of development.
        
               | dannymcgee wrote:
               | You forgot to mention the 3 or 4 different TypeScript
               | compilers!
               | 
               | I do have to admit at least some of the pain is self-
               | inflicted on my part. I _want_ those nice abstractions,
               | so I will write a damn Rollup or Babel plugin if it means
               | I can use Sass stylesheets in my TypeScript+JSX
               | components that compile to vanilla Custom Elements (so I
               | don't have to depend on a huge framework runtime).
               | 
               | But as nice as the Babel/Rollup/Vite plugin APIs are,
               | when you start doing stuff like that you then have to
               | deal with all the deep-in-the-weeds bullshit that comes
               | with it, like the fact that Webpack and Rollup and
               | Node.js all have subtly different (and mostly poorly
               | documented) module resolution rules and that they all
               | differ wildly from the official ES-module spec that the
               | standards committee finally shipped like 20 years too
               | late, so trying to get your unit-testing framework and
               | your bundle toolchain and your browser to all agree about
               | how to digest the mess you've made becomes this giant
               | clusterfucktastrophe that makes you question every life
               | decision and formative event that led you to the moment
               | you thought this might be a neat idea.
               | 
               | But yeah just like build a React app or whatever and
               | you'll probably be fine.
        
               | singhrac wrote:
               | Good luck trying to use these tools with anything other
               | than the blessed path of node on the backend.
               | 
               | The JS ecosystem absolutely has the problem of "too many
               | compilers", and of course as I'm typing this there's
               | someone out there writing a "one compiler to unify them
               | all".
        
         | npalli wrote:
         | But to flip this around, let's say you want to use this third
         | party in some other "modern" language how would this become
         | better?. Clearly if someone hadn't done the work to package in
         | vcpkg/conan you can expect it wouldn't exist in pip/cargo/npm
         | either. So if you had a bad time in C++, you would have a
         | dramatically worse time in other languages. Goes to show what
         | everyone else is saying here, there are parts of historic C++
         | which are in very bad shape particularly the build story.
         | However, if it's in vcpkg it is exactly as easy to install as
         | the other ones.
        
           | kouteiheika wrote:
           | > But to flip this around, let's say you want to use this
           | third party in some other "modern" language how would this
           | become better?. Clearly if someone hadn't done the work to
           | package in vcpkg/conan you can expect it wouldn't exist in
           | pip/cargo/npm either. So if you had a bad time in C++, you
           | would have a dramatically worse time in other languages.
           | 
           | Err, no?
           | 
           | In case of Rust usually there is really no work that's
           | necessary to package it and upload. You just type `cargo
           | publish` and you're done (after filling out metadata in
           | Cargo.toml). Even if someone wouldn't upload it to crates.io
           | as a Rust crate you can just add a single line to your
           | Cargo.toml:                   package_name = { git =
           | "https://github.com/user/repo", rev = "revision" }
           | 
           | and you're done, you can use it as a dependency.
        
             | dgfitz wrote:
             | I think you moved the goalposts. I can configure a CMake
             | file to pull a GitHub repo, which seems similar enough.
        
               | Spivak wrote:
               | I think the difference is that you can pip install a
               | github url and it will work, it will even work if the
               | upstream has done nothing to package it.
               | 
               | I think the issue could be broadly defined as how
               | difficult it is how difficult it is to take someone
               | else's code and use it as part of your project. For C/C++
               | the answer can be completely trivial to a massive pain in
               | the ass.
        
               | mattpallissard wrote:
               | Oh I dunno. With cmake it really is pretty straight
               | forward. You can pull from VCS, a tarball, even use a git
               | submodule.
               | 
               | If it's another Cmake project, that's the happy path.
               | Easy peasy. If it's not you still have the ability to run
               | ./configure && make or evoke whatever incantation is in
               | the dependency's requirements. I'm not the hugest fan of
               | cmake, but I've worked with it quite a bit and it's a
               | much more pleasant story than other languages I've used a
               | lot like python, JavaScript, OCaml (which I love), etc.
               | 
               | I do find rust and go dependency management a little
               | simpler due to the prescribed nature of them, but once
               | you get off the happy path, the flexibility of C land is
               | tough to beat. It sort of matches the language stories
               | themselves; you have more control and have to do a bit
               | more yourself. It's all about trade offs.
        
               | rddbs wrote:
               | How often do folks venture off the happy path with Rust
               | dependencies? Personally I've never once found myself in
               | that situation.
        
               | AlotOfReading wrote:
               | I've done it before to integrate rust into polyglot build
               | systems. There's a surprisingly long history of build
               | systems trying and failing to implement rust builds
               | without the "happy path" of simply wrapping cargo. As far
               | as I know no one's ever succeeded.
        
           | vlovich123 wrote:
           | The main difference being that Cargo is both for distributing
           | and building locally AND it's the blessed way of building all
           | Rust projects. This means that as long as you have a copy of
           | the codebase, it's going to be using Cargo & you can add it
           | with Cargo regardless of it being published formally to
           | crates.io (the copy can even be remote since you can build
           | from a git reference directly). Python packaging requires
           | more work although there's typically no build step so you can
           | probably just __import__ the path and move on. JS is closer
           | to Rust in that package.json is the standard way to manage
           | components and you can import them even if they're not
           | published via the npm registry.
           | 
           | Pretending the situation isn't very different for C++ is
           | completely ignoring the standard committee's complete
           | abdication of standardizing a build system (which by the way
           | if they're not going to do, why are they bothering to
           | standardize anything?)
        
         | carom wrote:
         | What was particularly difficult about it? Sometimes modifying
         | someone else's code to build statically or on another platform
         | is tricky. Linking is generally just include dir, lib path, and
         | lib though.
        
           | lairv wrote:
           | The library was duckdb
           | (https://duckdb.org/docs/installation/), and here are some of
           | the issues I ran into:
           | 
           | - trying to compile against the prebuilt duckdb_static.so
           | file got me a ton of undefined reference error, I asked about
           | this on their discord and it seems to be a knwon issue, there
           | are additional dependencies that are not part of the release
           | so I had to build it myself
           | 
           | - the library uses CMake but it contains a Makefile and they
           | recommend using that to build it
           | 
           | - It seems like on windows, if you create a dynamic library
           | you have to add __declspec(dllexport) before each function.
           | DuckDB has a #ifdef DUCKDB_STATIC_BUILD to toggle/disable it
           | which isn't documented anywhere, you have to read the code
           | 
           | I'm sure someone will tell me that this is very standard and
           | shouldn't take me 3 days to figure it out, but with basic
           | knowledge of cmake and build systems that's a bit of a pain,
           | and there's no other language where you have to do that
        
             | jpc0 wrote:
             | CMake, the defacto if not standard build system, when
             | correctly setup, does all this for you.
             | 
             | Your argument is along the lines of "the maintainer of X
             | rust package didn't setup cargo correctly and it's
             | impossible to include in my project, rust is a horrible
             | language". You can absolutely make an argument that the
             | lack of a standard build system is a pain point, and well
             | it's C++ you get to be a special snowflake and use a
             | makefile instead of CMake but then the onus is on you to
             | provide correct documentation.
        
               | lairv wrote:
               | In the case of duckdb they provide proper packages for
               | pip, cargo, npm, go get, and the only one that seems like
               | a PITA to use is the C/C++ dependencies, even though the
               | package is written is C++, so I think this tells
               | something about C++ dependency management
        
               | jpc0 wrote:
               | You seem to be agreeing with me then, weird take to do it
               | while sounding like you disagree...
               | 
               | As I said, you can make the argument C++ build systems
               | are no good. However the argument originally made is that
               | C++ the language caused these issues when in reality the
               | package maintainer hasn't put in the effort to properly
               | document and fix known issues in their chosen build
               | system for C++.
               | 
               | The fact that they in fact have built out proper packages
               | for pip, cargo, npm and go tells me they have the
               | necessary expertise on the team and made an active choice
               | to not do the same for C++. Create an issue with the
               | maintainer.
        
               | jodrellblank wrote:
               | The argument originally made was " _You can read front-
               | to-cover books about every details of C++ semantics and
               | it 'll still be a PITA to work on real world projects_"
               | 
               | Which is not disagreeing with you just because you are
               | explaining/disputing the reason it was a PITA.
        
               | jpc0 wrote:
               | Seeing as it's Christmas Eve and I has nothing better to
               | do...
               | 
               | Duckdb own documentation says the C++ API is internal and
               | you should use the C API[1]
               | 
               | The makefile also has a 'bundle-library' option which
               | seems to be exactly what you were looking for, it
               | generates a statically linked library which is what the
               | Golang package is using, probably others too but that's
               | the one I checked first.
               | 
               | This is purely a documentation problem, the build system
               | does what is needed it seems. Create an issue, or better
               | yet, add the necessary documentation...
               | 
               | 1. https://duckdb.org/docs/api/cpp
        
               | lairv wrote:
               | I used the C api but I did miss the 'bundle-library'
               | option, will look into that
        
               | jpc0 wrote:
               | I definitely don't blame you for missing it.
               | 
               | I found it by looking at the go package because they
               | claimed they are statically linking there.
        
               | oconnor663 wrote:
               | > the maintainer of X rust package didn't setup cargo
               | correctly and it's impossible to include in my project
               | 
               | That basically never happens, which is the point.
        
               | tdullien wrote:
               | I have seen way more projects with very broken CMake
               | integration than rust packages with broken cargo setup.
               | 
               | CMake _is_ a pain.
        
             | lr1970 wrote:
             | > trying to compile against the prebuilt duckdb_static.so
             | 
             | Typically you statically link against _.a object
             | library._.so are shared objects intended for dynamical
             | linking only. Does duckdb provide something like duckdb.a ?
        
       | anonnon wrote:
       | I had a similar reaction returning to C++ a few years ago, and
       | getting exposed to stuff like lambdas, smart pointers, and
       | template metaprogramming painpoints being fixed. One especially
       | nice thing about C++ is GCC, which lets you use relatively recent
       | features even on obscure HW/OS architectures that other, trendier
       | languages ignore. For example, you can use modern C++ features,
       | at least upto C++17, on OpenBSD.
        
       | jimberlage wrote:
       | Every article like this I scan to see if the author had previous
       | C++ experience. And every article, they do.
       | 
       | I will be very impressed and curious if I find a glowing article
       | about C++ from someone who didn't grow up knowing it as a
       | smaller, simpler language.
       | 
       | The C++ community needs enthusiastic converts who didn't do it
       | back in the 2000s if it's going to stay relevant.
        
         | unclad5968 wrote:
         | I learned c++ after c++20 and after several attempts to enjoy
         | rust, c#, go, and C, I always come back to c++ as the most
         | enjoyable language to develop.
        
           | jimberlage wrote:
           | Nice! If you blog at all your perspective would be super
           | interesting to hear.
        
       | NooneAtAll3 wrote:
       | I'm gonna be weird and not engage in language war (I love c++)
       | 
       | but, dear author:
       | 
       | > +95% of the compiler errors
       | 
       | this. this is unforgivable
       | 
       | +X means "additional X". As in "I have Y and I add +X to it".
       | When you are invited to an event, your invite states you can take
       | your +1 with you (one more person that will come within the same
       | invitation)
       | 
       | if you want to say "more than", you use X+ !! as in "95%+".
       | Because you have some X amount, and you add some more to get
       | X+...
       | 
       | get it together. you're awesome
        
       | anentropic wrote:
       | > I remember insane discussions with people who thought adding
       | two numbers with a template was "faster" than adding two numbers
       | directly, even though the assembly language output was exactly
       | the same.
       | 
       | I know almost nothing about C++ and have never programmed in
       | it... but I thought that the point of that kind of 'template
       | metaprogramming' was that the code got executed at compile time
       | instead of runtime?
       | 
       | i.e. instead of generating identical assembly output the goal
       | would have been to output a constant value
        
         | ch33zer wrote:
         | As per usual with c++ it depends. In some situations things are
         | guaranteed to be compile time evaluated. E.g. even in early
         | templates this would need to work:
         | 
         | Func<1+2>();
         | 
         | Something like this there's no guarantees around:
         | 
         | template <A, B> int Func() { return A + B; }
         | 
         | For almost all compilers it should constant fold this into a
         | constant but in theory it could end up with an add instruction.
         | Basically we can't second guess the author here because it
         | depends on the specifics.
        
       | andrewflnr wrote:
       | > I firmly believe that for creativity to blossom you need to be
       | able to get your idea out without fear of criticism and shame.
       | 
       | This section is, it seems to me, the linchpin of the "fun"
       | argument. But you've been able to do that with all the other
       | languages too, all this time. The much-loathed and feared Rust
       | Evangelism Strikeforce doesn't actually come to your house and
       | make you use a bunch of generic-heavy code from crates.io. The
       | React people can't stop you from using vanilla Js. The worst they
       | can really do is send you mean tweets, but Shaw thinks this is a
       | lethal threat to his creativity, enough to switch language
       | ecosystems over. For an article written in a superficially
       | rebellious, lone-wolf tone, that's kinda sad.
        
       | mcdeltat wrote:
       | This article seems kinda confused. It makes a lot of points, but
       | I'm struggling to extract why that means C++ is more/less fun.
       | 
       | The simultaneous description of modern C++ as "extremely high
       | quality" and yet pervasive legacy bs, horrible tooling, etc is
       | confusing. They say unique_ptr is great yet they "really hate
       | RAII". Many of the discussed topics are largely irrelevant or
       | incorrect. Metaprogramming used to be everywhere but now isn't
       | (what?? Take a look at concepts)? C++ has the best graphics
       | libraries (surely not true)? Installing Python is harder than
       | C++? These seems like odd obsessions of the author, with little
       | relation to the argument.
       | 
       | I think the author just finds C++ fun for some complex
       | combination of personal factors, which is fine. Perhaps partly
       | due to a "hacker" type personality. Some of the most fun I've had
       | with programming has been C++, due to its performance and
       | technicality. At the same time, C++ is in practice crap for
       | "real" software development where your own short-term enjoyment
       | is not paramount (for a billion reasons we all know). C++ is a
       | deeply conflicted language, scarred by decades of legacy and
       | politics. Ignoring the reality of C++ is the biggest mistake of
       | those who discuss it. My attitude towards C++ these days is of
       | tiredness. I don't want to jump through the hoops C++ has thrown
       | at me for the past many years. We don't need to beat an already
       | long dead horse. It's ok to let C++ be what it is.
        
         | mst wrote:
         | > I think the author just finds C++ fun for some complex
         | combination of personal factors, which is fine. Perhaps partly
         | due to a "hacker" type personality.
         | 
         | I think that sums up the point of the article just fine.
         | 
         | To me at least, it's not so much that it's confused as that
         | it's him being excited about having fun and doing his best to
         | share his joy. Which means that, sure, it's not a proper essay
         | at all, it's not really trying to convince you to agree so much
         | as saying "if you find this relatable without me trying to
         | actively convince you, maybe you'd find it fun too."
         | 
         | I think given you've been mugged by reality in commercial work
         | to the point of tiredness, your not finding it to make sense at
         | all is completely understandable, though.
         | 
         | I'm currently having a blast writing javascript of all things,
         | and I imagine if I wrote up a similar blog post explaining why
         | it'd come across just as badly to somebody burned out on the
         | last decade of commercial javascript too.
         | 
         | But I'm glad he's having fun, and I'm glad he decided to share
         | the joy.
        
       | PittleyDunkin wrote:
       | I am a bona fide C++ hater, but that's just because I resent
       | working on it for professional code that needs to work reliably
       | with coworkers I don't entirely trust. For personal projects it's
       | one of the most satisfying coding contexts I've ever worked and
       | it is indeed a blast to have such fine-grained control over
       | execution.
       | 
       | I abandoned the language about a decade ago and I don't see
       | myself looking back. My projects these days need long-term
       | reliability more than anything and rust + cd/ci hits a sweet
       | spot. That said, I do miss the thrill of designing and executing
       | a program that runs in a certain way exactly as I intended and
       | knowing that it was my expertise and insight that allowed this
       | execution. Would I want to work with someone that was driven by
       | that? Hell no! But it is personally a joy I won't forget.
       | 
       | Other inexcusable pain points: the build systems and package
       | management is an absolute nightmare; the pre-processor feels like
       | a sadistic joke; the syntax is horrible; there's so much cruft in
       | the runtime you need years of experience to not machine-gun your
       | foot off by using the most obvious tool at your disposal. But in
       | a sense this just increases the joy of shipping a working
       | executable with all your cleverness and blood and tears wrapped
       | with a bow.
        
         | nnadams wrote:
         | Kudos for one of the most relatable descriptions of C++ I've
         | read.
         | 
         | I did a couple years writing C/C++ professionally, and I hope
         | to not go back to that. Too many hours debugging other people's
         | code, suffering vague integration issues, and just trying to
         | get the build system spaghetti to run.
        
         | mempko wrote:
         | Work should be fun too, not just personal projects. I've
         | noticed that over the last 10 years, the tech world has seemed
         | to lose this idea. I blame this on the large tech companies who
         | seem to take the best people and put them in an adult prison.
         | Granted a prison with good food and soft chairs.
         | 
         | Even startups seem to be less fun. It seems the VC world
         | foments a narrow window of thought with a lot of copy cat
         | startups doing the same thing. Fads, lots of fads.
         | 
         | I use C++ for every new project because I know if I need to
         | build something myself, I can do it. Using frameworks all the
         | time sucks because frameworks never work the way you want.
         | Especially if it deals with the core of the project.
         | 
         | If you can build it yourself, then do it, otherwise use a
         | framework. And if you can build it yourself, C++ is a great
         | tool because it can do everything and doesn't get in your way
         | in all the important ways. Meaning, I can express my mental
         | model directly in C++, where a language like Rust might
         | complain I'm doing an unsafe thing. Sometimes I think in
         | pointers damned and pointers are a great thing!
         | 
         | Lets bring fun back! Not just in our personal lives, but work
         | too!
        
       | Animats wrote:
       | The fundamental problem with C++ is that it has hiding
       | ("abstraction") without safety. That's rare.
       | 
       | - C -- No hiding, no safety
       | 
       | - Python, Javascript, LISP, other interpreted languages -- hiding
       | with safety
       | 
       | - Pascal, Ada, Modula, Rust -- hiding with safety
       | 
       | - C++ -- hiding without safety.
       | 
       | C++ is, decades late, trying to get to hiding with safety. But
       | there's too much legacy.
        
         | gpderetta wrote:
         | Well C has functions. Isn't that the original hiding
         | abstraction?
        
           | pornel wrote:
           | It is an abstraction, but the safety requirements are neither
           | enforced nor abstracted away.
           | 
           | C's type system can't communicate how long pointers are valid
           | for, when and where memory gets freed, when the data may be
           | uninitialized, what are the thread-safety requirements, etc.
           | The programmer needs to know these things, and manually
           | ensure the correct usage.
        
       | everyone wrote:
       | C++ is great, but I hate .h files.. I'm kind of shocked that some
       | tool to automate writing .h files isnt the the standard.
        
       | moth-fuzz wrote:
       | I'm of two minds when I see comments complaining about header
       | files. Practically speaking, I think "have the preprocessor copy
       | & paste source files together" is a bit of a hackjob, but,
       | _conceptually_ speaking, having your interface and implementation
       | separate is ultimately a good thing.
       | 
       | The problem of course lies not with header files, but C++ the
       | language, as all public fields and private fields must be
       | specified in the class declaration so that the compiler knows the
       | memory layout. It's kind of useless in that sense. You can move
       | private methods out to a separate source file, but, you don't
       | gain much in doing so, at least in terms of strict encapsulation.
       | And of course, if you use templates at all, you can no longer
       | even do that. Which is its own can of worms.
       | 
       | Unfortunately, none of these problems are problems that modules
       | solve. Implementations very much disagree on interfaces vs
       | implementations, precompiled vs simply included, etc etc. In my
       | own usage of modules I've just found it to be header files with
       | different syntax. Any API implemented via modules is still very
       | leaky - it's hard to just import a module and know what's truly
       | fair for application usage or not. You still ultimately have to
       | rely on documentation for usage details.
       | 
       | At the end of the day I don't really care how the implementation
       | puts together a particular feature, I care about how it affects
       | the semantics and usability of the language. And modules do not
       | really differ in proper usage from headers, even though the whole
       | backend had to be changed, the frontend ends up being the same.
       | So it's net nothing.
       | 
       | All said and done, when it comes to defining library APIs, I
       | prefer C. No public/private, you just have some data laid out a
       | particular way, and some functions to operate on it. The header
       | file is essentially just a symbol table for the binary code - and
       | said code can be a .c file or a .o file or even a .a or .lib or
       | .dll or whatever - C doesn't care. Raw functionality, raw
       | usability. No hoops.
        
       | holografix wrote:
       | Tl;dr programming as a hobby building what and how I want is much
       | more fun than doing it for money and being told what to do.
        
       | globalnode wrote:
       | I have the luxury of only writing software for myself, which is
       | almost always Python, but after reading this ill go back and have
       | another look at C++. Did one big project in C++ after uni but
       | then never touched it again.
        
         | 8n4vidtmkvmk wrote:
         | It takes some getting used to. I wrote it for about 10 years
         | then didn't touch it for 10 years and now I write it full time
         | again. Took a few months to get up speed again and stop
         | shooting myself in the foot.
        
       | akoboldfrying wrote:
       | >I really hate RAII.
       | 
       | I'm baffled by this. Deterministic destruction (necessary and
       | basically sufficient for RAII) was one of the best design
       | decisions in C++, I think. RAII means you _can 't_ forget to
       | clean up a resource. You don't have to type anything for it to
       | get cleaned up at the right time, it just happens. It's basically
       | what GC promised developers, except for all resource types, not
       | just memory. Your code gets shorter _and_ more correct.
       | 
       | I'm extremely curious to hear how this could ever be bad.
        
         | AnimalMuppet wrote:
         | RAII isn't just about the destructor, though. It's about
         | writing the _constructor_ in such a way that you can always
         | safely destroy the object. If you don 't write the constructor
         | right, RAII might become something you really hate, because it
         | could blow up on you any time the destructor fires.
        
       | AHTERIX5000 wrote:
       | "I really hate RAII" but smart pointers are great?
        
       | g42gregory wrote:
       | For me, it's basically C++ for low-level, Python for high-level,
       | Java for insanely large corporate codebases, JavaScript (oh
       | boy...) for the Web. Tons of better languages are out there, but
       | they lack the same level of support, tooling and libraries'
       | availability.
        
       | EVa5I7bHFq9mnYK wrote:
       | There were 91 occurrences of the word "rust" in 264 comments so
       | far.
        
         | sseagull wrote:
         | Only 7 instances of "footgun" (or a variation) though. HN is
         | slacking - must be the holidays
        
       | teleforce wrote:
       | > Well, actually the Rust weirdos will bother you but they're
       | usually too busy making the borrow checker happy to actually get
       | anything done so you can ignore them.
       | 
       | Ouch...
        
       | medo-bear wrote:
       | I plead the 10th
       | 
       | https://en.m.wikipedia.org/wiki/Greenspun%27s_tenth_rule
        
       | doug_durham wrote:
       | The metaprogramming metapocolypse resonated with me. In the late
       | 1990's the entire software world got "pattern disease". Yikes. We
       | are still paying the price.
        
       | thdhhghgbhy wrote:
       | >shame grifters
       | 
       | Love this. This is an old post though right, still talking about
       | C+11?
        
       | anothername12 wrote:
       | I think I will take another look. I recently helped my grandson
       | with his university C++ assignment. It was a lot better than I
       | remember C++ in the 90s.
       | 
       | Fun wise though, I get the most fun with dynamic languages that
       | are highly interactive like Forth, Common Lisp and Smalltalk. I
       | don't have to drop out of the zone to kick the compiler all the
       | time.
        
         | jebarker wrote:
         | > I recently helped my grandson with his university C++
         | assignment.
         | 
         | That is awesome. I hope if my kids have kids i'll be of some
         | technical use to them too!
        
       ___________________________________________________________________
       (page generated 2024-12-24 23:02 UTC)