0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

D语言相对C/C++的衍生功能和优势

DPVg_AI_era 来源:lq 2019-07-07 07:22 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

对于开发者而言,开发语言就是工具,中途换工具一般需要付出的成本。本文是一篇开发者自述,讲述了自己是如何从C/C++改投D语言门下,并介绍了D语言相对C/C++的衍生功能和优势。

作为开发人员,换开发语言其实是一件需要很高成本的事,本文主要讲讲我是怎么从C语言转投D语言的。

其实我的经历和许多系统程序员的故事差不多。曾经有一段时间,C是大多数程序员的首选语言。有一天,我意识到我的大多数C程序都在重新实现C++中的东西:动态数组、更好的字符串、多态类等等。所以我尝试使用C++,起初我很喜欢它。RAII、类、泛型等新的组件和概念让编程再次变得有趣起来。

我曾经想象过,如果我把所有关于C ++的书籍都看一遍,并掌握了模板元编程之类的东西,我说不定会成为系统编程的全能之神,我写的代码会让人大吃一惊。但事后看来,学习也可能最终会产生更多相反的效果: 我写出的代码实际上变得更糟。

总之全能之神当不上了,我很伤心。

我记得我读过Scott Meyer著名的《Effective C ++》,这本书其实更多讲的是指出低效率的C ++编程的问题,我发现自己写的大多数C++代码都对上了号。让我们面对现实吧:C可能很难用,但它确实足够“优雅”,而提到C++,你很难跟“优雅”搭上边。

很多前C ++程序员最终都用回了C。就我而言,我发现了D语言。其实D也不完美,但是我使用它因为它让我感觉更像是C++应该有的样子(C+=1)。比如以下面这个简单的C程序为例(一加一等于几?):

#includeint main(){ printf("1 + 1 = %d! ", 1 + 1); return 0;}

如果使用C++标准库,代码是这样的:

#include int main(){ std::cout << "1 + 1 = " << 1 + 1 << "!" << std::endl; return 0;}

如果使用D语言,代码是这样的:

import std.stdio;void main(){ writef("1 + 1 = %d! ", 1 + 1);}

这个例子虽然浅显,但它体现出了C++和D之间背后理念的一些区别。

这篇关于C ++成员函数指针的文章也是对D的起源的一个很好的解释。如果你酷爱编程,这篇文章是一个很好的解读, 但我的解读是:C++成员函数指针应该是感觉像是一个低级功能(就像普通函数指针一样),但其实现的复杂性和多样性说明它们真的很“高级”。

这些指针的实现过程很复杂,因为关于它们能做什么/不能做什么的规则是很微妙的。作者解释了几个C ++编译器的实现,包括优雅而简单的Digital Mars C ++实现,即DMC。DMC编译器是由Walter Bright编写的,他是“D语言”的发明者。

D具有C ++的类和模板以及其他核心功能,但设计者花费了大量时间思考C ++规范,以及如何让设计和编程变得更简单。Walter曾经说过,他在部署C ++模板的痛苦经历,让他考虑过根本不把该功能纳入D,后来他意识到,这个过程本来不需要那么复杂。

下面对D语言的功能和特点进行一番大概的介绍,其实可以把D视作一个“改进版”的C语言。介绍中时刻少不了和C/C++的对比。

-betterC开关

D编译器支持-betterC开关,该开关可以启用/禁用D运行时以及依赖于它的所有高级功能。上面的C代码可以直接转换为betterC:

import core.stdc.stdio;extern(C):int main(){ printf("1 + 1 = %d! ", 1 + 1); return 0;}

$ dmd -betterC example.d$ ./example1 + 1 = 2!

生成的二进制文件看起来很像等效的C二进制文件。事实上,如果你在betterC中重写了一个C库,仍然可以链接到已经对C版本编译的代码,无需修改就可立即使用。

实际上,如果只是要在D语言中编写类似C的代码,并不需要-betterC开关。只有在没有D Runtime的特殊情况下才需要使用。

静态assert()

这个功能允许开发者在编译时验证一些假设。

static assert(kNumInducers<16);

系统代码通常对对齐或结构大小或其他事物做出假设。使用静态assert不仅可以记录这些假设,而且如果有人通过添加struct成员或其他东西来破坏假设,则会触发编译错误。

Slices

典型的C代码中存在大量的“指针/长度”参数对,一个常见bug就是二者的不同步。对于由指针和长度定义的一系列内存,Slice是一种简单且超级有用的抽象表示。现在不必使用这样的代码:

buffer_p += offset;buffer_len -= offset; // Got to update both

而可以用下边这种更不容易出bug的代码:

buffer = buffer[offset..$];

Slice 其实就是具备优秀语法功能的指针/长度对。

编译时间函数估计 (CTFE)

许多函数都可以用编译时间来评估。

long factorial(int n) pure{ assert (n >= 0 && n <= 20); long ret = 1; foreach (j; 2..n+1) ret *= j; return ret;}// Statically allocated array// Size is calculated at compile timePermutation[factorial(kNumThings)]permutation_table;

scope Guards

函数的一部分中的代码通常会在后续部分带上一段清理代码。一个常见的错误来源是未能正确匹配该代码,(尤其是涉及多个控制流路径时)。D的scope guards设定使得这个问题变得不再困难:

p = malloc(128);// free() will be called when thecurrent scope exitsscope (exit) free(p);// Put whatever if statements, or loops,or early returns you like here

你甚至可以在作用域中使用多个scope,或嵌套使用scope。清理代码将在需要时以正确的顺序被调用。

D语言还利用结构析构函数支持RAII。

常量和不可变量

有一个流行的说法是,C和C++中的const对编译器优化很有用。不过D的作者表示,每当他想到一个新的基于const的C++优化时,最终都发现它在实际代码中并不起作用。所以他对D的const语义做了一些修改,并添加了不可变量。可以在D const FAQ中阅读更多内容。

函数纯度

可以实施函数纯度功能。我之前写过关于pure关键字的一些好处。

@Safe

SafeD是D的一个部分,禁止使用指针类型转换和内联汇编等高风险语言功能。标记为@safe的代码由编译器强制执行,不使用这些功能,因此高风险代码可以仅限需要这些功能的应用程序的一小部分。

元编程

如前所述,元编程在一些C ++程序员中名声不好。但是D中的元编程具备一些没那么有趣的优点,程序员一般倾向于只在必要时才用,而不是一个有趣的谜题。

需要将枚举类型的名称作为数组?容易!

enum State{ stopped, starting, running, stopping,}string[] state_names =[__traits(allMembers, State)];

没有预处理器

好吧,这其实是一个“非功能”,但D没有相当于C的预处理器的功能。所有理智的用例都被替换为本机语言功能,如清单常量和模板。这包括适当的模块支持,这意味着D可以摆脱旧#include黑客的限制。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    183

    文章

    7649

    浏览量

    146400
  • 编程
    +关注

    关注

    90

    文章

    3725

    浏览量

    97526
  • C++
    C++
    +关注

    关注

    22

    文章

    2131

    浏览量

    77487

原文标题:开发者自述:我为什么从C语言转投了D语言?

文章出处:【微信号:AI_era,微信公众号:新智元】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    【文章转载】你不知道的Vector | VectorCAST/C++的AI辅助测试功能

    从2026版本开始,VectorCAST/C++推出首批AI辅助测试功能,旨在帮助开发团队解决单元测试过程中的两个核心难点:1.如何根据需求描述自动生成可验证逻辑功能的单元测试用例(Req2test
    的头像 发表于 04-29 10:03 344次阅读
    【文章转载】你不知道的Vector | VectorCAST/<b class='flag-5'>C++</b>的AI辅助测试<b class='flag-5'>功能</b>

    使用VectorCAST/C++的AI辅助测试功能

    从2026版本开始,VectorCAST/C++推出首批AI辅助测试功能,旨在帮助开发团队解决单元测试过程中的两个核心难点:
    的头像 发表于 04-27 14:37 399次阅读

    C++ 11 14 17 20内存管理-指针、智能指针和内存池基础与提升

    pan.baidu.com/s/1g64x9D_jp9ufk4uBpQBmvA?pwd=497f  未来 C++ 底层核心:内存管理实战,从指针到内存池全链路进阶 站在2026年的技术潮头,当AI
    的头像 发表于 04-20 15:51 608次阅读

    C++与lua联合编程

    在现代软件工程的庞大架构中,纯粹的 C++ 与动态脚本语言之间的关系,早已演变成一场精密的“商业分工”。C++ 扮演着提供极致性能的“底层重工业”,而 Lua 则充当着实现灵活业务逻辑的“轻量级
    发表于 04-19 16:27

    C++:const 的空间,常量也能占内存?

    5g.Nq6.dgdfgsg.cnJIWWQc++语言 c++语言5g.d51.dgdfgsg.cnJIWWQc++语言
    发表于 04-16 19:19

    汽车网络安全开发语言选型指南:C/C++/Rust/Java等主流语言对比+Perforce QAC/Klocwork工具支持

    汽车网络安全如何选编程语言CC++、Rust、Java……谁更适合AUTOSAR、ISO/SAE 21434?一文了解8种主流语言的优劣与适用场景,以及Perforce QAC/K
    的头像 发表于 12-26 11:13 734次阅读
    汽车网络安全开发<b class='flag-5'>语言</b>选型指南:<b class='flag-5'>C</b>/<b class='flag-5'>C++</b>/Rust/Java等主流<b class='flag-5'>语言</b>对比+Perforce QAC/Klocwork工具支持

    C语言C++的区别及联系

    C语言C++到底是什么关系? 首先C++C语言本来就是两种不同的编程
    发表于 12-24 07:23

    CC++之间的联系

    控制能力,这一点与C语言相似,使得它们在系统编程、嵌入式系统等领域都得到广泛应用。 3、发展历程: C++正是在C语言的基础上逐步发展起
    发表于 12-11 06:51

    C语言C++之间的区别是什么

    C++的标准库那样集成度高和功能齐全。 6、编译器与语言特性: C++编译器通常比C语言
    发表于 12-11 06:23

    C语言特性

    访问内存地址,对内存中的数据进行读写操作,还可以控制硬件的寄存器,实现对硬件设备的精确控制。这种底层操作的能力,使得 C 语言在嵌入式开发中能够充分发挥硬件的优势,实现各种复杂的功能
    发表于 11-24 07:01

    C语言和单片机C语言有什么差异

    单片机c语言相对于普通C语言增加了一些基本的指令,还有变量的赋值是16进制,当然单片机c
    发表于 11-14 07:55

    C/C++代码静态测试工具Perforce QAC 2025.3的新特性

     Perforce Validate 中 QAC 项目的相对/根路径的支持。C++ 分析也得到了增强,增加了用于检测 C++ 并发问题的新检查,并改进了实体名称和实
    的头像 发表于 10-13 18:11 813次阅读
    <b class='flag-5'>C</b>/<b class='flag-5'>C++</b>代码静态测试工具Perforce QAC 2025.3的新特性

    技能+1!如何在树莓派上使用C++控制GPIO?

    在使用树莓派时,你会发现Python和Scratch是许多任务(包括GPIO编程)中最常用的编程语言。但你知道吗,你也可以使用C++进行GPIO编程,而且这样做还有不少好处。借助WiringPi
    的头像 发表于 08-06 15:33 4597次阅读
    技能+1!如何在树莓派上使用<b class='flag-5'>C++</b>控制GPIO?

    C++ 与 Python:树莓派上哪种语言更优?

    Python是树莓派上的首选编程语言,我们的大部分教程都使用它。然而,C++在物联网项目中同样广受欢迎且功能强大。那么,在树莓派项目中选择哪种语言更合适呢?Python因其简洁性、丰富
    的头像 发表于 07-24 15:32 1218次阅读
    <b class='flag-5'>C++</b> 与 Python:树莓派上哪种<b class='flag-5'>语言</b>更优?

    基于LockAI视觉识别模块:C++目标检测

    本文档基于瑞芯微RV1106的LockAI凌智视觉识别模块,通过C++语言做的目标检测实验。本文档展示了如何使用lockzhiner_vision_module::PaddleDet类进行目标检测,并通过lockzhiner_vision_module::Visualiz
    的头像 发表于 06-06 13:56 1072次阅读
    基于LockAI视觉识别模块:<b class='flag-5'>C++</b>目标检测