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.