让我们说我已经编写了这个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;
}
Run Code Online (Sandbox Code Playgroud)
有没有办法检测我的程序中使用的C++ 11功能?是否有其他程序可以从我的源代码中提取这些信息?这样的程序可以输出一系列功能:
$ cat main.cc | some-clever-software
N2347
N1984
N2235
Run Code Online (Sandbox Code Playgroud)
(或者它可以输出URL:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf)
如果我有这样的列表,那么编写一个使用CMake命令target_compile_features()的CMakeLists.txt会更容易,比如这个
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})
Run Code Online (Sandbox Code Playgroud)
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;
^
Run Code Online (Sandbox Code Playgroud)
然后用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.
$
Run Code Online (Sandbox Code Playgroud)
当然,编译器的诊断程序给了我很好的提示,说明正在使用的C++ 11功能.但我想要的是更细粒度的信息:
N2235
代替
错误:'constexpr'未在此范围内声明
正如之前所说,这是源代码的静态分析。通过一些简单的 grep,您可以识别一些 C++11 功能,例如 C++11 STL 容器、noexcept、移动语义的使用、自动...
对于更精细的分析,我建议使用 clang API 来解析代码源。您可以轻松检查某个函数(并知道是哪一个!)是否被删除,constexpr...有了它,您可以做任何您想做的事情(创建报告,编写 CMake 文件...)
无论如何,我认为没有一个一体化的工具,您必须自己编写一些部分。