以下是C++的好处
C++提供了他们所询问的特定功能
他们的C编译器几乎肯定是一个C++编译器,所以没有软件成本的影响
C++和C一样可移植
C++代码可以和C一样有效(或者更多,或者更少)
是否有任何具体原因和特定场景,其中必须使用C over C++?
参考这个问题:C中的泛型库
这不是重复,因为这个问题是关于语言限制而不是关于应该/不应该学习一种语言而不是另一种语言.
Peter Kirkham的帖子对我来说是最有用的,特别是关于我没有考虑的C99问题,所以我接受了它.感谢参与其他所有人.
这是由我给当前问题的答案提示的,该问题询问C的泛型库 - 提问者特别声明他们不想使用C++.
C是一种完整的编程语言.C不是C++的任意子集.C根本不是C++的子集.
这是有效的C:
foo_t* foo = malloc ( sizeof(foo_t) );
要使其编译为C++,您必须编写:
foo_t* foo = static_cast( malloc ( sizeof(foo_t) ) );
这不再是有效的C. (你可以使用C风格的强制转换,它可以在C中编译,但是大多数C++编码标准都会避开,许多C程序员也会避开;见证Stack overflow上的"不要抛出malloc"注释) .
它们不是同一种语言,如果你在C中有一个现有的项目,你不想用另一种语言重写它只是为了使用一个库.您更愿意使用可以使用您正在使用的语言进行交互的库.(在某些情况下,可以使用一些extern "C"
包装函数,具体取决于C++库的模板/内联方式.)
以第一个C文件中的一个项目,我的工作,这是如果你只是交换会发生什么gcc std=c99
了g++
:
sandiego:$ g++ -g -O1 -pedantic -mfpmath=sse -DUSE_SSE2 -DUSE_XMM3 -I src/core -L /usr/lib -DARCH=elf64 -D_BSD_SOURCE -DPOSIX -D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112L -Wall -Wextra -Wwrite-strings -Wredundant-decls -Werror -Isrc src/core/kin_object.c -c -o obj/kin_object.o | wc -l In file included from src/core/kin_object.c:22: src/core/kin_object.h:791:28: error: anonymous variadic macros were introduced in C99 In file included from src/core/kin_object.c:26: src/core/kin_log.h:42:42: error: anonymous variadic macros were introduced in C99 src/core/kin_log.h:94:29: error: anonymous variadic macros were introduced in C99 ... cc1plus: warnings being treated as errors src/core/kin_object.c:101: error: ISO C++ does not support the ‘z’ printf length modifier .. src/core/kin_object.c:160: error: invalid conversion from ‘void*’ to ‘kin_object_t*’ .. src/core/kin_object.c:227: error: unused parameter ‘restrict’ .. src/core/kin_object.c:271: error: ISO C++ does not support the ‘z’ printf length modifier src/core/kin_object.c:271: error: ISO C++ does not support the ‘z’ printf length modifier
共有69行错误,其中4行是无效转换,但主要是针对C99中存在但未存在于C++中的功能.
这并不像我正在使用这些功能来获得它的乐趣.将它移植到另一种语言需要大量的工作.
所以建议这样做是完全错误的
[a] C编译器几乎可以肯定是一个C++编译器,所以没有软件成本的影响
将现有C代码移植到C++的过程子集中通常会产生很大的成本影响.
所以建议'使用C++ std :: queue class'作为问题的答案,在C中查找队列的库实现,而不是建议'使用目标C' 和'使用JNI调用Java java.util.Queue类'或者"调用CPython库" - Objective C实际上是C(包括C99)的正确超集,Java和CPython库都可以直接从C调用,而不必将不相关的代码移植到C++语言.
当然,您可以为C++库提供C外观,但是一旦您这样做,C++与Java或Python没有什么不同.
我意识到这既不是专业也不是特别好的答案,但对我而言,这只是因为我真的很喜欢C. C小而简单,我可以将整个语言融入我的大脑,C++对我来说似乎总是一个巨大的庞大混乱各种各样的层次我很难走动.由于这个原因,我发现每当我编写C++时,我最终会花费更多的时间来调试和敲击硬表面,而不是在编写C时.我再次意识到很多这很大程度上是由于我自己的"无知".
如果我选择,我将编写所有高级的东西,如python中的接口和数据库交互(或可能是C#)以及所有必须在C中快速的东西.对我来说,它给了我最好的世界.用C++编写所有东西感觉就像是最糟糕的世界.
编辑: 我想补充一点,我认为如果你要成为一个项目的几个人或者可维护性是优先考虑的话,那么带有一些C++特性的C在很大程度上是一个坏主意.关于什么构成'少数'以及哪些比特应该在C中完成以及哪些比特在C++中最终导致一个非常精神分裂的代码库,将会有分歧.
在某些真实环境中,例如低级嵌入式系统,不支持C++.并且有一个很好的理由:对于这样的事情,C很容易就足够了,为什么要使用更大的东西呢?
我讨厌用C++编程.
可能有以下几个原因:
缺乏支持 - 并非每个C编译器都是C++编译器.并非所有编译器都特别符合标准,即使他们声称支持C++.而一些C++编译器会产生无望的膨胀和低效的代码.一些编译器具有标准库的可怕实现.内核模式开发通常不可能使用C++标准库,以及一些语言功能.如果你坚持使用该语言的核心,你仍然可以编写C++代码,但是切换到C可能更简单.
熟悉.C++是一门复杂的语言.教C之人比C++更容易,而且找一个优秀的C程序员比一个优秀的C++程序员更容易.(这里的关键字是"好的".有很多C++程序员,但大多数都没有正确学习语言)
学习曲线 - 如上所述,教授某人C++是一项艰巨的任务.如果你正在编写一个将来必须由其他人维护的应用程序,而这些其他人可能不是C++程序员,那么用C语言编写它会让你更容易掌握.
我仍然更喜欢用C++编写,当我可以逃脱它时,总的来说,我认为好处大于缺点.但我也可以看到在某些情况下使用C的论点.
有很多关于嵌入式编程,性能和东西的争论,我不买.在这些领域,C++很容易与C进行比较.然而:
就在最近用C++编程超过15年后,我一直在重新发现我的C根.我必须说,虽然C++中有很好的功能可以让生活更轻松,但也有很多陷阱和一种"总是更好的方式".你从未真正对你所做的解决方案感到高兴.(不要误解我的意思,这可能是一件好事,但大多数情况下并非如此).
C++为您提供无限的枪声.这可能是好的,但不知怎的,你总是最终使用太多.这意味着您通过"漂亮"和"漂亮"的抽象层次,一般性等来伪装您的解决方案.
我发现回到C的原因是它实际上又是有趣的编程.花了这么多时间建模并思考如何最好地使用继承,我发现用C编程实际上使我的源代码更小,更易读.这当然取决于你的自律水平.但是在直接代码上放置过多的抽象是非常容易的,这实际上并不需要.
C的主要优点是,当你查看一些代码时,你可以看到真正发生的事情(是的预处理器:用-E编译,然后你看到它).当你看一些C++代码时,往往不常见的事情.在那里你有构造函数和析构函数,它们基于作用域或由于赋值而被隐式调用,你有操作符重载,即使它没有被严重误用,也会产生令人惊讶的行为.我承认我是一个控制狂,但我得出结论,对于想要编写可靠软件的软件开发人员来说,这不是一个坏习惯.我只是想有一个公平的机会说我的软件完全按照它应该做的那样,同时我的胃里没有一种不好的感觉,因为我知道它仍然会有很多错误,我不会
C++也有模板.我讨厌并爱他们,但如果有人说他或她完全理解他们,我称他/她为骗子!这包括编译器编写者以及参与定义标准的人(当你尝试阅读它时会变得很明显).有很多荒谬的误导性案例涉及到在编写实际代码时根本无法全部考虑它们.我喜欢C++模板,因为它们具有强大的功能.你可以用它们做什么真的很神奇,但它们同样可以导致最奇怪和最难找到错误的人可以(不)想象.而这些错误实际上发生了,甚至很少发生.阅读有关解决C++ ARM模板所涉及的规则几乎让我头疼.并且它让我感觉浪费时间不得不读取长度为1000个字符的编译器错误消息,我需要10分钟或更长时间才能理解编译器实际需要的内容.在典型的C++(库)代码中,您还经常在头文件中找到大量代码以使某些模板成为可能,这反过来使得即使在快速机器上编译/执行周期也很慢,并且当您更改某些内容时需要重新编译大部分代码那里.
C++也有const陷阱.除了最琐碎的用例之外,您可以避免使用const,或者您迟早要将其丢弃或者在它发展时重构代码库的大部分内容,尤其是当您即将开发一个漂亮而灵活的OO设计时.
C++具有比C更强的类型,这很好,但有时我觉得我在尝试编译C++代码时正在喂一个Tamagotchi.我通常从中得到的警告和错误的很大一部分并不是我做了一些不起作用的事情,而是编译器不喜欢我这样做的事情,如果没有在这里投出或添加一些额外的关键字,那里.
这些只是我不喜欢C++软件的一些原因,我只使用一些据称强大的外部库来单独编写软件.当你与其他人一起编写代码时,真正的恐怖就开始了.它们是非常聪明的C++黑客还是天真的初学者并不重要.每个人都会犯错误,但是C++会故意找到它们,甚至在它们发生之前更难发现它们.
使用C++,你总是在不使用调试器的情况下丢失,但我希望能够在头脑中验证代码的正确性,而不必依赖调试器来查找我在前所未有的路径上运行的代码.我实际上尝试在我的头脑中运行我的所有代码并尝试获取它拥有的所有分支,甚至在子程序等中.并且偶尔使用调试器只是为了看看它在我为它准备的所有舒适的地方运行得如何.编写和执行如此多的测试用例,使得所有代码路径都被用于所有类型的奇怪输入数据的组合是根本不可能的.所以你可能不知道C++程序中的错误,但这并不意味着它们不存在.C++项目越大越低,我相信它不会有很多未被发现的错误,即使它与我们手边的所有测试数据完美匹配.最终我把它丢弃并重新开始使用其他语言或其他语言的组合.
我可以继续,但我想我现在已经说清楚了.当我用C++编程并且让我对自己的代码的正确性失去信心,这意味着我将不再使用它,而我仍然使用并依赖于我编写的20多个C代码时,所有这些都让我觉得没有效果几年前.也许这只是因为我不是一个优秀的C++程序员,或者在C语言方面表现相当不错,而其他语言让我能够认识到在C++方面我实际上是什么样的,而且我永远无法完全理解它.
生命短暂...
在低级嵌入式环境中,一些"软件工程师"将拥有EE背景并且几乎没有掌握C. C++更复杂,其中一些人只是害怕学习一门新语言.因此,C被用作最小公分母.(在你建议摆脱这些家伙之前,他们至少和那些不了解核心模拟东西的CS专业人士一样重要.)
从继承和维护两者的经验谈起:C中的可怕设计很难理解,放松和重构成可用的东西.
随机抽象层将你的大脑放在代码库周围,试图找出哪些代码将在哪种情况下执行,因此C++中的可怕设计无限糟糕.
如果我必须与我知道不会产生出色设计的工程师合作,我宁愿拥有前者而不是后者.
即使对嵌入式系统和类似的东西进行编程,我也没有看到任何个人不喜欢的理由.在C++中,您仅为您使用的功能支付开销.在C++开销过高的某些特定情况下,您可以使用C++的C子集.这就是说,我认为一些C程序员高估了一些C++结构的开销.让我列举一些例子:
与普通函数相比,类和成员函数的开销为零(除非使用虚函数,在这种情况下与使用函数指针相比没有开销)
模板的开销很小(通常根本没有开销)
一个合理的原因是当你为一个没有合适的C++编译器的平台编程时(根本没有C++编译器,或者编译器存在,但实现很差,并且对某些C++特性施加了不必要的高开销).
为什么限制英语口语?也许你会成为塞尔维亚人更具创造力的作家.
这是相同的论点,有明显的谬误.如果您有任务,并且您的舒适工具可以有效地解决任务,那么您可能会使用舒适的工具.
C++有更长的学习曲线.C只有很少的构造需要注意,然后你就可以开始编写功能强大的软件了.在C++中,你需要学习C基础,然后是OO和泛型编程,异常等.经过一段时间你可能知道大多数功能,你可能会使用它们,但你仍然不知道编译器将如何翻译他们,他们有或没有隐含的开销.这需要很多时间和精力.
对于一个专业项目,这个论点可能不算数,因为你可以雇用已经熟悉C++的人.但是在开源项目中,C仍然使用了widley,人们会选择他们喜欢的语言并且能够使用.考虑到并非每个OS程序员都是专业程序员.
我想跟进Dan Olson的回答.我相信人们担心C++的潜在危险和适得其反的特性,并且理所当然.但与丹所说的不同,我不认为简单地决定编码标准是有效的,原因有两个:
编码标准可能难以严格执行
想出一个好的很难.
我认为这里的第二个原因比第一个原因重要得多,因为决定编码标准很容易成为一个政治问题,并在以后进行修订.考虑以下简化案例:
您可以使用stl容器,但不能在任何自己的代码中使用模板.
人们开始抱怨如果他们只是被允许编写这个或那个模板类,他们会更有效率.
修改编码标准以允许这样做.
将斜率滑动到一个过于复杂的编码标准,没有人遵循,并使用标准本应防止的那种危险代码,并结合标准周围的过多官僚作风.
(标准在步骤3中没有修改的替代方案在经验上太不可能考虑,反正也不会那么好.)
虽然几年前我曾经使用过几乎所有的C++,但我开始强烈地认为C在需要由C或C++处理的低级任务中是首选,而其他一切都应该在其他一些任务中完成.语言完全.(只有可能的例外是一些特定的高性能问题域,wrt.Blitz ++)
我使用C,或者在编写库代码时至少导出一个C接口.
我不想要不明确的ABI麻烦.
我从来没有见过任何关于使用C over C++的论据,我认为这些论点令人信服.我认为大多数人都害怕C++提供的某些功能,通常是合理的.然而,这并不能说服我,因为人们可以通过编码标准来强制执行是否使用某些功能.即使在C中,也有很多你想要避免的东西.完全抛弃C++本质上是说它没有提供超过C的实际好处,这有助于编写更好的代码,这是我认为非常无知的观点.
此外,人们似乎总是提出没有C++编译器的平台的情况.当然C在这里是合适的,但我认为你现在很难找到像这样的平台.
有一点,我还没有看到,我认为这是最重要的:
我每天使用的大多数库都是带有Python,Ruby,Perl,Java等绑定的C库.从我所看到的,用19种不同的语言绑定来包装C库要容易得多.包装C++库.
例如,我曾经学过一次开罗,并且已经使用过3到4种不同的语言.大赢!我宁愿编写一个可以在将来再次使用的程序,编写一个可以很容易被其他编程语言采用的程序就是这种情况的极端情况.
我知道绑定C++库是可能的,但AFAICT并不相同.我已经在其他语言中使用过Qt(v3和v4)并且使用起来并不是很好:他们感觉就像用其他语言编写C++,而不是像本机库一样.(你必须将C++方法sigs作为字符串传递!)
如果您正在编写一次使用的函数,或者如果您认为全世界都是C++,那么C++可能是一种更好的语言.如果你从一开始就设计语言可移植性,C似乎是一种更容易的语言.
Windows内核开发不支持c ++(遗憾的是).
你可以阅读一个有趣的咆哮,讲述为什么Linus Torvalds 在这里赞成C.
mac上的本机代码是objective-c.PC上的本机代码是c(window.h)或c ++(mfc).这两种环境都允许您在很少或没有更改的情况下使用c.当我想要一个代码库来跨平台时,似乎是个不错的选择.