编译工具链

Assembling a Complete Toolchain — Clang 20.0.0git documentation

LLVM每日谈之四十一 组装一个完整的工具链 从这个翻译摘录了一些内容

语法/语义分析的产物pch/preamble/pcm

-precompile但是实际上好像得是--precompile

生成中间代码 -emit-llvm

clang -emit-llvm -S hello.c
//-S表示人类易读格式

farzon’s blog: Cross-Compiling a Series - Part 1

这系列博客介绍了如何链接musl,如何编译到wasm和arm

clang会默认使用gnu linker,也就是ld

可以使用lld替代

clang会默认寻找gnu c runtime(我觉得这人表述有点容易误解,说的应该是编译器运行时),也就是glibc

可以使用compiler-rt替代

为了使用musl libc需要

手动设置将crt1.o,crti.o,crtn.o参与编译时,好像是因为这几个文件名不以lib开头,不能用-l选项来指定。而libc.a可以

三元组

cpu架构,操作系统,标准库(gnu,musl)

深入理解网络 IO 模型 | 编程沉思录

一个cpp链表实现

Interview question that became a meme - twdev.blog

9 most common pitfalls every C++ programmer eventually falls into - twdev.blog

cmake官方教程

没教第三方库咋用

教了如何支持本地安装(--install),如何打包(cpack),如何生成/修改文件来用于加入编译过程

CS100 笔记

常见的运算符中,其运算对象的求值顺序确定的只有四个: && , || , ?: , ,

出现了奇数次的数

另一种想法:考虑那个出现了奇数次的数

如果 的第i位是 1 ,意味着所有的数中,第i位一共有奇数个 1 。

如果 的第i位是 0 ,意味着所有的数中,第i位一共有偶数个 1 。

所以我们需要一种神奇的操作,让偶数个 1 变成 0 ,让奇数个 1 变成 1 。

或者说,这是二进制意义下的不进位加法。——这就是异或!

C语言ub

Undefined behavior - cppreference.com

void*

C中允许指针隐式地转为/转出void*

因此,在 C 中,接受 malloc 的返回值时不需要显式转换。

底层const

const T*

顶层const

T *const

更一般的,顶层const可以表示任意的对象是常量,这一点对任何数据类型都适用,如算术类型、类、指针等。底层const则与指针和引用等复合类型的基本类型部分有关。

成员初始化的方式

从特殊到一般:

  1. 如果这个成员在当前构造函数的初始值列表中出现了,则遵循初始值列表中给它的 初始化器。
  2. 否则,如果这个成员具有类内初始值,则使用类内初始值。
  3. 否则,如果它能默认初始化,则默认初始化。
  4. 否则,这个成员在当前构造函数中无法被初始化。 如果这是用户自己写的构造函数,则产生编译错误。 如果是编译器合成的构造函数,这个构造函数就是 deleted 的。

值初始化对于类类型几乎就是默认构造函数

对于基本类型就是各种0

默认初始化对于基本类型就是未定义值

const重载的例子

class Dynarray {
public:
const int &at(std::size_t n) const {
	if (n >= m_length)
		throw std::out_of_range{"Dynarray subscript out of range."};
	log_access();
	verify_integrity();
	return m_storage[n];
}
int &at(std::size_t n) {
	return const_cast<int &>(static_cast<const Dynarray *>(this)->at(n)); //先添加底层const,再删除。安全的,合理的
	//如果是用non-const函数实现const,那就是先移除底层const,再添加。不安全的
}
};