简体   繁体   English

在C ++代码中使用/混合C?

[英]Using/Mixing C in C++ code?

Is using C in C++ bad? 在C ++中使用C是不是很糟糕?

Many people have told me that using C in C++ is bad because it's not as safe, and it requires more memory management. 很多人告诉我在C ++中使用C是不好的,因为它不那么安全,而且需要更多的内存管理。 I keep telling them that as long as you know what you're doing, and you delete your "new"s and free your "malloc"s then C isn't a problem. 我一直告诉他们,只要你知道你在做什么,你删除你的“新”并释放你的“malloc”,那么C不是问题。

I'm currently on a forum where an argument over std::string vs. a char* is taking place. 我目前正在一个论坛上,正在发生关于std::stringchar*的争论。 Some people are saying that allocating a simple char* memory block is more efficient, and as long as you deallocate it, it's fine. 有些人说分配一个简单的char*内存块效率更高,只要你解除分配它就没问题了。 On the other hand we have people saying that std::string is superior because it has no memory management involved but is less efficient. 另一方面,我们有人说std::string是优越的,因为它没有涉及内存管理,但效率较低。

So the main question here is: 所以这里的主要问题是:

  • Is mixing C/C++ bad? 混合C / C ++不好吗? Should you ONLY use 100% C++ when you're coding C++? 在编写C ++时,你是否只能使用100%C ++?

Any answers would be appreciated! 任何答案将不胜感激!

I keep telling them that as long as you know what your doing, and you delete your new's and free your malloc's then C isn't a problem. 我一直告诉他们,只要你知道你在做什么,然后你删除你的新东西并释放你的malloc,那么C不是问题。

This is true; 这是真的; if you are extraordinarily careful and ensure that you manually clean things up, then it isn't a problem. 如果你非常小心并确保你手动清理,那么这不是问题。 But do you really have the time to do that? 但你真的有时间这样做吗? Every call to new can throw std::bad_alloc . 每次调用new都会抛出std::bad_alloc Do you always catch every exception that can be thrown and manually clean up any resources? 您是否始终捕获可以抛出的每个异常并手动清理任何资源?

I'd hazard to guess the answer to that is "no," because it is very tedious to write code like that and it is difficult to be absolutely sure that code written like that is correct, even in the case of rare failures. 我不敢猜测答案就是“不”,因为写这样的代码是非常繁琐的,而且很难确定这样编写的代码是正确的,即使在罕见的失败的情况下也是如此。

If the answer is "yes," then why are you wasting so much time worrying about resource management? 如果答案是“是”,那你为什么要浪费这么多时间来担心资源管理呢? C++ idioms like scope-bound resource management (SBRM; more commonly known as resource acquisition is initialization (RAII)) and libraries like the standard template library are there to help you write correct code more easily. C ++习语如范围绑定资源管理(SBRM;通常称为资源获取是初始化(RAII))和标准模板库之类的库可以帮助您更轻松地编写正确的代码。 Why do things the hard way when you don't have to? 当你不需要时,为什么事情很难?

Should you ONLY use 100% C++ when your coding C++? 你编译C ++时只能使用100%C ++吗?

Yes, though if there is a C library that does something you need, or if you have legacy C code that you want to use, you can certainly use that code; 是的,但是如果有一个C库可以做你需要的东西,或者如果你有你想要使用的遗留C代码,你肯定可以使用那些代码; just be sure to be careful. 一定要小心。 Often the cleanest way to interop with C code is to write a C++ wrapper around it. 通常,与C代码互操作的最简洁方法是围绕它编写C ++包装器。

My strong belief is that your question doesn't have to do with C or C++ at all. 我坚信你的问题与C或C ++完全没有关系。 Your question is about trading dubious efficiency for safety. 你的问题是交易可疑的安全效率。 Yes, C can be more efficient. 是的,C可以更有效率。 But how much more efficient? 但效率更高? And what do you pay for that? 你为此付出了什么? These are the questions you should answer. 这些是你应该回答的问题。 In most cases string vs. const char* overhead is unnoticeable. 在大多数情况下,字符串与const char *开销是不明显的。 If you are developing an efficiency-extremely-critical application, then why not code it in C in the first place? 如果您正在开发一个效率极其关键的应用程序,那么为什么不首先在C中编写它?

I'm genuinely surprised by the polarization in the answers and comments thereof. 我对答案和评论中的两极分化感到非常惊讶。

In my eyes, the answer is pretty simple: 在我看来,答案很简单:

When writing a C++ project, use C++, avoid C ( and family) and stick to the Standard Library and STL. 编写C ++项目时,使用C ++,避免使用C(和系列)并坚持使用标准库和STL。 Ensure a homogenous C++ interface (it is a C++ project after all!) When using an external project in C, which happens to be written in C, of course you can use it. 确保一个同质的C ++接口(毕竟它是一个C ++项目!)当在C中使用外部项目时,恰好用C语言编写,当然你可以使用它。 (see examples below) (见下面的例子)

Two prime examples: 两个主要的例子:

  1. Write a C++ program/library that does scientific calculations. 编写一个进行科学计算的C ++程序/库。 I would definitely use GSL (GNU Scientific Library), and it is written in C. There are only a few caveats (like specialized initialize and free functions for specific structs and functions within GSL), that can be absorbed in a std::unique_ptr typedef. 我肯定会使用GSL(GNU科学库),它用C语言编写。只有一些注意事项(如GSL中特定结构和函数的专用初始化和自由函数),可以在std::unique_ptr被吸收的typedef。 There is also the issue of error handling: checking error codes can be abstracted away in an exception mechanism if necessary/wanted, or you can keep the error codes contained within the calculation functions. 还存在错误处理的问题:如果需要/想要,可以在异常机制中抽象检查错误代码,或者可以保留计算函数中包含的错误代码。 GSL does have a way of setting up an error handler, I imagine some other C libraries have such a functionality. GSL确实有一种设置错误处理程序的方法,我想其他一些C库都有这样的功能。

  2. Writing a C++ program using the Win32 API, which is horribly C based. 使用Win32 API编写C ++程序,这是一个非常基于C的程序。 I'm talking about light API usage, like reading the files in a directory, checking if a file exists, etc., not heavy GDI+ or other stuff. 我在谈论轻量级API的使用,比如读取目录中的文件,检查文件是否存在等等,不是重GDI +或其他东西。 I like to wrap all the C functions the Win32 API exposes in nice C++ style functions, perhaps with the necessary exceptions and returning a std::string instead of having to pass a char* buffer as argument. 我喜欢将Win32 API公开的所有C​​函数包装在漂亮的C ++样式函数中,可能包含必要的异常并返回std::string而不必传递char* buffer作为参数。

I understand both examples are quite... shallow... but I feel they express a general enough idea. 我理解这两个例子都很......很浅......但我觉得它们表达了一个足够普遍的想法。

Yes it's bad to mix C and C++, any the reason has nothing to do with performance or security: 是的,混合使用C和C ++是不好的,任何原因都与性能或安全性无关:

It is bad cause of a maintainability: 这是可维护性的坏因素:
* a C++ programmer expects all code to behave like C++. * C ++程序员希望所有代码都像C ++一样运行。
* a C programmer expects all code to behave like C. * C程序员希望所有代码都像C一样。

So when you mix C++ and C, you break both programmers expectations on how things should work. 因此,当你混合使用C ++和C时,你会打破程序员对事情应该如何运作的期望。

The better question here is, why use C? 这里更好的问题是,为什么要使用C? The performance? 表现? Firstly, I believe that there is no measurable performance difference for a program with the same function. 首先,我认为具有相同功能的程序没有可测量的性能差异。 Secondly, you would have to profile and prove that for your specific case, C++ is slower. 其次,您必须分析并证明对于您的特定情况,C ++较慢。 Thirdly, you're giving up a huge quantity of application security by using C instead of C++. 第三,通过使用C而不是C ++,您放弃了大量的应用程序安全性。

regrading the argument over std::string vs char *. 重新调整std :: string vs char *的参数。

std::string is not going to be slower that char * (for heap char*); std :: string不会慢于char *(对于堆char *); many implementations are much faster because they use private memory pool. 许多实现都快得多,因为它们使用私有内存池。 And anyway the robustness of std::string far outweighs any (unlikely) perf hit 无论如何,std :: string的健壮性远远超过任何(不太可能的)性能

The answer is, of course: it depends. 答案当然是:这取决于。

Generally you want to avoid mixing things that can cause confusion, that can further lead to hard-to-find bugs. 通常,您希望避免混合可能导致混淆的事物,这可能会进一步导致难以发现的错误。 Just because "you know what your doing" doesn't mean that the next person to touch your code will know what you were doing. 仅仅因为“你知道你在做什么”并不意味着接触你代码的下一个人会知道你在做什么。 If you're developing code that only you will ever use, then it's probably okay, but that's rarely the case. 如果您正在开发只有您将使用的代码,那么它可能没问题,但这种情况很少发生。

Using C for performance is fine if you're careful. 如果你小心的话,用C来表现就好了。 But you should only do it if you KNOW that you need the performance. 但是,如果您知道自己需要性能,那么您应该这样做。 Premature low-level optimization is the work of the devil. 过早的低级优化是魔鬼的工作。

It's a very rare case where using char* over std::string will give you any noticeable performance benefits, and it's only worth the memory management hassle in those cases where it does for sure. 这是一种非常罕见的情况,使用char * over std :: string会给你带来明显的性能优势,而且只有在确实存在的情况下才能让内存管理变得麻烦。

The simple answer here is, profile ; 这里简单的答案是, 简介 ; determine which works best in your case and use it wisely! 确定哪种方法最适合您的情况并明智地使用它!

Is using C in C++ bad? 在C ++中使用C是不是很糟糕?

although a subjective question: in my opinion, take great measures to avoid using c in c++ programs. 虽然是一个主观问题:在我看来,采取了很多措施来避免在c ++程序中使用c。

Many people have told me that using C in C++ is bad because it's not as safe, and it requires more memory management. 很多人告诉我在C ++中使用C是不好的,因为它不那么安全,而且需要更多的内存管理。 I keep telling them that as long as you know what your doing, and you delete your new's and free your malloc's then C isn't a problem. 我一直告诉他们,只要你知道你在做什么,然后你删除你的新东西并释放你的malloc,那么C不是问题。

you're reintroducing deficiencies and dangers c++ was designed to overcome, and it's not the way things are done in c++ programs. 你重新介绍了c ++旨在克服的缺陷和危险,而不是c ++程序中的事情。

i routinely check/reject/rewrite code that enters codebases that is "c with c++ features", or "c++ with c features". 我经常检查/拒绝/重写进入“c with c ++ features”或“c ++ with c features”的代码库的代码。 i even go as far as to change malloc, free, etc. to assert in root namespaces (among other things). 我甚至可以将malloc,free等更改为在根命名空间(以及其他内容)中断言。

I'm currently on a forum where an argument over std::string vs. a char* is taking place. 我目前正在一个论坛上,正在发生关于std :: string与char *的争论。 Some people are saying that allocating a simple char* memory block is more efficient, and as long as you deallocate it, it's fine. 有些人说分配一个简单的char *内存块效率更高,只要你解除分配它就没问题了。 On the other hand we have people saying that std::string is superior because it has no memory management involved but is less efficient. 另一方面,我们有人说std :: string是优越的,因为它没有涉及内存管理,但效率较低。

there are more options for representing a string in c++ than std::string. 在c ++中表示字符串的选项多于std :: string。

in my opinion, it's completely valid to create a new class which represents a string and serves a particular purpose, or follows additional contracts (when necessary). 在我看来,创建一个代表字符串并用于特定目的的新类或遵循其他合同(必要时)是完全有效的。 part of the contracts of such string representations are (of course) that they manage their own resources using new[]/delete[] when dynamic memory is used. 当使用动态内存时,这些字符串表示的一部分合同(当然)是使用new[]/delete[]管理自己的资源。

if efficiency is that important and std::string is less than ideal for a specific task, then c++ is powerful enough to express your intent for these specific cases by creating a specialized interface in c++. 如果效率非常重要且std::string不是特定任务的理想选择,那么c ++就足以通过在c ++中创建专用接口来表达您对这些特定情况的意图。 there are plenty of cases where this is acceptable (imo), but not always worth the time investment. 有很多情况下这是可以接受的(imo),但并不总是值得花时间投资。 in any event, it's easier to manage than integrating c idioms/styles/dangers into c++ programs. 无论如何,它比将c惯用语/样式/危险集成到c ++程序中更容易管理。

So the main question here is: Is mixing C/C++ bad? 所以这里的主要问题是:混合C / C ++是不是很糟糕? Should your ONLY use 100% C++ when your coding C++? 您的编码C ++时,您是否只能使用100%C ++?

it's best to create reusable object based solutions for your needs. 最好根据您的需求创建可重用的基于对象的解决方案。 the dangers in the example provided can be completely encapsulated (if this optimization is truly worth the time investment), and be written to use c++ idioms, without performance loss and with better maintainability. 所提供的示例中的危险可以完全封装(如果这种优化真的值得花时间投入),并且可以编写使用c ++习语,而不会降低性能并且具有更好的可维护性。

In the specific case of string versus const char * , you should use bare const char * for all variables that hold string constants (and only string constants), converting to string only when passing to an API that requires string . 在特定情况下string对比const char * ,你应该使用裸const char *的持有字符串常量 (也只有字符串常量)所有变量,转换为string传递给需要的API只有当string Doing this consistently can eliminate enormous numbers of global constructors, does not cause memory allocation headaches (since string constants are permanent, constant data) and IMO actually makes the code clearer - you see const char * , you know that's gonna be a string constant. 一致地执行此操作可以消除大量的全局构造函数,不会导致内存分配问题(因为字符串常量是永久的,常量数据),IMO实际上使代码更清晰 - 你看到const char * ,你知道它将是一个字符串常量。

If your'e talking about techniques, I'd be careful to say that doing the above is okay. 如果你在谈论技巧,我会小心地说,做上述事情是可以的。

Writing C++ programs using C-style program organization techniques will likely result in lots of maintainability issues. 使用C风格的程序组织技术编写C ++程序可能会导致许多可维护性问题。 In general, the programmer is ignoring many of the benefits that an object-oriented language provides. 通常,程序员忽略了面向对象语言提供的许多好处。 Simply because much of C syntax is valid C++ and many coding techniques transfer does not mean you should do them in C++. 仅仅因为C语法的大部分是有效的C ++并且许多编码技术的转移并不意味着你应该在C ++中使用它们。

That said, using C functions and things isn't a problem, so long as your'e careful about their use. 也就是说,使用C函数和事物不是问题,只要你仔细考虑它们的使用。 In some cases, you have to. 在某些情况下,你必须。

Well, I'm in a strange situation. 好吧,我处境很奇怪。 I am working on a system that is supposed to be in C++ (C++ compiler is used and term C++ is used), but everything is written in C. This is very frustrating, because it is getting to a point where I have to 'prove' C++ is better to use than C, even though we are coding in C++. 我正在开发一个应该使用C ++的系统(使用C ++编译器并使用术语C ++),但所有内容都是用C语言编写的。这非常令人沮丧,因为它已经达到了我必须要证明的程度。 'C ++比C更好用,即使我们用C ++编写代码。 It was all hell when I introduced std::string. 当我介绍std :: string时,一切都很糟糕。 My take on it is that everything now is starting to get cluttered (mixing of C and C++). 我对此的看法是,现在一切都开始混乱(C和C ++的混合)。 There are rare instances of error handling. 很少有错误处理实例。 In fact, I think I can count 3 system wide try-catch statements. 事实上,我认为我可以计算3个系统范围的try-catch语句。 The code is messy, memory leaks are prominent and finding an error is a needle in a haystack. 代码很乱,内存泄漏很突出,发现错误是大海捞针。 There are hundreds of lines of code that can be replaced by C++ functions. 有数百行代码可以被C ++函数替换。 I'd say writing the code is more efficient, cleaner and easier to understand. 我会说编写代码更有效,更清晰,更容易理解。

From my experience, yes of course you can mix C and C++. 根据我的经验,当然可以混合使用C和C ++。 You can pretty much do whatever you want, but maintaining, debugging and actually figuring out what's going on becomes a problem. 你几乎可以做任何你想做的事情,但维护,调试和实际弄清楚发生了什么都会成为一个问题。 It's easy to say you're going to clean-up your memory allocations, but maybe someone else uses your code and doesn't. 很容易说你要清理你的内存分配,但也许其他人使用你的代码而不是。 Maybe you forget to do it and you waste hours on finding silly bugs, instead of using that time to do something productive. 也许你忘了这么做而浪费时间去寻找愚蠢的错误,而不是利用那段时间来做一些富有成效的事情。 I don't even think there should be an argument. 我甚至认为不应该有争论。 When you do C++, do C++. 当你做C ++时,做C ++。 When you do C, do C. 当你做C时,做C.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM