Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Nice list ... but that doesn't mean you understand what you have listed. Your list reads like what a noob "Modern C++" programmer would focus on (keywords and features to get through an interview) rather than any long-term (i have been programming in C++ since early nineties) real work experience.

Lots of good C++ based systems have been written before any of the above existed. That proves that they are not "needs" but merely "wants". Only some in the above list are worth adding to the language while others are just noise (as an example keywords like "override"/"default"/"nodiscard" just add to syntactic noise rather than any actual benefit). The members of the ISO C++ committee simply pushed through their pet "wants" for brownie points.



When override was introduced it immediately solved a few hidden bugs here so it definitely has value. I'd say that when doing development with inheritance it catches at least a bug or two a month at compile-time. Same for nodiscard, I started using it recently and immediately found bugs. So for me their value is infinite


As a counter anecdote i have not found any uses for the above and yet my code is running perfectly fine. That just reinforces my point that they are "wants" and not "needs".


Well, that is ok. It depends a lot on your codebase.

The fact is that you will have to check by hand or inspection what the compiler can tell you, right? That saves time and effort. Especially when refactoring.

Go refactor the signature 2 or 3 virtual functions with let us say a couple parameters each in two classes and 4 or 5 derived classes, one two levels deep (this is real code what I am talking about) and do it with and without override.

Try to measure the time it takes you with or without override keyword. You could use some refactoring tool, fair. But you do not have that available in every context.


>Go refactor the signature 2 or 3 virtual functions with let us say a couple parameters each in two classes and 4 or 5 derived classes, one two levels deep (this is real code what I am talking about) and do it with and without override.

This is just trivial and does not really support your arguments.

The way it was done before was to use the "virtual" prefix keyword for virtual functions across the entire class hierarchy. Merely a discipline which was enforced religiously via coding guidelines; it gave the programmer the needed cue while the compiler doesn't care. You then did a Search and Replace as needed.


How can you claim you do C++ and not evwn know that virtual did NOT check if it was an override of what you wanted or you were introducing an entirely new function? Your understanding of C++ is quite poor. You have a wrong mental model even about how virtual functions worked. There was no way for the compiler to say you were overriding or not hence now way to emit an error!!No religions here, just objectively better features. I bet you did not refactor hierarchies pre and post-C++11 otherwise you would not say that. It is not that trivial and marking overrides catches all intents of fake overrides. Before that was not possible.

Seems suspicious to me that you claim to have used C++ for long. You do not understand even how virtual functions worked in the language.


You are making inflammatory statements without understanding what has been written; it is not appreciated;

I said;

>to use the "virtual" prefix keyword for virtual functions across the entire class hierarchy.

What is meant is that the entire signature of the virtual function including the "virtual" keyword is reproduced in all derived classes thus ensuring that no mistakes are made.

I also said;

>it gave the programmer the needed cue while the compiler doesn't care

It was just good programming discipline rather than depending on compiler crutches.

Just to drive it home; here is an example: https://stackoverflow.com/questions/4895294/c-virtual-keywor...


> The way it was done before was to use the "virtual" prefix keyword for virtual functions across the entire class hierarchy. Merely a discipline which was enforced religiously via coding guidelines

No, that did not enforce safety or solved the refactoring problem I told you. It seems you do not want to listen that override fullfills the case where you assert that you are overriding (and it will be a compile error). You have a misunderstanding and a wrong mental model for how virtual worked. It did not enforce anything, just declared a virtual function, no matter it was new or an override. virtual can introduce a new virtual function by accident.

Example:

    class MyClass {
    public:
       virtual void f(int) {}
    };

    class MyDerived : public MyClass {
    public:
       virtual void f(int) {}
    };
Refactor:

    class MyClass {
    public:
       // NOTE: signature changed to double
       virtual void f(double) = 0;
    };



    class MyDerived : public MyClass {
    public:
       // FORGOT TO REFACTOR!!! STILL COMPILES!!!
       virtual void f(int) {}

       //void f(int) override {} // COMPILE TIME ERROR!
    };
> You are making inflammatory statements without understanding what has been written; it is not appreciated

No, I was not. I was just showing you do not know how the mechanism works with facts.

Above you have an example of why what you say does not work. I would recommend to talk more concretely and not to make too broad statements about tools you seem to not know in detail but it is up to you, I would not stop you. Just a friendly recommendation ;)


Have you really not understood what was written or are you just arguing for the sake of it? I cannot be spelling out every step of trivialities.

btw - Anybody who has been following this chain of responses can see who is the one using inflammatory language to hide their lack of comprehension and knowledge.

For the last time;

1) We did not depend on compiler crutches to help us.

2) We enforced coding discipline religiously so that all virtual functions are unambiguously identified with full signatures across the entire class hierarchy.

3) When you need to refactor you did simple search/replace on the full signature using grep/ctags/cscope/whatever across the entire codebase.

That is all there is to it.

This might be the most valueless discussion i have had on HN and that too over a utter triviality...sigh.


> 2) We enforced coding discipline religiously so that all virtual functions are unambiguously identified with full signatures across the entire class hierarchy.

> 3) When you need to refactor you did simple search/replace on the full signature using grep/ctags/cscope/whatever across the entire codebase.

That can break in a ton of ways. Still. For example, if the pattern is not correct for grep. ctags/cscope does not fully understand C++ also AFAIK. Then you are shifting from debug your code to debug your greps, etc.

Not sure how you did it exactly, but I see it as a fragile practice. Because you rely on absolute human discipline.

> This might be the most valueless discussion i have had on HN and that too over a utter triviality...sigh.

Sorry for that. Feel free to not reply. But do not take it to the emotional terrain so fast. I just argued since the start that C++ improvements are not an accumulation of "pet features" for the sake of it. It is you who presented that as facts without any kind of evidence in the first place.

To be clear, I do not care about C++ that much or anything particularly. But I have used it enough to identify one of your top posts as emotional and non-factual.

Greetings.


Your comment comes across as insincere. It reads like you have realized the triviality involved but not admitting it and still arguing that somehow programming discipline is not enough in this case (do we really need to talk about how to specify grep patterns?).

I should have probably said something like "override is just a compiler crutch for lazy programmers who can't be bothered to be careful in their job" but i thought it might get me banned from HN :-)

>It is you who presented that as facts without any kind of evidence in the first place.

My comments just in this whole thread refute your above statement.

>But I have used it enough to identify one of your top posts as emotional and non-factual.

I don't think you have understood the motivations behind the features you claim to have used, how they were solved earlier without those features and properly judging whether the change was worth it.


> Lots of good C++ based systems have been written before any of the above existed. That proves that they are not "needs" but merely "wants".

By the same argument, plenty of good code was written in C before C++ existed, so the entirety of C++ is "wants" rather than "needs".


Yes, In a very strict sense it is true for many experienced programmers and their domains of expertise. So when a expert embedded systems guy tells me that he will not touch C++ for his project, i understand and only ask him to look at C++ as a "Better C" and nothing more. All features are not equal and some are obviously more beneficial than others eg. simple user defined types i.e. class value types vs class hierarchies.

A good example is Linus Torvalds opposition to the use of C++ in the Kernel.


I do understand what I listed bc I basically have been doing C++ for a living for 13 years and started 20 years back at uni.

Of course good systems have been designed, but try to use the stl without lambdas. Or return big values by pointer bc u dnt have value semantics with all its associated usability problems. Try to write sfinae vs concepts or write a std::optional type without C++23 explicit self. Try to go and add boilerplate for free bc you did not have delegated constructors. Or try to build a table inside C++ at compile-time pre-constexpr. Do generic programming withou if constexpr. I have done myself all of that before C++11 and it was way more difficult to write a lot of code. Of course under your view anything is "nice to have". Then just grab assembly. But for the people like me that use it, I'd rather see it evolve with useful features.

Those keywords do NOT add noise. They add safety, since defaults cannot be changed. C++ is as good as it can get with its constraints. You can think it is bad, but C++ is an industrial language, real-world and with compatibility as a feature.

I can buy you could disagree with some of the decisions, but mostlyit fullfills well its purpose. Herb is just trying to create a C++ 2.0 that is simpler and 100% compatible. It is good, very good to not start from scratch if you are in industrial envs. You just do not throw away 40 years of code that has tested the pass of time pretty well, no matter it was written in C or C++.


I am not sure that you have understood my comment, hence let me explain;

I am a longtime programmer firmly in the C++ camp (as an example, see one of my earlier comments here: https://news.ycombinator.com/item?id=27854560). I am also not against the evolution of the language. But what I (and many other C++ programmers) are against is the messianic zeal of the "Modern C++" proponents hellbent on changing the language to be more "user-friendly" like Python/whatever in a mistaken belief that "C++ programming is now made simpler". By adding more and more features the interaction between them is now only more complicated then ever (i.e. When and How do you use them correctly and efficiently? How do you combine them into a clean design?) making the programmer's job that much more difficult (as an aside, this is also the reason beginning/new-to-C++ programmers give up on the language).

The above problem is compounded because C++ is already a multi-paradigm and multi-usage language i.e. situated in a co-ordinate plane with the above axes.

The paradigm axis:

- a) Procedural Programming i.e. "better C". - b) Object-Oriented Programming. - c) Generic Programming. - d) Compile-time Programming.

The Usage axis:

- a) Low-level Interface Programming eg. MCU programming. - b) Library Programming. - c) Application Programming.

Every feature ideally sits at an intersection of the above two axes. Thus for example, the "auto" keyword from C++11 is best suited for "Generic Programming paradigm" and "Library implementation usage" (eg. in the implementation/use of STL). But what is happening is that the "Modern C++" proponents are using it willy-nilly everywhere (because "hey i never declared any stinking types in <scripting language>") making the code that much harder to comprehend. Similar arguments can be raised against a lot of other features. This is the reason many of us are cautious w.r.t. the new features; we know the existing potholes, have worked around them and have our system under control and in hand. The ramifications of introduction of new features just for its own sake is unknown and makes us very nervous.


I do understand it, but you put yourself in a false dichotomy at the same time. You say you have to master every corner just because features are added. This is not true most of the time.

Of course you layer features on top of existing things. It is the only way to "simplify" the language and keep it compatible. For example, now you still have raw pointers: noone recommends managing raw memory anymore, the recommended thing is to return a smart pointer or do RAII inside your class (this last one pre-C++11).

How about virtual functions? Oh, now you have to know more (and this actually does not really hold true in every context, sometimes it is easier): of course you might need to know more! Recommendation is to mark with override! How about template metaprogramming with SFINAE! No! Hell, NO if you can avoid it! That is why constexpr, if constexpr and concepts exist!

It is not more difficult to program in the last standards, it is way easier to program. What is more difficult is that you need to know more. But you do not need to know absolutely every aspect of the language. They layered features that are more general so that you stop using the legacy ones, and that is an improvement inside the constraints of what C++ is allowed to do right now to keep it useful (compatibility).

If what you want is to learn to program in permutations of all styles, including the old ones, in C++ and in all kind of devices... I do not know people that are experts at all domains and levels of the stack, no matter the language you use. So again, you can use your subset.

> But what is happening is that the "Modern C++" proponents are using it willy-nilly everywhere (because "hey i never declared any stinking types in <scripting language>"). Similar arguments can be raised against a lot of other features.

You basically said nothing concrete above.

BTW, noone prevents you from using many of the inferior styles. And by inferior I do not mean non-modern, I do not buy modern for the sake of buying it, I use the features that make my life easier, and the same feature or library thing that makes my life easier in one context is the one I discard in another (for example dynamic memory in embedded or fancy ranges in videogames I might need to debug and understand to the vectorization loop level if I do not have the parallel algos).

You can still, as I told you in the comment above, ignore override, for example, and try the refactoring exercise I told you, making your life more difficult on your way.

Or ignore structured bindings in for loops and declare the variables yourself for pairs. Or you can do some fancy metaprogramming with SFINAE and spend 3 hours figuring out what is going on or why you cannot use it in the parameter type of an overloaded operator and have to use it in its return type or guess which overload you are selecting, because if there are two difficult things in C++ those are initialization and overloading.

In the meantime, some of us will be using some concepts to constraint the overload set, or, even better, present as interface the weakest of the concept fullfilling a function and use if constexpr inside to choose the optimized paths for each type as needed.

Those are improvements, BIG improvements on how I write everyday C++ code. The language is big, bc there is not a choice. But a good training and taste for what to use and what not to use in your area of work is necessary.


My other response is also applicable here: https://news.ycombinator.com/item?id=32894154




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: