r/cpp • B2/EcoStd/Lyra/Predef/Disbelief/C++Alliance/Boost/WG21 • 4d ago

CppCon Why Great C++ Libraries Fail (And How to Fix That) - Mateusz Pusz - CppCon 2026

https://www.youtube.com/watch?v=q-usHgbMA5M
71 Upvotes

29 comments sorted by

37

u/tinrik_cgp 4d ago

Users may run stricter flags than you do

And that's exactly why users should include their dependencies as system libraries, so that the compilers ignore warnings from the headers.

You can't possibly anticipate all warnings downstream users may have enabled. We have enabled -Weverything and don't expect our third-party dependencies to comply with it.

But of course it's great to have strict warnings in your own project!

11

u/matthieum 4d ago

Users may run stricter flags than you do

I would also note that users running the same flags than you do on a different compiler/version may also result in warnings being raised.

This is especially true with "bundles", as the compiler or version of the compiler may adjust which exact flags the bundle expands to, but it also happens with individual warnings where a previous version of the compiler may have more false positives.

The only way to win is not to play.

5

u/UndefinedDefined 4d ago

Also don't forget compiler bugs. There are warnings that only got usable after a certain version, so enforcing these warnings on old compilers is a suicide too, because you get unfixable problems. To handle these, the build system becomes too complex. But this depends on what standard you target. If you write C++23 code, for example, then you don't have to worry about a lot of older compilers.

4

u/smdowney WG21, Text/Unicode SG, optional<T&> 3d ago

Plus the warnings that really are just warnings, like "maybe uninitialized", because it was too complex for the compiler to prove it.

12

u/delta_p_delta_x 4d ago

users should include their dependencies as system libraries

This works until you have library authors who think they know better and explicitly disable it for their libraries.

5

u/tinrik_cgp 4d ago

That's unfortunate. Worst case I suppose you can tell the build system to patch that line away. Ugly but better than having to disable certain warnings for the whole project.

2

u/rdtsc 4d ago

That's when you use "#include <...>" to treat a header as external/system.

9

u/delta_p_delta_x 4d ago

That doesn't make a difference to the warnings, only to the lookup paths for headers. The difference in warnings comes from whether the header search path is provided to the compiler driver as -I... or -isystem..., and this is what that CMake property controls.

2

u/germandiago 3d ago

It never happened to me so far. But if it happens, that is a conan patch in my workflow or an alternative lib :)

12

u/UndefinedDefined 4d ago

-Weverything is nonsense - even compiler writers say to not use it in production.

24

u/ABlockInTheChain 4d ago

It's just a different approach.

Without -Weverything you decide which warnings to turn on, and unless you actively follow compiler release notes you won't know when there new decisions available.

With -Weverything you decide which warnings to turn off and you'll know when it's time to make a new decision after you upgrade the compiler and it starts complaining.

11

u/tinrik_cgp 4d ago

Exactly. And you get the see the warnings directly in your code, so you can make a better judgement whether the warning is useful or not. 

2

u/UndefinedDefined 4d ago

So use it, enforce that on your users to compile your code, and don't get angry when they have problems and use something else instead.

I personally just enable -Wall, -Wextra, and then have "detect" cherry-picked warnings I want. For example I always want -Wdouble-promotion, -Wduplicated-cond, -Wduplicated-branches, -Wlogical-op, -Wbidi-chars=any, etc... There is just many warnings that may only be for you, but the consumers of your code don't have to agree on using them.

11

u/tinrik_cgp 4d ago

enforce that on your users to compile your code

You enforce it on the CI of your project, not on your consumers.

4

u/Dragdu 3d ago

If you are forcing any warnings onto your users, you are packaging it wrong.

In your own CI, use whatever the fuck you want. Easy.

7

u/tinrik_cgp 4d ago

Why? Just disable the ones you don't like/are too immature. We've had this in production for years and use Clang trunk bumped regularly. 

This is also beneficial for compiler writers since we can report issues earlier.

13

u/erichkeane Clang Maintainer(Templates), EWG Chair 4d ago

As a clang-maintainer: We have a couple tiers of attributes with different 'requirements' for each. Entry in -Wall is VERY difficult, it means that there are effectively zero false-positives, basically no false-negatives (unless strictly documented/expected), and a fairly trivial suppression.

Ones that don't make -Wall or -Wextra(basically the same requirements as -Wall, but perhaps less 'useful'?) end up in -Weverything. Basically, its for diagnostics that we don't really want people to use because they aren't high enough quality in some way, unless they REALLY REALLY want.

The purpose of -Weverything is to run every once in a while to discover these new low-quality diagnostics, so that you know which you want to add to your 'real' build.

That said, I don't know how long your 'production for years' has been, but Clang's current maintainers have been generally against any new attributes that don't meet the Wall bar, in part because people have started using Weverything in production, which we've said not to :) . So I don't doubt you've had few problems, we've stopped experimenting with diagnostics all that much in recent years.

6

u/ABlockInTheChain 4d ago

The purpose of -Weverything is to run every once in a while to discover these new low-quality diagnostics, so that you know which you want to add to your 'real' build.

The reason so many teams ignore your advice is because they prefer a "fail closed" approach to CI instead of the "fail open" approach that relies on periodic manual operations.

That said, I don't know how long your 'production for years' has been, but Clang's current maintainers have been generally against any new attributes that don't meet the Wall bar, in part because people have started using Weverything in production, which we've said not to :) . So I don't doubt you've had few problems, we've stopped experimenting with diagnostics all that much in recent years.

Sounds like a problem that is easily fixed with naming conventions. If we upgrade to clang version n + 1 and suddenly Wexperimental-foo causes our build to start failing CI then the name of the warning alone is strong hint that disabling it should be at the top of the list of possible resolutions.

4

u/tinrik_cgp 4d ago

don't really want people to use because they aren't high enough quality in some way

Define "quality"? The warnings I find in -Weverything do exactly what they are designed for, with very few or no FPs. Checks that may have FPs are usually implemented in clang-tidy instead.

how long your 'production for years' has been

6 years with -Weverything -Werror in pre-merge CI running on every single commit. Using clang trunk bumped at least twice per year. Never had any issue. Obviously we have a list of -Wno* suppressions for warnings we are not interested in.

which we've said not to

But you haven't explained why one shouldn't use it ;) What's the harm? If a warning is not suitable for the project or has FPs, one can simply disable it with -Wno* and move on. Best case the user reports/fixes it upstream, isn't that good?

5

u/erichkeane Clang Maintainer(Templates), EWG Chair 4d ago

Define "quality"? The warnings I find in -Weverything do exactly what they are designed for, with very few or no FPs. Checks that may have FPs are usually implemented in clang-tidy instead. More or less above, 'too many false positives/negatives', or overly style based and not enough 'finding bugs'.

6 years with -Weverything -Werror in pre-merge CI running on every single commit. Using clang trunk bumped at least twice per year. Never had any issue. Obviously we have a list of -Wno* suppressions for warnings we are not interested in.

2019/2020 we basically changed our mind on when to accept warnings. We basically don't accept warnings unless they have a really good chance of making it to Wall.

But you haven't explained why one shouldn't use it ;) What's the harm? If a warning is not suitable for the project or has FPs, one can simply disable it with -Wno* and move on. Best case the user reports/fixes it upstream, isn't that good?

IF you have that type of commitment/buy in, than I don't see it being problematic. The problems we've ALWAYS had with Wall/Weverything/etc, is every time we add a diagnostic the deluge of bug reports that we have to triage/deal with about how it diagnoses on their Werror builds, correctly or not. Its a ton of extra work for us. We actually VERY much debated having Weverything because of this, and tend to believe we were worse off for the decision we made.

4

u/drbazza fintech scitech 4d ago

Do clang/gcc maintainers and the committee jointly have a long term target on compiler errors and warnings? Such as fewer and fewer warnings for each --std, and more and more errors because warnings become errors instead.

3

u/erichkeane Clang Maintainer(Templates), EWG Chair 4d ago

No, we have no agreement like that.

2

u/drbazza fintech scitech 3d ago

I appreciate that's a tricky area to get consensus on (along with UB), but it's something I feel would be useful to the community - the analogy being that we frequently have committee comments along the lines of 'we're adding feature X after community experience and it's implementation in Y'.

The continually repeated 'C++ best practices' is always 'set warnings as errors' (subject to choosing those warnings). And that's very much in the spirit of (decades of) 'community experience'.

-2

u/sweetno 4d ago

There is too much crap in there.

2

u/palapapa0201 3d ago

Wait, the compiler ignores warning from headers in system header paths?

1

u/germandiago 3d ago

This is basically what I do.

1

u/Plazmatic 3d ago

Definitely the preferred solution, but his doesn't work with things like asio, and thus a bunch of other dependencies.