Live data from Hacker News

3rd Edition of Programming: Principles and Practice Using C++ by Stroustrup

stroustrup.com

201–210 of 231 posts

Re: 3rd Edition of Programming: Principles and Practice Using C++ by Stroustrup

#201
post #136

Earlier quoted context omitted.

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. 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::thi…

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.

Re: 3rd Edition of Programming: Principles and Practice Using C++ by Stroustrup

#202

Earlier quoted context omitted.

> 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…

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 ex…

> 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"...

Re: 3rd Edition of Programming: Principles and Practice Using C++ by Stroustrup

#203
post #188

Earlier quoted context omitted.

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

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.

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!

Re: 3rd Edition of Programming: Principles and Practice Using C++ by Stroustrup

#204
post #186

Earlier quoted context omitted.

> 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…

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 so…

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.

Re: 3rd Edition of Programming: Principles and Practice Using C++ by Stroustrup

#205

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 whic…

would this help with your problem with modules, it's referenced on the book's page: https://www.stroustrup.com/module_use.html ?

> 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’?

Re: 3rd Edition of Programming: Principles and Practice Using C++ by Stroustrup

#206

Earlier quoted context omitted.

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 ex…

> 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 beca…

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.

Re: 3rd Edition of Programming: Principles and Practice Using C++ by Stroustrup

#207

Earlier quoted context omitted.

> 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 beca…

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…

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

Re: 3rd Edition of Programming: Principles and Practice Using C++ by Stroustrup

#208
post #34

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.

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 o…

I would be interested how you "fix-up object lifetimes"?

Re: 3rd Edition of Programming: Principles and Practice Using C++ by Stroustrup

#209

Earlier quoted context omitted.

I wonder what Stroustrup thinks about the Meta Object Compiler. In a way Qt is its own dialect of C++.

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

> 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.

Re: 3rd Edition of Programming: Principles and Practice Using C++ by Stroustrup

#210
post #134

Earlier quoted context omitted.

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...

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 indep…

> 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.

Post reply on HN