前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >全面解读curl团队的C语言代码规范

全面解读curl团队的C语言代码规范

作者头像
公众号guangcity
发布2024-04-28 15:23:33
700
发布2024-04-28 15:23:33
举报
文章被收录于专栏:光城(guangcity)光城(guangcity)

代码风格统一有助于团队协作与代码review,业界用的比较多的是google的风格,本节来点不一样的,看看咱们平时用的比较多的工具curl团队的代码规范是什么样子的。

curl简单说一下,它在命令行或脚本中传输数据非常有用,大家也肯定用过,其源码实现可以在github上查看

https://github.com/curl/curl

下面我们来从几个方面看看curl的C语言开发规范。

  • 命名
  • 缩进
  • 注释
  • 长行
  • 大括号
  • 'else' 在下一行
  • 括号前不加空格
  • 使用布尔条件
  • 条件中不要赋值
  • 新块在新行上
  • 运算符周围加空格
  • 返回值不加括号
  • sizeof 参数加括号
  • 列对齐
  • 平台相关代码
  • 不要 typedef 结构体

命名

新的函数和变量名称应该是逻辑的、可理解的,并且根据它们的用途进行命名。

文件局部函数应该被声明为静态的,建议是小写字母名称。

缩进

只使用空格进行缩进,不使用制表符。每个新的开放大括号使用两个空格。

代码语言:javascript
复制
if(something_is_true) {
  while(second_statement == fine) {
    moo();
  }
}

注释

由于编写的是 C89 代码,不允许使用 // 注释。它们直到 C99 标准才被引入。只使用 **/* 注释 */**。

代码语言:javascript
复制
/* 这是一个注释 */

长行

curl 中的源代码永远不应该超过 79 列,即使在现代大屏幕和高分辨率屏幕时代,仍然有两个原因要保持这一点:

  1. 较窄的列比较宽的列更容易阅读。有一个原因是报纸几十年甚至几个世纪来一直使用列。
  2. 较窄的列允许开发人员更容易地在不同的窗口中并排显示多个代码片段。它允许在同一个屏幕上并排显示两个或三个源代码窗口 - 以及多个终端和调试窗口。

大括号

在 if/while/do/for 表达式中,我们将开放大括号写在与关键字同一行,然后将闭合大括号设置在与初始关键字相同缩进级别的同一行。就像这样:

代码语言:javascript
复制
if(age < 40) {
  /* 显然是年轻人 */
}

如果它们只包含一个一行语句,则可以省略大括号:

代码语言:javascript
复制
if(!x)
  continue;

对于函数,开放大括号应该写在单独的一行上:

代码语言:javascript
复制
int main(int argc, char **argv)
{
  return 1;
}

'else' 在下一行

在使用大括号添加 else 子句到条件表达式时,我们将其添加到关闭大括号后的新行。就像这样:

代码语言:javascript
复制
if(age < 40) {
  /* 显然是年轻人 */
}
else {
  /* 可能是脾气暴躁的 */
}

括号前不加空格

在使用 if/while/do/for 表达式时,关键字与开放括号之间不应有空格。就像这样:

代码语言:javascript
复制
while(1) {
  /* 永远循环 */
}

使用布尔条件

在 if/while 条件中,我们更喜欢测试条件值,如布尔值与 TRUE 或 FALSE、指针与 NULL 或 != NULL 以及整数与零或非零,而不是:

代码语言:javascript
复制
result = do_something();
if(!result) {
  /* 出现了问题 */
  return result;
}

条件中不要赋值

为了增加可读性并减少条件的复杂性,避免在 if/while 条件中进行变量赋值。不赞成这种风格:

代码语言:javascript
复制
if((ptr = malloc(100)) == NULL)
  return NULL;

而是鼓励更清晰地表达:

代码语言:javascript
复制
ptr = malloc(100);
if(!ptr)
  return NULL;

新块在新行上

永远不会在同一行上写多个语句,即使是短的 if() 条件也不例外。

代码语言:javascript
复制
if(a)
  return TRUE;
else if(b)
  return FALSE;

永远不要这样:

代码语言:javascript
复制
if(a) return TRUE;
else if(b) return FALSE;

运算符周围加空格

请在 C 表达式中运算符的两侧使用空格。后缀 (), [], ->, ., ++, -- 和一元 +, -, !, ~, & 操作符除外,它们不应该有空格。

示例:

代码语言:javascript
复制
bla = func();
who = name[0];
age += 1;
true = !false;
size += -2 + 3 *

 (a + b);
ptr->member = a++;
struct.field = b--;
ptr = &address;
contents = *pointer;
complement = ~bits;
empty = (!*string) ? TRUE : FALSE;

返回值不加括号

在 'return' 语句中不加额外的括号:

代码语言:javascript
复制
int works(void)
{
  return TRUE;
}

sizeof 参数加括号

在代码中使用 sizeof 运算符时,我们更喜欢在其参数周围加上括号:

代码语言:javascript
复制
int size = sizeof(int);

列对齐

一些语句不能在单行上完成,因为行太长、语句太难读,或者是由于上述其他风格指南。在这种情况下,语句跨越多行。

如果一个连续行是表达式或子表达式的一部分,那么你应该在适当的列上对齐,以便能够清楚地知道它是语句的哪一部分。运算符不应该起始于连续行。在其他情况下,遵循 2 个空格的缩进指南。以下是来自 libcurl 的一些示例:

代码语言:javascript
复制
if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
   (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
   (handle->set.httpreq == HTTPREQ_GET ||
    handle->set.httpreq == HTTPREQ_HEAD))
  /* 没有要求 HTTP/1.0 并且是 GET 或 HEAD 请求 */
  return TRUE;

如果没有括号,使用默认缩进:

代码语言:javascript
复制
data->set.http_disable_hostname_check_before_authentication =
  (0 != va_arg(param, long)) ? TRUE : FALSE;

函数调用时使用开放括号:

代码语言:javascript
复制
if(option) {
  result = parse_login_details(option, strlen(option),
                               (userp ? &user : NULL),
                               (passwdp ? &passwd : NULL),
                               NULL);
}

与 "current open" 括号对齐:

代码语言:javascript
复制
DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
             "server response left\n",
             (int)clipamount));

平台相关代码

使用 #ifdef HAVE_FEATURE 进行条件代码。我们避免在 #ifdef 行中检查特定操作系统或硬件。HAVE_FEATURE 应该由 configure 脚本为类 Unix 系统生成,并且它们在其他系统的 config-[system].h 文件中硬编码。

我们还鼓励在 libcurl 构建时,使用可能为空或定义为常量的宏/函数,以使代码无缝。就像这个例子,其中 magic() 函数根据构建时的条件不同而工作:

代码语言:javascript
复制
#ifdef HAVE_MAGIC
void magic(int a)
{
  return a + 2;
}
#else
#define magic(x) 1
#endif

int content = magic(3);

不要 typedef 结构体

尽管可以使用结构体,但不要对其进行 typedef。使用 struct name 的方式来标识它们:

代码语言:javascript
复制
struct something {
   void *valid;
   size_t way_to_write;
};
struct something instance;

不要这样

代码语言:javascript
复制
typedef struct {
   void *wrong;
   size_t way_to_write;
} something;
something instance;

本文翻译自:https://curl.se/dev/code-style.html


本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-23,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 光城 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 命名
  • 缩进
  • 注释
  • 长行
  • 大括号
  • 'else' 在下一行
  • 括号前不加空格
  • 使用布尔条件
  • 条件中不要赋值
  • 新块在新行上
  • 运算符周围加空格
  • 返回值不加括号
  • sizeof 参数加括号
  • 列对齐
  • 平台相关代码
  • 不要 typedef 结构体
相关产品与服务
Prowork 团队协同
ProWork 团队协同(以下简称 ProWork )是便捷高效的协同平台,为团队中的不同角色提供支持。团队成员可以通过日历、清单来规划每?的工作,同时管理者也可以通过统计报表随时掌握团队状况。ProWork 摒弃了僵化的流程,通过灵活轻量的任务管理体系,满足不同团队的实际情况,目前 ProWork 所有功能均可免费使用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com