How to Convert C++ Code to C

Converting C source to C++

Having just started on pretty much the same thing a few months ago (on a ten-year-old commercial project, originally written with the "C++ is nothing but C with smart structs" philosophy), I would suggest using the same strategy you'd use to eat an elephant: take it one bite at a time. :-)

As much as possible, split it up into stages that can be done with minimal effects on other parts. Building a facade system, as Federico Ramponi suggested, is a good start -- once everything has a C++ facade and is communicating through it, you can change the internals of the modules with fair certainty that they can't affect anything outside them.

We already had a partial C++ interface system in place (due to previous smaller refactoring efforts), so this approach wasn't difficult in our case. Once we had everything communicating as C++ objects (which took a few weeks, working on a completely separate source-code branch and integrating all changes to the main branch as they were approved), it was very seldom that we couldn't compile a totally working version before we left for the day.

The change-over isn't complete yet -- we've paused twice for interim releases (we aim for a point-release every few weeks), but it's well on the way, and no customer has complained about any problems. Our QA people have only found one problem that I recall, too. :-)

Convert C program to C++

The code you posted should work in C++ as well as C. There shouldn't be a need to "convert" anything, unless there are specific requirements that you haven't told us about.

Your array-to-pointer conversion looks correct, although I would argue that the code is more readable in the array form.

For your decrypt method, you will want to write code that does the inverse of what the encrypt method does. The best way to approach this is to run some sample text through encrypt and examine what the output looks like. The function transforms the input a single character at a time, so you should be able to map input to output on a byte-by-byte basis. With this information, you can detect the pattern and construct a function that makes the transformation in the other direction.

How to convert this C code to C++?

static double covalent_radius[256] = {
0.85, /* ?, Unknown */
0.37, /* H, Hydrogen */
...
};

It's C89, not C99 so I suppose it should work.

how to convert this C++ code to Turbo C?

May be you are seeking for this:

printf("Roots are complex and different.\n");
printf("x1 = %lf+%lfi\n",realPart,imaginaryPart);
printf("x2 = %lf-%lfi\n",realPart,imaginaryPart);

if realPart and imaginaryPart variables are in data type double.

Use %f for float, %d for int, %s for string instead of %lf in the code otherwise.

How to update old C code?

First, you are fortunate to have a boss who recognizes that code refactoring can be a long-term cost-saving strategy.

I've done this many times, that is, converting old C code to C++. The benefits may surprise you. The final code may be half the original size when you're done, and much simpler to read. Plus, you will likely uncover tricky C bugs along the way. Here are the steps I would take in your case. Small steps are important because you can't jump from A to Z when refactoring a large body of code. You have to go through small, intermediate steps which may never be deployed, but which can be validated and tagged in whatever RCS you are using.

  1. Create a regression/test suite. You will run the test suite each time you complete a batch of changes to the code. You should have this already, and it will be useful for more than just this refactoring task. Take the time to make it comprehensive. The exercise of creating the test suite will get you familiar with the code.
  2. Branch the project in your revision control system of choice. Armed with a test suite and playground branch, you will be empowered to make large modifications to the code. You won't be afraid to break some eggs.
  3. Make those struct fields private. This step requires very few code changes, but can have a big payoff. Proceed one field at a time. Try to make each field private (yes, or protected), then isolate the code which access that field. The simplest, most non-intrusive conversion would be to make that code a friend function. Consider also making that code a method. Converting the code to be a method is simple, but you will have to convert all of the call sites as well. One is not necessarily better than the other.
  4. Narrow the parameters to each function. It's unlikely that any function requires access to all 30 fields of the struct passed as its argument. Instead of passing the entire struct, pass only the components needed. If a function does in fact seem to require access to many different fields of the struct, then this may be a good candidate to be converted to an instance method.
  5. Const-ify as many variables, parameters, and methods as possible. A lot of old C code fails to use const liberally. Sweeping through from the bottom up (bottom of the call graph, that is), you will add stronger guarantees to the code, and you will be able to identify the mutators from the non-mutators.
  6. Replace pointers with references where sensible. The purpose of this step has nothing to do with being more C++-like just for the sake of being more C++-like. The purpose is to identify parameters that are never NULL and which can never be re-assigned. Think of a reference as a compile-time assertion which says, this is an alias to a valid object and represents the same object throughout the current scope.
  7. Replace char* with std::string. This step should be obvious. You might dramatically reduce the lines of code. Plus, it's fun to replace 10 lines of code with a single line. Sometimes you can eliminate entire functions whose purpose was to perform C string operations that are standard in C++.
  8. Convert C arrays to std::vector or std::array. Again, this step should be obvious. This conversion is much simpler than the conversion from char to std::string because the interfaces of std::vector and std::array are designed to match the C array syntax. One of the benefits is that you can eliminate that extra length variable passed to every function alongside the array.
  9. Convert malloc/free to new/delete. The main purpose of this step is to prepare for future refactoring. Merely changing C code from malloc to new doesn't directly gain you much. This conversion allows you to add constructors and destructors to those structs, and to use built-in C++ automatic memory tools.
  10. Replace localize new/delete operations with the std::auto_ptr family. The purpose of this step is to make your code exception-safe.
  11. Throw exceptions wherever return codes are handled by bubbling them up. If the C code handles errors by checking for special error codes then returning the error code to its caller, and so on, bubbling the error code up the call chain, then that C code is probably a candidate for using exceptions instead. This conversion is actually trivial. Simply throw the return code (C++ allows you to throw any type you want) at the lowest level. Insert a try{} catch(){} statement at the place in the code which handles the error. If no suitable place exists to handle the error, consider wrapping the body of main() in a try{} catch(){} statement and logging it.

Now step back and look how much you've improved the code, without converting anything to classes. (Yes, yes, technically, your structs are classes already.) But you haven't scratched the surface of OO, yet managed to greatly simplify and solidify the original C code.

Should you convert the code to use classes, with polymorphism and an inheritence graph? I say no. The C code probably does not have an overall design which lends itself to an OO model. Notice that the goal of each step above has nothing to do with injecting OO principles into your C code. The goal was to improve the existing code by enforcing as many compile-time constraints as possible, and by eliminating or simplifying the code.

One final step.

Consider adding benchmarks so you can show them to your boss when you're done. Not just performance benchmarks. Compare lines of code, memory usage, number of functions, etc.

Is there a tool to convert ANSI C code to C#?

If manual refactoring is "only" going to take a few days, that would get my vote. Depending on what the C code is doing and how it is written (pointers, custom libraries, etc.) an automated converter may just make a mess. And untangling that mess could be a larger task than just converting by hand.

Convert C libaries into C++ libs

The answer to your question, you don't need to convert the C libraries to C++. Basically, you can link the C library(Linux:.a/.so) or (Win:*.dll) and use that function into your corresponding modules.

Access C Code from Within C++ Source

  • In C++ language provides a "linkage specification" with which you declare that a function or object follows the program linkage conventions for a supported language.

  • The default linkage for objects and functions is C++. All C++ compilers also support C linkage, for some compatible C compiler.

  • When you need to access a function compiled with C linkage (for example, a function compiled by the C compiler, or a function written in assembler), declare the function to have C linkage.

Declaring Linkage Specifications

Use one of the following notations to declare that an object or function has the linkage of language language_name:

Example:

extern "C" void howdy(int);
extern "language_name" declaration ;
extern "language_name" { declaration ; declaration ; ... }
  • The first notation indicates that the declaration (or definition) that immediately follows has the linkage of language_name.
  • The second notation indicates that everything between the curly braces has the linkage of language_name, unless declared otherwise. Notice that you do not use a semicolon after the closing curly brace in the second notation.

You can nest linkage specifications, but the braces do not create scopes. Consider the following example:

extern "C" {
void f(); // C linkage
extern "C++" {
void g(); // C++ linkage
extern "C" void h(); // C linkage
void g2(); // C++ linkage
}
extern "C++" void k(); // C++ linkage
void m(); // C linkage
}

All the functions above are in the same global scope, despite the nested linkage specifiers.

Including C Headers in C++ Code

If you want to use a C library with its own defining header that was intended for C compilers, you can include the header in extern "C" brackets:

    extern "C" {
#include "header.h"
}

SIDENOTE: You need to to add this guard in your c header files in order to use that in C++.

#ifndef __YOURLIB_H_
#define __YOURLIB_H_

#ifdef __cplusplus
extern "C" {
#endif

int sample_func(int n);

#ifdef __cplusplus
}
#endif

#endif

Tutorial to use C lib in C++.



Related Topics



Leave a reply



Submit