为什么有人会使用C over C++?

127 c c++

虽然人们似乎想抱怨 C++,但我还没有找到很多证据证明你为什么要选择C over C++.C似乎没有得到几乎同样多的瑕疵,如果C++有所有这些问题,为什么你不能把自己限制在C子集?你有什么想法/经历?

Ada*_*vis 124

Joel的回答很好,你可能不得不使用C,尽管还有其他一些:

  • 您必须符合行业准则,这些准则在C中更容易证明和测试.
  • 您有工具可以使用C,但不能使用C++(不仅要考虑编译器,还要考虑所有支持工具,覆盖范围,分析等)
  • 您的目标开发人员是C大师
  • 您正在编写驱动程序,内核或其他低级代码
  • 您知道C++编译器不擅长优化您需要编写的代码类型
  • 您的应用程序不仅不适合面向对象,而且更难以以该形式编写

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

  • 你想要汇编程序的性能,而不需要在汇编程序中编写代码(理论上,C++能够实现'完美'的性能,但编译器并不擅长看到优秀的C程序员会看到的优化)
  • 你正在编写的软件是微不足道的,或几乎是如此 - 扼杀微小的C编译器,编写几行代码,编译并完成所有设置 - 无需打开一个带帮助程序的巨大编辑器,无需编写实际内容空的和无用的类,处理命名空间等等.你可以用C++编译器做几乎相同的事情,只使用C子集,但C++编译器速度较慢,即使对于小型程序也是如此.
  • 您需要极高的性能或小的代码大小,并且知道C++编译器实际上会因为库的大小和性能而难以实现

你认为你可以使用C子集并使用C++编译器进行编译,但是你会发现,如果你这样做,你会得到略有不同的结果,具体取决于编译器.

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

  • 表演部分不一定是真的.C++可以在很多方面进行优化,远远优于C.(当然反过来也是偶然的,但一般来说,出于性能原因选择C而不是C++是一个坏主意). (57认同)
  • @Adam:使用"漂亮"代码,C++比C表现更好.C++可以使用C需要宏的模板和内联函数.C++开销仅在被要求时出现,否则与C相同(虚拟,try/throw,dynamic_cast).大部分开销仅显示在程序图像大小中. (19认同)
  • 我会对更多性能信息感兴趣.我不明白为什么C只会"偶尔"表现得更好.给定一个普通的程序员,可能是C++使性能更容易实现(良好地使用模式)但是专家编写的C程序应该更快 - 更低的开销. (9认同)
  • 当然,更快的C程序需要更长的时间来编写和调试,因此需要权衡,并且考虑到机器的速度,除了专门的应用程序之外,权衡很少是值得的,这就是为什么C++通常更好.(到代码完成时,计算机速度更快,吃掉了差异) (3认同)
  • 还有MISRA C标准,AFAIK对C++还不是很稳定. (2认同)
  • 但是,世界上编写的大多数代码都会嵌入到嵌入式处理器中,并且通常存在代码大小/性能限制,其中C闪耀.更低的功耗,对处理器和外设的直接控制等 - 有时会超越C++的优势. (2认同)
  • @Zan“ C ++开销仅在需要时出现,否则与C相同”,太好了,我真的很想看看一些参考。 (2认同)
  • @Adam:个人经验,并确保我刚刚用gcc和g ++编译了一个相同的hello world C程序,而main的目标代码是相同的,只有一点库加载不同.提供您的开销参考. (2认同)
  • @Tom我完全同意!在教育中使用C++是个好主意. (2认同)
  • 对于数值计算,通过模板使用惰性求值,您实际上可以拥有比 C 代码更高效的 C++ 代码。参见 [Eigen](http://eigen.tuxfamily.org/index.php?title=Main_Page)。事实上,排序之类的功能可以[在 C++ STL 中更快](https://isocpp.org/wiki/faq/c#sort-qsort) 而不是 C 标准库。AFAIK,C++ 二进制文件比 C 二进制文件性能差的唯一情况是当 C++ 大量使用虚函数时,但是一旦您考虑 C 函数指针,这种差异就会消失。完全同意@jalf。 (2认同)
  • 一般来说,就像这个答案一样,但 -1 表示 C 是一个更好的主意,因为您正在编写驱动程序、内核或低级代码。相反,丰富的抽象以及对编译时执行和优化的关注在较低级别的代码中更为重要。当然,您不会随意编写任何类型的 C++,但您肯定会使用它。例如,考虑用于 GPU 内核的 CUDA。 (2认同)

pla*_*ler 81

我喜欢简约和简约.

  • 我喜欢你答案的极简主义和简约...... :) (27认同)
  • 我猜他也喜欢有图书馆,书籍,论坛吗? (13认同)
  • 好的 - 足够公平......那么为什么不呢? (8认同)
  • 同意.C非常简单且"小".C总是看起来一样,如果你是一个项目的新贡献者,很容易理解它是如何工作的.c ++有一些无用的东西,当看到一个c ++项目时,我立即感到困惑.我可以理解c ++人(具有OO功能的C语言)但C更简单易行. (8认同)
  • 我同意 100000000000000000%。一个优秀的 C 程序员甚至可以维护一个大型的 C 应用程序,而不会迷失在所有的废话类和 Boost 中! (2认同)

Joe*_*orn 65

  • 因为他们已经知道C.
  • 因为他们正在为只有C编译器的平台构建嵌入式应用程序
  • 因为他们正在维护用C编写的遗留软件
  • 您正在编写操作系统,关系数据库引擎或零售3D视频游戏引擎的级别.

  • 有些微控制器只有C编译器,真的很糟糕.基本的C++特性(名称空间,除虚拟函数之外的类,枚举,在块顶之外的其他地方声明变量)是最有价值的,恕我直言. (4认同)
  • 从这一点来看,只有在没有合理的选择时才会选择C. (2认同)
  • @Joe:除了第一点,关于总结它.很多后来的语言都拿了C说,"嘿,我们可以做_better_." (2认同)
  • 实际上,大多数3D游戏引擎都使用C ++。UE4主要使用C ++。 (2认同)

And*_*ant 53

对性能或膨胀的担忧并不是放弃C++的好理由.每种语言都有其潜在的缺陷和权衡 - 优秀的程序员可以了解这些,并在必要时制定应对策略,糟糕的程序员会犯规并责怪语言.

解释Python在许多方面被认为是一种"慢"语言,但对于非平凡的任务,熟练的Python程序员可以轻松地生成比没有经验的C开发人员执行更快的代码.

在我的行业,视频游戏中,我们通过避免内部循环中的RTTI,异常或虚函数等内容在C++中编写高性能代码.这些可能非常有用,但具有可避免的性能或膨胀问题.如果我们要更进一步并完全切换到C,我们将获得很少的东西并失去最有用的C++结构.

偏爱C的最大实际原因是支持比C++更广泛.有许多平台,特别是嵌入式平台,甚至没有C++编译器.

供应商也存在兼容性问题.虽然C具有稳定且定义明确的ABI(应用程序二进制接口),但C++却没有.由于诸如vtable和constructurs/destructors之类的东西,C++中的ABI更加复杂,因此每个供应商甚至是供应商工具链的版本都实现了不同的实现.

实际上,这意味着您不能使用由一个编译器生成的库并将其与代码或另一个库中的库链接,这会为分布式项目或二进制库的中间件提供程序创建噩梦.

  • 同样没有经验的c dev会产生比他的c代码慢的python代码.Python比c慢. (14认同)
  • "解释的Python在许多方面被认为是一种"慢"语言,但对于非平凡的任务,熟练的Python程序员可以轻松生成比没有经验的C开发人员更快执行的代码." 我想一个程序员(不一定是Python Progammer)参加算法课程可以产生比没有经验的开发人员(一般)更快执行的代码. (7认同)

小智 36

我选择用C语写作,因为我喜欢用一种小而紧张的语言.我喜欢访问一个可以在合理的时间内阅读的标准(对我来说 - 我是一个非常慢的读者).而且,我用它来编写嵌入式系统的软件,因为很少有理想的C++编译器存在(比如一些 PIC微控制器).


Din*_*nah 34

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

" C编程语言"(又名:K&R)一书清楚地告诉你如何在300页以内完成语言所能做的一切.这是极简主义的杰作.没有C++书甚至接近.

显而易见的反驳是大多数(如果不是全部)现代语言也可以这样说 - 他们也无法告诉你如何在几百页内完成所有事情.真正.那么为什么要使用C++呢?功能丰富?功率?如果您需要更丰富或更强大的功能,那么请使用C#,Objective C,Java或类似的东西.为什么要担心C++的复杂性呢?如果您需要C++授予的控制程度,那么我认为使用C. C可以做任何事情并且可以做得很好.

  • @Dinah:1/2路点为您提供更高级别的表达能力,而无需C#或Java的性能和内存成本. (6认同)
  • @Zan Lynx:你是对的.但是我希望通过采取我在原帖中所做的反对立场,我对C over C++的可行性提出了一个观点......即使它是,正如你所指出的,不是一个开放和关闭的案例. (5认同)

Ric*_*kyo 27

Linus对你的问题的回答是"因为C++是一种可怕的语言"

他的证据充其量只是轶事,但他有一点......

更多的是低级语言,你更喜欢它的C++ .. C++是C,增加了库和编译器支持额外的功能(两种语言都有其他语言没有的功能,并以不同的方式实现),但如果你有使用C的时间和经验,您可以从额外增加的低级别相关功能中受益... [编辑](因为您习惯于手动完成更多工作而不是从语言/编译器本身获得的某些功能中受益)

添加链接:

为什么C++用于嵌入式

你为什么还在使用C?PDF

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

  • Linus没有资格谈论C++的优点.引用他好像他是某种神谕一样只是愚蠢.关于"以艰难的方式做事"的一点点没有意义.有充分的理由使用C,但"它更多的工作",或"Linus说的如此"不在其中. (23认同)
  • 我在C中做了很多编码,然后用C++做了很短的一段时间,然后用VB很长时间,现在我在过去的几年里一直在使用C#.从那以后我编写了一些C和C++代码,我意识到C语言定义明确且紧凑,C#很酷且功能强大,而且C++很糟糕. (16认同)
  • @jalf,没有引用Linus好像他是某种神谕,很高兴提到一位知名程序员对他在世界上最常用程序之一中的选择的看法:linux内核.这个问题要求意见(为什么有人会选择C),这是我想要回答的问题. (8认同)
  • Linus是关于C++观点的一个不好的来源,因为他没有使用它,据我所知,它只在1990年试过一次. (6认同)
  • @Zan Linus在其他地方展示了更多的自我控制:"我们本来希望使用C++及其带来的额外功能,但更难以看出C++中的代码比C中的代码更糟糕".我的答案的引用是一个意见记录,而不是"跟随领导者". (3认同)
  • 这看起来很糟糕,这是一个有趣的家伙的有趣观点. (2认同)

jdi*_*isk 27

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

少惊喜

也就是说,更容易看到一段代码将完全做什么.在C++中,您需要接近大师级别才能确切地知道编译器生成的代码(尝试模板,多重继承,自动生成的构造函数,虚函数的组合,并混合使用一些命名空间魔术和参数依赖查找).

在许多情况下,这种魔力很好,但是例如在实时系统中,它可能会让你的一天变得糟透了.


Mic*_*hel 26

因为他们正在编写插件而C++没有标准的ABI.

  • 虽然如此,但坚持使用C并不是一个令人信服的理由,因为您可以使用C链接导出必要的函数,并且仍然可以使用C++实现. (8认同)
  • C也没有标准的ABI. (6认同)
  • @codelogic - C++项目倾向于导出比同等C项目更多的类型和函数.可以在最终的共享库中隐藏它,但它可能比它的价值更多的努力. (2认同)

Fra*_*ank 25

编译时间长可能很烦人.使用C++,您可以拥有非常长的编译时间(当然,这意味着Stack Overflow会有更多时间!).

  • 我使用C++进行实际工作,但由于近乎即时的编译时间,我总是在C中进行原型设计. (6认同)
  • @Tom:我想知道您的实际工作C ++是什么样的,如果可以在C中进行原型制作。您是否未使用C ++的功能?你能详细说明吗? (2认同)

Cal*_*ius 23

我习惯在我的项目中使用C++.然后我找到了一个使用普通C的工作(一个20年前不断发展的AV软件代码库,文档很差......).

C中我喜欢的3件事是:

  • 没有什么是隐含的:你看到你的程序究竟做了什么或不做什么.这使调试更容易.

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

  • 我重新发现了函数指针的强大功能.基本上它们允许你做你在C++中做的所有多态的东西,但它们更灵活.

  • +1然而,C中的这种多态性通常是通过void*获得的,这很危险,因为它会禁用编译器检查你是否正在做一些令人讨厌的事情的任何能力. (8认同)
  • 我几乎从未在程序中遇到内存损坏,但如果可能的话,我宁愿在运行程序之前检测到错误.将`void*`转换为`what*'是编译器真诚接受的东西.我更喜欢我的编译器不信任我,并且有可能强制执行健壮的类型检查.C++编译器发出的模板替换错误很难读,但至少垃圾不能编译. (4认同)
  • @ gd1实际上,我不记得这种`void *`引起麻烦的情况。有许多防御性的编程技术可以防止错误:将断言放到任何地方,在您的结构中(在调试版本中)添加幻数,等等。但是如今,我们有valgrind博士。内存,甚至MSVC都使用代码来检测问题,因此很容易解决内存损坏问题。 (3认同)

Big*_*ich 15

我很惊讶没有人提到过图书馆.许多语言可以链接到C libs并调用C函数(包括带有extern"C"的C++).C++几乎是唯一可以使用C++库的东西(定义为'使用C++中不在C中的特性的库[比如重载函数,虚方法,重载运算符......],并且不导出一切都通过C兼容接口通过extern"C"').

  • C lib可以在更多地方工作. (2认同)
  • 互操作性问题最明显的原因是名称错误,我认为这值得提出. (2认同)

Lir*_*evi 14

如果您希望几乎任何程序员都能用C语言来理解您的代码.


Dou*_*oug 12

因为他们想要使用C99中没有C++等价物的功能.


但是,正如人们第一眼看到的那样,没有那么多对C++有用的C99功能.可变长度数组?C++有std :: vectors.支持复数/虚数?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) { }
    ...
};
Run Code Online (Sandbox Code Playgroud)

这允许你写下这样的东西:

My_class mc(My_class_params().set_i(5).set_name("Me"));
Run Code Online (Sandbox Code Playgroud)

  • 我 100% 使用初始化器!!! (2认同)

dkr*_*etz 10

因为对于许多编程任务,C更简单,也足够好.当我特别编写轻量级实用程序时,我觉得C++希望我自己构建一个优雅的超结构,而不是简单地编写代码.

OTOH,对于更复杂的项目,优雅提供了更好的结构严谨性,而不是自然流出键盘.


Tok*_*Guy 8

c ++的大多数重要功能都以某种方式涉及类或模板.除了编译器将这些转换为目标代码的方式之外,这些都是很棒的功能.大多数编译器使用名称修改,而那些不做任何事情的编译器至少就像混乱一样.

如果您的系统独立存在,就像许多应用程序一样,那么C++是一个不错的选择.

如果您的系统需要与不是用C++编写的软件(最常见的是汇编程序或Fortran库)进行交互,那么您就处于紧张状态.要与这些类型的案例进行交互,您需要为这些符号禁用名称重整.这通常是通过声明这些对象来完成的extern "C",但它们不能是模板,重载函数或类.如果那些可能是您的应用程序API,那么您将必须使用辅助函数包装它们,并使这些函数与实际实现保持同步.

实际上,C++语言为可以在纯C中轻松实现的功能提供标准语法.

简而言之,可互操作的C++的开销对于大多数人来说太高了.

  • 我很惊讶听到这个,因为我在C++中编写了很多带有外部"C"接口的.DLL,因此可以从C或任何其他CLR语言调用它们.当然你不能简单地公开成员函数指针,但是为__cdecl调用编组数据真的没那么麻烦. (3认同)
  • 实际上,您可以导出模板代码。它只需要为您想要使用的每种类型提供非模板化函数包装器,以避免名称冲突。 (2认同)

vin*_*456 8

这很浅,但作为一个忙碌的学生我选择了C,因为我认为C++需要很长时间才能学习.我大学的许多教授都不会接受Python的作业,我需要快速学习.

  • 老师的聪明才智! (8认同)

Dav*_*eau 6

关于"只使用你想要使用的C++子集"的一句话:这个想法的问题在于强制执行项目中的每个人都使用相同的子集.我自己的观点是松散耦合项目(例如开源项目)的成本相当高,而且C++完全失败了成为一个更好的C,因为你无论在哪里使用C都不能使用C++.


Jon*_*ker 5

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

你很难将我要说的话称为证据;这只是我的意见。

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

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

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

在捍卫 C++ 的过程中,它确实带来了有价值的功能;不过,我最看重的可能是参数多态性:采用一种或多种类型作为参数的操作和类型。

  • `++score`:您的陈述*“人们喜欢 C,因为它非常适合程序员的思想”* 是一个非常好的陈述。能够使用一种简单的语言进行编程,并且知道所见即所得,这对于编程语言来说是一个真正有吸引力的特性。 (3认同)

小智 5

哦,我的C vs C++,一个开始火焰战争的好方法.:)

我认为C更适合驱动程序和嵌入式代码.

C++具有C所没有的一些强大功能,但是当人们编写具有在幕后发生的非明显副作用的代码时,C++的许多面向对象特性会导致巨大的编码混乱.疯狂的代码可以隐藏在构造函数,析构函数,虚函数中...... C代码的美妙之处就是语言在你的背后没有什么不明显的,因此你可以阅读代码而不必查看每个构造函数和析构函数等等.很多问题是有些人编写错误的做法.

我的完美语言将是C99与最安全的C++功能的最小子集的组合,它将ZERO(或接近零)编译器开销添加到二进制输出.完美的补充是类封装和数据和函数的命名概念.