Vico Bill< 刘 利 波 > 的个人网站

记录关于学习、工作中的技术点滴

C,C++,Rust,Ruby爱好者;热衷于游戏开发、任务自动化与跨平台;沉迷于游戏引擎与图形表现;深信'简单、多元'哲学的力量。


访问主页

编程语言-C

翻译阶段

  1. 以实现定义方式,映射源文件的单独字节,为源字符集的字符。特别是以换行字符替代依赖OS的行尾指示符。以对应的单字节表示替换三标符。
  2. 删除行尾反斜杠和换行符
  3. 以空格字符替换注释;并分析语法。
  4. 执行预处理器。#include语句所引入的每个文件都经历上面4各过程,递归执行。此阶段结束,从源码移除所有预处理器指令。
  5. 将字符常量和字符串字面量所有字符及转义字符,从源字符集转换成执行字符集。
  6. 连接相邻的字符串字面量
  7. 编译。按照语法和语义分析记号,并将它们翻译成翻译单元。
  8. 链接。将翻译单元与外部引用所需库汇集成程序映像,它含有在其执行环境(OS)中执行的所需信息。

作用域

C包含以下作用域:块作用域(某个代码块)、文件作用域、函数作用域、函数签名作用域、声明点作用域。

类型支持

类型 用途
size_t sizeof运算符返回的无符号整型
ptrdiff_t 指针相减返回的有符号整型
NULL 空指针常量
offsetof 从指定结构体类型的起始,到指定成员的字节偏移

变参

宏与类型 用途
va_start 令函数得以访问可变参数
va_arg 访问下一个函数的可变参数
va_copy 创造函数可变参数的副本
va_end 结束函数可变参数的行程
va_list 保有以上宏所需信息

错误处理

处理 用途
errno POSIX线程局域错误编号变量
assert 断言

动态内存管理

函数 作用
malloc 分配内存
calloc 分配并清零
realloc 扩充之前分配的内存块
free 归还之前分配的内存
aligned_alloc 分配对齐内存

时间管理

函数 作用
difftime 计算时间差
time 返回纪元开始经过的当前系统日历时间
clock 返回未加工的程序启动时开始经过的处理器时间
asctime 将tm转换成文本展示
ctime 将time_t转换成文本展示
strftime 将tm转换成自定义文本表示
gmtime 返回UTC的机缘开始经过的日历时间
localtime 本地时间表示的日历时间
mktime 将日历时间转换成纪元开始经过的时间
   
CLOCKS_PER_SEC 处理器每秒的时间秒
tm 日历时间类型
time_t 纪元开始的日历时间类型
clock_t 从时间点开始的处理器时间类型
   

算法

函数 作用
qsort 快速排序
bsearch 搜索元素

数学:

  • 随机数生成

    函数 作用
    rand 生成伪随机数
    srand 设置随机数生成器种子
  • 复数

  • 三角函数等常见函数

输入输出

文件操作

I/O 流是 FILE 类型对象,只能通过 FILE* 类型指针访问及操作(注意:在可能通过解引用合法的 FILE* 复制创建 FILE 类型局部对象时,在 I/O 函数使用这种副本的地址是未定义行为)。每个流与外部物理设备(文件、标准输入流、打印机、序列端口等)关联。

I/O 流能用于无格式和有格式的输入及输出。它们对本地环境敏感,并可在需要时提供宽/多字节转换。所有流都访问同一本地环境对象:最近 setlocale 所安装者。

在系统指定的需要访问设备的信息(例如 POSIX 文件描述符)外,每个流对象保有下列信息:

1) (C95)字符宽度:未设置、窄或宽。

2) 缓冲状态:无缓冲、行缓冲、全缓冲。

3) 缓冲区,可为外部的用户提供缓冲区所替换。

4) I/O 模式:输入、输出或更新(兼具输入与输出)。

5) 二进制/文本模式指示器。

6) 文件尾指示器。

7) 错误状态指示器。

8) 文件位置指示器( fpos_t 类型对象),对于宽字符流包含剖析状态( mbstate_t 类型对象(C95))。

9) (C11)在多个线程读、写、寻位或查询流时避免数据竞争的再入锁。

函数 作用
fopen 打开文件
freopen 以不同名称打开既存的文件流
fclose 关闭文件
fflush 将输出流与实际文件同步
setbuf 为文件流设置缓冲区
setvbuf 为文件流设置缓冲区和其大小
fread 从文件读取
fwrite 写入到文件
fgetc,fgets 从文件流读取一个字符或字串
fputc,fputs 将字符或字串写入文件流
getchar,gets 从stdin读取一个字符或字串
putchar,puts 将字符或字串写入到stdout
ugetc 将一个字符送回文件流
scanf,fscanf,sscanf,vscanf,vfscanf,vsscanf 从stdin,文件流或缓冲区读取格式化输入
printf,fprintf,sprintf,snprintf 打印格式化输出到stdout、文件流或缓冲区
vprintf,vfprintf,vsprintf,vsnprintf 打印格式化输出到stdout、文件流或缓冲区,使用可变参数列表
ftell 返回当前文件位置指示值
fgetpos 获取文件位置指示器
fseek 将文件位置指示符移动到文件中的指定位置
fsetpos 将文件位置指示器移动到文件中的指定位置
rewind 将文件位置指示器移动
clearerr 清除错误
feof 检查文件结尾
ferror 检查文件错误
perror 将错误显示到stderr
remove 删除文件
rename 重命名文件
tmpfile 返回指向临时文件的指针
tmpnam 返回唯一的文件名

读写模式:

模式 含义 解释 若文件已存在 若文件不存在
r 打开文件以读取 从头读 打开失败
w 创建文件以写入 销毁内容 创建新文件
a 后附 后附到文件 写到结尾 创建新文件
r+ 读扩展 打开文件以读写 从头读 错误
w+ 写扩展 创建文件以读写 销毁内容 创建新文件
a+ 后附扩展 打开文件以读写 写到结尾 创建新文件

本地化支持

函数 作用
setlocale 获取和设置当前C本地环境
localeconv 查询当前本地环境的数值及货币格式化细节
lconv localeconv返回的细节化格式

注意事项:

  • 指针:是间接引用,用于我们创建和销毁的复杂、持久对象。在初始化之前,指针是nullptr(即任意空间)。

字面量

  • 修饰符
    • 变量修饰符: register, const,
    • 函数修饰符: inline,
    • 访问限定符: public, protected, private
  • 作用域: static, extern
    • 局部/自动: 基于代码块
    • 静态: 基于翻译单元(.cpp)和代码块(函数内部静态变量,只在函数内可见并初始化一次; 类内部则为类全局)
    • 全局: 跨代码块和翻译单元
  • 声明与定义:声明不会有链接属性;不占内存空间。

工具:

  • 预处理器:对#语句进行处理

  • 编译器:将.c++翻译为.o。此过程不涉及链接,外部声明姑且认为存在。
    • object文件,包含编译后的机器码和全局、静态变量。所有Object文件都是可重定位(未决定代码的内存地址)和未链接(未解决外部函数引用以及外部定义的全局数据)的。
  • 库归档:将多个.o联合成.a

  • 链接器:将.a,.o链接成最终目标.exe.so。解决所有外部依赖,存在以下结果:依赖未找到;重定义;找到并正确链接。
    • 动态链接库:是未完全链接(内存地址只在载入时确定)的。

附录

  • 内存布局:
    • 代码段:所有函数的可执行机器码
    • 数据段:所有获得初始化的全局、静态变量(内存地址确定)
    • BBS(Block started By Symbols):未初始化的全局和静态变量
    • 只读数据段(Read Only Data Segment): 程序中定义的常量。整数常量常会直接嵌入到机器码(类似预处理操作),而不会存在于RODATA中。
  • 程序运行堆栈: 由系统维护,开始于函数调用,结束于函数调用结束。存储3种数据:
    • 调用函数的返回地址
    • CPU寄存器的内容
    • 局部变量
  • 结构体/类内存布局: 如果类有虚函数即有虚函数表,每个实例。 虚函数表: | 基类虚函数表指针…| 本类虚函数指针… | | 虚函数表指针 | 基类内存布局 | 派生类内存布局 |

重回C/C++

MS Windows C++工具链

  • cl: C++编译器。支持C,C++, C++/CLI, C++/CX。cl也可进行代码分析:cl /analyze demo.cpp

  • link: C++链接器。

  • lib: 用于创建和管理(Common Object File Format )对象文件的通用对象文件格式库。它还可以用于创建导出文件和导入库以便引入导出的定义。

  • editbin: 修改COFF二进制文件

  • dumpbin: 显示信息(如有关COFF二进制文件的符号表)

  • nmake: 读取和执行makefiles。类似Linux平台的make工具。

    NMAKE只能通过Developer Command Prompt打开。它通过vcvars描述不同目标平台的环境变量(如工具、库、包含文件路径等)。

  • xdcmake: 用于处理含XML标签的文档注释的源码文件

  • rc:编译本地资源。

  • msbuild: 是构建管理工具。可创建项目文件(如vcxproj)。如msbuild myproj.vcxproj /p:configuration=debug。可指定生成事件、生成工具

cl编译器选项:

优化

选项 目标
/O1 创建小代码。
/O2 创建快速代码。
/Ob 控制内联展开。
/Od 禁用优化。
/Og 已弃用。 使用全局优化。
/Oi 生成内部函数。
/Os 代码大小优先。
/Ot 代码速度优先。
/Ox 不包含/GF 或/Gy. 的/O2 子集
/Oy 省略帧指针。 (仅限 x86)
/favor 生成针对一个指定体系结构或一系列体系结构进行优化的代码。

代码生成

选项 目标
/arch 使用 SSE 或 SSE2 指令生成代码。 (仅限 x86)
/clr 生成要在公共语言运行时上运行的输出文件。
/EH 指定异常处理模型。
/fp 指定浮点行为。
/GA 针对 Windows 应用程序进行优化。
/Gd 使用 __cdecl 调用约定。 (仅限 x86)
/Ge 已弃用。 激活堆栈探测。
/GF 启用字符串池。
/Gh 调用挂钩函数 _penter
/GH 调用挂钩函数 _pexit
/GL 启用全程序优化。
/Gm 已弃用。 启用最小重新生成。
/GR 启用运行时类型信息 (RTTI)。
/Gr 使用 __fastcall 调用约定。 (仅限 x86)
/GS 检查缓冲区安全性。
/Gs 控制堆栈探测。
/GT 支持使用静态线程本地存储分配的数据的纤程安全。
/guard:cf 添加控制流防护安全检查。
/guard:ehcont 启用 EH 继续元数据。
/Gv 使用 __vectorcall 调用约定。 (仅限 x86 和 x64)
/Gw 启用全程序全局数据优化。
/GX 已弃用。 启用同步异常处理。 改为使用 /EH
/Gy 启用函数级链接。
/GZ 已弃用。 启用快速检查。 与) (相同 /RTC1
/Gz 使用 __stdcall 调用约定。 (仅限 x86)
/homeparams 强制将传入寄存器的参数写入其在函数入口的堆栈上的位置。 此编译器选项仅适用于 x64 编译器 (本机编译和跨平台编译) 。
/hotpatch 创建可热修补的映像。
/Qfast_transcendentals 生成快速先验。
/QIfist 已弃用。 当需要从浮点型转换为整型时,取消调用 Helper 函数 _ftol 。 (仅限 x86)
/Qimprecise_fwaits 删除 fwait 块内 try 的命令。
/QIntel-jcc-erratum 缓解 Intel JCC 错误微代码更新对性能的影响。
/Qpar 启用循环的自动并行化。
/Qpar-report 启用自动并行化的报告级别。
/Qsafe_fp_loads 将整数移动指令用于浮点值,并禁用特定浮点加载优化。
/Qspectre 为 CVE 2017-5753 启用缓解,适用于一类 Spectre 攻击。
/Qspectre-load 为每个加载指令生成序列化说明。
/Qspectre-load-cf 为每个加载内存的控制流指令生成序列化说明。
/Qvec-report 启用自动矢量化的报告级别。
/RTC 启用运行时错误检查。
/volatile 选择如何解释 volatile 关键字。

输出文件

选项 目标
/doc 将文档注释处理到一个 XML 文件中。
/FA 配置程序集列表文件。
/Fa 创建程序集列表文件。
/Fd 重命名程序数据库文件。
/Fe 重命名可执行文件。
/Fi 指定预处理输出文件名。
/Fm 创建映射文件。
/Fo 创建对象文件。
/Fp 指定预编译头文件名。
/FR, /Fr 名称生成 .sbr 的浏览器文件。

预处理器

选项 目标
/AI 指定在解析传递到 #using 指令的文件引用时搜索的目录。
/C 在预处理期间保留注释。
/D 定义常数和宏。
/E 将预处理器输出复制到标准输出。
/EP 将预处理器输出复制到标准输出。
/FI 预处理指定的包含文件。
/FU 强制使用文件名,就像它已被传递到 #using 指令一样。
/Fx 将插入的代码与源文件合并。
/I 在目录中搜索包含文件。
/P 将预处理器输出写入文件。
/U 移除预定义宏。
/u 移除所有的预定义宏。
/X 忽略标准包含目录。

语言

选项 目标
/constexpr constexpr 在编译时控制计算。
/openmp #pragma omp在源代码中启用。
/vd 取消或启用隐藏的 vtordisp 类成员。
/vmb 对指向成员的指针使用最佳的基。
/vmg 对指向成员的指针使用完全一般性。
/vmm 声明多重继承。
/vms 声明单一继承。
/vmv 声明虚拟继承。
/Z7 生成与 C 7.0 兼容的调试信息。
/Za 禁用 C89 语言扩展。
/Zc 指定下的标准行为 /Ze
/Ze 已弃用。 启用 C89 语言扩展。
/Zf 在并行生成中改善 PDB 生成时间。
/ZH 为调试信息中的校验和指定 MD5、SHA-1 或 SHA-256。
/ZI 将调试信息包含在与“编辑并继续”兼容的程序数据库中。 (仅限 x86)
/Zi 生成完整的调试信息。
/Zl 删除文件中的默认库名称 .obj
/Zpn 封装结构成员。
/Zs 只检查语法。
/ZW 生成要在 Windows 运行时上运行的输出文件。

链接

选项 目标
/F 设置堆栈大小。
/LD 创建动态链接库。
/LDd 创建调试动态链接库。
/link 将指定的选项传递给 LINK。
/LN 创建 MSIL 模块。
/MD 使用 msvcrt.lib 编译以创建多线程 DLL。
/MDd 使用 msvcrtd.lib 编译以创建调试多线程 DLL。
/MT 使用 libcmt.lib 编译以创建多线程可执行文件。
/MTd 使用 libcmtd.lib 编译以创建调试多线程可执行文件。

杂项

选项 目标
/? 列出编译器选项。
@ 指定响应文件。
/analyze 启用代码分析。
/bigobj 增加 .obj 文件中可寻址节的数目。
/c 编译但不链接。
/cgthreads 指定用于优化和代码生成的 cl.exe 线程数。
/errorReport 已弃用。 错误报告由 Windows 错误报告 (WER) 设置控制。
/FC 在诊断文本中显示传递给 cl.exe 的源代码文件的完整路径。
/FS 强制写入 PDB 文件,以便通过 MSPDBSRV.EXE 进行序列化。
/H 已弃用。 限制外部(公共)名称的长度。
/HELP 列出编译器选项。
/J 更改默认 char 类型。
/JMC 支持本机 c + + 仅我的代码调试。
/kernel 编译器和链接器将创建可在 Windows 内核中执行的二进制文件。
/MP 同时生成多个源文件。
/nologo 取消显示登录版权标志。
/sdl 启用更多安全功能和警告。
/showIncludes 在编译期间显示所有包含文件的列表。
/sourceDependencies 列出标头、模块和其他源依赖项。
/Tc 指定 C 源文件。
/TC 指定所有源文件均为 C。
/Tp 指定 C++ 源文件。
/TP 指定所有源文件均为 c + +。
/V 已弃用。 设置版本字符串。
/w 禁用所有警告。
/W0, /W1, /W2, /W3, /W4 设置输出警告级别。
/w1, /w2, /w3, /w4 针对指定的警告设置警告级别。
/Wall 启用所有警告,包括默认情况下禁用的警告。
/wd 禁用指定的警告。
/we 将指定的警告视为错误。
/WL 在从命令行编译 C++ 源代码时启用错误消息和警告消息的单行诊断。
/wo 仅显示指定的警告一次。
/Wv 禁用更高版本的编译器引入的警告。
/WX 将警告视为错误。
/Yc 创建 .PCH 文件。
/Yd 已弃用。 将完整的调试信息放在所有对象文件中。 改为使用 /Zi
/Yl 创建调试库时插入 PCH 引用。
/Yu 在生成期间使用预编译头文件。
/Y- 忽略当前生成中的所有其他预编译头编译器选项。
/Zm 指定预编译头内存分配限制。
/await ) 扩展启用协同程序 (可恢复的函数。
/source-charset 设置源字符集。
/execution-charset 设置执行字符集。
/utf-8 将源和执行字符集设置为 UTF-8。
/validate-charset 仅验证 UTF-8 文件的兼容字符。
/diagnostics 控制诊断消息的格式。
/permissive- 设置标准一致性模式。
/std C + + 标准版本兼容性选择器。

实验性选项

实验性选项只能由某些版本的编译器支持。 它们在不同的编译器版本中也可能具有不同的行为。 对于试验性选项,通常是最好的文档,也是 Microsoft c + + 团队博客

选项 目标
/experimental:module 启用实验性模块支持。
/experimental:preprocessor 已弃用。 启用实验相容预处理器支持。 使用 /Zc:preprocessor

弃用并删除的编译器选项

选项 目标
/clr:noAssembly 已弃用。 改用 /LN (创建 MSIL 模块)
/errorReport 已弃用。 错误报告由 Windows 错误报告 (WER) 设置控制。
/Fr 已弃用。 创建无局部变量的浏览信息文件。
/Ge 已弃用。 激活堆栈探测。 默认已启用。
/Gm 已弃用。 启用最小重新生成。
/GX 已弃用。 启用同步异常处理。 改为使用 /EH
/GZ 已弃用。 启用快速检查。 改为使用 /RTC1
/H 已弃用。 限制外部(公共)名称的长度。
/Og 已弃用。 使用全局优化。
/QIfist 已弃用。 曾用来指定如何从浮点类型转换到整型类型。
/V 已弃用。 设置 .obj 文件版本字符串。
/Wp64 已过时。 检测 64 位可移植性问题。
/Yd 已弃用。 将完整的调试信息放在所有对象文件中。 改为使用 /Zi
/Zc:forScope- 已弃用。 在 for 循环范围中禁用一致性。
/Ze 已弃用。 启用语言扩展。
/Zg 在 Visual Studio 2015 中移除。 生成函数原型。

xdcmake 注释文档工具中的特殊标记:

通常使用Doxygen替代。

  • code: 表示为代码
  • example: 示例代码
  • exception: 表明代码会抛出的异常
  • cref: 可交叉引用的
  • include:引用文档
  • list: 列表项
  • para: 段落
  • param:方法的参数名说明
  • permission:指明权限
  • remarks:成员说明。如同doxygen 中的description
  • returns:返回值的说明
  • see:参见,文档内的引用
  • seealso: 同see,但可跨文档引用
  • summary:摘要信息。
最近的文章

编程语言-编程语言特性

编程语言选取 当你选择一个编程语言时,选择的是它的生态圈。 当一款新编程语言不能给你带来新的思想时,它毫无用处。 候选者: 编程语言 特点 C 静态。简单,快速,包含指针,基本宏,内存自管理。原始的模块(文件包含) C++ 静态。C基础上,添加面向...…

继续阅读
更早的文章

编程语言-Javascript编码规范

命名规范 当我们为变量, 函数和实例命名时, 使用 camelCase 命名法. // bad var FOOBar = {}; var foo_bar = {}; function FOOBar () {} // good var fooBar = {}; function fooBar () {} 当我们为类或者模块命名时, 使用 PascalCase 命名法. // bad var foobar = cc.Class({ f...…

继续阅读