Reputation: 11398
Let us say I've written this C++ program (that essentially is doing nothing)
#include <cstdlib>
int main(int argc, char *argv[]) {
enum class Color { Red, Orange, Yellow, Green, Blue, Violet };
constexpr float a = 3.1415f;
auto b = a;
return EXIT_SUCCESS;
}
Is there a way to detect which C++11 features that are used in my program? Is there maybe some other program that could extract this information out of my source code? Such a program could output a list of features:
$ cat main.cc | some-clever-software
N2347
N1984
N2235
(Alternatively it could output URL:s http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf instead)
If I had such a list it would be easier to write a CMakeLists.txt that makes use of the CMake command target_compile_features(), such as this one
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(foobar CXX)
add_executable(foobar main.cc)
set(needed_features
cxx_strong_enums
cxx_constexpr
cxx_auto_type)
target_compile_features(foobar PRIVATE ${needed_features})
The C++11 features that CMake let us choose from are listed in the CMake variable CMAKE_CXX_KNOWN_FEATURES. I know that the CMake command target_compile_features() has not yet been released in a stable CMake release. It currently lives in the development branch so it might come to change in the future. But nevertheless I'm interested if it is possible to detect what C++11 features are used in some C++ source code.
Update:
Compiling without the -std=c++11 compiler option was suggested in a comment:
First compiling with g++
$ g++ --version
g++ (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ main.cc
main.cc: In function ‘int main(int, char**)’:
main.cc:4:3: warning: scoped enums only available with -std=c++11 or -std=gnu++11 [enabled by default]
enum class Color { Red, Orange, Yellow, Green, Blue, Violet };
^
main.cc:5:3: error: ‘constexpr’ was not declared in this scope
constexpr float a = 3.1415f;
^
main.cc:5:13: error: expected ‘;’ before ‘float’
constexpr float a = 3.1415f;
^
main.cc:6:8: error: ‘b’ does not name a type
auto b = a;
^
and then compiling with clang
$ clang --version
Debian clang version 3.2-7ubuntu1 (tags/RELEASE_32/final) (based on LLVM 3.2)
Target: x86_64-pc-linux-gnu
Thread model: posix
$ clang main.cc
main.cc:4:8: error: expected identifier or '{'
enum class Color { Red, Orange, Yellow, Green, Blue, Violet };
^
main.cc:4:3: warning: declaration does not declare anything [-Wmissing-declarations]
enum class Color { Red, Orange, Yellow, Green, Blue, Violet };
^~~~
main.cc:5:3: error: unknown type name 'constexpr'
constexpr float a = 3.1415f;
^
main.cc:5:13: error: expected unqualified-id
constexpr float a = 3.1415f;
^
main.cc:6:3: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto b = a;
^
main.cc:6:12: error: use of undeclared identifier 'a'
auto b = a;
^
2 warnings and 4 errors generated.
$
Of course, the diagnostics from the compilers give me good hints of which C++11 features that are in use. But what I would like to have is more fine-grained information:
N2235
instead of
error: ‘constexpr’ was not declared in this scope
Upvotes: 23
Views: 4909
Reputation: 71979
Try using Clang with -std=c++11 -Wc++98-compat
and parsing the error output. (Clang also has some way to generate more machine-friendly diagnostics.) This should be pretty complete, though probably not 100%, and it definitely won't find C++11-only library features you use.
Upvotes: 2
Reputation: 2397
As said before, this is static analysis of source code. With some simple grep, you can be able to identify some C++11 features such as C++11 STL containers, noexcept, use of move semantic, auto ...
For a more subtle analysis, I would recommend the use of clang API to parse the code source. You can easily check whether a function (and know which one!) is deleted, constexpr... With that, you can do what ever you want (create a report, write the CMake file...)
In all case, I don't think there is a all-in-one tool and you will have to write some parts yourself.
Upvotes: 3
Reputation: 10868
What you are describing is static code analysis. The canonical tool is of course lint, but things have moved on. Wikipedia lists 23 tools for C/C++. http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis
Unfortunately none of them list compliance with specific levels of C++ as a feature. However many of them are rule based and make it easy to add your own rules. The examples you gave are well within the capabilities of many of these tools.
I'm not going to recommend one, partly because I don't know enough, partly because that would be just an opinion. If you are lucky someone has already created a set of rules to do what you want.
Upvotes: 3