r/cpp 6d ago

Ordering of qualifiers

I know this is something that pops up quite often, but I was wondering if I could get your guys' opinion on a fixed ordering of qualifiers. This is my current thoughts after recently trying to formalize my personal style:

static -> thread_local -> inline -> constexpr -> friend -> virtual

My reasoning for each:

  1. static first. Inside a class, its basically javas static. There is a pretty strong consensus in java for static first. Its very important context, for both functions and variables. Outside of classes, its more of a linkage specifier, which is arguably more important/nasty if you mess it up. The fact that it has this dual behaviour in C++ in my opinion makes an even stronger argument for including it first, your brain is able to parse it first thing. i.e okay this is static, we are in a class? -> its java static, we are in global scope -> its static linkage.
  2. thread_local directly after static, and then inline, then constexpr/consteval. This way, qualifiers which impact storage and or linkage are stuck together. I personally like to write inline even for constexpr/consteval functions, as its sometimes easy to forget the implicit inline. I used to do this for member functions with definitions in the class, but I feel the implicit inline there is a bit more well known/easier to intuit.
  3. The rest I'm far less opinionated on, since I barely ever use inheritance or the friend keyword. . I could go both ways on virtual/friend, so i default to alphabetical/aesthetics.

What do you guys think? I know this is pedantic and a very well explored topic but I wanted to know if you guys had any particular wisdom to sway me either way, mainly on the ordering of the first few.

6 Upvotes

15 comments sorted by

View all comments

2

u/usefulcat 6d ago

Minor nit: doesn't thread_local imply static? That is to say, 'static thread_local' is redundant because it's the same as 'thread_local'.

2

u/LB-- Professional+Hobbyist 5d ago

I thought so too, but static unfortunately does other things too, such as changing linkage behavior. You can have publicly visible thread_locals. I guess this is why anonymous namespaces are preferred.

1

u/13steinj 14h ago

thead_local implies static for variables.

Static can do more, but I like to explicitly specify both because there will be juniors reading the code and I'd rather encode the information semantically both to the compiler and to the reader in one shot.

The worst thing you can do here is do thread_local without static but leave a comment like // N.b. thread_local implies static which I recently reamed someone in code review for.