杰克-逊の黑豹,恰饭了啦 []( ̄▽ ̄)

keywords: Redis c cpp

厌弃c言语的现象

长久以来,程序员们对待c言语的态度十分矛盾,主要应该有这么几种:

  • 喜爱、作业中运用c言语;
  • 不恶感、作业中运用c言语;
  • 不恶感、作业中不运用c言语;
  • 恶感、作业中运用c言语;
  • 恶感、碰都不碰c言语;

赞赏c言语的程序员,或许会有这些观点:

  • 运用c言语的程序员是最nb的;
  • 真实的编程大佬都运用c言语;

厌烦c言语的程序员,大抵是因为这些:

  • 没有舒服的包办理机制;
  • 没有丰厚的规范库;
  • 没有面向对象的语料支撑;
  • 内存不行安全(内存走漏、悬垂指针、不合法指针、无效指针等等);
  • 编译器输出信息不行好;
  • 错误处理不行舒服;
  • 项目办理杂乱;

再加上,像Rust/Go/Swift等这种现代编程言语的呈现,更让许多程序员厌弃c言语。

现代编程言语和c言语比起来,有什么最大的特色?以我个人而言,最大的特色便是编程言语的表达能力 十分出色,不是C言语能够比拟的。表达能力更具体地讲便是更灵活、更模块化、更适合人阅览。

难道说c言语真的是魔鬼吗?

反驳者一定会举出嵌入式开发、操作系统开发、驱动开发范畴的成功案例。

但我觉得,这样就又大又空洞了。

近来,我在看Redis1.3.6源码,觉得却是个很好的例子说说这事儿,不过读者大可放心,本文不是xx源码阅览, xx源码细品的文章,更不是什么八股文,单纯作为一个例子,解释下c言语是不是魔鬼这回事儿。

先说下我个人的定论吧。

c言语是不是魔鬼,取决于你能hold住多少c言语代码量。hold住,c言语的缺点不是事儿;hold不住,c言语就会带来悲惨剧。一定程度上,这就像咱们尝试三个小时坚持精神高度集中相同,固然你说自己的c言语功夫十分扎实,可是随着项目规模增大,我可不信任你照样能够注意到每个角落的c言语隐患。

假如你是95后,c言语不适合作为你的主力开发言语,可是你能够学习由c言语开发且十分稳定的项目,也能够基于c言语ABI将这些c言语项目植入到其他编程言语开发的项目中,比方Rust/Go/Javascript/Swift项目。

为什么挑选Redis1.3.6

事物总是由简入繁,功用总是由少渐多,项目总是由骨到肉。

越早的版别,越简单看出作者的微观思路。

越新的版别,越会充斥各种新功用、小功用,越发讳饰作者最初的构思。

我从github下载好Redis后,发现最早的一个版别号便是1.3.6, 所以就用这个做参考了。

实际上,我硬着头皮看了两天最新的版别,发现的确啃不动。

看看Redis怎样处理包办理问题的

在1.3.6版别中,redis没有依靠的包,可是在最新版别中,redis将这些依靠放置于deps文件夹下。这里边没有什么特其他地方,便是将依靠的库房源码放置在一个独自的文件夹下,定时去看看库房源码有没有更新,假如更新的话,按需求将本地做更新,就和你的本地库房、长途库房相同。

透过Redis看待我们是否应该继续使用c语言

一起,你也看到了,依靠并不多的确能够这样做,假如依靠多的话,这么搞就难搞了,就需求包办理程序(第三方的或许自己开发的)。不过嘛,一般用c言语开发的项目,都是追求极度功用,功用十分专注的项目,不会掺入太多的依靠。可是应用层项目就不同了,依靠贼多。

看看Redis怎样处理规范库不太丰厚的

c言语开发时用到的API基本上是操作系统原生供给的API,这些API都散布在操作系统供给的固定的.h文件中,比方:

  • unistd.h
  • sys/sysctl.h
  • pthread.h
  • sys/stat.h
  • fcntl.h
  • execinfo.h
  • ucontext.h

当然也需求c言语供给的规范库.h文件,比方:

  • stdlib.h
  • stdio.h
  • stdarg.h
  • erron.h
  • ctype.h

例如redis.c文件中就用到了许多耳熟能详的.h文件:

透过Redis看待我们是否应该继续使用c语言

两类之外的功用,要么从第三方复制,要么就要自己写。当然,在redis1.3.6中依靠并不多,只需求一些数据结构的完成,比方哈希表(hash table)、动态字符串(dynamic string)、双向链表(double linked list)、压缩型字符串映射表(zip map, 应该是redis作者首创的)。这些都是redis作者完成的。

可不要被完成吓坏了。

自己创造式地想到一个数据结构,然后用代码写出来,叫做完成;

自己参考数据结构书本、论文中的理论,给出自己的完成,这也叫做完成。

都成年人了,要知道:考试不是只叫做闭卷考试

像pqsort(部分快速排序),redis作者便是参考NetBSD平台下的libc源码完成的,作者在代码注释中给出了声明:

透过Redis看待我们是否应该继续使用c语言

你或许会问了,我完成的版别功用无法保证怎样办?redis作者其实也告诉咱们答案了,那便是先搞出一版完成,至于功用好坏是另一个问题,能够先不必管它。所以,在ae.c的文件中,咱们看到redis作者写到这样的注释:

透过Redis看待我们是否应该继续使用c语言

c项目一般坚持功用专注、功用卓越,常常要定制化一些数据结构的代码,所以即使规范库参加这些数据结构,也未必能满意c项目的需求,或许也派不上多大用场。

如此看来,c项目不太需求那种普适、一致的规范库,更需团队开发、企业开发、安排开发范围内的规范库。

可是关于技能经历尚浅(没查阅论文、手册、其余资料,独立完成一些功用库)的开发者来说,他们需求的是包括功用的规范库,而不是刚提到的那种高度定制化的规范库。

所以规范库不太丰厚的这种问题,关于项目不大、开发者具有经历的情况而言,不成问题;关于经历不足的开发而言,是个头大的问题;关于项目贼大的情况而言,无论经历多少,都是头大的问题。

看看Redis是怎样处理面向对象编程的

面向对象编程,说的便是一种编程思想,但一部分开发者常常会被编程言语的办法所蒙蔽,以为编程言语给出了面向对象代码办法(供给class extends public等关键字),才算面向对象了,关于没有给出这种办法的编程言语,就无法面向对象编程。

看看Redis是怎样做的吧。

透过Redis看待我们是否应该继续使用c语言

struct等效于classaeBeforeSleepProc便是类中界说的成员办法啊,其界说如下:

透过Redis看待我们是否应该继续使用c语言

至于继承,能够运用组合的办法代替;

至于多态,能够持续运用函数指针或许改用函数映射表代替;

宽泛地讲,只要有了封装, 即使没有给出严厉的继承多态, 也能够以为是面向对象。究竟,面向对象是一种编程思想,不是僵死的格局。

不过呢,言语本身假如供给了面向对象概念的关键字,代码直接了解起来的难度就大大降低,加之有IDE功用的协助,读代码愈加顺利,这是c代码所不及的。这也便是说,当项目的概念变得十分多,c代码即使能够面向对象编程,但也是个问题,会让读代码的人一通找啊找。

Redis怎样处理内存安全问题的

这个问题的确是要害,在这个版别中,redis并没有给出什么十分好的内存安全手段,有的话,也只是在界说数据结构的时候,给出该数据结构的内存开释办法:

透过Redis看待我们是否应该继续使用c语言

和cpp的析构函数一个道理,只不过cpp是编译器刺进内存开释代码,c言语是开发者手动参加。

在代码量hold的住的情况下,开发者的确有满足的精力和耐心保证内存问题,可是代码量一旦上涨,开发者恐怕就顾不过来了。你能够看到像linux这样大型的项目有不少issue,但你很少听说hello-world级其他c代码有什么issue。

所以,到底是人去处理内存问题还是编译器处理内存问题,归根到底便是在大量作业的条件下,你更信任人的体现还是机器的体现。相比之下,我觉得机器更靠谱一些。

c项目很杂乱,无法阅览?

一般而言,在相同老练的情况下,c项目的代码读起来会麻烦一些。但这是老练之后,也便是在参加杂七杂八功用、BUG布丁等等之后的c项目。以Redis 1.3.6为例,其结构适当简练:

透过Redis看待我们是否应该继续使用c语言

主体结构就这么直白,后续版其他杂乱化,都是功用扩展、结构调整,这条主线是不或许断掉的。所以,别把C项目幻想的那么杂乱,那么难。C项目的杂乱还有一种或许是C言语表达能力导致的。因为C言语语法满足简练,直接用的操作系统API,封装比较少,其他言语三言两语交代的工作,C言语或许要多说许多话才能够表述出来,可是编译到了二进制办法的产品,C言语就比其他言语“简练”了。

后话

C言语并没有那么可怕,它不是开发者的定时炸弹,也不是开发者的无双宝剑。C言语到底怎样样,很大程度上要看代码量和开发者的承受能力。并不是说许多项目由C言语编写,就证明C言语是一门你能够信赖并运用的言语,很大程度上讲,许多项目用C言语开发是历史问题,在那个时代和阶段,编程言语的挑选余地太少,哼不能从1980年比及2010年今后,再运用现代化编程言语编写代码吧?

从另一个角度上看,这个时代你完全能够不运用C言语,没必要跟着上古大佬的品尝走。须知,东西是用来解放你的生产力的,不是给你的生产力添堵的。你用不必C言语,和你是不是一个合格的软件工程师,没什么必要的联络。

不过,不必归不必,学习还是要学习的,究竟ABI层面还是以C言语为规范的,想了解函数调用、指令跳转等内容,C言语是避不开的。

关于要不要持续运用C言语,你有什么观点呢,欢迎留言。