• hark@lemmy.world
    link
    fedilink
    arrow-up
    78
    ·
    6 months ago

    The graph goes up for me when I find my comfortable little subset of C++ but goes back down when I encounter other people’s comfortable little subset of C++ or when I find/remember another footgun I didn’t know/forgot about.

    • LANIK2000@lemmy.world
      link
      fedilink
      arrow-up
      42
      ·
      edit-2
      6 months ago

      That’s one thing that always shocks me. You can have two people writing C++ and have them both not understand what the other is writing. C++ has soo many random and contradictory design patterns, that two people can literally use it as if it were 2 separate languages.

    • henfredemars@infosec.pub
      link
      fedilink
      English
      arrow-up
      33
      ·
      6 months ago

      When I became a team leader at my last job, my first priority was making a list of parts of the language we must never use because of our high reliability requirement.

        • henfredemars@infosec.pub
          link
          fedilink
          English
          arrow-up
          25
          ·
          6 months ago

          strtok is a worst offender that comes to mind. Global state. Pretty much just waiting to bite you in the ass and it did, multiple times.

          • mormegil@programming.dev
            link
            fedilink
            arrow-up
            13
            ·
            edit-2
            5 months ago

            Sure, strtok is a terrible misfeature, a relic of ancient times, but it’s plainly the heritage of C, not C++ (just like e.g. strcpy). The C++ problems are things like braced initialization list having different meaning depending on the set of available constructors, or the significantly non-zero cost of various abstractions, caused by strange backward-compatible limitations of the standard/ABI definitions, or the distinctness of vector<bool> etc.

            • henfredemars@infosec.pub
              link
              fedilink
              English
              arrow-up
              4
              ·
              6 months ago

              No you are right! Honestly it was several years ago and I struggled to remember exactly what I came up with before I left.

              In our application we for example never use dynamic memory allocation. It has to be done very carefully so we don’t crash. Problem is there’s lots of sneaky ways one can accidentally do it from the standard library.

      • hark@lemmy.world
        link
        fedilink
        arrow-up
        5
        ·
        6 months ago

        C is almost the perfect subset for me, but then I miss templates (almost exclusively for defining generic data structures) and automatic cleanup. That’s why I’m so interested in Zig with its comptime and defer features.

        • jas0n@lemmy.world
          link
          fedilink
          arrow-up
          2
          ·
          6 months ago

          You may also like Odin if you haven’t already started zig. It’s less of a learning curve and feels more like what c should have always been. It has defer and simple generics, but doesn’t have the magic of comptime.

      • uis@lemm.ee
        link
        fedilink
        arrow-up
        3
        ·
        6 months ago

        Damm, C23 has a lot of changes. Some of them are really good, some of them I strongly dislike(keyword auto, addition of nullptr).

  • xmunk@sh.itjust.works
    link
    fedilink
    arrow-up
    82
    arrow-down
    12
    ·
    6 months ago

    This graph cuts off early. Once you learn that pointers are a trap for noobs that you should avoid outside really specific circumstances the line crosses zero and goes back into normal land.

    • Pelicanen@sopuli.xyz
      link
      fedilink
      arrow-up
      49
      arrow-down
      1
      ·
      6 months ago

      C++ is unironically my favorite language, especially coding in python feels so ambiguous and you need to take care of so many special cases that just wouldn’t even exist in C++.

        • Narwhalrus@lemmy.world
          link
          fedilink
          arrow-up
          26
          ·
          6 months ago

          Typically, I can read an “average” open source programmers code. One of the issues I have with C++ is the standard library source seems to be completely incomprehensible.

          I recently started learning rust, and the idea of being able to look at the standard library source to understand something without having to travel through 10 layers of abstraction was incredible to me.

          • barsoap@lemm.ee
            link
            fedilink
            arrow-up
            6
            ·
            6 months ago

            One of the issues I have with C++ is the standard library source seems to be completely incomprehensible.

            AAAAAAhhh I once read a Stroustrup quote essentially going “if you understand vectors you understand C++”, thought about that for a second, coming to the conclusion “surely he didn’t mean using them, but implementing them”, then had a quick google, people said llvm’s libc++ was clean, had a look, and noped out of that abomination instantly. For comparison, Rust’s vectors. About the same LOC, yes, but the Rust is like 80% docs and comments.

            • uis@lemm.ee
              link
              fedilink
              arrow-up
              1
              ·
              edit-2
              6 months ago

              I think some of those abominational constructs were for compile-time errors. Inline visibility macro is for reducing bynary size, allowing additional optimizations and improving performance and load time.

              In my projects I set default visibility to hidden.

          • magic_lobster_party@kbin.run
            link
            fedilink
            arrow-up
            5
            ·
            6 months ago

            I wonder what went into their minds when they decided on coding conventions for C++ standard library. Like, what’s up with that weird ass indentation scheme?

        • xmunk@sh.itjust.works
          link
          fedilink
          arrow-up
          10
          ·
          6 months ago

          You can absolutely read my code. The ability (similar to functional languages) to override operators like crazy can create extremely expressive code - making everything an operator is another noob trap… but using the feature sparingly is extremely powerful.

    • 5C5C5C@programming.dev
      link
      fedilink
      arrow-up
      39
      arrow-down
      2
      ·
      6 months ago

      Your graph also cuts out early. Eventually you want to get performance gains with multi-threading and concurrency, and then the line drops all the way into hell.

        • 5C5C5C@programming.dev
          link
          fedilink
          arrow-up
          26
          arrow-down
          1
          ·
          edit-2
          6 months ago

          I’m not saying you can’t do multi-threading or concurrency in C++. The problem is that it’s far too easy to get data races or deadlocks by making subtle syntactical mistakes that the compiler doesn’t catch. pthreads does nothing to help with that.

          If you don’t need to share any data across threads then sure, everything is easy, but I’ve never seen such a simple use case in my entire professional career.

          All these people talking about “C++ is easy, just don’t use pointers!” must be writing the easiest applications of all time and also producing code that’s so inefficient they’d probably get performance gains by switching to Python.

          • deadcream@sopuli.xyz
            link
            fedilink
            arrow-up
            7
            ·
            6 months ago

            That’s the problem of most general-use languages out there, including “safe” ones like Java or Go. They all require manual synchronization for shared mutable state.

            • 5C5C5C@programming.dev
              link
              fedilink
              arrow-up
              20
              arrow-down
              1
              ·
              edit-2
              6 months ago

              There’s a difference between “You have to decide when to synchronize your state” and “If you make any very small mistake that appears to be perfectly fine in the absence of extremely rigorous scrutiny then this code block will cause a crash or some other incomprehensible undefined behavior 1/10000 times that it gets run, leaving you with no indication of what went wrong or where the problem is.”

          • uis@lemm.ee
            link
            fedilink
            arrow-up
            4
            ·
            6 months ago

            that’s so inefficient they’d probably get performance gains by switching to Python.

            Damn, this goes hard for no reason.

          • uis@lemm.ee
            link
            fedilink
            arrow-up
            1
            ·
            6 months ago

            Well, threadsanitizer catches them in runtime. Not sure about GCC static analyser and other SA tools.

            • 5C5C5C@programming.dev
              link
              fedilink
              arrow-up
              3
              ·
              edit-2
              6 months ago

              I use thread sanitizer and address sanitizer in my CI, and they have certainly helped in some cases, but they don’t catch everything. In fact it’s the cases that they miss which are by far the most subtle instances of undefined behavior of all.

              They also slow down execution so severely that I can’t use them when trying to recreate issues that occur in production.

              • uis@lemm.ee
                link
                fedilink
                arrow-up
                1
                ·
                6 months ago

                They caught lock inversion, that helped to fix obscure hangs, that I couldn’t reproduce on my machine, but were constantly happening on machine with more cores.

    • lazyneet@programming.dev
      link
      fedilink
      arrow-up
      20
      arrow-down
      5
      ·
      6 months ago

      I’ve been using C++ almost daily for the past 7 years and I haven’t found a use for shared_ptr, unique_ptr, etc. At what point does one stop being a noob?

      • AngryPancake@sh.itjust.works
        link
        fedilink
        arrow-up
        26
        arrow-down
        1
        ·
        6 months ago

        Given that you probably are using pointers, and occasionally you are allocating memory, smart pointers handle deallocation for you. And yes, you can do it yourself but it is prone to errors and maybe sometimes you forget a case and memory doesn’t get deallocated and suddenly there is a leak in the program.

        When you’re there, shared_ptr is used when you want to store the pointer in multiple locations, unique_ptr when you only want to have one instance of the pointer (you can move it around though).

        Smart pointers are really really nice, I do recommend getting used to them (and all other features from c++11 forward).

        • arendjr@programming.dev
          link
          fedilink
          arrow-up
          7
          ·
          6 months ago

          Smart pointers are really really nice, I do recommend getting used to them (and all other features from c++11 forward).

          You’re recommending him to give up his sanity and/or life?

          • porgamrer@programming.dev
            link
            fedilink
            arrow-up
            2
            ·
            6 months ago

            I would have said the same thing a few years ago, but after writing C++ professionally for a while I have to grudgingly admit that most of the new features are very useful for writing simpler code.

            A few are still infuriating though, and I still consider the language an abomination. It has too many awful legacy problems that can never be fixed.

      • riodoro1@lemmy.world
        link
        fedilink
        arrow-up
        11
        arrow-down
        1
        ·
        6 months ago

        This guy probably still uses a char*.

        What have you been using it daily for? arduino development? I’m hoping no company still lives in pre C++17 middle ages.

      • MajorHavoc@programming.dev
        link
        fedilink
        arrow-up
        8
        ·
        6 months ago

        At what point does one stop being a noob?

        I recognize that trick question. For C++, the answer is always “soon”.

      • whou@lemmy.ml
        link
        fedilink
        arrow-up
        7
        ·
        6 months ago

        well, if I have an object on the heap and I want a lot of things to use it at the same time, a shared_ptr is the first thing I reach for. If I have an object on the heap and I want to enforce that no one else but the current scope can use it, I always reach for a unique_ptr. Of course, I know you know all of this, you have used it almost daily for 7 years.

        In my vision, I could use a raw pointer, but I would have to worry about the lifetime of every object that uses it and make sure that it is safe. I would rather be safe that those bugs probably won’t happen, and focus my thinking time on fixing other bugs. Not to mention that when using raw pointers the code might get more confusing, when I rather explicitly specify what I want the object lifetime to be just by using a smart pointer.

        Of course, I don’t really care how you code your stuff, if you are comfortable in it. Though I am interested in your point of view in this. I don’t think I’ve come across many people that actually prefer using raw pointer on modern C++.

      • SubArcticTundra@lemmy.ml
        link
        fedilink
        arrow-up
        3
        ·
        6 months ago

        Do you still use raw pointers? You know they’ve discovered fire? (Jk coming from C I too havent learnt how to use smart pointers yet)

      • Fushuan [he/him]@lemm.ee
        link
        fedilink
        English
        arrow-up
        2
        ·
        6 months ago

        Shared poibters are used while multithreading, imagine that you have a process controller that starts and manages several threads which then run their own processes.

        Some workflows might demand that an object is instantiated from the controller and then shared with one or several processes, or one of the processes might create the object and then send it back via callback, which then might get sent to several other processes.

        If you do this with a race pointer, you might end in in a race condition of when to free that pointer and you will end up creating some sort of controller or wrapper around the pointer to manage which process is us8ng the object and when is time to free it. That’s a shared pointer, they made the wrapper for you. It manages an internal counter for every instance of the pointer and when that instance goes out of scope the counter goes down, when it reaches zero it gets deleted.

        A unique pointer is for when, for whatever reason, you want processes to have exclusive access to the object. You might be interested in having the security that only a single process is interacting with the object because it doesn’t process well being manipulated from several processes at once. With a raw pointer you would need to code a wrapper that ensures ownership of the pointer and ways to transfer it so that you know which process has access to it at every moment.

        In the example project I mentioned we used both shared and unique pointers, and that was in the first year of the job where I worked with c++. How was your job for you not to see the point of smart pointers after 7 years? All single threaded programs? Maybe you use some framework that makes the abstractions for you like Qt?

        I hope these examples and explanations helped you see valid use cases.

    • orbitz@lemmy.ca
      link
      fedilink
      arrow-up
      13
      ·
      6 months ago

      First year programming in the late 90s … segmentation fault? I put printfs everywhere. Heh. You’d still get faults before the prints happened, such a pain to debug while learning. Though we weren’t really taught your point of the comment at the time.

      Least that was my experience on an AIX system not sure if that was general or not, the crash before a print I mean.

      • xmunk@sh.itjust.works
        link
        fedilink
        arrow-up
        9
        ·
        6 months ago

        Yea, pointer arithmetic is cute but at this point the compiler can do it better - just type everything correctly and use []… and, whenever possible, pass by reference!

    • WormFood@lemmy.world
      link
      fedilink
      arrow-up
      5
      ·
      6 months ago

      pointers are fine, but when you learn about the preprocessor and templates and 75% of the STL it goes negative again

      c++ templates are such a busted implementation of generics that if I didn’t have context I’d assume they were bad on purpose like malbolge

  • mindbleach@sh.itjust.works
    link
    fedilink
    arrow-up
    52
    ·
    6 months ago

    The C++ feature set is a giant tome written in an unsteady hand and bound with suspicious leather. You’re supposed to study it deeply, use as little as possible, and ideally have a backup plan if things go wrong for this plane of existence.

    • MajorHavoc@programming.dev
      link
      fedilink
      arrow-up
      14
      ·
      edit-2
      6 months ago

      Perfect description.

      It also describes why I now love GoLang so much.

      “How has GoLang improved on this unholy tome or horrors?”

      “Well, it fits in my pocket now.”

    • lseif@sopuli.xyz
      link
      fedilink
      arrow-up
      10
      ·
      6 months ago

      i like to think of C++ as a testing ground for new features and paradigms. to see how some concepts will handle in production.

  • nothacking@discuss.tchncs.de
    link
    fedilink
    arrow-up
    53
    arrow-down
    5
    ·
    6 months ago

    Hot take, C is better then C++. It really just has one unique footgun, pointers, which can be avoided most of the time. C++ has lots of (smart)pointer related footguns, each with their own rules.

    • Valmond@lemmy.world
      link
      fedilink
      arrow-up
      17
      ·
      6 months ago

      If you do C, and avoid pointers, do tell me what the point is using the language at all?

      I mean if memory management is “the only way to shoot yourself in the foot” in C, then thats a quite big part of the language!

      • uis@lemm.ee
        link
        fedilink
        arrow-up
        4
        ·
        edit-2
        6 months ago

        If you do C, and avoid pointers, do tell me what the point is using the language at all?

        Person is saying that C has one big footgun, while C++ has armory of them

    • MajorHavoc@programming.dev
      link
      fedilink
      arrow-up
      11
      ·
      6 months ago

      Yeah. My journey of love, loathing, hatred, adoration, and mild appreciation for C++, ended with the realization that 90% of the time I can get the job done in C with little hassle, and a consistent, predictable, trustworthy set of unholy abominations.

    • jas0n@lemmy.world
      link
      fedilink
      arrow-up
      5
      ·
      edit-2
      6 months ago

      Preach brother, I don’t think that’s a hot take at all. I’ve become almost twice as productive since moving from c++ to c. I think I made the change when I was looking into virtual destructors and I was thinking, “at what point am I solving a problem the language is creating?” Another good example of this is move semantics. It’s only a solution to a problem the language invented.

      My hot take: The general fear of pointers needs to die.

      • porgamrer@programming.dev
        link
        fedilink
        arrow-up
        2
        ·
        edit-2
        6 months ago

        I’m not a fan of C++, but move semantics seem very clearly like a solution to a problem that C invented.

        Though to be honest I could live with manual memory management. What I really don’t understand is how anyone can bear to use C after rewriting the same monomorphic collection type for the 20th time.

        • jas0n@lemmy.world
          link
          fedilink
          arrow-up
          1
          ·
          6 months ago

          Maybe I’m wrong, but aren’t move semantics mostly to aid with smart pointers and move constructors an optimization to avoid copy constructors? Neither of which exist in c.

          I’m not sure what collection type you’re referring to, but most c programmers would probably agree that polymorphism isn’t a good thing.

          • porgamrer@programming.dev
            link
            fedilink
            arrow-up
            2
            ·
            6 months ago

            That’s what std::move does, and you’re right that it’s quite an ugly hack to deal with C++ legacy mistakes that C doesn’t have.

            I say move semantics to refer to the broader concept, which exists to make manual memory management safer and easier to get right. It’s also a core feature of Rust.

            Also I’m talking about parametric polymorphism, not subtype polymorphism. So I mean things like lists, queues and maps which can be specialised for the element type. That’s what I can’t imagine living without.

            • jas0n@lemmy.world
              link
              fedilink
              arrow-up
              2
              ·
              6 months ago

              Hahaha. I knew I was wrong about the polymorphism there. You used big words and I’m a grug c programmer =]

              We use those generic containers in c as well. Just, that we roll our own.

              Move semantics in the general idea of ownership I can see more of a use for.

              I would just emphasize that manual memory management really isn’t nearly as scary as it’s made out to be. So, it’s frustrating to see the ridiculous lengths people go to to avoid it at the expense of everything else.

              • porgamrer@programming.dev
                link
                fedilink
                arrow-up
                2
                ·
                6 months ago

                I definitely agree on the last point. Personally I like languages where I can get the compiler to check a lot more of my reasoning, but I still want to be able to use all the memory management techniques that people use in C.

                I remember Jonathan Blow did a fairly rambling stream of consciousness talk on his criticisms of Rust, and it was largely written off as “old man yells at clouds”, but I tried to make sense of what he was saying and eventually realised he had a lot of good points.

                I think it was this one: https://m.youtube.com/watch?v=4t1K66dMhWk

                • jas0n@lemmy.world
                  link
                  fedilink
                  arrow-up
                  2
                  ·
                  edit-2
                  6 months ago

                  Just watched this. Thank you. I think I’d agree with most of what he says there. I like trying languages, and I did try rust. I didn’t like fighting with the compiler, but once I was done fighting the compiler, I was somehow 98% done with the project. It kind of felt like magic in that way. There are lots of great ideas in there, but I didn’t stick with it. A little too much for me in the end. One of my favorite parts C is how simple it is. Like you would never be able to show me a line of C I couldn’t understand.

                  That said, I’ve fallen in love a language called Odin. Odin has a unique take on allocators in general. It actually gives you even more control than C while providing language support for the more basic containers like dynamic arrays and maps.

    • porgamrer@programming.dev
      link
      fedilink
      arrow-up
      1
      arrow-down
      2
      ·
      6 months ago

      The only conceivable way to avoid pointers in C is by using indices into arrays, which have the exact same set of problems that pointers do because array indexing and pointer dereferencing are the same thing. If anything array indexing is slightly worse, because the index doesn’t carry a type.

      Also you’re ignoring a whole host of other problems in C. Most notably unions.

      People say that “you only need to learn pointers”, but that’s not a real thing you can do. It’s like saying it’s easy to write correct brainfuck because the language spec is so small. The exact opposite is true.

    • scrion@lemmy.world
      link
      fedilink
      arrow-up
      25
      ·
      6 months ago

      It’s actually a lot worse than ASM, there are far more ambiguities in C++. And yet here I am, still developing with it some 30+ years later.

      Don’t worry, I’m using Rust were it makes sense.

      • OpenStars@discuss.online
        link
        fedilink
        English
        arrow-up
        9
        ·
        6 months ago

        Assembly was my first language after BASIC - I know I’m weird, and I’m okay with that:-). Tbf it was for a calculator, so simplified. Any language ofc can go off the deep end in terms of complexity, or if you stick to the shallows it can be fairly simple to write a hello world program (though it took me a month to successfully do that for my calculator, learning on my own and with limited time spent on that task:-).

      • OpenStars@discuss.online
        link
        fedilink
        English
        arrow-up
        4
        ·
        6 months ago

        Okay so they are both quite “fun” :-)

        C++ is a bit easier to use on a daily basis though, and a scripting language easier still:-D.

        Damn asm was fun though…

  • erp@lemmy.world
    link
    fedilink
    arrow-up
    32
    arrow-down
    1
    ·
    6 months ago

    C++: C with blackjack and 40 year old hookers. Anyway, only the rich can inherit diamonds or something. Or perhaps not, my memory is corrupted. I’m open to any pointers though…

      • AVincentInSpace@pawb.social
        link
        fedilink
        English
        arrow-up
        4
        ·
        6 months ago

        In the early days of C#, before it was called C#, Microsoft gave it the most Microsoft name ever conceived for anything ever: Visual J++

          • AVincentInSpace@pawb.social
            link
            fedilink
            English
            arrow-up
            4
            ·
            6 months ago

            update: i just looked it up and they are not. Visual J++ is a predecessor to C#. Nevertheless, the name “Visual J++” in all its Microsoftian goodness(?) is as good a descriptor as any for what C# turned into

            • skuzz@discuss.tchncs.de
              link
              fedilink
              arrow-up
              3
              ·
              6 months ago

              So more an iterative family member, which I suppose was more what I’d expect with how Microsoft hisorically handled programming languages. Still interesting! Thanks for the fact-check!

    • henfredemars@infosec.pub
      link
      fedilink
      English
      arrow-up
      4
      ·
      6 months ago

      Me too. If I can use it, I prefer C# — that is — if I’m not doing systems programming, I don’t have to worry about legacy code, and mainly I’m supporting Windows then it’s really quite cozy.

      • MajorHavoc@programming.dev
        link
        fedilink
        arrow-up
        3
        ·
        6 months ago

        That’s a solid description. I’m stealing that. “Cozy” is an excellent word for that sets C# apart from other languages.

    • Jimb@lemmy.world
      link
      fedilink
      arrow-up
      3
      ·
      6 months ago

      I like C# too. I feel like I shouldn’t because of how Microsoft it is, but I can’t help but see it as a better put together/structured Java when I use it.

      • penquin@lemm.ee
        link
        fedilink
        arrow-up
        2
        ·
        6 months ago

        I feel the same, but to me, it’s more understandable than the other C derivatives. I just understand it better. I’ve been thinking of diving into rust lately.

  • TangledHyphae@lemmy.world
    link
    fedilink
    arrow-up
    11
    ·
    6 months ago

    As someone who writes C++ every day for work, up to version C++20 now, I hate the incoming C++23 even more somehow. The idea of concepts, it just… gets worse and worse. Although structured binding in C++17 did actually help some with the syntax, to be fair.