23 comments

  • xdavidliu 12 days ago
    I find it really problematic that the "classic first program" in this book includes "import std;" as the very first line, and as far as I know not a single compiler with the possible exception of MSVC supports that out of the box.

    Writing this on a debian machine, and trying "g++ --std=c++23 -fmodules-ts" does not work, and from https://en.cppreference.com/w/cpp/23 looks like the "paper" for this is P2465R3, for which clang++ 17 has "partial support". I apt installed clang++17, and it still didn't work, complaining "module 'std' not found"

    I understand that "import std;" is a very new feature and not "finalized" or whatever, but this book is supposed to be for beginners to C++; I wonder how the average beginner would react to that?

    (I found the same thing a year or two ago when reading "Tour of C++")

    • davidthewatson 8 days ago
      Good point! Me too.

      My g++ emits exactly the errors and instructions you described.

      I haven't read the current Stroustrup version under discussion, but I did read the earlier version when C++ was all day, every day for me.

      I prefer Koenig and Moo's Accelerated C++ twenty years on though I admit there may be better books since which I've not read.

      IIRC, their hello world was:

          // a small C++ program
          #include <iostream>
          int main()
          {
              std::cout << "Hello, world!" << std::endl;
          }
      
      Which copy pastas into my current arch linux, builds in:

          g++ a.cpp 
      
      and runs in:

          ./a.out
          Hello World!
      
      as it has since I first read it twenty years ago, and likely did before that.

      The rest of the book was a tour de force of making modern C++ emulate the near-pseudocode, sans pointer arithmetic of C, simple-and-clean, buttoned-up style seen in early python, where none of those things existed until pandas brought wrapped C++ libs along with it like numpy and scipy.

      Professionally, I've not seen clean C++ code in the wild, though I don't work at FAANG and code reviews are unusual in rapid prototypes so I'm not sure how widely Koenig and Moo are mentored outside the greenfield world I've lived in with the possible exception of radiotherapy where you're trying to avoid being the next Therac 25.

    • adrian_b 12 days ago
      The current gcc documentation (13.2.1) says:

        "_Standard Library Header Units_
           The Standard Library is not provided as importable header units.
           If you want to import such units, you must explicitly build them
           first.  If you do not do this with care, you may have multiple
           declarations, which the module machinery must merge--compiler
           resource usage can be affected by how you partition header files
           into header units."
      
      So for now any "import" can work only if one writes appropriate module files first.

      Nevertheless, I do not expect that the updating of the standard C++ library of gcc will take a long time, so later this new book will become directly usable as it is.

      For someone who already knows older C++ and just wants to update their knowledge, writing the corresponding module files can be a good learning experience in itself.

    • humanrebar 12 days ago
      At this point, it's not realistic to maintain interesting C++ programs without a build system. That being said, I expect the specific g++ example you provide will end up working with some special casing in the compiler, at least eventually, when someone submits patches to GCC to get it to work.

      But mostly, it's not realistic to directly wire up calls to g++ anymore outside of research examples. Note that other compiled languages use systems like gobuild, cargo, Maven, etc. instead of fiddling with gccgo, rustc, javac, etc. directly.

      https://www.kitware.com/import-std-in-cmake-3-30/

      • billforsternz 12 days ago
        I think your point is orthogonal to OP's point. I agree with him, the first chapter of a book about a programming language should include hello world and it should ruthlessly minimise barriers to the broadest range of possible readers being able to try that out. They can then supplement their reading with active experimentation, a vital step. You can't learn to swim by reading a book about swimming.
    • randomname93857 12 days ago
      would this help with your problem with modules, it's referenced on the book's page: https://www.stroustrup.com/module_use.html ?
      • xdavidliu 12 days ago
        > GCC

        > CGG (sic) uses .cxx for module files Use -fmodules to use modules.

        no it does not. Trying this on Fedora 39 for example, my original comment above already had -fmodules-ts, and when I use -fmodules, g++ errors with

        g++: error: unrecognized command-line option ‘-fmodule’; did you mean ‘-Mmodules’?

  • tejohnso 13 days ago
    Oh, he switched to QT for the GUI chapter. That's a significant change from FLTK. Should be well received as QT is popular in industry. Not sure how the learning curve will be affected.
    • iso8859-1 13 days ago
      I wonder what Stroustrup thinks about the Meta Object Compiler. In a way Qt is its own dialect of C++.
      • SubjectToChange 12 days ago
        The MOC is just a code generation tool, it's about as objectionable as bison. A far greater sin, especially in the eyes of Stroustrup, is disabling exceptions
        • chipdart 11 days ago
          > The MOC is just a code generation tool, it's about as objectionable as bison.

          I think you've missed the whole point. No one cares about implementation details. The critical aspect is that Qt imposes the use of a superset of C++ which includes keywords such as signals and slots. Technically it's not even C++, but a language which has its own unique keywords, concurrency model, object ownership and life cycle, etc.

          • jcelerier 11 days ago
            This is overly dramatic. The "keywords" are just macros. If you don't want an additional preprocessor to generate code in a separate .cpp file from these macros, you can use https://github.com/woboq/verdigris

            The concurrency model, object ownership and life cycle you are mentioning are not part of C++, those are just conventions in specific C++ user groups - Qt code compiles plain and simple with pretty much every conformant C++ compiler and that makes it as much C++ as anything else.

      • justin66 12 days ago
        He's name-dropped CopperSpice in some of his speeches, so he's certainly aware that it's not universally adored.
    • pjmlp 13 days ago
      For the better, with Qt there is QtCreator.
      • spacechild1 13 days ago
        Not sure what you are trying to say here. Qt, the library, and QtCreator, the IDE, are completely separate products. You can use QtCreator without Qt and vice versa.

        Now, I'm pretty sure you know that, hence my confusion...

        • Kranar 12 days ago
          Qt Creator makes working with Qt a heck of a lot easier in a way that working with Visual Studio or vim does not. It comes with an integrated Qt form designer, Quick Designer for QML, supports Qt's moc syntax out of the box, integrated support for Qt Test Integration, native support for Qt Assistant and documentation and integration with Qt's internationalization tools.

          The idea that "QtCreator" is some totally independent IDE that just coincidentally happens to have the letters Qt at the beginning in the same way that Java and JavaScript are independent of one another, but otherwise has no relationship to Qt the library is just patently absurd HN pedantry.

          • chipdart 11 days ago
            > Qt Creator makes working with Qt a heck of a lot easier in a way that working with Visual Studio or vim does not.

            That's only true if you intentionally ignore all the aspects where Qt Creator falls way short of what "visual studio or vim" are leaps and bounds ahead.

          • spacechild1 12 days ago
            > that just coincidentally happens to have the letters Qt at the beginning

            That's not what I was trying to say. I just thought it's worth pointing out that QtCreator is really a general-purpose C++ IDE. (It's my favourite C++ IDE, btw.)

            • Kranar 12 days ago
              It can be a general-purpose C++ IDE and also very tightly coupled to Qt at the same time.

              Visual Studio is also a general-purpose C++ IDE and yet I don't think anyone would say it's independent of Windows.

              • spacechild1 12 days ago
                Sure. Actually, I think I misunderstood OP. I think what he was trying to say is that by switching to Qt you also get a nice visual editor in the form of QtCreator, to which I agree!
        • earthnail 13 days ago
          QtCreator helps with the learning curve as it‘s a very accessible IDE. One of the first IDEs I used in my career.
          • spacechild1 12 days ago
            Sure, QtCreator is nice and it's actually my IDE of choice. I just wanted to point out that it is independent of Qt, the library.
    • layer8 13 days ago
      He uses a custom wrapper library, so not sure how much (if anything) of QT proper is exposed.
    • UncleOxidant 13 days ago
      All of the 4 AI coding assistants I've tried (claude3, gemini, gpt4, deepseek) used SFML for graphics when I asked them to code boids and game of life in C++. I'm wondering if that's because it's cross platform or that there's more code out there using SFML that these models got trained on? SFML seems relatively recent compared to Qt or even FLTK, so it seems kind of odd that there would be more SFML training data. It also seems odd that all 4 were in agreement here that SFML should be used for graphics in a C++ program.
      • forgotpwd16 12 days ago
        SFML is a graphical library but not a GUI framework/toolkit that Qt/FLTK are.
      • swatcoder 12 days ago
        SFML is more accessible for lightweight/exploratory/educational use, and so I wouldn't be surprised if it appears more often in training data associated with those simple "let's learn" sized projects.
  • chuckadams 13 days ago
    Know what I like about Stroustrup's code? "using namespace std;". The typical convention of sticking std:: in front of std::every std::last std::bloody std::thing drives me std::insane.
    • HarHarVeryFunny 13 days ago
      It depends ...

      You should NEVER have "using namespace" (for any namespace) in a header file, since that is how you create name clashes, which is what the namespaces are there to avoid.

      I don't personally like "using namespace std;" even in implementations, since I think it makes code less readable, and the contents of std:: is so large, and growing, that I'd again prefer to just avoid the possibility of name clashes.

      We write code once, but read it many times, so shorter names (incl. namespaces) seems like a poor efficiency choice.

      • Kranar 12 days ago
        >We write code once, but read it many times, so shorter names (incl. namespaces) seems like a poor efficiency choice.

        I think it's fascinating how different people can interpret this so differently. I feel like it's precisely because we read code so much more than we write it that we should prefer using names that get to the point, instead of having so much noise and repetitive boilerplate.

        Reading a soup of std::this, std::that, std::foo, std::bar is so difficult to parse through. Especially if you're like me and you sound things out in your head, which I recently learned is not how everyone reads.

        The only justification for writing all those std::'s is because compilers can't disambiguate names from their context, but you're not going to find a human who comes across a use of vector<Foo>, or sort(...) and throw their hands up in confusion wondering what was meant.

        >We write code once, but read it many times, so shorter names (incl. namespaces) seems like a poor efficiency choice.

        This to me seems like a cargo cult justification, where you've heard the argument that descriptive names are helpful for readability, so we should name our variables in a way that conveys their intention as opposed to 1 letter names or obfuscated abbreviations, but instead of genuinely understanding the principle behind the rule, you think the rule is simply that it's better to have long names over short names.

        Descriptive names that can be used to disambiguate variables from one another on the basis of their purpose... yes, please do that. Writing long names just so that they are long, especially by giving everything a shared prefix like std::... no, that's a misunderstanding of the justification behind the rule.

        It's similar to that saying along the lines of when a principle becomes a metric, it ceases to be a useful principle.

        • HarHarVeryFunny 12 days ago
          > This to me seems like a cargo cult justification, where you've heard the argument ...

          Well, no, I've been a professional programmer since 1982, and a hobbyist one both before then and to this day.

          I might be wrong, but these are the lessons I've learnt over the decades working on a variety of projects of different size and durations ...

          Of course consise code is nice, and while you're in the heat of development it's easy to pretty much memorize an entire codebase, even a large one, but it's when you have to come back to it years later, and barely even recognize the code as your own, that you'll be happy it's self-documenting. Now, on a large team that "future self" may just be the new hire, or the guy who replaces you when you quit ...

          • Kranar 12 days ago
            I am not saying you are cargo cult programming, but being a cargo cult programmer has nothing to do with seniority. There are plenty of people who have been programming for decades who blindly follow rules because that's how they learned things, that's what they were taught is good practice, and they never bothered to question it, reflect on it, and they go along with it because of cultural reasons rather than because they have a genuine understanding of the principles.

            >I might be wrong, but these are the lessons I've learnt over the decades working on a variety of projects of different size and durations ...

            But what lesson did you learn? That long names are better than short names, which is what I called cargo cult programming and an instance of mixing up the metric for the principle? Or did you instead learn that descriptive names are better than non-descriptive names?

            If it's that long names are better than short names, then by all means continue using std:: everywhere. If instead it's that descriptive names that communicate purpose or intention or actual information are better than non-descriptive names, then having a bunch of std:: everywhere doesn't do much of anything to help readability, it just adds noise.

            Now people can and do justify the use of std:: but I've never heard it on the basis of making code more readable. There is nothing self documenting about a bunch of names that all share a common prefix.

            And this doesn't even touch on how ironic it is that std is itself non-descriptive jargon that is an abbreviation of standard, but I am almost certain that if everyone had to liter their codebase with standard:: everywhere, no one would think twice about what the right thing to do is.

            • HarHarVeryFunny 12 days ago
              > But what lesson did you learn? That long names are better than short names, which is what I called cargo cult programming and an instance of mixing up the metric for the principle? Or did you instead learn that descriptive names are better than non-descriptive names?

              Do you always suppose that the people you are talking to are morons and cargo-cultists?

              Rhetorical question - have fun.

              • Kranar 12 days ago
                I like to present questions to people to justify their position so that others reading the advice can better evaluate it, understand the reasons and make a more informed judgement on it.

                I am also principled in critiquing an argument and never critiquing a person. I said that the advice you gave is a form of cargo culting, but I also said in the very first sentence that "I am not saying you are cargo cult programming".

                I don't think there is anything wrong with getting into the subtleties of whether the advice is what you originally said it was, which is that longer names are better than shorter names, or whether the advice you learned was that descriptive names are better than non-descriptive names.

                I think the subtlety between those two statements is not being appreciated and without a clear distinction other people may read that advice and take away the wrong conclusion.

                Take care.

                • HarHarVeryFunny 12 days ago
                  > which is that longer names are better than shorter names, or whether the advice you learned was that descriptive names are better than non-descriptive names

                  Are you even a developer?

                  In the programming world "longer names" is universally understood (except apparently by you) to mean "longer due to being more descriptive". NOBODY thinks that making identifier names longer just for the hell of it beneficial.

                  It's as if a chess player is describing to you the importance of controlling the center of the board, and you are wondering out load if they mean controlling it by clamping it to the table.

                  Perhaps you think suggestions like this make you sound smart. They don't.

                  • Kranar 12 days ago
                    Which is why that advice confuses the metric for the principle.

                    This is your exact quote:

                    "We write code once, but read it many times, so shorter names (incl. namespaces) seems like a poor efficiency choice."

                    And the point being made is that there are cases where shorter names are actually more readable than longer names and one of those cases is when every name shares a common prefix. By prefixing everything with something common code becomes more uniform, and names become less distinctive and consequently less readable because it's harder to identify and differentiate sections of code. Code ends up looking like a soup of std::s everywhere.

                    It would be like a chess player who only tries to control the center because someone told them that controlling the center is important, but then repeatedly loses to the King's Indian Defense [1] because they never took the time to fundamentally understand why the center is important and so they don't realize how the King's Indian Defense is used precisely to destabilize the center of the board with sharp angles of attack.

                    They just blindly apply what they hear... and let me tell you there are plenty of mediocre chess players who do just that.

                    In almost any field from programming to chess to sports, you can find guidelines and good rules of thumb and I do not want to discourage people from knowing those rules because having heuristics certainly improves productivity. But don't ever let those rules become dogma; at some point it's worth understanding what the principles behind those rules are, when do they apply and when don't they apply.

                    >Are you even a developer?

                    Note that you keep trying to make this discussion personal whereas I have kept this discussion about the topic and the argument.

                    I would respectfully ask you to do the same, let's discuss the topic and avoid making this personal. It's irrelevant how long you've been programming for or how long I've been programming for or even if I am a programmer at all.

                    Trying to justify arguments on the basis of who you are or who I am is a poor way to go about engineering best practices.

                    What matters is whether your points can be justified.

                    [1] https://en.wikipedia.org/wiki/King%27s_Indian_Defence

                    • HarHarVeryFunny 12 days ago
                      The chess analogy seemed to go over your head. It's not about the value of chess theory, but about you repeatedly wanting to assume the person you are talking to is stupid, and throwing out your own straw man theories of what they are thinking, rather than actually engaging in discussion.

                      If someone was explaining to you why a particular chess move was good, then it'd be reasonable to assume they have some familiarity with chess, but your approach would be to trot out your (newly learned?) "cargo cult" accusation, and wonder why they think screwing the center of the board to the table is a good thing, or as you have just done, assume that they are too dumb to have any familiarity with book openings.

                      You are obviously young, and as you get older you will realize that experience does matter. Future you in 10 years time will hopefully (if you pay attention to your craft, whatever that may be) be smarter and more capable than current you, and future you in 20 years a level-up from that.

                      You ask to not make this personal, but you made it personal right from the start of your response, throwing out straw man arguments and cargo cult accusations. It's a bit ridiculous to then come back and say "don't make it personal". So, rather than give you a technical discussion, I'm giving you the one you are really asking for.

                • chipdart 11 days ago
                  > I like to present questions to people to justify their position so that others reading the advice can better evaluate it, understand the reasons and make a more informed judgement on it.

                  Frankly, this is puerile and pointless. You're doing nothing of the sort. You're just being needlessly contrarian while framing issues from a place of arrogant ignorance, and not having others bite your troll bate doesn't mean you made any point or anyone was enlightened by the engagement.

            • chipdart 11 days ago
              > I am not saying you are cargo cult programming, but being a cargo cult programmer has nothing to do with seniority.

              One thing that is a clear tell that you are not senior is this belief that just because you are oblivious to problems it somehow means they don't exist.

              Between someone who "blindly follows rules" and someone who doesn't think there's any problem in tearing down any example of a Chesterton's fence that comes across them, I'd take the cautious developer who understands tradeoffs.

              In this case, mindlessly peppering include headers with using namespace directives leads to name conflicts in your code and in code that consumes your code. You need to understand what is the whole point of namespaces and what you are doing by essentially removing them. Think about it for a second.

        • chipdart 11 days ago
          > I think it's fascinating how different people can interpret this so differently.

          Sneaking using namespace directives in interface headers is a well known source of problems, as it inadvertently introduces names to lookup which can and often clash. I mean, think for a second: why are namespaces used? What problem do they solve? And why do people think it's a good idea to add all names to a custom namespace?

          Well, adding those names to interface headers negates all that.

          That's why some people interpret things differently: they are oblivious to this problem as their negligible experience means they never experienced any of the problems they cause.

        • krimskrams 12 days ago
          I'd like to bring some perspective as someone who comes from a non-programmer background (mainly academic data science with Python and R) and just starting to learn C++.

          Bjarne's book seemed to be a comprehensive introduction and I'm currently going through it. I found that adding "using namespace std" at the beginning of the file reduced some of C++'s syntactic overhead that a beginner such as myself has to account for. It allows me to focus on the essential by learning the programming principles, rather than getting stuck on the syntax and having to (annoyingly) repeat std:: every line.

          Nevertheless, I think every beginner should know the disadvantages of setting the namespace at the beginning of the file and that no one should use it in production code, but it does its job at keeping things simple if I'm just starting out with C++. There is a reason why Bjarne does this in his book, and I can see why.

          • chipdart 11 days ago
            > Bjarne's book seemed to be a comprehensive introduction and I'm currently going through it. I found that adding "using namespace std" at the beginning of the file reduced some of C++'s syntactic overhead that a beginner such as myself has to account for. It allows me to focus on the essential by learning the programming principles, rather than getting stuck on the syntax and having to (annoyingly) repeat std:: every line.

            That's a false dichotomy. You are free to add using namespace directives in scopes that aren't propagated to other components, such as private headers, source files, functions definitions, etc. including using namespace directives in interfaces is a notorious source of problems.

            The problem with Stroustrup's pedagogical style is that it conveys to newbies that this approach is the right way to write code although this is a known source of nontrivial problems that will leave any newbie stumped.

            • krimskrams 9 days ago
              You make a good point. After more reading on this, I change my mind. The slew of problems caused by using namespace directives far outweigh the positives of avoiding the use of prefixes for convenience sake.

              Even if there are cases where they can be safely used as you've mentioned, its introduction in the book early on, especially in the examples, seems to be a crutch that could lead to an eventual footgun for beginners like me who are following along. I'll reconsider its use from now on.

      • ryandrake 12 days ago
        Not only that, but you have no idea what's going to be put into the standard tomorrow.

        If code I write today has a class called bubble_sorter, and then one day, the C++ standard library decides to add std::bubble_sorter, then:

        1. If I had "using namespace std;" then all of my code is suddenly broken.

        2. If I didn't have it, I'm fine.

        Also, and this is just personal preference, but I simply like to be able to clearly distinguish when my code is calling into the standard library. Typing in that short "std::" reminds me that I am calling into someone else's code.

        • wakawaka28 12 days ago
          >If I had "using namespace std;" then all of my code is suddenly broken.

          If this happened and if you included that specific header, you would get a simple compiler error due to ambiguous methods. Then you can simply add a namespace somewhere and move on. I know sometimes this can involve a lot of changes (if we're talking about other `using namespace ...` usage) but in general you're not gonna have problems.

          If you're really worried about this, you can move the statement closer to where you need it. This is very helpful for dense code that you normally want to be verbose.

          • chipdart 11 days ago
            > If this happened and if you included that specific header, you would get a simple compiler error due to ambiguous methods. Then you can simply add a namespace somewhere and move on.

            ...or, hear me out, you can not make the mistake of mindlessly adding using namespace directives and therefore ensure neither you nor any consumer of your code will risk.having to handle perfectly avoidabld name clashes.

            And by the way, name clashes will also happen if you include code from two or more dependencies which introduce ambiguous symbols. This is code outside of your control.

            • wakawaka28 11 days ago
              >...or, hear me out, you can not make the mistake of mindlessly adding using namespace directives and therefore ensure neither you nor any consumer of your code will risk.having to handle perfectly avoidabld name clashes.

              I'm not talking about "mindlessly" adding these namespace statements. I'm saying, use good judgement. As I pointed out, if you use a little common sense you won't have name clashes and even if you did, they usually cause compile errors. Just don't put them in headers ffs... If you really just need a lot of stuff from another namespace in a function, put the using statement in that function.

              >And by the way, name clashes will also happen if you include code from two or more dependencies which introduce ambiguous symbols. This is code outside of your control.

              The using statements are not outside your control, unless someone put them in a header. That's the only place I broadly object to them.

      • culi 12 days ago
        Conversely,

        We write code once, but read it many times, so longer names seems like a poor efficiency choice.

        • HarHarVeryFunny 12 days ago
          What's the logic of that though? Longer more descriptive names (self-documenting code) help readability, not hinder it.

          Certainly time to enter code (which is increasingly going to be automated) should be the last consideration - if we're considering full software lifecycle then coding probably takes up some small single-digit percentage of the time we're interacting with the code.

          • nuancebydefault 12 days ago
            Longer names are harder to read. Think about any math formula. Does energy=mass * math::powerf(speed_of_light, 2) read more fluently? Context matters. Make sure the context is ways clear and code is written there where it belongs. Then names can be shorter while being readable.
            • HarHarVeryFunny 12 days ago
              I'm not sure that's a great example. Of course e = mc^2 is so iconic and well known that most people know it, and will probably even perceive it as a whole. Once you recognize it then no need to explain what e, m and c are.

              However, most code is not that obvious, and in the real world you're probably not looking at one mystery line of code who's function becomes obvious by context - you are more likely looking at entire functions or blocks of code, maybe without comments, trying to figure out what is going on. Try inheriting 10K of mostly undocumented code, and then you'd probably be a lot more grateful that the original author used descriptive names and comments, even though he knew what it all meant when he wrote it.

          • culi 7 days ago
            Shorter files allow us to have shorter names. You can read the namespace once at the top instead of 50 times.

            And it's not about time to enter code. It's about time to read code

        • chipdart 11 days ago
          > We write code once, but read it many times, so longer names seems like a poor efficiency choice.

          How can you tell what's the type of an ambiguous name if you have no indication of which namespaces are within scope?

          I mean, think about it. If your concern is readability, doesn't this mean it's important to know what code you're looking at?

          • culi 7 days ago
            Shorter files, shorter names. You can read the namespace once at the top instead of 50 times throughout

            This drastically reduces the amount of time it takes to read code.

    • winwang 12 days ago
      Yep, although I do like not having clashing names.

      But I mean... somehow every other language solved this.

      • Jtsummers 12 days ago
        > But I mean... somehow every other language solved this.

        Did they? C, Lisp, Rust, Python, Ada, Go, Java, C#, ...

        They all require you to qualify conflicting names if some other characteristics (for instance the number or types of arguments) don't provide enough information, or outright don't permit it (C, since it has no notion of name spaces).

        Can you point to the "every other language[s]" which have solved this problem?

        • chuckadams 12 days ago
          It's certainly not every other language, but Unison has a novel approach to solving the problem of name clashes: function names are just local aliases for a content hash of the function's AST. Compiling involves replacing function names with those hashes, and putting the names back is a matter of pretty-printing. I'm sure there's an arsenal of footguns lurking in Unison's system, but for sure it opens up interesting opportunities (distributed code becomes "grab this function out of cache").
          • Jtsummers 12 days ago
            Does that actually solve name clashes? If I have two functions compiled at the same time:

              def foo(n):
                return n + 2
              def foo(n):
                return n * 2
              foo(3) # which one is called?
            
            (I don't know Unison syntax so using Python for the example)

            It's still a name clash at compile time.

            • chuckadams 12 days ago
              TBH I've only dipped my toe into Unison, but I don't believe it would let you re-bind the same identifier in the same scope in the same compilation unit. It's more that `foo(3)` becomes a call to the hashed version `#e0ca5f(3)` forevermore. Once a function has been compiled, it doesn't care what the names of any functions it uses are afterward, until you explicitly recompile them to use the new names. So it really has more to do with preventing versioning conflicts ... others can explain it much better than me, sorry.
        • Kranar 12 days ago
          Most languages you mention let you import the individual names that you want, and you can resolve potential clashes at the point of import. In C++ you basically ```#include``` a file and with it comes a flood of names that are often times unpredictable.
          • Jtsummers 12 days ago
            C++ has had namespaces for a very long time (since the beginning? not sure, I wasn't using computers when it was created), just like those other languages. The name collision issue that it has is the same as them.

            And with those C++ namespaces you can do `using some_namespace::some_specific_name;`. Which resolves the issue just like in those other languages.

        • tylerchurch 12 days ago
          If C++ was JavaScript you would do:

          import {vector} from 'std';

          Which I think is a reasonable compromise, you're only bringing vector into scope rather than all of the standard library.

    • zengid 12 days ago
      I hear that once c++ modules lands this shouldn't be controversial anymore, right?
    • Koshkin 11 days ago
      It’s not so much the ‘std’ thing, it’s the double colon that is an abomination. I never understood why they couldn’t simply use a single dot like some other languages have done.
      • Maxatar 11 days ago
        To resolve ambiguities due to the fact that in C, type names live in a separate namespace from variable names so that it's possible to have a variable with the same name as a type.

        C++ inherits this distinction so that it is possible to write the following:

        struct foo { int x; };

        struct bar : foo { ::foo foo; };

        bar b;

        b.foo::x = 1;

        b.foo.x = 2;

        The b.foo::x and b.foo.x are two different x's, and the only way to disambiguate them is through the use of the . or the ::

    • pif 13 days ago
      You learned to program on Windows, didn't you?
      • chuckadams 12 days ago
        I learned on C on Unix. The naming conventions in Windows are the same kind of syntactic noise I dislike: long identifiers that are just long without actually being descriptive, with extra crap ladled on top in the form of Hungarian notation (which had its uses in the Excel codebase, but doesn't belong anywhere near C++)

        BeOS probably had the nicest looking API. Let's hear it for is_computer_on_fire()

      • marcosdumay 13 days ago
        lpsiNo, spbI uiOnly lpwAdopted iThe spdwStyle usLater.
  • ben7799 13 days ago
    Haven't used C++ in 10+ years but I remember studying an earlier version of this book in stupid depth. And this was at the end of 4 years of using 99% C++ in college.

    It's such a good book. If you really take the time to understand the book C++ it seems kind of sad the world was so afraid of it.

    But of course after all this I of course met an army of people who had never read a book like this at all and wrote horrifying C++ code.

  • jdlyga 13 days ago
    I miss my days working with C++. It's moved further down the development stack than where it used to be. We used to handle UI, API parsing, and pretty much everything using C++.
    • JonChesterfield 13 days ago
      I felt some nostalgia for Fortran a while ago. Spent half an hour programming in it, cured. Maybe take a shot at parsing JSON in C++ and see if the nostalgia survives the process.
      • jbandela1 13 days ago
        >Maybe take a shot at parsing JSON in C++ and see if the nostalgia survives the process.

        I have used this library in the past and was actually pretty easy

        https://github.com/nlohmann/json

        • JonChesterfield 12 days ago
          A mere 25k lines of self contained C++, bundled in a single header as the one true distribution format. I note the CI cmake script at a thousand lines of cmake. That's a very idiomatic representation of a C++ library, thank you for the example.
          • SubjectToChange 12 days ago
            A mere 25k lines of self contained C++,…

            Oh come on now, about 7.5k of those lines are comments and/or blank lines. Furthermore, a good chunk of the code is devoted to type checking, thorough error handling, compiler compatibility and/or workarounds, etc, all within the restrictions of C++11.

            … bundled in a single header as the one true distribution format.

            Yes, build systems are a significant pain point for C++ and C. Many users prefer to largely avoid the issue and use header-only libraries. That said, Conan and vcpkg are making genuine strides at improving the issue.

            I note the CI cmake script at a thousand lines of cmake.

            This is ridiculous. It’s a CI script running multiple test suites over dozens of compiler versions, of course it’s going to be a lot. Would it make you feel better if that CI script didn’t exist? If not, then what’s the “correct” size for CI script?

            That's a very idiomatic representation of a C++ library, thank you for the example.

            The library is genuinely good. It’s portable, well tested, user friendly, and widely supported. Your snark is unwarranted.

        • celie56 12 days ago
          Your recommended json solution was also my first thought but if you do not have the ability to easily introduce a new dependency then the op is correct.

          If I have an existing JSON file that I want to quickly parse for a demo project there is almost zero chance I would pick C++. In comparison, Python is already installed in many environments and has built-in json parsing.

      • ChuckMcM 13 days ago
        It took 30 minutes to cure you?!?

        One of the first things I did when I got my PiDP-11 which can run RSX-11M and the DEC fortran compiler. I spent many many hours programming in Fortran when I was in college and thought wow I could relive some of that, about 5 minutes in I was "okay, step slowly away from the console." :-)

        • tialaramex 13 days ago
          There's a fun stream where tsoding decides to learn Fortran, and the instructions he's working from say to turn off implicit typing (ie write "implicit none"). He's familiar with modern languages with type inference and with C++ type deduction which is a similar idea to full blown inference - and so he has no reason to even guess what Fortran is going to do without that admonition and you can see he's not happy when he finds out.
          • ChuckMcM 13 days ago
            I was teaching one of the local highschool kids how to program in C and they asked "So why does everybody use i,j, and k for their indexes in loops?"
            • magpi3 12 days ago
              i stands for index. j and k because we can't use i anymore, and maybe because they are close together on the keyboard
            • pklausler 13 days ago
              I only use 'j' and 'k', not 'i ' -- the rarely-used letters are easier to search for.
          • pklausler 13 days ago
            I don't get that at all. Old FORTRAN has a mildly confusing feature that is easy to disable. He then got upset about the mildly confusing feature that everybody now disables. If one wants to bitch about Fortran, at least complain about the modern language (which is still a horror show of poorly defined and often unportable features), not the stuff that has been made obsolete.
      • VHRanger 12 days ago
        Let me carefully copy paste my personal stringutils.hpp file of string handling routines and I'll be right up to it!
        • rightbyte 12 days ago
          Gotta have those "readfile()", "replace_substr()", "split()" etc! I do have a copy paste string util header. ..

          I really wish there were more string util functions in Cpp. I mean C had strtok()!

          • PaulDavisThe1st 12 days ago
            strtok() is one of the most dangerous string handling functions in any language!
            • rightbyte 12 days ago
              strtok() is like a hot art student, smoking a cigarette. I think I've got to it once.
              • PaulDavisThe1st 12 days ago
                In the C language, you do not get to strtok(3), strtok(3) gets to you.
      • petsfed 13 days ago
        I recently had to port an existing C++ JSON parser into a new project, and even though it was complete in terms of what we needed it to do right now, adding any kind of additional functionality to it would've been a nightmare.
      • pantsforbirds 12 days ago
        If you have any problem that isn't vector math, it's absolutely awful. Even IO is unpleasant
        • JonChesterfield 12 days ago
          Vector math on raw floating point that is. If you want to wrap that float in a type to force (physical) dimensional consistency, you are going to have a bad time.
    • freedomben 13 days ago
      Same. I really miss it. Not terribly long ago we had an app that has a client and server, both in c++. UI, API, everything was c++. It really felt like the universal language had arrived. I won't pretend everything was perfect as it wasn't, but work was fun and the high caliber of people who could work in that stack was a joy to work with. I've never had a more exciting lunch than when we got distcc running on our blades so we could execute builds way faster. It was also a joy not being the only Linux zealot :-D
      • zerr 13 days ago
        I guess the scarcity of cheap labour contributed to the demise of C++ in the applications world.
    • VyseofArcadia 13 days ago
      At my work pretty much everything but the UI is in C++. I suspect the only reason the UI isn't C++ is so we have a portion of the cosebase that recent grads can work on right away without having to train them up in C++.
    • dkersten 13 days ago
      I still tinker on a game engine personal project just to scratch the C++ itch. I really like using C++, despite all the hate it gets.
    • KptMarchewa 13 days ago
      I just wish to _not_ work with Python.
      • REDS1736 13 days ago
        Why is that? I'm genuinely curious. Also, what languages / environments do you prefer?
        • xedrac 13 days ago
          Because Python falls all over itself in larger projects, and is poor at utilizing resources efficiently. It's fine for smaller things that don't care about cpu cycles. I would much rather use Rust in a large project.
        • 01HNNWZ0MV43FF 13 days ago
          Not gp but I prefer rust to python and I'm itching to try that "just write your build scripts and stuff in rust too"

          Sure the builds are slow and Python _kinda_ has static typing, but rust just has a lot of stuff I like and it's practical to install and use natively without learning all the jargon like venvs and eggs and wheels and which package manager and package manager manager (rye?) to use this year

          I tried Python years ago and never got the motivation to push through that learning curve. I've used c++ a lot but it always required me to "keep my hands inside the ride at all times". Rust feels like it actually wants to be easy to use

          • gorjusborg 13 days ago
            The idea of using Rust for scripting is bizaar.

            I can understand not wanting to use Python for everything, but I see the problem being the 'use it for everything' not the language choice.

            Use the tool that excels at the job. There is no language that is good at everything.

            • steveklabnik 12 days ago
              Incidentally, this thing comes up a lot: Python vs Rust for scripts. I wrote a comparison four years ago:

              https://news.ycombinator.com/item?id=22712441

              And updated it six months later:

              https://news.ycombinator.com/item?id=24595081

              That's still how I'd do this task today.

              Anyway, I don't think that Rust is always a great choice for scripting, but if you already know Rust, it's totally fine at it.

              • germandiago 12 days ago
                Same for C++ with a good options library and std::filesystem IMHO. You can kind of script with that. I did it and was surprised it did well for some of my engine tooling.
            • n_plus_1_acc 13 days ago
              cargo -Zscript is in nightly
            • weinzierl 12 days ago
              > The idea of using Rust for scripting is bizaar.

              Not at all, I do the same.

            • natsucks 13 days ago
              Rust is cool now. Python is not cool anymore.
              • smallstepforman 13 days ago
                The current project I’m working on has tons of resource caches (for performance), with tons of non-owning pointers sharing cache references. I’d hate to do this in opinionated languages like Rust.
              • steve1977 13 days ago
                I think Python fell victim to the Peter Principle. It got promoted beyond its competence.
                • germandiago 12 days ago
                  Python does well for several reasons.

                  Some that come to my mind: its versatility binding native code and its easy-to-fit in your brain mental model for many tasks. The fact that you can script with Python without a compilation step also helped a lot to spread its popularity I think.

                  • rightbyte 12 days ago
                    The way you define the entry point function is so bizarre I assume scripting was the original use case.
                    • germandiago 12 days ago
                      Could be. But it also gives you the flexibility to set tests inside the module files.
              • AnimalMuppet 13 days ago
                Having to use the wrong tool is not cool, ever. So I don't care how cool Rust is right now, I still am not going to use it for scripting.
                • weinzierl 12 days ago
                  Have you tried it? How would you know that Rust is the wrong tool.

                  I'm indifferent when it comes to Python vs Rust for scripting, but I'd take Rust over a shell script (of any variety) any day.

                  • AnimalMuppet 12 days ago
                    There are many things I have not tried, ranging from Rust to heroin. "You don't know because you haven't tried it" is really bad epistemology.

                    It's also totally impractical. Rust isn't the only language I haven't tried; there are more than a thousand of them. I'm not using JOVIAL for scripting, or Fortran, or a bunch of others. No, I haven't tried any of those either. No, I'm not going to.

                    Turning specifically to Rust, I don't use it for scripting because it's not what I look for in a scripting language. It's compiled; I look for a language that doesn't have that extra step. It has the borrow checker; I don't write scripting code that needs that level of discipline and care.

                    In fact, most of my scripting is of the form "pick some bits out of a text file". For that, Perl is my tool of choice. Sure, other languages have regexes. None of them do it as cleanly and simply as Perl. (Note well: "clean" does not apply to the Perl syntax...)

          • e44858 12 days ago
            For a single file script, you can avoid managing environments by using a nix shebang: https://github.com/NixOS/nixpkgs/blob/master/doc/languages-f...
        • IshKebab 13 days ago
          Same for me. Mainly due to the packaging fiasco (and to a lesser extent, imports).

          The actual language is not awful. Some features are even nice, like infinite precision integers by default, and separate / and // operators.

          Language is ok. Setting everything up is atrocious.

          The other quite annoying thing is that the docs are extremely badly organised so Google rarely points you directly at what you want. Instead you get stuff like w3schools which is trash, but much better organised. Also annoying that the docs still don't include types.

          I would use Typescript (via Deno), Go or Rust instead. There are some other Python replacement languages I haven't tried yet that might be an option like Mojo, Lobster, Nim. Probably still too niche for production; I'd stick with Typescript.

          • emmanueloga_ 13 days ago
            Pixi.sh has been great for me so far, it’s a single binary install that can install Python, conda packages and PyPi packages, maybe give it try!
            • IshKebab 12 days ago
              Looks nice but I can't really require the whole team of like 100 people to use this quite niche tool.

              Python needs an official solution.

          • dlahoda 13 days ago
            poetry with poetry2nix with nix flakes will do magic in terms of setup.

            if stick with pyright(inference) it is as modern as rust.

            python speed increases heavily in all directions.

            • IshKebab 12 days ago
              > poetry with poetry2nix with nix flakes will do magic in terms of setup.

              I'm sure, but it also sounds like it will take about 2 weeks of reading manuals and learning Nix before I'll get to the same point as Rust and Go start at.

              And that's not really an option for big teams, which is the only situation where I'm forced to use Python anyway.

        • DrBazza 12 days ago
          Any non-trivial python is indistinguishable from magic.
    • zerr 13 days ago
      Often I think that I'm lucky, still working on C++ desktop applications.
    • Night_Thastus 13 days ago
      Where I am, we still do!
      • freedomben 13 days ago
        What libraries are you using? Qt? Do you use anything for database access and rest API (or protobufs like we did) or just custom code?
        • Night_Thastus 13 days ago
          Qt for everything UI-related, yes. SQLite for databases, though looking again that code is actually Python. Nothing networked, so REST isn't relevant.
  • deeznuttynutz 13 days ago
    Over the past year, I've completed most of the second edition. It truly is an amazing book that has helped me overcome many mental barriers I've faced with programming for years. The main reason for the reduced size of this edition is the removal of 'Part IV: Broadening the View.' This section, which covers additional topics such as text manipulation, numerical computing, and embedded systems, is now available online. The chapters have not been updated from the second edition, as the topics are still relevant and utilize C++11/14.
  • dzogchen 13 days ago
    Sharing the C++ Annotations here, which is a continiously updated book on modern C++. http://www.icce.rug.nl/documents/cplusplus/
    • hnthrowaway0328 13 days ago
      If I just use C with classes, plus smart pointers and auto, for my emulator project(s), would that be a reasonably good approach?

      I once heard that the C++ language contains 4 components: the first catalog is "C", the second is for OOP, the third is for productivity and flexibility such as stl and templates, and the last one is for special cases such as volatile, asm, etc. He then recommends to use catalog 1 with care, and avoid scenarios that one has to use catalog 4. Does that make sense?

      • Night_Thastus 13 days ago
        I started off writing C++ this way, basically writing it like it was C89.

        This is fine if you do not plan to share your work with others, but it's not well-written C++. It will bite you later on. It's best to learn the C++ way of doing things. It will save you so much time and headache. Don't use character arrays, use strings. Don't use C arrays, use std::vector or std::array. Don't write your own lists or sets, use std::list/set or std::unordered_list/set. Don't use strcat when std::string operator + exists. Etc.

        I personally rarely use smart pointers or make_shared/make_unique these days. I just don't need pointers. Most of the time allocation can be done without them, and when I need to pass things around I use references. There are exceptions for C APIs for cross-platform/cross-compiler work, of course. And sometimes library code needs it, ofc.

        The STL and <algorithm> are your friend. They solve so many problems in a very elegant way. Learning them should be a priority.

        I'd go easy on the OOP elements unless you know OOP programming very well. Just using classes as containers for data and functions is more than fine for C++ most of the time.

        Writing your own templates can be a bit of a footgun until you understand them. Feel free to put that off awhile.

        Don't mess with volatile and asm unless you are 100% sure that what you're doing needs it.

        Also: Be cautious with use of auto. A bit here and there is fine, but too much and code can become unreadable. C++ is a typed language for a reason.

        • hedora 13 days ago
          In particular, you don't need volatile unless you're writing hardware device drivers. If you're doing that, then you also need to understand the semantics of the memory mappings of the I/O pages you're writing. You also need to know about bus ordering and request coalescing guarantees for PCIe (or AXI, or whatever your embedded system uses).

          If that paragraph doesn't make any sense, and you think you need volatile then there are basically two possibilities: You're writing a Java program (which uses that keyword for something else), or you need std::atomic (or __sync_* for C) instead.

          • gpderetta 13 days ago
            > (or __sync_* for C)

            Actually even C has _Atomic these days!

        • HarHarVeryFunny 13 days ago
          > Be cautious with use of auto. A bit here and there is fine, but too much and code can become unreadable.

          Yes, although one place where "auto" should almost always be used is to declare iterators (not that one should be needing them so much nowadays), and I think harmless for range-based for loops "for (auto i : v)" although as you say there's definitely a convenience/readability trade off.

      • HarHarVeryFunny 13 days ago
        Yes, roughly so.

        1) The major part of C to avoid is raw pointers and malloc, and generally anything where C++ has a more modern alternative. Don't use C datastructures (pointers, strings, arrays) where C++ replacements exist (smart pointers, std:string, std::array and std::vector, etc), or use C libraries where C++ replacements exist (e.g. C++ std::string vs C's string.h).

        Of course you can't avoid all of C, since the syntax of C++ is an extension of C.

        2) I wouldn't characterize what C++ adds to C as OOP. OOP is a design methodology, whereas the main addition C++ gives you is classes which are better thought of just as powerful and convenient type of data structure.

        The core feature of classes you always want to use are constructors and destructors. Any initialization of the class's data members should be done in the constructor (don't leave things uninitialized), and any final cleanup (releasing memory or locks, closing files, etc) should be put in the destructor so that it always happens (even if your program throws exceptions).

        Don't feel that just because classes support subclassing, polymorphism (virtual methods), etc, that you should be using them. They are there in case you need them, but if in doubt don't.

        3a) The STL is just the standard library for C++. You should always be using STL data structures (std::string, std::list, std::vector, std::map, etc) when applicable - not just "for productivity".

        3b) Templates (template classes, constructors/methods, functions) are not needed for most everyday use of C++. They are there for library writers, and on occasion for writing your own class and libraries. Think of them a bit like class inheritence - they are there in case you need them, but not something you should be reaching for unless there is no better way.

        4) C++ has a LOT of stuff (esp. libraries) that might be considered as "for special case use only". A rookie mistake might be to think that C++ has all this stuff - I should be using it! In general you should ignore the obscure stuff, and only use it when some special circumstance requires it.

        • tialaramex 13 days ago
          Although Microsoft refers to their implementation of the standard library as the STL (and this is convenient naming, since one of its most important maintainers is STL, Stephan T. Lavavej) actually the STL and the C++ standard library aren't the same thing.

          The Standard Template Library is Alexander Stepanov's generic programming achieved via the relatively new (at the time) C++ Templates feature. At this point (the late 1980s through early 1990s) Generic Programming is an obscure academic idea, it's not how normal software works. Stepanov is persuaded to present his library to WG21 ("the committee") in 1993 and their work is eventually standardised as C++ 98 a few years later.

          The most important part of the STL is the algorithms, generic algorithms are an amazing idea. The collections, eh, they're nothing to write home about, there are a dozen takes on the iterator problem with different trade-offs, but this idea of generic algorithms unlocks so much power and that's why lots of languages grew generics or for new languages had them on day one.

          • HarHarVeryFunny 12 days ago
            Sure, but that's really more of a historical perspective. The STL is still there as part of the standard library, although basically just the containers portion. It's been so long since I used the original standalone (SGI) version of the STL, that I can't even recall exactly what was in it other than containers and iterators (any algorithms?).
      • hedora 13 days ago
        These days, OO programing is mostly frowned upon. OO added the idea of implementation inheritance to interfaces, and that's mostly a bad idea.

        Newer languages and modern C++ favor composition instead. You define interfaces that provide some well-defined capability, and then you write things that wrap the interfaces to provide additional functionality. In C++ you can use templates to do this without any runtime overhead. In C, you can either use preprocessor macros (ouch) or you can build your own vtables. The vtable approach adds virtual method invocations all over the place, so it's not zero cost.

        The C++ approach actually isn't zero-cost either: You can end up having many copies of the same template logic, which blows up your instruction cache. One of the big innovations of swift was to avoid that. As far as I know, Rust macros and "go generate" produce binaries that are closer to the C++ approach.

        Anyway, especially for emulators, you should look into getting good with C++ template meta programming, or just learn rust and then use its implementation of generics. Both approaches will let the compiler inline the heck out of stuff that ends up in the inner loop. In particular, clang + gcc are both good at constant propagation.

        One problem with jumping straight from C to rust is that you basically have to already be able to write stable C++ code in order to get it to compile at all. The borrow checker moves subtle but common C++ errors from runtime to compile time. If you have a lot of experience with C already, the jump might be OK.

        (edit: I should add that C++ isn't standing still, and there are lots of cool efforts to backport the good ideas from Rust to it. Systems language competition is a good thing, and they're my two favorite languages!)

        • AnimalMuppet 13 days ago
          > These days, OO programing is mostly frowned upon.

          Only in certain circles. For the software world as a whole, "mostly" is rather an overstatement. (For that matter, for the software world as a whole, "mostly" is an overstatement no matter what claim follows the "mostly".)

          > OO added the idea of implementation inheritance to interfaces, and that's mostly a bad idea.

          There is more than one flavor of OO. Not all of them support implementation inheritance. You're using a feature of a sub-part to complain about the whole. (In fairness, though, this is a thread about C++...)

          Current best practice is "prefer composition over inheritance". There are places, though, where inheritance is the correct answer. When you hit those places, use it. Where it's not, don't use it.

        • jcelerier 13 days ago
          > You can end up having many copies of the same template logic, which blows up your instruction cache.

          linkers have been able to perform identical-code-folding optimizations for a few decades now

        • Jtsummers 13 days ago
          https://www.tiobe.com/tiobe-index/

          Without having to squint, 12 of those languages are easily categorized as OO languages. Given the mindshare of those 12 languages, I don't think it makes sense to say that "OO programming is mostly frowned upon." [emphasis added] Maybe it's frowned upon by some, maybe even many, but if it's mostly frowned upon then a lot of people must hate their work.

          • bmoxb 12 days ago
            They are, if I'm understanding correctly, referring to what may be considered the 'traditional' OOP style (Animal, which has various properties and behaviours, is extended by Dog, which has its own properties and behaviours, maybe overriding those of Animal) vs a style where inheritance is use primarily to define and implement interfaces (i.e., an expected set of behaviours with no implementation included in the base class). In other words, the different ways a language supporting OOP may be used rather than what the language supports in and of itself.
        • m_nyongesa 12 days ago
          Do you have a recommended link to a book or tutorial that teaches one how to do composition rather than inheritance in C++ (the way you are describing)?

          Thank you in advance!

    • Thorrez 13 days ago
      I get a 404
      • Jtsummers 13 days ago
        • repelsteeltje 13 days ago
          Link works for me (firefox 125), but only if I use http (port 80), port 443 get me 404 not found as well.
          • Jtsummers 13 days ago
            Ah, you're right. The issue is the link switching from http to https (even though the supplied link is http) and Chrome making it difficult (by default) to see whether http or https is being used. If I just copy/paste the link it works fine in Chrome and Edge but clicking on the link they both switch it to https. Brilliant.

            Just tested, works fine with Safari (mobile, but desktop usually has the same behavior).

            • repelsteeltje 13 days ago
              The webserver setup seems sloppy. If the site is http only, have https redirect to port 80 or remove the vhost altogether. Not great for an educational institution doing serious computer science.

              Chrome's attempt to use a secure connection resulting in 404 while the actual link works fine isn't great. But it's understandable and the TLS-first assumption the're using probably works just fine in the other 99.999% situations.

              If only they'd taken the time to copy the http config and setup let's encrypt or cert from GEANT Vereniging CA apparently preferred by rug.nl...

              • dzogchen 8 days ago
                Your browser is sloppy.
  • rubymancer 13 days ago
    I expected it to be even more of a tome, but surprisingly it's been cut in half!

    2nd edition:

    Paperback ‏ : ‎ 1312 pages

    Item Weight ‏ : ‎ 4.81 pounds

    3rd edition:

    Paperback ‏ : ‎ 656 pages

    Item Weight ‏ : ‎ 2.71 pounds

    • giaour 13 days ago
      From the preface, it looks like a bunch of the reference material has been cut from the book in favor of C++ documentation on the internet:

      "The third edition of Programming: Principles and Practice Using C++ is about half the size of the second edition. Students having to carry the book will appreciate the lighter weight. The reason for the reduced size is simply that more information about C++ and its standard library is available on the Web."

    • mirekrusin 13 days ago
      Nice to see C++ knowledge counted in pounds! :)
      • JAlexoid 13 days ago
        And it's 1229g for the rest of us.
      • kevindamm 13 days ago
        To be fair, someone should print the online reference material to get the real comparison.. it's not like we have fewer details in the standard library -- footnotes about compatibility with which version(s) and the related semantics could fill a book on its own.
    • kstrauser 13 days ago
      Literally exactly in half. Did they pick a smaller font or something?
  • bluedino 12 days ago
    Why does Bjarne only sometimes use a space after #include?

      #include<stdint.h>
      #include<list>
      #include <map>
      #include<unordered_map>
      #include <set>
      #include<memory>
      #include <algorithm>
    
    https://www.stroustrup.com/PPPheaders.h
    • lstamour 12 days ago
      Could be missed if there was a mix of typed by hand and auto-inserted by IDE headers, plus maybe a setting that collapses (folds) imports by default... and clang-format wasn't run on save? ;-)
    • frazar0 12 days ago
      Might be Morse code
  • CSMastermind 12 days ago
    A new version is extremely exciting.

    Even if you're an experienced programmer or have no interest in C++ you should still read this book.

    It's one of the best examples of technical writing and teaching computer programming that I'm aware of.

  • tiptup300 13 days ago
    I've always wanted to learn C++. I have a great handle on C#, making large applications and architectures as well as legacy refactoring in C#, and I would love to learn C++.

    I recently started at a company with a bit of a hairy c++ application that I would love to refactor or understand more thoroughly. Is this book a good place.

    Note that I have read a very basic book on C++ much more learning programming book, but got me introduced to the memory management concepts.

    As well I've been getting through Effective C++: 55 ways..., but this seems more like a tips and tricks and I don't think I'm getting much out of it.

    • dlachausse 13 days ago
      I personally recommend starting with Stroustrup’s other book…A Tour of C++. It really brings you up to speed quickly with what you need to know in the language without a lot of excess fluff. It’s also very up to date compared to other books.
      • justinhj 13 days ago
        I love that format, more languages should do it. One of the few pure language books I read cover to cover.
        • dlachausse 12 days ago
          I agree!

          Another approach I really like are interactive “notebook” style language tutorials. Swift Playgrounds is an excellent implementation of this.

    • MontagFTB 13 days ago
      Scott Meyers’ “Effective C++” series are digestible reads that cover the corner cases a modern C++ developer might hit, as well as guidelines and best practices to keep from shooting yourself in the foot.
      • jcelerier 13 days ago
        Those are starting to be pretty out-of-date. Proper C++23 code looks nowhere like code from Effective Modern C++ (published in 2014) just like you wouldn't expect C# or JS books from 2014 to be up-to-date with 2024 good practices - compare for instance Eloquent Javascript 1st edition (2011) and 4th edition (2024) : `let`, `const`, `use strict;` and a ton of other things taken for granted today weren't there.
    • ska 13 days ago
      I haven't read this new edition, but the previous ones are pretty decent for the why's and hows.

      If you want to work on your "hairy c++ application" you'll benefit from understanding how "modern c++" it is (and what your toolchain supports).

      Meyer's effective books are good with two caveats: first, they are really meant to improve practice for people who are already working in the language (e.g. don't do it that way, and here's why). Second, the older ones are now dated and some advice need updating to work with newer language spec.

      If 3rd edition of this one lives up to previous, it should be a pretty good read but as others have mentioned the "Tour of C++" book is a good entry.

    • on_the_train 13 days ago
      I would be wary of older literature. They're often full of classic polymorphism, something that modern c++ has largely moved away from.
  • slekker 13 days ago
    Sorry if it is a bit off-topic.

    If you just started learning C++, why did you choose it instead of another language? (Rust, C#, Go, etc)

    I know a bit of C but feel that the sheer "thickness" of C++ is too daunting and scary to even start.

    • npalli 13 days ago
      The most complex, demanding and cutting edge computational fields - Machine Learning, Artificial Intelligence, Real-time multi-user Gaming, High frequency Trading, Rendering/Animation, High Performance Computing, Compiler infrastructure (LLVM) - are all at the core written in C++ for the most part. There is no other option in the foreseeable future as the investment needed to rewrite (if you can find the people) is in the $100's of billions. So you will need to know C++ if we want to be the cutting edge and need extreme performance.

      On the other hand, if you don't need these "hard-core" features then any language will do. In fact, most of these have Python or other language interfaces so you don't need to know much C++.

      • tialaramex 13 days ago
        > So you will need to know C++ if we want to be the cutting edge and need extreme performance.

        I would suggest a better phrasing might be that you should learn C++ if you want to cling to existing software in the state it is today, certain that history ended yesterday and the future is just the same forever from here on.

        You won't get "extreme performance" from C++ because it is buried under the weight of decades of compatibility hacks.

        • CyberDildonics 12 days ago
          I don't even know what you are trying to say here. C++ is great to program in and has a fantastic eco system of tools and libraries. It is something you can safely base a business around.

          You won't get "extreme performance" from C++ because it is buried under the weight of decades of compatibility hacks.

          This doesn't even make sense. What is an example of something that can't be fast because it is done in C++? What "compatibility hacks" are slowing programs down?

          This does not sound like something someone with experience in C++ would say.

          • tialaramex 12 days ago
            > This doesn't even make sense. What is an example of something that can't be fast because it is done in C++? What "compatibility hacks" are slowing programs down?

            Let's look at two very different perf leaks in ISO C++. Firstly move assignment which is right at the heart of the language. Initially C++ doesn't have move semantics at all, which is a problem because in a bunch of cases that's key to "extreme performance". So in the "lost decade" period between C++ 03 and C++ 11 considerable work was done to figure out a way to unlock this, but of course C++ insisted on backwards compatibility with the code written for C++ 98 with no such semantic.

            The result is that the actual move semantic people wanted can't quite be done, this is now called "destructive move" and proponents of the compatible option C++ 11 and later had claim it's equivalent to the move they delivered, plus delete. But that's... disingenuous. The C++ 11 move is actually (move + create), so to build "destructive move", when that's what you need, you must write (move + create) + destroy. Sometimes the compiler can see what's happening here and emit the same machine code you'd get in a language with native move semantics, but sometimes it has no way to figure this out, and you're emitting move + create + destroy, which is markedly slower as well as of course being more error prone.

            Secondly right up at the surface, where we can feel the rain, and appropriately something Bjarne Stroustrup (author of the book we're talking about here) has noticed himself, the provided growable array, std::vector lacks the bifurcated reservation. Vec::reserve_exact isn't enough, you need Vec::reserve as well for good performance with a growable array API, but C++ doesn't provide this, it provides only Vec::reserve_exact under the name "reserve" and there's no room to offer both in the compatible API, which means as a user/ application programmer this fundamental type is a small perf leak.

            Bjarne shrugs this off, oh well, just don't use the reserve API to get performance benefits. But everybody else can do so, this choice means C++ is leaving it on the table for somebody else with a better growable array type.

            Finally though, I want to look at a beacon over the horizon, where "extreme performance" really is something they're thinking about. Iterator Loops (sometimes "Chunk Loops") are a technique where the language lets you directly express in your definition of a loop how it can be performed in a SIMD-fashion, so e.g. you write the code to search an N byte buffer for the byte you're looking for, but then revisit that loop and also write code for searching N=M*16 bytes, using 16 bytes at once. This lets you write, in a high level language, code which will be easy for a compiler to SIMD accelerate without fragile idiom recognition. C++ of course does not provide Iterator Loops and instead you'd reach for manual inline assembler in these cases today.

            • CyberDildonics 12 days ago
              Who is filling your head with all this? I have never seen any program slow down over a move, because you should be moving enough data that copying a pointer doesn't matter anyway. This is trivial stuff. Show me in an actual program somewhere that shows what you're talking about.

              Vec::reserve_exact isn't enough, you need Vec::reserve

              Reserve reserves the amount that you give it. This isn't hard or complicated. What exactly do you think it should do differently, and how hard would it be to write your own? Vector is a simple data structure. Anything you don't like about it isn't a language limitation.

              this fundamental type is a small perf leak

              Show me a program that illustrates what you are talking about.

              I want to look at a beacon over the horizon,

              You can do this with intrinsics or libraries that use intrinsics.

              the language lets you directly express in your definition of a loop

              This isn't a performance limitation it's a convenience you want integrated into the language. There is one that does this, it's called ISPC. Is that what you use?

              This seems to me like you've gone down some sort of anti C++ rabbit hole where people who don't know what they're doing get worked up about things that don't matter.

              Meanwhile in the standard library there is actually the unordered_map design which is stifled by algorithmic complexity requirements, but people use flat maps to get around that.

              • tialaramex 12 days ago
                > I have never seen any program slow down over a move

                I'm sure, and yet the people who care have noticed that C++ is slower, that's what P1144 and P2786 and so on are trying to solve, without quite saying "destructive move" out loud.

                Here's the current iteration of P1144: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p11... Like pointer provenance this is something WG21 would prefer not to think about because it's embarrassing, so it has hung around like a bad smell for quite a few years but I suspect (unlike provenance work) it'll get into C++ 26 in some form.

                > Reserve reserves the amount that you give it. This isn't hard or complicated. What exactly do you think it should do differently

                It's OK, after all Bjarne Stroustrup didn't see this either, but you've missed something quite important

                The whole idea of this type is amortized constant time growth, typically via doubling although any fixed ratio would work and there could be a benefit to choosing other ratios in principle (Folly has a long paper about this). For this purpose it's crucial that capacity doesn't grow linearly. But if our only reservation mechanism is Vec::reserve_exact (aka C++ reserve) we end up with linear growth. Bjarne's solution is to abandon use of reserve for performance, but we can do much better by just bifurcating the API as Rust did (and as some other languages do)

                I started writing a program to illustrate this, but it's probably easier to just spell it out with an example. Suppose we receive Doodads over the network, they arrive in groups of say up to 20 Doodads at a time, and we don't know in advance how many there will be, until the last group indicates it's the end of the Doodads. Typically in total there's maybe 40-50 Doodads, but there can be as few as five (one group of just five) or as many as a thousand. We're going to put all the Doodads in a growable array as we receive them. Let's walk through receiving 19, 14, 18, 12 and finally 6 Doodads.

                Bjarne says don't bother with reservation as in C++ this doesn't work for performance, so we just use the "natural" doubling. Our std::vector allocates space for 1, 2, 4, 8, 16, 32, 64 and finally 128 Doodads (eight allocations), and does a total of 127 copy Doodad operations. Surely we can do better knowing what's coming?

                If we ignore Bjarne's advice and use C++ std::vector reserve to reserve for each group, we allocate space for 19, 33, 51, 63 and finally 69 Doodads (five allocations), and we perform 19 + 33 + 51 + 63 = 166 copy operations. Fewer allocations, more copies.

                If we have the bifurcated API, we allocate space for 19, 38 and 76 Doodads (three allocations) and we do 19 + 33 = 52 copy operations. Significantly better.

                > This isn't a performance limitation it's a convenience you want integrated into the language

                I disagree and the results speak for themselves.

                > There is one that does this, it's called ISPC. Is that what you use?

                I've never used ISPC. It's somewhat interesting although since it's Intel focused of course it's not actually portable.

                > This seems to me like you've gone down some sort of anti C++ rabbit hole where people who don't know what they're doing get worked up about things that don't matter.

                It's always funniest to read about what "doesn't matter" right before it gets fixed and suddenly it's important. The growable array API probably won't get fixed, education means that Bjarne's "Don't use reserve" taints a whole population so even if you fix this today it'd be years before the C++ programming community use reserve where it's appropriate but I expect "relocation" in some form will land, and chances are in a few years you'll be telling people it's why C++ has "extreme performance"...

                • CyberDildonics 12 days ago
                  You said You won't get "extreme performance" from C++ because it is buried under the weight of decades of compatibility hacks.

                  Now your whole comment is about vector behavior. You haven't talked about what 'decades of compatibility hacks' are holding back performance. Whatever behavior you want from a vector is not a language limitation.

                  You could write your own vector and be done with it, although I'm still not sure what you mean, since once you reserve capacity a vector still doubles capacity when you overrun it. The reason this is never a performance obstacle is that if you're going to use more memory anyway, you reserve more up front. This is what any normal programmer does and they move on.

                  Show what you mean here:

                  https://godbolt.org/

                  I've never used ISPC. It's somewhat interesting although since it's Intel focused of course it's not actually portable.

                  I guess now the goal posts are shifting. First it was that "C++ as a language has performance limitations" now it's "rust has a vector that has a function I want and also I want SIMD stuff that doesn't exist. It does exist? not like that!"

                  Try to stay on track. You said there were "decades of compatibility hacks" holding back C++ performance then you went down a rabbit hole that has nothing to do with supporting that.

                  • tialaramex 11 days ago
                    Actually first my comment explicitly talks about move, but you just decided you don't care that C++ move has a perf leak and claimed that you didn't notice so therefore it doesn't count, which I guess could equally apply to somebody who wants to claim Python has extreme performance, or Visual Basic.

                    I deliberately picked two examples from ends of the spectrum, a core language feature and then a pure library type. Both in some ways of equal practical performance necessity.

                    > The reason this is never a performance obstacle is that if you're going to use more memory anyway, you reserve more up front.

                    We often don't know how big a growable container will finally be when we're adding things to it, and so without travelling back from the future to tell ourselves how big it will grow this is useless even though we know how much we're adding right now. This is the essence of the defect in std::vector

                    Here's the demonstration I wrote about in my previous post, no I am not going to build a replacement for std::vector with the correct API in C++ so this is Rust where the appropriate API already exists. It provides a policy knob, so you can pick Bjarne, Cpp or Best in the main function to see what happens for yourself.

                    https://rust.godbolt.org/z/16qooGo69

                    • CyberDildonics 11 days ago
                      you just decided you don't care that C++ move has a perf leak and claimed that you didn't notice so therefore it doesn't count, which I guess could equally apply to somebody who wants to claim Python has extreme performance, or Visual Basic.

                      Are you seriously implying copying a pointer makes C++ like python or visual basic in speed? Where did you even get these ideas? Show me any program anywhere, any github ticket any performance profile where a C++ move is somehow a performance problem.

                      I looked at your link and I still have no idea how doubling the size of std::vector "destroys" amortization. The std link you had before wasn't even about this, it was about memcpy.

                      Please link the origins of where you are getting this stuff. It doesn't sounds like there is some niche rust forum where people are looking for anything, no matter how far fetched to pretend C++ has a performance problem.

                      Meanwhile literally everything that needs performance is being written in C++. Why aren't codecs and browsers and games written in something else?

                      • tialaramex 11 days ago
                        > Are you seriously implying copying a pointer makes C++ like python or visual basic in speed?

                        No, but I get the feeling you really do think that "copying a pointer" is somehow what's at stake here which suggests you've badly misunderstood how move works on C++ in general.

                        > Show me any program anywhere, any github ticket any performance profile where a C++ move is somehow a performance problem.

                        There's a CppNow talk from 2018 or so in which Arthur demonstrates a 3x perf difference. That's obviously an extreme case, you're not magically going to save most of your runtime by fixing this in most software, but it shows this is a real issue.

                        Since you're the one who believes in "extreme performance" you're probably surprised fixing this wasn't a priority. But P2137 gives a better indication of the status quo, or rather, what happened to the paper does rather than what's inside it. You can read the paper if you want (if you don't recognise at least most of the authors that means you're way past your depth for whatever that's worth) https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p21... -- WG21 gave a firm "No" to that paper, which is what it was for. C++ is not a language for "extreme performance". It's a language which prizes backwards compatibility. The authors, or rather their employers, needed to be explicitly told that. No, if you want perf you are in the wrong place just as surely as if you want safety, use a different language. C++ is for backwards compatibility with yet more C++.

                        > It doesn't sounds like there is some niche rust forum where people are looking for anything, no matter how far fetched to pretend C++ has a performance problem.

                        Indeed, this isn't the product of a "niche rust forum". It's WG21, the C++ Standards Committee.

                        I think the problem is on your end, C++ demands a very high price in terms of safety, ergonomics, learning curve - and to some people that means it ought to be really good. Otherwise why such a high cost? Those are the same people who figure if they paid $500 for a T-shirt that must mean it's a good T-shirt. Nah, it just means you're a sucker.

                        > Why aren't codecs [...] written in something else?

                        This is especially frustrating because C++ is an incredibly bad choice for this work, as you'll have seen with the incidents at Apple. Nobody should be choosing the unsafe language with less than stellar performance to write codecs in 2024, and yet here we are.

                        And yet, most of the time when somebody even realises they shouldn't write codecs (and file compression and various other similar technologies) in C++ their next guess is Rust which while obviously an improvement over C++ is hardly a good choice for this work either.

                        The sad truth is that often it's inertia. We used this crap C++ code in 2008, and we re-used it when we refreshed this product in 2018, so it's still C++ today because nobody changed that.

                        • CyberDildonics 11 days ago
                          All these rants are a classic case of some sort of emotional investment that isn't about evidence. Your links and evidence either don't apply to what you're talking about or they are vague references to "find it yourself" in something large.

                          First, you are now ignoring your own claims that "amortization is broken" when your own link just showed normal doubling and I asked what was supposed to be wrong. Your link before was about a trivial copying attribute not the doubling of a vector's size.

                          There's a CppNow talk from 2018 or so in which Arthur demonstrates a 3x perf difference.

                          A "3x perf difference" compared to what? Prove it and link a timestamp. This barely makes sense. It's a vague claim with vague evidence.

                          It's WG21, the C++ Standards Committee.

                          Now your evidence that "fixing this" (no specific of what 'this' means) is linking the entire 2020 iso C++ plan? This is one step removed from the classic "I'm not going to do your homework, google it yourself".

                          I think the problem is on your end, C++ demands a very high price in terms of safety, ergonomics, learning curve - and to some people that means it ought to be really good. Otherwise why such a high cost? Those are the same people who figure if they paid $500 for a T-shirt that must mean it's a good T-shirt. Nah, it just means you're a sucker.

                          This seems like some personal frustration. When I write C++ it's very simple and direct. Small classes, value semantics, vectors, hash maps and loops.

                          Then your 'answer' is that nothing is good enough and nothing works. You say C++ is a bad choice for codecs, yet half the planet is using video codecs written in C++ all day every day. You ignore browsers and games being written in C++ too. You have no solutions, it's just that everything sucks but you can't be bothered to even write your own vector.

                          This is just your frustrations wrapped in rants with some hand waving non evidence to act like it's based on something other than emotion.

                        • 6equj5 11 days ago
                          > And yet, most of the time when somebody even realises they shouldn't write codecs (and file compression and various other similar technologies) in C++ their next guess is Rust which while obviously an improvement over C++ is hardly a good choice for this work either.

                          Not C++ nor Rust?! What then, tia? C? Ada??

            • _gabe_ 12 days ago
              In addition to what CyberDildonics already said, C++ is also an (almost) superset of C. You can also inline assembly. If you find particular hot loops that need to be optimized at any point while profiling, it’s trivial to drop down levels of the stack to get the extreme performance you may need. There is no FFI needed in C++ to drop down a level. There is no barrier at all. You can write your code directly for the CPU, inline it into your code, and fine tune it as much as you want. I don’t know how that wouldn’t qualify as extreme performance.
              • tialaramex 12 days ago
                > You can also inline assembly.

                That's not C++ any more, you can inline assembly into several other languages for whatever that's worth, which isn't much in this context. "But I could use assembly language" is no more C++ having "extreme performance" than "But I could book a minicab" would give the London Underground "24/7 service".

        • slekker 13 days ago
          A more extreme version of this would be COBOL right? Even if people stopped writing C++ today the amount of code that's already written will last many lifetimes.
          • tialaramex 12 days ago
            Sure, I do not advise people to go learn COBOL either. In fact, I never learned COBOL, they were writing COBOL at the first place I "worked" as a teenager† and it was clearly not the future.

            † in the UK there was a discrepancy between what happens to the sort of teenager who exhibits talent and interest in an area like writing software, who is sent to just watch adults doing that and mostly doesn't do any actual work themselves as "Work Shadowing", versus those whose direction seems more... manual who are expected to actually go do stuff in the same period, supervised by adults of course, but still very much doing the actual work, "Work Experience". This seems very obviously unfair, although of course as the teenager who wasn't expected to actually do much I wasn't complaining at the time...

            • boppo1 12 days ago
              What is the future?
              • tialaramex 12 days ago
                What is the future now? Or what was the future when I was watching grown-ups programming in COBOL over thirty years ago?

                Thirty years ago the future was C++. How did that work out? Seems like it was pretty popular, this thread is about the third edition of a book about it.

    • jandrewrogers 12 days ago
      There are still some high-performance software domains where (modern) C++ is unambiguously the best tool for the job. Database engines are a good example of this, they pervasively break the compiler's understanding of object lifetimes which requires flexibility in the language that C++ can explicitly express in an ergonomic way.

      No one learns all of C++, you just need to learn the bits that are useful for the kinds of applications you write. If, for example, you are building database kernels then you are unlikely to use any of the STL containers (even std::array and std::vector are infrequent) in most of the code. However, you will need to know how to manually fix-up object lifetimes using semi-obscure language features you would never need to know about for most server apps.

      If you stay within a relatively narrow application domain, the useful parts of C++ for that domain crystallize pretty readily in my experience, which is much easier to learn.

      • jstimpfle 11 days ago
        I would be interested how you "fix-up object lifetimes"?
        • jandrewrogers 11 days ago
          Sure, it is pretty simple, just esoteric.

          The compiler attempts to track object lifetimes for the purpose of optimization e.g. if the object contains a notionally immutable value it doesn’t have to re-read the value during the object’s lifetime. A lot of compile-time code optimization is based on knowing when an object at a memory address is changed or destroyed. If the objects don’t get destroyed but merely disappear, or worse, are replaced with a different object at the same address, and the compiler can’t see that at compile-time then the compiler assumes it doesn’t happen. This violates strict aliasing rules in C/C++ even though there are legitimate reasons for this to occur. C/C++ systems code, like Linux, commonly disable strict aliasing rules because it causes undefined behavior, even though it also disables certain optimizations.

          In the last several revisions of C++, they have added blessed methods of informing the compiler when these object lifetime rug-pull situations occur, so that it can optimize around them without disabling the optimizations enabled by strict aliasing. This includes functions like std::launder, which acts like a constant folding barrier i.e. the compiler can’t assume that constants at that address prior to the barrier call are still operative when generating code. There are a couple other functions in C++23 that explicit take a memory address and explicitly start a new lifetime with an arbitrary type, without constructing a type at that address; these are no-ops, all of these functions are compiler annotations, they don’t generate code. These are blessed ways of doing more hack-ish ways of effecting the same result in recent versions of C++ (e.g. the memmove/launder trick). In old versions of C and C++, the ways of doing this were technically undefined behavior but the compiler writers unofficially provided ways to work around this that would behave as needed since it had valid use cases, which is not a great way to work.

          This doesn’t just affect lifetimes, though that is most of what the fix-up is about. Mutability of references is similarly fuzzy and it is impossible for a good design to guarantee that multiple mutable references don’t exist, so you need other mechanisms to guarantee they never conflict. However, these fix-ups are above the level of the compiler.

          In the extreme case of database kernels, most objects have an ambiguous lifetime and uncertain address. Consequently, you have to create object reference wrappers that hide what is required to ensure strictly defined behavior in these cases and to ensure conflicts can’t happen. Wrapping your object references with some small hygienic functions can eliminate the issue.

    • spacechild1 13 days ago
      I started because I became interested in graphics and audio programming. Audio plugin development in particular is completely dominated by C++.
      • cuanim 13 days ago
        Do you have any recommendations for someone interested in audio programming?
        • spacechild1 12 days ago
          Personally, I started by writing externals for Pure Data, then started to contribute to the core. Later I took the same path for SuperCollider.

          You may start with simple audio plugins. Have a look at JUCE (https://juce.com/)!

          Realtime audio programming has some rather strict requirements that you don't have in most other software. Check out this classic article: http://www.rossbencina.com/code/real-time-audio-programming-...

        • cageface 12 days ago
          The Will Pirkle books are good.
  • FrustratedMonky 13 days ago
    I love this book. I wish other languages had something similarly held in high regard to provide some touchstone.

    Is there something like this for Rust?

  • aquir 12 days ago
    Great but I am unable to find an IDE or compiler that supports C++ 20 and every one of them complains about import std;

    Any recommendations?

  • skilled 13 days ago
    Excellent! I have recently started doing the learncpp.com tutorial and I think this book might have come at the right time.
  • dmarchand90 13 days ago
    Can anyone recommend a good book for numerical c++ in 2024?
    • AlexeyBrin 12 days ago
      Maybe Discovering Modern C++ 2nd edition. But check the table of content before buying, it may be too beginner level for you.
  • aero-glide2 13 days ago
    This is the book i used to learn programming 10 years ago! After that I never really learnt anything new.. been using the same concepts.
    • nocoiner 13 days ago
      Did you use it to learn programming as a novice to the field? I have always wanted to learn programming as a hobby, but never really found the right entry point. Would you recommend this?
      • AlexeyBrin 12 days ago
        For hobby programming, Python is the best (unless you want to do web development in which case JavaScript is what you want). For Python, a really good book for beginners is Python Crash Course.
      • semanticc 13 days ago
        I would start with Python instead of C++, if you just want to learn a useful tool as a hobby. The official tutorial is a good starting point: https://docs.python.org/3/tutorial/index.html
      • boppo1 12 days ago
        This is a solid entry point, though you'll get more immediacy out of learn python the hard way. However starting with python (like I did) will 'leave things out' and Principles is great for filling those holes.
  • OnionBlender 13 days ago
    My problem with newer C++ books is that all of my projects are stuck using C++17.
    • nicce 13 days ago
      If they are purely your projects, then it is just a matter of will :-D
      • OnionBlender 12 days ago
        I mean the work projects I work on. Mostly Android NDK stuff that uses C++17.
  • zerr 13 days ago
    Are there any university lectures/videos based on this book?
  • dboreham 13 days ago
    First edition was the right thickness imho.
  • uwagar 12 days ago
    why not P3 instead of PPP3?
  • mindcrime 13 days ago
    Huh. The ISBN shown at the top of the page (currently "9780136816485") appears to be incorrect. That seems to be the ISBN for "A Tour of C++" from 2022. The ISBN for this book is, according to the Amazon product page[1], "9780138308681".

    [1]:https://www.amazon.com/Programming-Principles-Practice-Using...

    Edit: emailed Mr. Stroustrup and he just replied to say that the bad ISBN has been corrected.

    • sebstefan 13 days ago
      Already teaching you about the maintainability of tightly coupling different parts of your system before you've even opened the book
      • arrowleaf 13 days ago
        It would have been awesome if that ISBN issue were an actual ISBN re-use issue. I've run into issues coupling my system's design to the assumption that ISBNs uniquely identify a single edition of a single book. The intent of ISBNs are to be unique, but mistakes are made and resellers lose track or straight up abuse some ISBNs.
        • lstamour 12 days ago
          Not just that but when ISBNs were first introduced, it was common thought that they were used for cash register price scanning rather than computer-controlled inventory, so a number of early books had ISBNs re-used by publishers and it wasn't caught because they were meant to be the same price. These days you often see two barcodes on books, one is the ISBN and the other is the price.
    • b33j0r 12 days ago
      Darn, I don’t think Bjarne sends $2.56 checks.

      I think you just earned yourself a coveted check for `sizeof(attaboy)`, and I’m jealous.

      • mindcrime 12 days ago
        Just being able to say that I got a response from Bjarne Stroustrup is reward enough in its own right!
        • dlachausse 12 days ago
          Actually he does respond to emails and he is responsive to constructive feedback from my experience.
      • beryilma 12 days ago
        I still remember "reading" his entire 1000-page C++ book for the sole purpose of finding an error on it, for which I was handsomely rewarded with a $32 check from Bjarne. Still not cashed. Good times...
    • layer8 13 days ago
      Even Stroustrup falls prey to copy&paste programming.
  • Mikhail_K 13 days ago
    [flagged]
    • riazrizvi 13 days ago
      It helps to understand the rationale behind the language choices. Though, sure, if Linus Torvalds ever put substantial effort into writing a concise book on programming in C, I’d choose that over Kernigan & Ritchie’s great starter book.
    • bregma 13 days ago
      Well, he's articulate and very experienced with software development who invented the original C++ out of necessity. In fact, he sounds like an ideal person to tech good programming practices using the language he helped design.
      • Kranar 12 days ago
        OP is making a dig at C++ the language. A lot of people, most likely OP included, consider the language to be a monstrosity, so how can the person who developed such a monstrosity possibly share good advice on programming?

        That said, I sometimes get the impression that Bjarne recognizes the monstrosity that he created and a large part of his talks and his book is how to make use of the good parts of C++ without making use of the bad parts.

    • layer8 13 days ago
      Maybe you should read his books.
    • zerr 13 days ago
      TC++PL book is full of wisdom in general programming, easily transferable to other languages.
    • anonymous_union 12 days ago
      c++ is so bad. when i see threads like this one praising it, i feel bad for all the mental energy these people have put into understanding an unorganized and unelegant garbage dump of ideas. even his coworkers at bell labs tried to convince him c++ was a bad idea.

      ken thompson wouldn't use it. then he invented go to spite him.