C3C编译器项目代码风格指南解析
c3c Compiler for the C3 language 项目地址: https://gitcode.com/gh_mirrors/c3/c3c
前言
在参与C3C编译器项目开发时,遵循统一的代码风格对于保持代码库的一致性和可维护性至关重要。本文将深入解析C3C项目的编码规范,帮助开发者快速掌握项目要求的代码风格和最佳实践。
命名规范
大小写约定
C3C项目采用以下几种命名约定:
-
常量命名:使用全大写字母和下划线组合(UPPER_SNAKE_CASE)
#define MAX_BUFFER_SIZE 1024
-
宏定义:同样使用全大写字母和下划线组合
#define SAFE_FREE(ptr) do { if (ptr) free(ptr); } while(0)
-
自定义类型:采用首字母大写的驼峰命名法(PascalCase)
typedef struct TypeInfo { // 成员定义 } TypeInfo;
-
函数和变量:使用小写字母和下划线组合(snake_case)
int calculate_buffer_size(int elements);
面向对象风格的函数命名
对于操作特定类型的函数,采用"类型名_操作"的命名方式:
// 推荐
type_info_new();
// 不推荐
new_type_info();
代码格式规范
大括号风格
项目采用Allman风格的大括号放置方式:
if (condition)
{
// 代码块
}
缩进与标签
-
goto标签:不缩进,顶格书写
int function() { // 代码... LABEL: // 更多代码... }
-
case语句:使用一个制表符缩进
switch (value) { case 1: do_something(); break; case 2: do_another_thing(); FALLTHROUGH; default: handle_default(); }
空格使用规范
-
控制语句与括号之间需要空格:
if (condition) ... while (loop_condition) ...
-
逗号后和表达式间需要空格:
int array[] = {1, 2, 3};
-
赋值运算符周围需要空格:
int a = b + c;
-
括号内部不留空格:
int result = calculate(a * (b + c));
缩进与换行
-
使用制表符(Tab)进行缩进,禁止使用空格缩进
-
禁止使用CRLF换行符,统一使用LF
-
包含else的if语句必须使用大括号:
if (condition) { // 代码块 } else { // 其他情况 }
-
单行if语句可以省略大括号:
if (is_valid()) return true;
设计原则
头文件管理
建议使用较大的头文件,能够被多个源文件共享,而不是为每个源文件创建单独的头文件。例如使用sema_internal.h
这样的综合性头文件。
代码简洁性
- 避免过度设计,不要添加"以防万一"的代码
- 保持代码直接和目的明确
- 每个功能应该有明确的存在理由
测试驱动开发
- 未经测试的代码视为不可靠代码
- 添加新功能时应同时添加测试用例
- 修复bug时应添加回归测试
依赖管理
- 尽量减少外部库依赖
- 当前仅依赖LLVM和libc(可选libcurl)
- 如需功能,可考虑重写子集而非引入完整库
内部实现细节
内存分配器
- 使用arena分配器,直到编译器退出才释放
- 特定类型(如Decl、Ast)有专用分配器
- 注意分配的生命周期,确保不在代码生成阶段使用已释放内存
动态数组
广泛使用基于arena的动态数组:
// 声明
Type* array = NULL;
// 添加元素
vec_add(array, (Type){field1, field2});
// 遍历
VECEACH(array, element)
{
// 处理element
}
字符串处理
使用global_context
中的临时字符串缓冲区处理临时字符串,避免频繁内存分配。
标准库编码规范
大括号风格
标准库代码必须使用Allman风格:
fn void example_function(String param)
{
@pool()
{
// 实现代码
}
}
类型命名
- 使用PascalCase而非Ada_Case
- 绑定系统API时尽量保留原名,必要时可加前缀或调整首字母
// 推荐
enum FileMode
{
READ,
WRITE
}
// 绑定系统类型
typedef void* Win32_HANDLE;
typedef int Mode_t;
函数与变量
- 使用snake_case命名
- 方法第一个参数通常命名为
self
- 分配器参数统一命名为
allocator
并作为第一个常规参数
int global_counter = 0;
fn void object_method(Object self, Allocator allocator)
{
// 方法实现
}
测试要求
所有标准库修改必须包含对应的单元测试,放置在test/unit/stdlib
目录中。
结语
遵循这些编码规范将有助于保持C3C编译器代码库的一致性和可维护性。在贡献代码前,请确保熟悉这些规范,并在开发过程中始终如一地应用它们。良好的代码风格不仅能提高代码质量,也能让其他开发者更容易理解和维护你的贡献。
c3c Compiler for the C3 language 项目地址: https://gitcode.com/gh_mirrors/c3/c3c
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考