聊聊 C++ 中的 unit types

我们通常把一个只有一个值的类型,称为 unit type ,如 OCaml 的 unit 类型,就只有一个值 ()。unit type 类型的值通常不被用于携带信息,而往往是出于形式的需要。 在 C++ 引入 monadic operations 以后,一个传统的 unit type 的重要性开始凸显。然而,C++ 仍旧在使用 void 。在传统上,其它语言...

阅读全文

使用 cmake-file-api 获取链接信息

假设你现在是一个 IDE 的作者,正在添加对 cmake 项目的支持。你需要从 cmake 的执行结果中,获取所有源代码的信息,比如,使用什么参数编译,都有哪些文件,等等。这时候你会使用什么方法?我相信大多数人第一个想到的是 compilation database ,很多简易版本的 IDE 支持也是使用这个方法。不过,这种方式只能获取很简单的参数信息。如果...

阅读全文

如何优雅的释放内存(二):使用 GC 库

在 上一篇文章 中,我们提到 C 语言中可以使用 GC 库。这个 GC 库就是 The Boehm-Demers-Weiser conservative C/C++ Garbage Collector ,常说的 bdwgc, libgc, boehm-gc 都是指这个 GC 库。基本上,一个带 GC 的编程语言的实现,如果不是选择自己实现 gc 库(如官方 ...

阅读全文

C++ 不会 “move”

很多人以为 C++ 中的 std::move() 或者所谓的 move semantics (很多人认为这两者等同)就是对内存中的对象进行移动。更有甚者,认为只要命令内存,把一块内存移动到另一个地方,这块内存就像一个乐高一样,被拆了,然后装到另一个地方上去。 内存数据的移动和复制 其实内存没有这么厉害的功能啦!当我们讲“将一块内存移动到另一个地方”的时候,意...

阅读全文

如何优雅的释放内存(一)

我发现很多人都不懂的怎么管理内存,一旦失去了 GC,就不知道怎么释放内存了。本人写了几十年程序,自始自终没有感觉到这是一个问题。下面这些小经验可以让你让你在绝大多数情况下都游刃有余。 成对的分配和释放 当你写分配内存的代码的时候,同时也写内存释放的代码。然后再写别的代码。这样的好处是可以避免忘了释放内存。 “谁分配?谁释放?”原则 任何一个程序,首先要回答一...

阅读全文

使用 std::ignore 避免 unused warnings

通常情况下,要避免 unused warnings ,可以使用 [[maybe_unused]]。例如下面的程序,去掉 [[maybe_unused]] ,那么就会提示 unused variable 的 warning 。 https://godbolt.org/z/cW3Wsnaqj123int main() { int x [[mayb...

阅读全文

不断补充的现代 CAI 列表

CAI (Computer-Assisted Instruction, 计算机辅助教学) 这个词起码二十年没听人提起过了。简单说就是一些教学软件。在90年代,CAI 软件《开天辟地》曾经风靡一时。下面列出一些现代的 CAI 系统。 Racket 这既是一个编程语言开发环境,也是最有名的 Scheme 开发平台,同时也是一个 CAI 软件。当你第一次打开 Dr...

阅读全文

对 Prolog 代码进行反汇编

很多人对 Prolog 的印象都是“不就是枚举吗?”。实际上 Prolog 是跟 C/C++/Java 一样的通用编程语言。Prolog程序通常跑在WAM虚拟机上[1]。和JVM不同的是,WAM是一个概念模型,因而各家WAM差别还是蛮大的。 既然 Prolog 是跑在虚拟机上的编程语言,那就有字节码,而对应的字节码也有相应的汇编形式。因此我们也可以对我们的 ...

阅读全文

ABCL - 最快的 Common Lisp 实现

很多人都认为 SBCL 是“最快”的 Common Lisp 实现。然而,这种情况,在OpenJDK 11出来后被反转了。ABCL是 JVM 上的 Common Lisp 实现。可能由于投入不足,这个实现基本上是没有多少编译优化的,生成的代码又臭又长又慢。即便如此,凭借JVM的优化,这些又臭又长的代码也能优化成最快的 Common Lisp 代码。下面的例子...

阅读全文

在 Clozure Common Lisp 中使用汇编(二) - 使用GDB调试

在 上一篇文章 中,我们提到了在 CCL 中编写汇编代码的方法。那么,怎么对这些汇编代码设断点并调试呢?这就需要使用 gdb 了。 通过 gdb 加载 CCL 首先,确保拥有全套 CCL 的源代码,假设ccl的binaries和源代码都在 ~/ccl中。 编译 CCL 在第一次加载前,先完整的重新编译一次 CCL 的源代码,确保 binaries 和 源代码...

阅读全文