
Ask HN: Which C++ style guide do you follow? - ycombonator
Options shamelessly copy-pasted from https:&#x2F;&#x2F;clang.llvm.org&#x2F;<p>LLVM A style complying with the LLVM coding standards<p>Google A style complying with Google’s C++ style guide<p>Chromium A style complying with Chromium’s style guide<p>Mozilla A style complying with Mozilla’s style guide<p>WebKit A style complying with WebKit’s style guide
======
tzhenghao
We follow Google's as good as we can. I think they have a stronger stance on
some best practices which I personally don't agree with, but I also can't
think of a better forcing function for less experienced C++ devs to write
dangerous code and shoot themselves in the foot anyway.

------
bollu
Whatever clang-format and clang-tidy says! Seriously, using automated tools
just takes away all of the bikeshedding revolving this issue.

~~~
lrsjng
What's the difference between clang-format and clang-tidy? Do they have
different configuration options? I'm only using clang-format so far.

~~~
danpat
clang-format kinda does what it says - parses your code, then indents and
spaces it according to the rules. It doesn't try to understand code intent, it
just looks at syntax.

clang-tidy does some deeper inspection and can be used to flag things that are
"bad practice", not just "bad formatting". There's a big list of checks here:

[https://clang.llvm.org/extra/clang-
tidy/checks/list.html](https://clang.llvm.org/extra/clang-
tidy/checks/list.html)

At a minimum, I like to enable all the `bugprone-*` tidy rules, they just seem
sensible to turn on.

e.g. [https://clang.llvm.org/extra/clang-tidy/checks/bugprone-
stri...](https://clang.llvm.org/extra/clang-tidy/checks/bugprone-string-
constructor.html)

You're able to run `clang-tidy -fix` to automate fixing of many of the things
it will flag.

------
CoolGuySteve
While it's very popular, I find Google's to be the most distasteful. It's very
opinionated in a very curmudgeonly kind of way.

In particular, the emphasis on 80 char wide lines hurts readability by
encouraging shorter variable names and wastes quite a bit of vertical space.
For example, this example line from the spec violates the spec: "using
TimeSeries = std::unordered_set<DataPoint, std::hash<DataPoint>,
DataPointComparator>;"

And it's strangely opinionated but in way that's particularly fearful of
templates, macros, and SFINAE such that it causes more strife than it's worth.
Like by forcing you to justify otherwise reasonable things like
"template<typename Thing> RedisSerializeTheThing(const Thing& thing);" or
"template<typename Thing>
LexicalCastLoggerThatCanOptionallyTemplateSpecialize(const Thing& thing);"

Variadic templates fall under the template ban I guess and __VA_ARGS__ stuff
is based around macros, so there's not really any good way under that standard
to express something like a safer sprintf or tuple marshalling.

Essentially my problem with the guide is that it bans a lot of type-inference
that makes C++ safer and faster. C++ is already dangerous, so I think that's
the wrong choice.

~~~
sys_64738
The Google style guide developed over time through iterations involving
several thousand programmers. It's the culmination of all those programmers
and operational aspects which got it to this point. So when you say it's
'opinionated', the data has said the styling in the document is the right
thing to do.

~~~
CoolGuySteve
That's a funny way of putting it, almost like an appeal to tradition.

It reads more like Google had to herd a lot of junior programmers and rather
than teaching better judgement or patterns, just walled off huge sections of
the language completely.

~~~
zawerf
Is there any other way at google scale?

I haven't written more than 100k LOC of C++ and yet there are already lots of
code (mostly template meta programming) that I wrote that even I can't read
anymore.

Now imagine blowing that up to (literally) billions of lines of C++ written by
overly clever engineers all eager to prove themselves.

~~~
CoolGuySteve
Quite a few things:

\- Allow whatever C++ inside the project but force each project to export a
plain C API and .so file. This has the quadruple bonus of (1) avoiding ABI
problems between compilers, (2) hiding complexity from other teams, (3)
forcing teams to think more about their APIs, and (4) being trivially callable
from any other language.

\- Large API/SPI review mailing lists. This worked quite well at Apple.

\- Add a section to the style guide about what's appropriate template use and
what's not. Banning one of the language's most important features is just a
cop out.

\- Better mentorship from senior engineers.

------
saulrh
What do you mean by style? Whitespace and casing in names, chunks of the
standard to use or not (unique_ptr, mutable refs as function arguments, auto),
interface design paradigms (RAII, exceptions vs error codes, composition vs.
inheritance)? It doesn't really change my answer (the Google style guide), but
the reasons are somewhat different in each case. I choose Google's formatting
basically because it meshes with the feature-set they recommend and their
interface design philosophy. I choose the feature-set they recommend because
their guide's coverage and reasoning are more comprehensive than those of
comparable guides I've seen. I choose their interface design philosophy
because it meshes with the feature-set and is better than trying to figure it
out myself.

(I do work at google and got the "writes idiomatic c++" certification, but I'm
writing the above from the perspective of the (very tiny amount of) c++ I
write for personal projects, including things I worked on before I got past
their interviews to get hired.)

------
ndesaulniers
Google's style guide has been beaten in to me to get "C++ readability" at
Google. Makes working on LLVM tough some times. .clang-format is a must for
any project IMO.

------
badsectoracula
I do not write C++ often as i'm not a fan of the language, but when i do... i
don't follow any of these :-P. I have my own style which is pretty much an
"evolution" of what i see a lot of C++ projects, mainly from the MSVC/Windows
world, use.

In short, whitespace is mostly Allman style with spaces for indentation. Names
use mostly CamelCase, with some exceptions. Public members go first, protected
members go middle, private members go last.

Instance fields have an m_ prefix, static fields that have an s_ prefix and
both use javaCase instead of CamelCase. Function parameters and local
variables also use javaCase. In the cases where javaCase is used, whenever
possible single word identifiers are used. Classes have a C prefix except
mixings which have an M prefix and interfaces which have an I prefix, structs
have an S prefix, enums have an E prefix, namespaces have an N prefix,
templates have a T prefix (not C/S, etc), function types have an F prefix,
typedefs meant for aliasing have an A prefix. Exported/imported global
variables have a G prefix, static toplevel variables have an L prefix. Macros
all in all caps with underscores separating words. Pointer and reference
declarations have the start/ampersand right after the type name, whenever
possible there is a single declaration per line and only a single
pointer/reference use (using aliases for more complex stuff). All types are
declared in the global namespace, however functions are grouped in topic-
specific namespaces. When inheriting a class and overriding virtual methods,
the overrides are declared in a separate block in the class with the comment
"// Baseclass methods" or something like that. Other members have a single
line documenting their purpose (no doxygen, plain text, i find doxygen
comments to be noise, if there is need for explicit documentation it should be
in a separate file).

There are other minor things, like how header files are laid out, "getter"
functions that only return a private/protected member being inlined, etc but
the above are the main stuff. I do not have any of these rules written out
anywhere, i just happen to "grow" to write C++ code like that over time.
Interestingly my C code style is totally different (snake_case, _t suffix for
types, _s suffix for structs, etc).

Here is an example:

[https://pastebin.com/anLvHRQ2](https://pastebin.com/anLvHRQ2)

It is the model document (as in document/view) for the mesh editor in this
video:

[https://www.youtube.com/watch?v=rr1Sr9hTkzg](https://www.youtube.com/watch?v=rr1Sr9hTkzg)

~~~
asveikau
This is how a huge chunk of the Windows or Windows-trained world writes C++.
You don't have to like it but it's recognizable and common.

~~~
badsectoracula
Yes, especially the m_, I, C, S, E and G stuff are very common. I think it
comes from MFC. The T stuff is less common - in my current company templates
are also C-prefix, but in the previous company i worked at they were
T-prefixed.

Some other stuff like L, F, A, s_, etc are things i came up with myself for my
own code (for work code i use whatever others are using) since i didn't like
the more common uses (in the previous company i worked at statics were also S
prefixed, but i wanted something to separate from structs so i used L for
"local"). Of course once you get used to the common style above, these
"extensions" are mostly obvious so i'm certain that others are using them too.

------
yodon
Is there a style guide for using exceptions in code that people like? (at the
time I'm writing this there is a lot of pro google style guide, which is great
in my opinion except for their no-exceptions approach)

------
manca
I use Google's, but don't follow it to the word. I use their linter with
couple of my own rules related to C++11 headers (chrono, etc), lines width,
whitespaces, etc.

But in general, I try to follow good practices from it like: namespace
formatting, as well as anonymous/unnamed namespaces, names and order of
includes, #define guard (although I prefer #pragma once), use of smart
pointers (fixed owners for dynamically allocated objects), explicit
constructors, etc.

------
sytelus
Unfortunately lot of these guidelines are incompatible to each other. Many
have certain rules just because of legacy they had inherited (for ex, Google)
and you are much better off ignoring those rules. After spending too much time
on this, I use this for my projects:

[https://microsoft.github.io/AirSim/docs/coding_guidelines/](https://microsoft.github.io/AirSim/docs/coding_guidelines/)

------
saagarjha

      $ cat ~/.clang-format
      ---
      BreakStringLiterals: 'false'
      ColumnLimit: '0'
      IndentWidth: '4'
      ObjCBlockIndentWidth: '4'
      ObjCSpaceBeforeProtocolList: 'false'
      PenaltyBreakComment: '0'
      SortIncludes: 'true'
      TabWidth: '4'
      UseTab: ForIndentation
      
      ...
    

Otherwise, whatever the project I'm working on uses.

------
sail0rm00n
Google's style-guide, but prefering references over raw ptrs and using
SNAKE_CASE_CAPS for constants instead of 'kSnakeCaseCaps'

~~~
wutbrodo
> prefering references over raw ptrs and using

I started my career doing C++ at Google, so for those engineering habits that
I haven't thought through or otherwise have a strong opinion about, my
defaults are in line with the GSG. But avoiding non-const references is
something that I find myself in pretty strong agreement with, as part of a
coding style that makes function signatures for complex logic as simple and
comprehensible as possible. I'd be interested in hearing the perspective
behind your reasoning otherwise. Is it mainly for the ability to signal non-
nullability in the signature?

~~~
Jyaif
> Is it mainly for the ability to signal non-nullability in the signature?

Can't answer for the parent, but for me yes it's exactly that.

When I'm calling a function I'm going to look up the prototype anyways so I
don't really care whether it's taking a reference or a pointer.

When I'm implementing the function, I want to make sure that all my callers
never pass me a nullptr. Because of the styleguide I'm forced to put a
"DCHECK(ptr);" and add a comment in the prototype saying "|ptr| must not be
null".

------
gumby
Last time we needed one we chose google. Not because we necessarily liked it
but because then there was no argument about what the guide is or should be
and so we didn’t spend any time writing one.

It’s ok, not great, and definitely google specific (e.g. even google would
prefer to use exceptions but for legacy reasons they can’t. So we couldn’t
either)

~~~
wutbrodo
Was there a reason you couldn't use GSG but change the section on exceptions?
I don't think there are any logical dependencies between the exception ban and
other parts of the style guide, but I could be mistaken. Every company I've
worked at since starting at Google uses the GSG, so I've never had occasion to
learn how to use exceptions in C++.

~~~
gumby
Yes there was a reason: once you change one thing you open everything else up
for discussion as well. And while that would probably lead to a better guide
(for us) than Google's, the time and thought involved in that would take away
from solving the problems we wanted to solve in the first place.

~~~
wutbrodo
Hm yea, I figured that might be the case, but to me, the "this is only for
legacy purposes" claim stands out enough from the rest of the GSG that I
figured it would be easy to separate it from the rest of the guide. I
obviously don't know the dynamics of your team though and totally find your
explanation plausible.

------
deepaksurti
I use Chromium style[1], worked out well. Have to check my notes on PC why I
picked that.

[1]: [https://github.com/dmsurti/AssimpKit/blob/master/.clang-
form...](https://github.com/dmsurti/AssimpKit/blob/master/.clang-format)

------
AndrewGaspar
We more-or-less use Google's. Formatting level style is enforced via clang-
format + CI.

------
Rexxar
The standard committee one :
[https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)

------
jcelerier
[https://github.com/OSSIA/score/blob/master/.clang-
format](https://github.com/OSSIA/score/blob/master/.clang-format)

------
zbowling
Google and Chromium are extremely similar. Very very minor differences.

------
berbec
[https://en.wikipedia.org/wiki/Indentation_style#Allman_style](https://en.wikipedia.org/wiki/Indentation_style#Allman_style)

------
lqet
Google's, but clang-format does most of the work. I used it for so long that I
now get nervous whenever I see a non-const reference somewhere :)

------
gHosts
Sanity check for any whitespace style guides....

If you're not prepare to wire an auto-indent into every ones commit hooks....

....you're just not serious are you?

Bottom Line on White space....

Have some.

Be mostly consistent.

------
guessmyname
Game studio, 80+ people writing C++ and Lua, we use Google’s style guide.

~~~
meritt
Curious, do you guys use an engine (unreal, unity, godot, etc) or something
in-house?

~~~
guessmyname
We use Unreal Engine extensively for multiple projects.

Some of my colleagues are also developing a voxel game engine for another
game.

And we have also used Lua LÖVE multiple times during our yearly hackatons.

~~~
meritt
Cool. Thanks. So I take it you primarily write code leveraging the Unreal
engine but the point-n-click functionality of the Unreal editor is more
utilized by people doing the world design and artists?

I've explored Unity a small amount but I was really turned off by the overly
simplistic approach to game development. The whole scene-first approach where
you'd just drag in your hero object, set some attributes, drag and drop some
enemy objects, etc. It reminded me heavily of Flash game development 15 years
ago.

~~~
maccard
The editor is used by design and art lots, bit lots of programming in UE4
involves exposing controls for people who are using the things you write.
There's also blueprint which is a visual scripting language which you can use
for behaviour.

I think tarring unity as overly simplistic is unfair. Unity let's you write
code ( in as a game object) and use them, it's not really drag and drop.

(Disclaimer: I work in games, for Epic)

------
je42
LLVM

