注意
本文最后更新于 2024-05-16,文中内容可能已过时。
cppinsights
通过展示编译器眼里的源代码,可以让我们更直观地看到编译器做了哪些预处理,从而更好的理解代码生成过程(非汇编)。
我们可以在 nvim
安装一个插件,通过快捷键即可看到转换后的代码了,尤其对于现代 c++
提供的语法糖,可以更进一步的理解背后的语法。
关于 cppinsights
这里引述开发者原文:
2017年,我开始研究我们在C++11、C++14和C++17中得到的一些新特性。像lambda表达式、基于范围的for循环和结构化绑定这样令人惊奇的事物。我在一次演讲中将它们整合在一起。你可以在网上找到演讲幻灯片和视频。
然而,所有的研究以及我的一些培训和教学工作让我开始思考,如果我们能够像编译器一样“看”代码会怎样。当然,至少对于Clang来说,有一个AST转储功能。我们可以使用像Compiler Explorer这样的工具来查看编译器从C++代码片段生成的代码。然而,我们看到的是汇编语言。无论是AST还是Compiler Explorer的输出,都不是我用编写代码时使用的语言。因此,我对这种输出并不熟悉。此外,在教授学生C++时,展示一个AST并解释说这就是全部,对我来说并不十分令人满意。
我开始编写一个基于Clang的工具,它可以将基于范围的for循环转换为编译器内部版本。之后,我对结构化绑定和lambda表达式也做了同样的处理。最终,我完成的工作比最初计划的要多得多。它展示了操作符被调用的位置,以及编译器进行类型转换的地方。C++ Insights可以推断出auto或decltype背后的类型。目标是生成可编译的代码。然而,在所有地方都实现这一点是不可能的。
例如,你可以看到lambda表达式、基于范围的for循环或auto的转换。当然,你也可以转换任何其他C++代码片段。
安装 insight.nvim 插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
return {
"rossjaywill/insights.nvim",
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-telescope/telescope.nvim",
},
config = function()
require("insights").setup{
insights_bin = 'insights',
async = true,
use_default_keymaps = true, -- disable default keymaps, to be user defined
use_libc = true, -- do not use libc++ headers
vim.api.nvim_set_keymap('n', 'ci', ':lua require("insights").run_current_buf()<CR>', { noremap = true, silent = true })
}
end,
}
-- local_only = false, -- only allow insights.nvim to invoke a local cppinsights binary
-- http_only = false, -- only allow insights.nvim to make HTTP requests to cppinsights.io
-- -- If both of these are not set (i.e. the default), then insights.nvim
-- -- will use a local binary, if available, otherwise it will fallback to HTTP
-- -- WARNING: You should think carefully about sending source code over HTTP -
-- -- especially if you are working on a proprietary system.
-- async = true,
-- insights_bin = 'insights',
-- use_default_keymaps = true,
-- use_libc = true,
-- use_vsplit = true,
|
有两点需要说明一下:
- 如果没有在本地找到
cppinsights
,则插件会向网站请求,并把结果传送到本地
- 如果本地有安装二进制,需要
llvm
支持
安装 llvm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# 下载源码
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-13.0.1/llvm-project-13.0.1.src.tar.xz
# 解压源码
tar xvf llvm-project-13.0.1.src.tar.xz
# 新建安装目录
sudo mkdir -p /usr/local/llvm
# 新建编译目录
sudo mkdir -p llvm-project-13.0.1.src/build
# 进入编译目录
cd llvm-project-13.0.1.src/build
# cmake生成编译信息
cmake -G "Unix Makefiles" -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_TARGETS_TO_BUILD=X86 -DCMAKE_BUILD_TYPE="Release" -DLLVM_INCLUDE_TESTS=OFF -DCMAKE_INSTALL_PREFIX="/usr/local/llvm" ../llvm
# 编译
cmake --build .
# 安装到安装目录
cmake --build . --target install
|
安装 cppinsights