Easy way to detect where the C++11/C++14 features are used in a C++ project
cppdepend.com
cppdepend.com
http://lists.llvm.org/pipermail/llvm-bugs/2017-June/056419.h...
For example, this is the error message GCC returns when it catches an "override" keyword when compiling with --std=c++03 flags:
> controls (override/final) only available with -std=c++11 or -std=gnu++11
#include <memory>
#define u8 }{
struct Foo {
char const *foo() {
char const *r = u8"foo";
std::make_unique<int>(1);
return r;
}
};
Maybe now you can argue it won't happen in practice, and my intuition is you'd still be wrong for large projects, but I don't have the time to try to come with a more realistic example. Hopefully this is enough to get the point across though. The syntax has changed, and the compiler can be only so smart trying to decipher it efficiently.Test code:
#include <memory>
int main()
{
std::unique_ptr<int> pPointer = std::make_unique<int>();
return 0;
}Here's the GCC output (v4.9.2) with C++14:
geezerjay@debian:tmp$ g++ --std=c++14 main.c++
geezerjay@debian:tmp$
And now the GCC output with C++11:
geezerjay@debian:tmp$ g++ --std=c++14 main.c++
main.c++: In function ‘int main()’:
main.c++:5:34: error: ‘make_unique’ is not a member of ‘std’ std::unique_ptr<int> pPointer = std::make_unique<int>();
^
main.c++:5:51: error: expected primary-expression before ‘int’ std::unique_ptr<int> pPointer = std::make_unique<int>();
geezerjay@debian:tmp$Perhaps recent GCC versions catch this issue, but errors are indeed thrown if make_unique, a C++14 feature, is present while compiling C++11 code.
I'm not blaming anybody/anything though
> It never gets to the make_unique because there's another error before it.
Yes, that was literally the entire point of this example, because the prior commenter had said that GCC doesn't stumble on parsing errors and keeps going anyway.
(a) It's a fundamental (but common) mistake to view processing as a logically "separate" stage from compiling C++ code. The two are semantically intertwined for all intents and purposes. Trivial example: the value of std::numeric_limits<int>::max() MUST match that of INT_MAX. Another trivial example: #pragmas (like omp parallel or vectorize) are "preprocessor" directives that can't really be "preprocessed"; they're often tightly coupled to the actual code. You cannot preprocess a program with a compiler that differs in any semantically visivle way from the actual compiler and expect the program to behave as the C++ standard specifies. The correct way to see a preprocessed file is as a convenient text-format snapshot/dump of the compiler's memory in the overall compilation process, nothing more.
(b) I don't want to spend more time on this but I'm pretty sure you could find a counterexample that doesn't depend on the preprocessor if you try hard enough. Just pretend I'm claiming the opposite and you're arguing with me about that, trying to prove me wrong. I'm sure you'll find a counterexample. Look at >> vs. > > and the like if you have no idea where to start.
Sounds like you've found a bug in GCC. Why not report it?