在 C++ 代码中使用/混合 C?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4025869/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using/Mixing C in C++ code?
提问by Brad
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. 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.
许多人告诉我,在 C++ 中使用 C 很糟糕,因为它不安全,而且需要更多的内存管理。我一直告诉他们,只要您知道自己在做什么,并且删除“new”并释放“malloc”,那么 C 就不是问题。
I'm currently on a forum where an argument over std::string
vs. a char*
is taking place. Some people are saying that allocating a simple char*
memory block is more efficient, and as long as you deallocate it, it's fine. 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
与 a的争论char*
。有人说,分配一个简单的char*
内存块效率更高,只要释放它就可以了。另一方面,我们有人说它std::string
更好,因为它不涉及内存管理,但效率较低。
So the main question here is:
所以这里的主要问题是:
- Is mixing C/C++ bad? Should you ONLY use 100% C++ when you're coding C++?
- 混合 C/C++ 不好吗?当您编写 C++ 代码时,您应该只使用 100% C++ 吗?
Any answers would be appreciated!
任何答案将不胜感激!
采纳答案by James McNellis
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.
我一直告诉他们,只要您知道自己在做什么,并且删除 new 并释放 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
. Do you alwayscatch everyexception that can be thrown and manually clean up any resources?
这是真的; 如果您非常小心并确保手动清理东西,那么这不是问题。但你真的有时间这样做吗?每次调用都new
可以抛出std::bad_alloc
。您是否总是捕获可以抛出的每个异常并手动清理任何资源?
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. Why do things the hard way when you don't have to?
如果答案是肯定的,那么您为什么要浪费这么多时间来担心资源管理?C++ 习惯用法,如范围绑定资源管理 (SBRM;更常见的是资源获取即初始化 (RAII)) 和标准模板库等库,可帮助您更轻松地编写正确的代码。为什么在不需要的时候做一些困难的事情?
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; 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 代码,你当然可以使用该代码;一定要小心。通常,与 C 代码互操作的最简洁方法是围绕它编写一个 C++ 包装器。
回答by Armen Tsirunyan
My strong belief is that your question doesn't have to do with C or C++ at all. Your question is about trading dubious efficiency for safety. Yes, C can be more efficient. 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. If you are developing an efficiency-extremely-critical application, then why not code it in C in the first place?
我坚信您的问题根本与 C 或 C++ 无关。你的问题是为了安全而交易可疑的效率。是的,C 可以更高效。但是效率高多少?你为此付出了什么?这些是你应该回答的问题。在大多数情况下,字符串与 const char* 的开销是不明显的。如果您正在开发一个效率极其关键的应用程序,那么为什么不首先用 C 编写它呢?
回答by rubenvb
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. 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. (see examples below)
在编写 C++ 项目时,使用 C++,避免使用 C(和家族)并坚持使用标准库和 STL。保证同质的C++接口(毕竟是C++项目!)当使用C中的外部项目时,恰好是用C编写的,当然可以使用它。(见下面的例子)
Two prime examples:
两个主要例子:
Write a C++ program/library that does scientific calculations. 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. 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.Writing a C++ program using the Win32 API, which is horribly C based. 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. 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 achar*
buffer as argument.
编写一个进行科学计算的 C++ 程序/库。我肯定会使用 GSL(GNU 科学库),它是用 C 编写的。只有一些注意事项(例如 GSL 中特定结构和函数的专门初始化和自由函数),可以在
std::unique_ptr
typedef 中吸收。还有错误处理的问题:如果需要/需要,可以在异常机制中抽象检查错误代码,或者您可以将错误代码包含在计算函数中。GSL 确实有一种设置错误处理程序的方法,我想其他一些 C 库也有这样的功能。使用 Win32 API 编写 C++ 程序,该 API 非常基于 C。我说的是轻量级的 API 使用,比如读取目录中的文件、检查文件是否存在等,而不是大量的 GDI+ 或其他东西。我喜欢将 Win32 API 公开的所有 C 函数包装在漂亮的 C++ 样式函数中,也许有必要的例外并返回 a
std::string
而不是必须将char*
缓冲区作为参数传递。
I understand both examples are quite... shallow... but I feel they express a general enough idea.
我知道这两个例子都非常......浅薄......但我觉得它们表达了一个足够普遍的想法。
回答by UnixShadow
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++.
* a C programmer expects all code to behave like C.
可维护性不好的原因是:
* C++ 程序员希望所有代码的行为都像 C++。
* C 程序员希望所有代码的行为都像 C。
So when you mix C++ and C, you break both programmers expectations on how things should work.
所以当你混合 C++ 和 C 时,你打破了两个程序员对事情应该如何工作的期望。
回答by Puppy
The better question here is, why use 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. Thirdly, you're giving up a huge quantity of application security by using C instead of C++.
这里更好的问题是,为什么要使用 C?表现?首先,我相信具有相同功能的程序没有可测量的性能差异。其次,您必须分析并证明对于您的特定情况,C++ 速度较慢。第三,通过使用 C 而不是 C++,您放弃了大量的应用程序安全性。
回答by Gerald
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 probablyokay, but that's rarely the case.
通常,您希望避免混合可能导致混淆的东西,这会进一步导致难以发现的错误。仅仅因为“你知道你在做什么”并不意味着下一个接触你代码的人会知道你在做什么。如果您正在开发只有您会使用的代码,那么这可能没问题,但这种情况很少见。
Using C for performance is fine if you're careful. But you should only do it if you KNOW that you need the performance. Premature low-level optimization is the work of the devil.
如果你小心的话,使用 C 来提高性能是没问题的。但是,只有当您知道自己需要性能时才应该这样做。过早的低级优化是魔鬼的工作。
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.
这是一种非常罕见的情况,在 std::string 上使用 char* 会给您带来任何显着的性能优势,并且只有在确实如此的情况下才值得内存管理麻烦。
回答by pm100
regrading the argument over std::string vs char *.
在 std::string 与 char * 上重新调整参数。
std::string is not going to be slower that char * (for heap 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 不会比 char * 慢(对于堆 char*);许多实现要快得多,因为它们使用私有内存池。无论如何, std::string 的健壮性远远超过任何(不太可能的)性能命中
回答by Nim
The simple answer here is, profile; determine which works best in your caseand use it wisely!
这里的简单答案是,profile;确定哪种最适合您的情况并明智地使用它!
回答by justin
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. 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.
许多人告诉我,在 C++ 中使用 C 很糟糕,因为它不安全,而且需要更多的内存管理。我一直告诉他们,只要您知道自己在做什么,并且删除 new 并释放 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". i even go as far as to change malloc, free, etc. to assert in root namespaces (among other things).
我经常检查/拒绝/重写进入代码库的代码,该代码库是“具有 c + 特性的 c”或“具有 c 特性的 c +”。我什至将 malloc、free 等更改为在根命名空间(除其他外)中进行断言。
I'm currently on a forum where an argument over std::string vs. a char* is taking place. Some people are saying that allocating a simple char* memory block is more efficient, and as long as you deallocate it, it's fine. 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 与 char* 的争论。有人说,分配一个简单的 char* 内存块效率更高,只要释放它就可以了。另一方面,我们有人说 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++. there are plenty of cases where this is acceptable (imo), but not always worth the time investment. in any event, it's easier to manage than integrating c idioms/styles/dangers into c++ programs.
如果效率如此重要并且std::string
对于特定任务来说不太理想,那么 C++ 足够强大,可以通过在 C++ 中创建专门的接口来表达您对这些特定情况的意图。在很多情况下这是可以接受的(imo),但并不总是值得花时间投资。无论如何,比将 c 习惯用法/样式/危险集成到 c++ 程序中更容易管理。
So the main question here is: Is mixing C/C++ bad? Should your ONLY use 100% C++ when your coding C++?
所以这里的主要问题是:混合 C/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++ 惯用语,没有性能损失并且具有更好的可维护性。
回答by zwol
In the specific case of string
versus const char *
, you should use bare const char *
for all variables that hold string constants(and onlystring constants), converting to string
only when passing to an API that requires 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.
在string
vs的特定情况下const char *
,您应该const char *
对所有保存字符串常量(且仅字符串常量)的变量使用裸露,string
仅在传递给需要string
. 始终如一地这样做可以消除大量的全局构造函数,不会导致内存分配问题(因为字符串常量是永久性的常量数据)并且 IMO 实际上使代码更清晰 - 你看const char *
,你知道这将是一个字符串常量。