为什么会有人用 C 而不是 C + + 呢?

虽然人们似乎喜欢用 抱怨来描述 C + + ,但是我还没有找到足够的证据来说明为什么要选择 C 而不是 C + + 。C 似乎没有受到那么多的批评,如果 C + + 有所有这些问题,为什么不能把自己限制在 C 子集中呢?你的想法/经验是什么?

162539 次浏览
  • 因为他们已经知道 C 了
  • 因为他们在为一个只有 C 编译器的平台开发嵌入式应用
  • 因为他们在维护用 C 语言写的遗留软件
  • 你所写的东西在操作系统、关系数据库引擎或零售3 d 视频游戏引擎的水平上。

我认为 C 比 C + + 能够更好地控制优化和效率,因此在内存和其他资源有限的情况下,每次优化都会有所帮助。当然,它的占地面积也更小。

因为他们正在编写一个插件,而 C + + 没有标准的 ABI。

我选择用 C 语言写作,因为我喜欢使用一种小巧、紧凑的语言。我喜欢访问一个可以在合理的时间内阅读的标准(对我来说——我是一个非常慢的阅读者)。此外,我使用它来为嵌入式系统编写软件,这些系统的 C + + 编译器很少(如 一些 PIC 微控制器)。

因为他们希望使用 C99中没有在 C + + 中等效的特性。


然而,对 C + + 有用的 C99特性并不像人们第一眼看到的那样多。可变长度阵列 FL? ?C + + 有 std: : 向量。支持复数/虚数?C + + 有一个模板化的复杂类型。类型泛型数学函数?C + + 重载了标准的数学函数,导致了相同的结果。

命名初始化程序? C + + 中没有,但有一个解决方案:

struct My_class_params {
int i;
long j;
std::string name;


My_class_params& set_i(int ii)
{
i = ii;
return *this;
}


My_class_params& set_j(long jj)
{
j = jj;
return *this;
}




template <typename STRING>
My_class_params& set_name(STRING&& n)
{
name = std::forward<STRING>(n);
return *this;
}


My_class_params()
{
// set defaults
}
};


class My_class {
My_class_params params;
public:
My_class(const My_class_params& p) : params(p) { }
...
};

这样你就可以写下这样的东西:

My_class mc(My_class_params().set_i(5).set_name("Me"));

莱纳斯对你问题的回答是 “因为 C + + 是一种可怕的语言”

他的证据充其量只是道听途说,但他说的有道理。

作为一种低级语言,您更愿意使用它而不是 C + + 。.C + + 是 C,增加了库和编译器对额外功能的支持(这两种语言都有其他语言没有的特性,并且实现方式不同) ,但是如果你有时间和经验使用 C,你可以从额外增加的低级相关功能中受益... ... [编辑](因为你 习惯吧手动做更多的工作,而不是从语言/编译器本身的一些功能中受益)

添加链接:

为什么 C + + 用于嵌入式

你为什么还在使用 C? PDF

我会为此 谷歌. . 因为在网上已经有很多评论

较长的编译时间可能很烦人。使用 C + + ,你可以有很长的编译时间(这意味着,当然,更多的时间堆栈溢出!).

Joel 的回答很好,因为你可能会选择 来使用 C,尽管还有其他一些原因:

  • 您必须满足行业指导方针,这些方针在 C 语言中更容易证明和测试
  • 你可以使用 C 语言,但不能使用 C + + (不仅要考虑编译器,还要考虑所有的支持工具、覆盖率、分析等)
  • 你的目标开发者是 C 大师
  • 您正在编写驱动程序、内核或其他低级代码
  • 你知道 C + + 编译器并不擅长优化你需要编写的代码
  • 您的应用程序不仅不适合面向对象,而且在这种形式下编写起来更加困难

但是,在某些情况下,您可能使用 想要而不是 C + + :

  • 你想要汇编程序的性能而不是在汇编程序中编码的麻烦(理论上,C + + 能够“完美”的性能,但是编译器并不像一个优秀的 C 程序员那样善于看到优化)

  • 你正在编写的软件是琐碎的,或者说几乎是琐碎的——拿出小小的 C 编译器,编写几行代码,编译,然后一切就搞定了——不需要打开一个带有帮助程序的大型编辑器,不需要编写实际上是空的和无用的类,不需要处理名称空间等等。对于 C + + 编译器,您可以做几乎相同的事情,只是使用 C 子集,但是 C + + 编译器速度较慢,即使对于很小的程序也是如此。

  • 您需要极端的性能或者较小的代码大小,并且知道由于库的大小和性能,C + + 编译器实际上会使其难以完成。

您声称可以只使用 C 子集并使用 C + + 编译器进行编译,但是您会发现,如果这样做,根据编译器的不同,您将得到略有不同的结果。

不管怎样,如果你这样做,你就是在使用 C 语言,你的问题真的是“为什么 C 程序员不使用 C + + 编译器?”如果是这样,那么你要么不理解语言的差异,要么不理解编译器理论。

对性能或臃肿的担忧不是放弃 C + + 的好理由。每种语言都有其潜在的陷阱和权衡——优秀的程序员了解这些,并在必要的时候制定应对策略,差劲的程序员会犯错并责怪语言。

在许多方面,解释 Python 被认为是一种“缓慢”的语言,但是对于非琐碎的任务,有经验的 Python 程序员可以轻松地生成比没有经验的 C 开发人员执行得更快的代码。

在我的视频游戏行业中,我们用 C + + 编写高性能代码,避免在内部循环中使用 RTTI、异常或虚函数。这些方法可能非常有用,但是需要避免性能或膨胀问题。如果我们更进一步,完全切换到 C 语言,我们得到的很少,失去的是 C + + 最有用的结构。

选择 C 的最大的实际原因是支持比 C + + 更广泛。有许多平台,尤其是嵌入式平台,甚至没有 C + + 编译器。

还有供应商的兼容性问题。虽然 c 有一个稳定和定义良好的 ABI (应用二进制接口) ,但是 c + + 没有。C + + 中的 ABI 更加复杂,因为诸如 vtables 和结构/析构函数之类的东西,所以每个供应商甚至是供应商工具链的版本实现都是不同的。

实际上,这意味着您不能使用一个编译器生成的库,并将其与代码或来自另一个编译器的库链接起来,这将给分布式项目或二进制库的中间件提供者带来噩梦。

因为您正在为一个资源紧张的系统编写代码(比如嵌入式系统,或者某种真正的金属代码,比如内核) ,并且您希望尽可能少的开销。

大多数嵌入式系统没有 C + + 编译器是有原因的——不是人们不想要,而是把 C + + 代码塞进这么小的空间是一项几乎不可能完成的任务。

  • 直到几年前,现有的 C + + 编译器还缺少重要的特性,或者支持不足,支持的特性在它们之间差异很大,因此很难编写可移植的应用程序。
  • 由于没有标准的符号命名,其他语言/应用程序很难直接支持 C + + 类。

还有一种方法是,一些商店以类似 C 的方式使用 C + + 特性的 一些,但避免使用那些令人反感的特性。例如,使用类、类方法和函数重载(这些通常对于那些顽固的 C 语言爱好者来说都很容易处理) ,但是不要使用 STL、流操作符和 Boost (它们更难学,而且可能有糟糕的内存特性)。

C 需要的是一个更好的预处理器。 Cfront 是1,因此诞生了 c + +

我将使用 C 语言,其中“ c + + 作为预处理器”是不行的。

我很确定,在任何编写得很好的 c + + 库/框架/工具箱的底部, 您会发现脏-old-c (或静态强制转换,它们是相同的)

我很惊讶没人提到图书馆。许多语言可以链接到 C 库并调用 C 函数(包括外部“ C”的 C + +)。C + + 几乎是唯一可以使用 C + + lib 的东西(定义为“使用 C + + 中不在 C 中的特性的 lib (比如重载函数、虚方法、重载操作符,...) ,并且不通过外部“ C”导出所有通过 C 兼容接口的内容”)。

C + + 的大多数重要特性都涉及到类或模板。除了编译器将它们转换成目标代码的方式之外,这些都是很棒的特性。大多数编译器使用名称混淆,而那些不做任何事情的编译器至少也使用名称混淆。

如果您的系统像许多应用程序一样独立运行,那么 C + + 是一个很好的选择。

如果您的系统需要与不一定用 C + + 编写的软件进行交互(最常见的是在汇编程序或 Fortran 库中) ,那么您就陷入了困境。要与这些类型的情况交互,您需要禁用这些符号的名称错位。这通常是通过声明这些对象 extern "C"来完成的,但是它们不能是模板、重载函数或类。如果这些可能是您的应用程序 API,那么您必须使用 helper 函数包装它们,并使这些函数与实际实现保持同步。

实际上,C + + 语言为特性提供了一种标准语法,这些特性可以很容易地在纯 C 中实现。

简而言之,可互操作的 C + + 开销太大,大多数人都无法承受。

因为对于许多编程任务来说,C 语言更简单,而且足够好。特别是在编写轻量级实用程序时,我可能会觉得 C + + 希望我为了自己的目的而构建一个优雅的上层结构,而不是简单地编写代码。

OTOH,对于更复杂的项目,优雅提供了更好的坚实的结构比自然流出我的键盘更严谨。

关于“只使用你想要使用的 C + + 的子集”的一句话: 这个想法的问题在于,强制项目中的每个人使用相同的子集是有代价的。我个人的观点是,对于松散耦合的项目(例如开源项目)来说,这些成本是相当高的,而且 C + + 完全不能成为一个更好的 C,因为无论你在哪里使用 C,你都不能使用 C + + 。

我还没有找到足够的证据来说明为什么你会选择 C 而不是 C + + 。

你不能把我要说的称为证据,那只是我的观点。

人们喜欢 C 语言是因为它非常适合程序员的思维。

C + + 有很多复杂的规则[你什么时候需要虚拟析构函数,什么时候可以在构造函数中调用虚方法,重载和重写是如何交互的... ] ,要掌握它们都需要很多努力。此外,在引用、运算符重载和函数重载之间,理解一段代码可能需要你理解其他代码,这些代码可能很容易找到,也可能不容易找到。

关于为什么组织更喜欢 C 而不是 C + + 的另一个问题。我不知道,我只是一个人; -)

为了保护 C + + ,它确实给表带来了有价值的特性; 其中 I 值最多的可能是参数(‘ ish)多态性: 将一个或多个类型作为参数的操作和类型。

除了已经提到的其他几点之外:

没那么惊讶了

也就是说,很容易看到一段代码将如何执行 没错。在 c + + 中,你需要接近大师级别,才能准确地知道编译器生成的代码(尝试结合模板、多重继承、自动生成的构造函数、虚函数,混合一些名称空间魔术和依赖参数的查找)。

在许多情况下,这种魔法是好的,但是例如在实时系统中,它真的可以搞砸你的一天。

这是相当肤浅的,但作为一个忙碌的学生,我选择了 C,因为我认为 C + + 将需要太长的时间来学习。我所在大学的许多教授不愿意接受 Python 的作业,因此我需要尽快学习一些东西。

我持另一种观点: 为什么使用 C + + 而不是 C?

这本书 C 程序设计语言(又名: K & R)清楚地告诉你如何做一切的语言可以做在300页以下。这是极简主义的杰作。没有一本 C + + 的书能与之相提并论。

显而易见的反对意见是,大多数现代语言(如果不是全部的话)都可以这样说——它们也不能在仅仅几百页内告诉你如何处理所有事情。没错。那么为什么要使用 C + + 呢?特色丰富?权力?如果你需要一些更加丰富或者强大的特性,那么使用 C # 、 Objective C、 Java 或者其他类似的东西。为什么要用 C + + 的复杂性来增加自己的负担呢?如果你需要 C + + 授予的控制程度,那么我认为使用 C C 可以做任何事情,而且可以做得很好。

如果您希望您的代码能够被几乎所有的程序员理解,请使用 C 语言编写。

我喜欢极简主义和简洁。

哦,天哪,C vs C + + ,一个引发口水战的好方法。 :)

我认为 C 语言更适合于驱动程序和嵌入式代码。

C + + 有一些 C 所没有的优秀特性,但是当人们在幕后编写没有明显副作用的代码时,C + + 的许多面向对象特性会导致巨大的编码混乱。疯狂的代码可以隐藏在构造函数、析构函数、虚函数中... ... C 代码的美妙之处在于,它在你背后没有做任何不明显的事情,因此你可以阅读代码,而不必查看每一个构造函数和析构函数等等。很多问题都是由于某些人糟糕的编码实践造成的。

我的完美语言应该是 C99和一小部分更安全的 C + + 功能的组合,这些功能在二进制输出中增加了 ZERO (或接近零)编译器开销。完美的补充是类封装和数据和函数的命名概念。

我习惯于在我的项目中使用 C + + 。然后我得到了一份使用普通 C 语言的工作(一个有20年历史的 AV 软件代码库,文档很差... ...)。

我在 C 语言中喜欢的三件事是:

  • 没有什么是隐式的: 您可以看到您的程序到底做了什么或者没有做什么。这使得调试更加容易。

  • 缺少名称空间和重载可能是一个优势: 如果您想知道某个函数的调用位置,只需查看源代码目录,它就会告诉您。不需要其他特殊工具。

  • 我重新发现了函数指针的威力。基本上,它们允许你在 C + + 中做所有多态的事情,但是它们更加灵活。