[cfe-dev] How to control C++0x adoption in a large codebase?

Chandler Carruth chandlerc at google.com
Thu Oct 13 23:55:55 PDT 2011

On Thu, Oct 13, 2011 at 11:13 PM, David Blaikie <dblaikie at gmail.com> wrote:

> Consider just a single warning flag: "-Wc++98-compat", designed for use in
>> "-std=c++11" mode. The goal is to warn about obvious code patterns that
>> break backwards compatibility. Why is this flag useful from a strictly
>> functional perspective? Because developers may need to have non-trivial
>> amounts of code compiled in both C++98 and C++11 contexts. Imagine some
>> libraries are expected to work with projects whose compilers do not yet
>> support C++11, *and* projects which actively use C++11. Because of
>> libstdc++ issues, all of the code may need to be compiled as C++11 in the
>> latter case. Even without this, headers will leak across the TU boundary
>> and thus be compiled in both modes.
> In this case, the library authors would maintain & develop in C++98,
> presumably - relying on forward compatibility warnings (-Wc++11-compat) to
> help guide them. Then for release they'd build both 98 and 11 versions of
> their binaries. Targeting your LCD makes a fair bit of sense to me.
> Is there a particular case where one would be compelled to work in C++11
> when developing and maintaining a library designed for backwards
> compatibility? I suppose the use case you're describing is where the library
> author is actively consuming the library in a C++11 context & tweaking the
> C++98 library day-to-day as they work on their C++11 consumer of that
> library. Possible, if somewhat inefficient, perhaps (that their build system
> is actively building both libs all the time if the C++98/11 lib is such a
> commonly used/general tool - I'd expect it to be built authoritatively,
> perhaps)

I don't think your conclusion follows from your statement of my use case...
Let me try to more concretely describe the practices and patterns I'm
seeing, and would like to support:

Project X develops some utility code. Eventually it becomes useful, and so
it gets factored into a library. I've seen lots of OSS compression,
protocol, and toolkit libraries start this way here at Google (Snappy,
Protobuf, Omaha, ...). The project that initially used it is still the
primary maintainer and consumer, but they grow additional users. Now if that
project starts using C++11 actively, they face (in my view) an unfortunate
choice of maintenance burdens:

a) Separate development of features in the library from the development of
consuming use cases s.t. the library development activity can use a
different build / test / release model, or
b) Develop the library in C++11, but for each release, run it through C++98
builds to make sure it still works for other consumers of the library.

In case (a), essentially they have to double their builds. I think that's
really unfortunate and an undue burden to impose, but maybe others disagree.
In case (b), they have a really slow feedback cycle in learning about issues
in the code they've written. I think that's also bad.

How do we solve it? My proposal is the same way we have solved it for
projects in the reversed position, with some consumers using C++11 but not
the primary maintainers: we give them a compatibility warning flag.

Perhaps this is just an edge use case, but I'd like to point out that
I foresee Clang itself getting into this situation. Imagine if the static
analyzer becomes a nicely separated project, and begins using C++11 features
heavily. Many Clang developers, actively contributing to both the core and
the analyzer, would likely choose to build in C++11 mode. How frustrating
would it be to catch in the build bots when we accidentally used 'auto' in
the wrong file?

> This argument may be invalid, there may be reasons why it's not worth doing
>> (although unless other problems / options arise, it seems to be worth our
>> time at Google), but I don't this is style related.
> Not exactly 'style', no. Perhaps, let's say, "situational", and I think
> that's what Doug's getting at - if it's not on-by-default, clang developers
> aren't really paying much attention to it (I'm not sure I necessarily agree
> with this method - but it's possibly a reality I can't change).

I think that this argument is much weaker, and indeed we have many
"situational" warnings in Clang today. Some key differences to me:
- Style is elected by groups and subject to change rapidly with that group.
As such, introducing it into the compiler couples an external set of
requirements with the internals of the compiler
- Style is more highly variable among users than the situation buckets we're
looking at, as we only address situations impacting multiple important
consumers of Clang
- Style has lower consequences of a violation, and so providing style checks
in the compiler is low bang-for-buck overall (you don't crash when you
violate style)

In contrast, let's look at a clearly situational warning: -Wthread-safety
- Many systems necessitate concurrent, multithreaded programming
- The concerns of thread-safety addressed by the warning are not domain
specific, but theoretical/inherent in any multithreaded application
- Concurrency is something many users deal with, and they all deal with the
same situation: multiple threads sharing memory
- Concurrency bugs yield incorrect programs, crashes, data loss, you name it

The other interesting aspect of warnings which fit into these well-defined
situations is that we can reach out to experts in that particular domain to
ensure what Clang does is sound and applicable across users. That clearly
isn't the case for style checking, but I think it also highlights why
language compatibility warnings should be in the compiler or no where: who
else can possibly get this correct? The compiler and its authors *are* the
experts here.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20111013/df501364/attachment.html>

More information about the cfe-dev mailing list