
C++ Core Guidelines - octoploid
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md
======
aurelian15
It is great to have such a collection of rules and I hope they will be
integrated into some easy-to-integrate static code analysis tool (as mentioned
in the introduction). Maybe this will help people to transition to more modern
C++ and to avoid some pitfalls (e.g. forgetting the "noexcept" for move
constructors/assignments).

However, in some respect this list also shows what is wrong with C++: The fact
that you even need such a huge set of rules to write safe and efficient code
is somewhat unsettling. I'd rather hope a new version of the language standard
would at least allow to hide deprecated constructs behind a "safe/unsafe"
pragma.

~~~
something123
It always seemed to me that it should be relatively not difficult to write
some kind of language that limited you to the "right" way of doing things and
that compiled down to C++

You could:

\- prevent people from using deprecated features

\- immediately remove TONS of boilerplate

\- automatically generate header files from the cpp's

\- have high level keywords that would generate design patterns for you (no
more having to re-implement a Visitor for the first time that year and having
to spend a day debugging it)

At the same time you could still leverage C++ libraries and when you do need
to write an allocator or do some fancy diamond inheritance friend method
templating magic shenanigans you could always drop back down to C++

EDIT: What I find kind of amusing is that with time you can do more and more
of these things through Visual Studio's magical "wizards" and checkboxes
(maybe it's the same for the other IDEs.. not sure), but ofcourse it's rather
silly, clunky and slow to use. In the latest version you can finally make
matching declarations/definitions with a couple of clicks - saves a lot of the
mildly frustrating copy/past'ing!

~~~
kllrnohj
What you're describing basically already exists, it's Rust.

~~~
something123
that compiles to C++ and has 2 decades of libraries and tools written for it?

~~~
pcwalton
Rust compiles to LLVM IR, which is better than compiling to C++ (for reasons
I've elaborated on before).

As for library and tool support, I think a safe subset of C++ couldn't
actually use tools for "real" C++, because the languages would be too
different.

~~~
something123
I'm sorry, but I feel like all these "Just use Rust!" comments are written by
idealistic college students.

Yes, maybe Rust is better, and maybe if we could push a button and make
everyone use it the world would be a better place.

But the reality is that there are very few code bases written in Rust and an
uncountable amount written in C++ - there are decades of work behind C++ and
decades of work will still be done in C++. I need to earn a living TODAY and
work in the current reality, and I need tools to help me be more productive. I
can't wait 5 years for some brand new language to take over.

~~~
yokohummer7
I think you're misinterpreting what pcwalton said. Sure, seeing "use Rust" in
every possible place is quite annoying, but what pcwalton described is why
"compiles to C++" and "has 2 decades of libraries" don't work for new
languages. He didn't say to use Rust, he was just pointing out that your two
ideas aren't viable.

------
okasaki
I'm only a bit in but I've already found myself disagreeing with some of these

for example

    
    
        drawline(int,int,int,int);  // obscure
        drawline(Point,Point);      // clearer
    

this is only "clearer" until you find yourself at the very common case where
you use several libraries where each defines its own "Point".

Now you're writing something like

    
    
        drawline(Point(vec.x1, vec.y1), Point(vec.x2, vec.y2))
    

Pretty ugly!

And of course drawline(Point, Point) isn't clearer at all imo. What's the
coordinate system? What are the units? Any performance notes on this function?
Etc. I'll be checking the documentation the first time anyway.

    
    
        void do_something(vector<string>& v)
        {
            string val;
            cin>>val;
            // ...
            int index = 0;                      // bad
            for(int i=0; i<v.size(); ++i)
                if (v[i]==val) {
                    index = i;
                    break;
                }
            // ...
        }

this is shown to be inferior to the find() version. Again, it's only inferior
until the very common case where you're doing something else with the index,
which is pretty common during debugging. Then you'll be rewriting the above
"bad" version anyway.

Similar problems other higher order functions like for_each().

~~~
randomprog
> What's the coordinate system? What are the units?

That information can be encoded into the class type, in which case you get
compile time checking. I wrote a blog post about this some time ago:

[http://www.randomprogramming.com/2014/06/quote-of-the-
week-t...](http://www.randomprogramming.com/2014/06/quote-of-the-week-type-
systems-and-unit-tests/)

The summary is that we had two different coordinate systems in play and had
many bugs caused by passing values in the wrong coordinate system around. By
making the different coordinate systems different classes everything became
explicit and checked by the compiler. We completely eliminated a whole class
of bugs from our program.

The great thing about using an int is that it can be anything (integer). It
can be an x coordinate, or the number of eggs or a selection between multiple
options.

The bad thing about using an int is that it can be anything, and sooner or
later you will pass the number of eggs into a function that really wants an x
coordinate.

~~~
RogerL
I prefer having member functions that convert to a different value, and friend
functions that create instances from another type:

    
    
        Distance d = feet(7);
        d += meters(3);
        std::cout << d.yards();
    
        Distance d2 = 3; // I won't compile
    

This assumes that you _want to_ mix units, not defeat it. It all ends up being
very efficient; use MKS for the underlying representation. You can multiply,
add, and so on, quite efficiently; the only conversions happen on input and
output.

------
raincom
All these guidelines are good for those who have been in C++ trenches for a
while. For others, it will become another list, a list similar to what non-
native English speakers have to learn by rote in order to predict the
pronunciation of English words.

We have Scott Meyer's effective c++, more effective c++, effective STL,
effective STL, modern effective c++.

I have read Bjarne's "A tour of C++", which is a good one to read. Also read
his "design and evolitution of C++", which gives rationale for what we see the
ugliness of C++.

I think we need a small book that describes the history of C++ until now, such
a book can help us to remember "C++ core guidelines". This is similar to how
great vowel shift in the history of Enlgih langauge helps us to see deeper
patterns in English pronunciation.

I hate a bunch of guidelines, without historical explanations, because such
guidelines are very hard to pin to one's brain unless one is working in
hardcare C++ everyday. Maybe, this sounds like playing Piano scales:)

------
inglor
It's amazing how many people get these core principles wrong. I recently
visited a C++ shop who hasn't even heard of RAII and don't use smart pointers
or standard containers. What a nightmare.

It's great to see C++ getting an ecosystem and Bjarne's excellent writings
help a lot.

~~~
bluecalm
Or you know, maybe they have different view on these things. There are good
programmers out there who don't use RAII or smart pointers and think that most
of this modern stuff is just added cruft for little gain. Standard containers
are nice but if performance is your problem you often need to re-implement
them anyway and if it is not then maybe you could have done it in the higher
level language in the first place.

Whatever float your boat (and your particular niche).

~~~
deeringc
I don't see many valid reasons why you wouldn't want to use RAII patterns for
any sort of resource management. I would go as far as saying that if you
aren't doing so, you're probably doing it wrong. Having said that, I'd be
genuinely interested to hear some resource managment sceanrios where you're
better off not using RAII.

~~~
to3m
You can end up needing a lot of different RAII types, which can get a bit
annoying. If you're trying to interface with anything that wasn't written with
RAII in mind - e.g., any library that tries to be C-compatible - this is
pretty much inevitable.

In theory, doing without is a huge problem, because you're running the risk of
resource leaks and stale identifiers - but in practice, neither is a huge
problem. Picking these sorts of bugs out has been pretty simple in every
project I've worked on. I've had far more heartache from the bugs stemming
from RAII-type mechanisms holding on to resources longer than they should,
than I've had from fixing bugs caused by resource leaks or stale resource
identifiers.

~~~
Quiark
With std::unique_ptr (you can set the deleter) and ScopeGuard you don't need
to create new types for every type of resource.

I respectfully disagree with leaks not being a problem.

------
enqk
The more I develop in C++, the more I wish I had a very restructure transpirer
that would remove some of its most silly constructs or switch ite base
defaults around.

Some examples: \- making all constructors explicit and adding an implicit
keyword instead for that rare case \- automatically generated !=, <=, >= etc
from == and < (with an explicit override when you want to be silly) \-
removing some of the redundant syntaxes (const positioning, typedefs vs using
etc \- removing the class keyword

~~~
tragomaskhalos
You can easily do your != et al from < thing by using CRTP inheriting from a
'comparable' template class that provides the implementations. Sort of thing
that should be in std really.

~~~
ourson
It is. using namespace std::rel_ops;

~~~
ant6n
It looks like this isn't attached to the class definition, but rather to the
uses. I.e. for every use of a class that only defines ==, <, you have to
include rel_ops. But then it would basically provide the other comparators to
all classes, maybe not something you'd want.

------
ubercow
>This document is a very early draft. It is inkorrekt, incompleat, and
pÂµÃ¸oorly formatted.

It's the little things in life that make it so great.

~~~
a_e_k
That's a bit of a running joke. It's funnier in the working draft PDFs of the
standard, e.g.: [http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2014/n429...](http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf)

------
dunkelheit
I must confess I am tired of all these guidelines. I mean I have learned C++
once, gone through the ordeal of learning all the best practices, memorizing
all the gotchas etc. And now the language just got bigger. New features
arrived along with new unexpected gotchas. Scott Meyers has written a new book
and all is well. Except that the more C++ I write the more I yearn for
something simpler with less arbitrary rules to memorize.

~~~
humanrebar
> And now the language just got bigger.

If you want to master the whole thing, sure. But for in-the-trenches
application devs, it's a lot simpler now. For example, if you want to disable
copying:

    
    
        MyClass(const MyClass &) = delete;
    

That's a lot simpler than knowing the declared-private-but-not-implemented
trick. There's a decent-sized list of these simplifications, especially using
'auto' instead of remembering the 102 characters necessary to describe the
return type of 'begin()'.

~~~
dunkelheit
Yes, some of it is great and the ability to write

    
    
        for (const auto& item: collection) {
    

is probably my favorite feature of C++11. Ironically it makes the recommended
approach of using standard algorithms with lambdas look abstruse in
comparison. Considering your example, I still feel that inheriting from
boost::noncopyable is the cleanest way to declare the class noncopyable. It
feels almost like a language keyword!

But the amount of new gotchas is significant too. In particular to use move
semantics effectively you have to be aware of such obscure things as xvalues,
std::move_if_noexcept and rules for autogenerated move constructors. The fact
that the committee itself did not get it right on the first try speaks for
itself.

------
ilurk
It's posts like these that remind me how hard it is to write idiomatic/correct
C++, when compared to something like Python or Java.

~~~
Retra
I've only really ever made one project in C++, and I spent a good deal of time
learning the "right way" to make different kinds of constructors. And all I
could think is, if there is a "right way" to do it, then why isn't it the
default? Why am I actually doing _research_ on how to write boilerplate?

It's because C++ is a disaster.

Everyone likes to point out that you should only use a subset of the language.
But that's not my experience with C++; only using a subset makes you
vulnerable to all the problems associated with not understanding the _actual_
language that is implemented, not just the subset you wanted it to be.

~~~
Joky
This is not completely false, but clearly the view of someone who does not
understand C++.

Yes C++ carries decades of history, but since C++11 even if you can still make
use of this you don't _have to_ cope with. It is perfectly fine to use only a
subset of C++, you just have to use the right one and this is what this
documentation is about IMO. Yes you have to understand the language to be
efficient with it, but it is a language that allows high performance and
maintainable large scale software.

Python was cited as an example in this thread and I don't get it. There a many
ways to write the same thing in Python and I always end up spending more time
looking on the web to figure out what is the "Pythonic" way.

~~~
jlarocco
The difference is that not being "Pythonic" is a style issue. A Python guru
may scoff and point out that you could write the same thing more elegantly
some other way, but most of the time the performance is the same, and the
behavior is correct either way.

On the other hand, not following some of these C++ guidelines can mean your
code is subtley broken and depending on undefined behavior, or leaking memory,
or accessing something it shouldn't, etc.

I write C++ at work. We all know the language pretty well. We send people to
conferences. We have somebody presenting at CppCon next week. We still get
bitten by C++ more than you would belive.

~~~
dman
You are comparing apples and oranges here. Please compare C++ to other systems
languages that are regularly used to write systems / fast / "unsafe" code.

~~~
Retra
I'm pretty good with C, and while C has some safety issues, it doesn't usually
bury them under miles of encapsulation. It's also a small, tight language that
isn't trying to reinvent its syntax every 5 years.

And there's Rust: it's a pleasure to work with and has almost none of C++'s
problems.

~~~
dman
Its hard to not like C, so I dont have any disagreement with you there.
However after coming to C++, I do miss RAII when I program in C now.

I am excited about Rust as well, and look forward to using it professionally
in the future.

------
acconsta
I wonder how many of these could be implemented in clang tidy:

[http://clang.llvm.org/extra/clang-
tidy/index.html](http://clang.llvm.org/extra/clang-tidy/index.html)

~~~
something123
From the introduction:

"The rules are designed to be supported by an analysis tool. Violations of
rules will be flagged with references (or links) to the relevant rule. We do
not expect you to memorize all the rules before trying to write code.

The rules are meant for gradual introduction into a code base. We plan to
build tools for that and hope others will too."

So it sounds like they will be introducing some tooling in the near future.
It'd be nice if they leveraged existing tools (like clang-tidy)

~~~
wnissen
One exception "NL.1: Don't say in comments what can be clearly stated in code
Enforcement: Build an AI program that interprets colloqual English text and
see if what is said could be better expressed in C++." Pretty funny stuff for
a style guide.

------
mellery451
most of this is stuff Herb (and others) has been promoting for years...and
It's great to see it codified in one place.

~~~
something123
This is definitely a step up from having to look through his blog (where a lot
of the old stuff is waiting to be updated to C++11)

------
mmphosis
I first started looking at this when Cfront by AT&T Bell Telephone
Laboratories came out. Let me know when the language stabilizes and maybe I'll
take a look at it again.

~~~
laichzeit0
Do you feel the same way about the English language?

~~~
criddell
Exactly. I hear Latin is pretty stable these days.

~~~
laichzeit0
Yeah, Classical Latin is pretty stable. Try use it in a modern conversation
and you'll realize how painful that property is. Anything that's made of
plastic, uses electricity, steam, actually any original idea in the last 300
years would require inventing some neologism just so you could talk about it.

~~~
JoeAltmaier
Im not so sure? The word 'plastic' existed before plastic did. Does Latin not
have a word for that property? And so on.

~~~
laichzeit0
I think you might still end up with something like the Lexicon Recentis
Latinitatis [1] maintained by the Vatican. And unless you "make up" neologisms
you'll end up with stuff like "timer - instrumentum tempori praestituendo"
which would be extremely tedious to use in a conversation. Purists might argue
that it would be awesome if we could make grammar "stable" though. It's an
interesting thought.

[1]
[http://www.vatican.va/roman_curia/institutions_connected/lat...](http://www.vatican.va/roman_curia/institutions_connected/latinitas/documents/rc_latinitas_20040601_lexicon_it.html)

~~~
JoeAltmaier
Again, the word 'timer' could be some variant of 'temporia', a shortcut for
the device that isn't descriptive, just like in English?

------
hit8run
That's what I really value about Go: gofmt and very good linting that embraces
best practices. I know C++ is way more complex but for someone starting out it
seems impossible to code in the "right (tm)" style.

------
jheriko
started losing me at exceptions. the philosophy bit is quite nice, but seeing
auto in the example... not for me. not even close.

its a shame we are ruining C++. can't we just have something better... :/

~~~
rleigh
auto can be a great aid to readable and maintainable code. It can also be used
to obfuscate when not used in moderation.

    
    
         for(const auto& elem : container)
    

is vastly more readable than

    
    
         for(my_long_type<specialised_type>::const_iterator iter = container.begin(); iter != container.end(); ++iter)
    

I recently had to rewrite some C++11 code to C++98 to fit into a project.
Using nothing but auto and range-based for loops, it nearly doubled in size by
switching back to the older more verbose syntax. So long as you don't go to
the other extreme, these have much value.

~~~
jheriko
its also a death trap in winrt when combined with templates in the way they
do.

debugging that typoing a callback signature results in nothing happening in
asynchronous code controlled by the ppl task library is a massive pain for
even an experienced programmer.

auto is nice in principle, but it is introduced in such a powerful and
dangerous environment that there are subtle gotchas in real world use cases.
including targetting a major platform by using its system libraries.

programming is about thinking, not typing and programmer convenience. i don't
enjoy auto for that reason either... if it were to save me time it would be
little. i find using the stl algorithms and avoiding the nasty stl iterator
pattern like the plague means the problem you describe just doesn't exist for
me as a day-to-day case.

------
mreiland
P.4 mentions using variant, but I couldn't find any information on this. Does
standard C++ have a built in variant now?

If so, could someone link me to a resource?

~~~
RotsiserMho
There's a proposal to include it in C++17. See also:
[https://www.justsoftwaresolutions.co.uk/cplusplus/standardiz...](https://www.justsoftwaresolutions.co.uk/cplusplus/standardizing-
variant.html)

~~~
mreiland
thank you, all I could find were references to boost or home grown solutions,
it makes sense now :)

