c++ - 如何检测我的源代码中使用了哪些 C++11 功能

标签 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”未在此范围内声明

最佳答案

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

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

在所有情况下,我不认为有一个多合一的工具,你必须自己编写一些部分。

关于c++ - 如何检测我的源代码中使用了哪些 C++11 功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23042722/

相关文章:

c++ - 如何最好地为 Visual Studio 2017 构建的 CMake C++ 项目设置输出目录?

C++ popen() 参数

c++ - 我应该在 C++ 中内联它吗?

c++ - Visual Studio 在调试时将不相关的 DLL 加载到我的项目中

android - 如何防止 Gradle/Android Studio 覆盖 CMake 提供的 C++ 编译器设置?

directx - 如何使用 cmake 编译 .fx 文件

c++ - 具有尾随返回类型的通用 lambda 取决于 C++11 中的可变参数

c++ - 从 C++98 过渡到 C++0x

c++ - 在 constexpr 中使用非常量变量?

c++ - 将重载函数转换为模板仿函数