如何检测源代码中使用的C ++ 11功能

时间:2014-04-13 12:25:23

标签: c++ c++11 cmake

让我们说我已经编写了这个C ++程序(基本上什么都不做)

#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;
}

有没有办法检测我的程序中使用的C ++ 11功能? 是否有其他程序可以提取此信息 我的源代码? 这样的程序可以输出一系列特征:

$ cat main.cc | some-clever-software
N2347
N1984
N2235

(或者它可以输出URL:s http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf代替)

如果我有这样的列表,那么编写CMakeLists.txt会更容易 使用CMake命令 target_compile_features() ,例如这个

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})

CMake允许我们选择的C ++ 11功能列在CMake变量CMAKE_CXX_KNOWN_FEATURES中。我知道CMake命令 target_compile_features()尚未在稳定的CMake版本中发布。它目前存在于开发分支中,因此将来可能会发生变化。但是,如果有可能检测到某些C ++源代码中使用了哪些C ++ 11特性,我感兴趣。

更新

在评论中建议不使用-std = c ++ 11编译器选项进行编译:

首先使用 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;
        ^

然后使用 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.
$

当然,编译器的诊断程序可以很好地说明正在使用的C ++ 11功能。但我想要的是更细粒度的信息:

N2235

而不是

错误:'constexpr'未在此范围内声明

3 个答案:

答案 0 :(得分:3)

您所描述的是静态代码分析。规范工具当然是lint,但事情已经发生了变化。维基百科列出了23种用于C / C ++的工具。 http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis

不幸的是,他们都没有列出符合特定级别的C ++作为功能。但是,其中许多都是基于规则的,可以轻松添加自己的规则。您提供的示例完全在许多这些工具的功能范围内。

我不打算推​​荐一个,部分是因为我不够了解,部分原因是因为那只是一个意见。如果你很幸运,有人已经创建了一套规则来做你想做的事。

答案 1 :(得分:3)

如前所述,这是源代码的静态分析。 使用一些简单的grep,您可以识别一些C ++ 11功能,例如C ++ 11 STL容器,noexcept,使用移动语义,自动...

对于更细微的分析,我建议使用clang API来解析代码源。 你可以轻松检查一个函数(并知道哪一个!)被删除,constexpr ...有了这个,你可以做任何你想做的事情(创建报告,编写CMake文件......)

在所有情况下,我认为没有一体化工具,您必须自己编写一些零件。

答案 2 :(得分:2)

尝试将Clang与-std=c++11 -Wc++98-compat一起使用并解析错误输出。 (Clang还有一些方法可以产生更加机器友好的诊断。)这应该是相当完整的,虽然可能不是100%,但它肯定不会找到你使用的仅限C ++ 11的库功能。