Erik Sjölund
Erik Sjölund

Reputation: 11398

How to detect which C++11 features are used in my source code

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

Answers (3)

Sebastian Redl
Sebastian Redl

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

Davidbrcz
Davidbrcz

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

david.pfx
david.pfx

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

Related Questions