Is using C in C++ bad?
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 tha
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. 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.
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
. 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.
The simple answer here is, profile; determine which works best in your case and use it wisely!
Is using C in C++ bad?
although a subjective question: in my opinion, take great measures to avoid using c in c++ programs.
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.
you're reintroducing deficiencies and dangers c++ was designed to overcome, and it's not the way things are done in c++ programs.
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).
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.
there are more options for representing a string in c++ than 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.
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.
So the main question here is: Is mixing C/C++ bad? Should your ONLY use 100% C++ when your coding 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.
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.
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 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. Why do things the hard way when you don't have to?
Should you ONLY use 100% C++ when your coding 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.
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)
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 a char*
buffer as argument.
I understand both examples are quite... shallow... but I feel they express a general enough idea.