语言学习类
Learn Cpp
Learn Cpp是一个英文的C++教程网站,教你如何从完全没有编程基础到使用c++进行编程。目前共有23章以及3个附录。如果你喜欢在在线教程并且英语勉强过关,这是一个不错的学习网站。
Runoob
如果实在是英语不行或者指向看中文的教程,作为入门,Runoob也可以一看。这个网站提供了常见的各种语言的入门教程,网站本身也可以在线编译和运行c++程序。
地址:https://www.runoob.com/cplusplus/cpp-tutorial.html
编译运行工具
C++ shell
C++ shell是一个在线编译运行网站。支持从98到23的c++标准,三个警告选项(-Wall, -Wextra, -Wpedantic)以及五个优化级别选项(-O0, -O1, -O2, -O3, -Oz)。功能相对简单,但是测试一些随手写的代码足够了。
Online GDB
Online GDB是一个多语言的在线编译运行网站,可以看成是C++ shell的增强版。就像它的名字说的一样,特色就是提供了在线的GDB调试功能。GDB对于使用Linux编程的同学来说可能更加熟悉,建议不熟悉的同学都可以学习一下使用,绝对是调试程序的利器。
Wandbox
也是一个多语言的在线编译网站。特点是可以选择是否使用boost,也可以手动往里面填编译选项。
性能Profiler
Quick Bench
在线的benchmark网站,可以快速比较多段代码的性能。它可以让你选择编译器、c++标准、优化级别以及使用的stl版本。Run Benchmark之后你可以在左边看到用图展示的benchmark的结果,然后在Assembly这个tab里面还可以看到到底是哪部分比较吃性能。
Perf Bench
一个跟QuickBench类似的benchmark网站。里面有两个特点:
- 除了图标还有更加详细的报表数据;
- 记录每一次运行的数据。
个人是更喜欢这个网站的profile功能。
探索内部编译
Godbolt
Compiler Explorer是2019年在Cpp大会上做过presentation(CppCon 2019: Matt Godbolt “Compiler Explorer: Behind The Scenes”)的在线网站,它主要的特点是把c++实时转换成汇编。汇编可选种类也比较多,arm汇编,x86汇编配合各个版本的编译器。非常有特色的一点是你把鼠标放在左边的cpp文件的某一行的时候,右边对应的汇编也会被高亮,这样你能够很容易知道每一行转换出的对应的汇编是什么样的。
这绝对是一个你直接去尝试一下的一个网站。
Cpp Insights
这是一个探索C++的source-to-source的变换的网站。它不想Godbolt给你展示最后的汇编,而是展示C++源码中间转换的过程。比如下面的简单的模版,它可以展示给你特化后的样子。
源码:
#include <cstdio>
template <typename T>
struct Vec
{
Vec(): Vec(0, 0, 0){}
Vec(T a, T b, T c): x{a}, y{b}, z{c}{}
Vec operator+(const Vec &rhs) const
{
return Vec{x+rhs.x, y+rhs.y, z + rhs.z};
}
T x, y, z;
};
int main()
{
using Vec3i = Vec<int>;
using Vec3f = Vec<float>;
Vec3i v1, v2;
auto v = v1+v2;
printf("%d, %d\n", v.x, v.y);
return 0;
}
CppInsight展示的转换之后的代码:
#include <cstdio>
template<typename T>
struct Vec
{
inline Vec()
: Vec<T>{0, 0, 0}
{
}
inline Vec(T a, T b, T c)
: x{a}
, y{b}
, z{c}
{
}
T x;
T y;
T z;
inline Vec<T> operator+(const Vec<T> & rhs) const
{
return Vec<T>{{this->x + rhs.x, this->y + rhs.y, this->z + rhs.z}};
}
};
/* First instantiated from: insights.cpp:21 */
#ifdef INSIGHTS_USE_TEMPLATE
template<>
struct Vec<int>
{
inline Vec()
: Vec<int>(0, 0, 0)
{
}
inline Vec(int a, int b, int c)
: x{a}
, y{b}
, z{c}
{
}
int x;
int y;
int z;
inline Vec<int> operator+(const Vec<int> & rhs) const
{
return Vec<int>{this->x + rhs.x, this->y + rhs.y, this->z + rhs.z};
}
};
#endif
int main()
{
using Vec3i = Vec<int>;
using Vec3f = Vec<float>;
Vec<int> v1 = Vec<int>();
Vec<int> v2 = Vec<int>();
Vec<int> v = v1.operator+(v2);
printf("%d, %d\n", v.x, v.y);
return 0;
}
欢迎关注公众号“探知轩”。