tags:

views:

707

answers:

9

What should I keep in mind when converting my projects from C to C++? Is there any reason to use C at all? The only thing in my mind now is to make sure it's friendly to DLLs so I can create a C interface if I need it.

Note: I know C++ just fine. Templates, partial specialization, why multiple inheritance is bad (I've only seen one proper use for it), etc. I mostly want to know why I would use C over C++. DLLs and script language bindings is one reason. So I just need to keep in mind I should have a C interface for certain things. Is there anything else?

+1  A: 

The main issue will be keywords. Have you used 'new', 'private', 'public' etc as variable names?
Unless you are targetting a specific embedded platform or kernel mode driver there is no real need to limit yourself to 'c' anymore.
You won;t gain all the benfits of C++ by simply writing c code in a c++ compiler of course - it takes a little more rethinking than that!

Martin Beckett
A: 

Yes. C code seems to be simpler for smaller projects; LOC-wise and binary-wise.

Paul Nathan
+4  A: 

You can always include raw C code into a C++ project. So even if you have a C library which somewhat messes with C++, just use extern "C" {} for referencing, then call it inside your C++ code.

http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html

It is also perfectly possible to link C object files with C++ object files.

This (link to c++ FAQ lite) is basically all you know to convert your project to C++ and stay legacy-compatible.

ypnos
A: 

Is there any reason to use C at all?

C++ code compiles much too slowly for small projects.
A long compilation disturbs the loop: write some code -> test it -> write more code -> test it ...

J.F. Sebastian
It doesn't compile any faster for large projects...
Steve Jessop
I personally feel that C is more elegant to code, but C++ is easier to code big projects in.
coppro
On most systems these days the C compiler is the same as the C++ compiler so the compile time is identical.
Jimmy J
@Jimmy J: You are soo.. wrong. I didn't write that C++ compilers compile C code slowly. I wrote that C++ compilers compile *C++* code too slowly for my taste (compared with C code).
J.F. Sebastian
@Jimmy J: Take a couple of open-source projects (similar in size) one in pure C (e.g., `git`) another in C++ (e.g., some `boost` library) and compile them. See the difference for youself.
J.F. Sebastian
+10  A: 

At the risk of being obvious, I'd say the main thing to keep in mind is not to fix anything that isn't broken.

If you have a working C library, and want it to have a more "C++ ish" interface, then wrapping it in classes might be smarter than converting it. Certainly this satisifies the requirement to provide a DLL-friendly C interface: keep the one you've already got.

Steve Jessop
+9  A: 

As a C programmer, I find it annoying when C++ programmers try to "port" C to C++. While there are many advantages to using the C++ language structures, they don't always improve on the simple function oriented approach of C. Since you can always get at the C functionality via extern "C", there's little reason to alter working code. In projects I've worked on, creating object wrappers around C code has worked well. That way the core code can be shared among teams working in either language and everyone can use a interface that matches their environment. We've even "back-ported" some C++ code to C to encourage code reuse.

I work with several different project teams that use a C++ wrapper around a C core for database access. Some teams use C++ and others are C only, but the core functionality is shared among the teams. We are in the maintenance period, so even if a C team wanted to port to C++ it wouldn't be feasible. The attempts I've seen to convert C to C++ have resulted in longer, more convoluted, but no more expressive code. YMMV, of course.

Jon Ericson
Probably about as annoying as C++ programmers find it when C programmers write C++ ;-)
Steve Jessop
What part of "C++ is a superset of C" don't you understand? ;-)
Jon Ericson
not a strict superset! Don't let that bite you!
coppro
In your projects; has creating C frontends to C++ classes worked well? or have they been avoided or was there never a need for C++ -> C?
acidzombie24
We have had to bring C++ functionality into C programs, but we do tend to port the code. C doesn't really have any analog to extern C, so I'm not sure how to go about wrapping C++ classes for C.
Jon Ericson
Define an opaque pointer type for each class. Write a function for each method. It takes "self" as a param, casts and calls the method. Wrap them all in extern "C" and compile them into a library using the C++ compiler. The C linker should then be able to use that library. I think.
Steve Jessop
This does mean that all objects must be on the heap, although you might be able to do something with placement new. Also, methods which take further UDT objects as parameters need to cast those parameters, just like the "self" param. I suspect that anything too template-y is doomed.
Steve Jessop
Hey, at least he figured out that C and C++ are different beasts.
Jimmy J
+1  A: 

Is there any reason to use C at all?

Although it's getting rarer, it's still possible to find platforms which don't have a viable c++ compiler. ADI's Blackfin chip fell into this category a few years ago, I'm not sure if a decent one exists now.

AShelly
A: 

why multiple inheritance is bad

Hey, now. Multiple inheritance can be very good. It's just easy to misuse. One example of multiple inheritance that is good in inheriting several abstract base classes.

rlbond
+1  A: 

Since I have ported a few C projects to C++ before I can relay my experiences:

I will guess that what you really means is "Make classes and objects from code that already works fine", when you say you are porting from C to C++. That is probably what you are doing. I imagine the reason you want to do the porting is to make the code more reusable and maintainable. Bear in mind I am assuming this is a medium to large sized project (at least 10000 LOC).

If so, then I can imagine some problems you will come up against, but are also problems that are encountered in C++ in general:

Newly introduced bugs when making it

'OO'**

As C is procedural, it is going to be a judgement call as to what is "reusable" in the sense of an object in C++. You will probably find sometimes that your initial observation was incorrect. Not because your code doesn't compile, but because the logic doesn't perform the same as it used to. In which case: Test, test, test (incrementally) and do all of your fancy refactoring with design patterns at the end, when you know that your basic C++ objects have not mangled the C program's original intended logic.

Memory management problems

C's malloc and free and C++'s new and delete do very different things. What your C++ object allocations are going will depend very much on how you have reinterpreted your understanding of what the C code is doing, and so you will need to be very skilled at both. But initially I would keep the malloc and free calls and just abstract them with C++ unless there is a very good reason to do otherwise. So once your classes are created and are allocating and deallocating memory your application will have memory leaks. This is a guarantee and the very reason why you must test incrementally.

Refactoring and Design Patterns

I think there is sometimes this temptation to go nuts with inheritance and design patterns to make the code more 'leet'. Try to resist this temptation at the start of the port because design patterns are essentially a way to optimise code so that it is more efficient and maintainable but it is much harder have to think about porting the C code to C++ AND think about design patterns AND refactoring AND "crap now it doesn't work" AND "I used the wrong design pattern before I must change it"... As you can see it can very quickly spiral out of control so focus on doing ONE thing at a time to keep the porting process bug free and easy on your mind so you don't get overwhelmed.

Globals

You will need to carve out the globals and figure out where to limit their scope. Try to preserve the meaning and function of the C code by creating simple C++ objects one at a time with nothing fancy in the way of namespaces, inheritance, design patterns etc. Again, something that I would suggest doing after your code is converted into classes.

Brock Woolf