home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
c2cpp.zip
/
C2CPP.TXT
Wrap
Text File
|
1993-12-12
|
23KB
|
643 lines
C2C++(TM) Paper
Copyright(c) 1993. All rights reserved worldwide.
December 1993
_________________________________________________________________
1. Introduction
This paper describes an automated suite of tools named C2C++(TM)
which provides the conversion of C code into object oriented C++
code. I will attempt to make this paper short and punchy rather
than long- winded since time is money.
This paper is targeted to those who have an existing investment
in C and would like to embrace object orientation through the
latest ANSI draft C++ language. It is expected that you are
familiar with object oriented terminology since you would have
done some up-front investigation as to what you should do with
your existing investment in C code.
I believe it is widely accepted amongst the programming
fraternity that object orientation offers enormous productivity
gains in both large and small projects, for the creation and
maintenance of code and believe me, no matter what the critics
say, it does.
For those who would like to become more familiar with object
oriented terminology and methodology, and those who have yet to
accept object orientation, I recommend reading in the following
order some of the most thought provoking titles available on the
subject specifically for C programmers:
"C++ Inside and Out "
by Bruce Eckel.
(This is for those who want to get up to speed quickly)
"Effective C++"
by Scott Meyers,
(This is for those who want to find out why their code
does not work)
"The Annotated C++ Reference Manual" (also known as the
ARM)
by Bjarne Stroustrup and Margaret Ellis,
(This for those who think they know it all)
"Advanced C++"
by James Coplien
(This is for those who realize "we aren't worthy" see
the movie "Waynes World", then you'll understand)
_________________________________________________________________
2. Protecting Your Existing Investment in C code
With this new wave of technology, comes many questions and
challenges. One with the most economic and technical impact, is
what to do with your existing investment in C code, since this
will directly affect your bottom line?
It is simply not viable to throw out your existing C code which
has been debugged and proven reliable over its development life
cycle.
There are many "challenges" (this is the word people use when it
is extremely difficult) which prove painful and time consuming in
interfacing C code to C++ code if you really want to take
advantage of the object oriented paradigm (which is obviously why
C++ was created).
Having experienced the "challenges" and pain on the conversion of
a number of commercial projects, the smallest of which has been
no less than 400, 000 lines of code, with more than 1000 modules
in more than 100 sub directories, I have developed a strong
foundation of a suite of programs called C2C++(TM).
I have decided to market C2C++(TM) which will provide your
organization with the same competitive advantage that many other
commercial publishers now have through the leveraging of their
existing investment in C code.
Simply put, if you want to convert your C code to C++ code, I
believe, having gone through the exercise a number of times, that
C2C++(TM) is the least painful and most economical way to do it.
_________________________________________________________________
3 C2C++(TM) conversion will:
1. Preservation and enhance your existing investment in C
code.
This has already been discussed above.
2. Automate the migration of your procedural C world to
the object oriented C++ world.
Manual migration is error prone and not economical.
3. Separate the interface description from the
implementation of classes
This is a classic benefit of object orientation which
is achieved through organization and structuring with
C++.
4. Simplify maintenance
For example: declarations are no longer scattered
throughout your code.
5. Make extensions easier
You can code entirely with C++ without having to worry
about burdensome interfaces between C code and C++
code, making further extension simpler and easier.
6. Provide a rapid development process of C++ classes to
establish a working base from code that you are already
familiar with.
There cannot be any quicker way for your organization
to exploit this new technology with minimized risk.
7. Enable your programmers through a faster learning curve
by observing their existing code, which they are
familiar with, transformed into well organized object
oriented C++ code.
There is minimal time lag between deciding upon
exploiting object orientation and experiencing its
benefits, without abandoning your existing code.
_________________________________________________________________
4. Technical consideration of the C2C++(TM) conversion:
1. C2C++(TM) considers your program from a global
perspective,not just one module or one directory of
modules in isolation.
This is achieved through a multi-pass program analyzer
that creates its own database to describe your code.
2. Converts existing C code (data and functions) into
object oriented C++ code and objects.
C2C++(TM) makes full use of classes, structures and
organizes your code through the process.
3. Automatic conversion of structs into classes.
Fast, painless and error-free.
4. Automatic detection of member functions and static
functions of classes.
Structures your functions by collecting them into
groups which manipulate the same type of data making
your code more understandable and therefore simpler to
maintain.
5. Automatically classifies functions into
private,protected or public given simple rules.
This will allow you to take advantage of the facilities
that class inheritance provides.
6. Automatically formats your class declarations and
header files into a standard layout.
This provides an orthodox canonical format (a better
structure from within which to work) and therefore
makes your code more readable for better maintenance
and bug finding.
7. Automatically produces nested classes.
This will reduce global name space crowding. ( You can
achieve this manually, but you might work up a sweat)
8. Automatically detects normal and static data members of
classes.
This is simply good C++ programming practice because it
collects related information together.
10. Automatically generates new translated header and
source code files.
This is why you are doing the conversion in the first
place.
_________________________________________________________________
5. A simple example of the C2C++(TM) conversion for the
uninitiated
Some of the features shown in this example includes:
1. Classification of a function into its class.
2. Simplification of a function name through renaming.
3. Removal of the first parameter of a class member
function.
4. Translation of references to the member object within
expressions within a member function.
5. Translation of member function call expressions.
Comments that I have inserted afterwards for better reading
regarding the conversion process are inserted into the example
code and are recognizable by their prefix of: // **
_________________________________________________________________
6. Original C source code:
BOOL IsControlVisible(Form* pForm, int idControl)
{
Control* pControl;
if (idControl < 0 || idControl > pForm->cControls) return FALSE;
pControl = pForm->pControls[idControl];
return ControlIsVisible(pControl);
}
_________________________________________________________________
7. Converted C++ source code:
// ** The function was classified to be a member of the Form class.
// ** Its first parameter was removed because it is now implied.
BOOL Form::IsControlVisible(int idControl)
{
Control* pControl;
// ** Member object reference pForm removed.
if (idControl < 0 || idControl > cControls) return FALSE;
// ** Member object reference pForm removed.
pControl = pControls[idControl];
// ** The expression was translated to put its first parameter in front
// ** of the function call brackets.
// ** The function call uses the new function name.
return pControl->IsVisible();
}
_________________________________________________________________
8. A more complex example of C2C++(TM) conversion
Some of the features shown in this example includes:
1. Classification of a function into its class.
2. Simplification of a function name through renaming.
3. Removal of the first parameter of a class member
function.
4. Translation of references to the member object within
expressions within a member function.
5. Translation of member function call expressions.
6. Creation of a nested class.
7. Classification of generic POBJECT pointers into
pointers to specific classes.
8. Usage of C++ templates to handle reference counted
class pointers.
9. One method of detection of static data members of a
class.
10. Classification of a function as being a static member
of a class.
11. Standardized layout of header files.
12. Automatic header file inclusion of reference classes
within a class declaration.
13. Creation of default assignment and copy constructors.
14. Automatic protection against including a header file
multiple times.
15. Consolidation of multiple related header files.
_________________________________________________________________
9. Original C header file 'Pane.h':
typedef struct {
HWND hwnd; // window handle (client if in
MDI frame)
} VIEWPANE, *PVIEWPANE;
_________________________________________________________________
10. Original C header file 'Control.h':
typedef struct {
// Window interface related information.
FLAG fHidden; // whether Control should be allowed to be visible
USHORT cViews; // number of views of this object
PVIEWPANE pViews; // definition of each view
// Relationships.
POBJECT pParent; // parent control (for nesting within dialogs)
POBJECT pForm; // Form containing the Control
USHORT cSub; // number of related subordinate Controls
PPOBJECT ppSub; // related Controls subordinate to this one
// Actions in response to standard events.
POBJECT apAction[EVENT_LAST];
} CONTROL, *PCONTROL;
typedef struct {
// status variables for controlling mouse dragging
USHORT usButton; // button 1 or 2 or none or both.
FLAG fAlt; // whether Alt pressed when drag started
FLAG fControl; // whether Control pressed when drag started
FLAG fShift; // whether Shift pressed when drag started
} CONTROL_STATIC;
_________________________________________________________________
11. Original C source code file 'Control.c':
// --------------------------------------------------------------------------
HWND ViewPaneQueryHWND(PVIEWPANE pViewPane)
{
return pViewPane->hwnd;
}
// --------------------------------------------------------------------------
// Finalise all updating of views of the Control.
FLAG ControlViewsUpdate(PCONTROL pControl)
{
USHORT i;
for (i=0; i<pControl->cViews; i++) {
WinUpdateWindow(ViewPaneQueryHWND(&pControl->pViews[i]));
}
return TRUE;
}
// --------------------------------------------------------------------------
PVOID ControlWait(FLAG fWait, PVOID hptrOld)
{
if (fWait) {
hptrOld = (PVOID) WinQueryPointer(HWND_DESKTOP);
WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE));
}
else {
WinSetPointer(HWND_DESKTOP, (HPOINTER) hptrOld);
}
return hptrOld;
}
_________________________________________________________________
12. Generated C++ header file 'Control.hpp':
// ** Automatic protection against including a header file multiple times
#ifndef _CONTROL_
#define _CONTROL_
// -------------------------------------------------------------------------
// INCLUDE FILE DEPENDENCIES:
// ** Automatically includes headers for common and reference classes.
#ifndef _Common_
#include "Common.hpp"
#endif
#ifndef _Handle_
#include "Handle.h"
#endif
#ifndef _Object_
#include "Object.hpp"
#endif
// -------------------------------------------------------------------------
// FORWARD DECLARATIONS OF ALL NON-NESTED CLASSES DEFINED WITHIN THIS MODULE:
// ** Predeclares all classes declared in this module to allow cross-references from one class to another
// ** Uses a typedef to simplify access to a template class used for managing Control pointers.
class Control;
typedef Control* PCONTROL;
typedef ObjectHandle < Control > HandleControl;
// =======================================================================
// ** You can define rules on the database which establish the parent class of a class
class EXPORT Control : public SharedObject {
// ** Automatically creates nested classes where appropriate
// ** and insert then into the enclosing class
// ----------------------------------------------------------------------
// NESTED CLASSES:
// --------------------------------------------------------------------
class EXPORT ViewPane : public Object {
// ** Automatically labels each section of the class declaration for better
// ** readability and maintainability.
// ----------------------------------------------------------------------
// DATA MEMBERS:
public:
HWND hwnd; // window handle (client if in MDI frame)
// ----------------------------------------------------------------------
// FUNCTION MEMBERS:
private:
// ** Automatically inserts these declarations so that your C++ compiler
// ** won't surprise you
// ** by quietly creating its own code for them.
// ** It also serves as a reminder for you top implement these functions
// Declared private and not defined in order to trap unwanted usage.
ViewPane(const ViewPane& rItem);
ViewPane operator= (const ViewPane& rItem);
public:
HWND QueryHWND();
};
typedef Control::ViewPane VIEWPANE;
typedef Control::ViewPane* PVIEWPANE;
// ** The banner and indentation tells us we are back to the main class' definition of Control.
// ----------------------------------------------------------------------
// DATA MEMBERS:
public:
// Window interface related information.
FLAG fHidden; // whether Control should be allowed to be visible
USHORT cViews; // number of views of this object
PVIEWPANE pViews; // definition of each view
// ** This section shows a special feature of C2C++(TM) which allows for improved
// ** conversion of quasi object oriented C code.
// ** In this case the old C code uses a generic "POBJECT" which is a pointer
// ** to a member of an unknown class, but
// ** C2C++(TM) was able to transform this pointer into a managed pointer
// ** (a handle) to the correct class of object, as determined
// ** by the application of rules defined to C2C++(TM).
// Relationships.
HandleControl pParent; // parent control (for nesting within dialogs)
HandleForm pForm; // Form containing the Control
USHORT cSub; // number of related subordinate Controls
HandleControl* ppSub; // related Controls subordinate to this one
// Actions in response to standard events.
HandleAction apAction[EVENT_LAST];
// ----------------------------------------------------------------------
// FUNCTION MEMBERS:
private:
// ** Automatically inserts these declarations so that your C++ compiler
// ** won't surprise you by quietly creating its own code for them.
// ** It also serves as a reminder for you top implement these functions
// Declared private and not defined in order to trap unwanted usage.
Control(const Control& rItem);
Control operator= (const Control& rItem);
public:
FLAG ViewsUpdate();
// ** Notice how the class declaration is ordered according to
// ** standard layout which allows for quick finding of declarations and
// ** easy detection of missing functions.
// ----------------------------------------------------------------------
// STATIC DATA MEMBERS:
private:
// ** These variables were known to be static because of the naming convention of the struct.
// status variables for controlling mouse dragging
static USHORT usButton; // button 1 or 2 or none or both.
static FLAG fAlt; // whether Alt pressed when drag started
static FLAG fControl; // whether Control pressed when drag started
static FLAG fShift; // whether Shift pressed when drag started
// ----------------------------------------------------------------------
// STATIC FUNCTION MEMBERS:
static PVOID Wait(FLAG fWait, PVOID hptrOld);
};
#endif
_________________________________________________________________
13. Converted C++ source code file 'Control.cpp':
// --------------------------------------------------------------------------
// ** The function was classified into the nested Control::ViewPane class.
// ** The first parameter was removed because it is now implied.
HWND Control::ViewPane::QueryHWND()
{
// ** The expression was simplified because this is a member function.
return hwnd;
}
// --------------------------------------------------------------------------
// Finalise all updating of views of the Control.
FLAG Control::ViewsUpdate()
{
USHORT i;
// ** Superfluous references to the member function object are removed
// ** from all expressions.
for (i=0; i<cViews; i++) {
// ** Note that more complicated expressions that involve multiple
// ** translations are also translated correctly.
WinUpdateWindow(pViews[i].QueryHWND());
}
return TRUE;
}
// --------------------------------------------------------------------------
// ** Static functions are detected and categorised into classes by rules.
// ** Notice how the function name was also simplified by removal of the
// ** prefix 'Control'.
PVOID Control::Wait(FLAG fWait, PVOID hptrOld)
{
if (fWait) {
hptrOld = (PVOID) WinQueryPointer(HWND_DESKTOP);
WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE));
}
else {
WinSetPointer(HWND_DESKTOP, (HPOINTER) hptrOld);
}
return hptrOld;
}
_________________________________________________________________
14. Summary
The effectiveness of C2C++(TM) has been proven on commercial
projects of over 400,000 lines of C code. Migrating a project of
this size, without automation, is a mammoth proposition, and was
only made feasible (time-wise and financially) through the use of
C2C++(TM).
This above project was estimated to cost between $80,000 and
$150,000 based on a conversion rate of 100 to 150 lines per hour
at a cost of $30 to $40 per hour, and still does not take into
consideration the learning curve or the cost of gaining
sufficient familiarity with the original source code to be able
to reliably and correctly convert the code to C++ ( In other
words it does not take debugging into consideration).
Even a small project of 20,000 lines of code would cost between
$4,000 and $8,000 to convert, again not taking into consideration
the learning curve or the cost of gaining sufficient familiarity
with the original source code to be able to reliably and
correctly convert the code to C++.
Furthermore the drawback of a manual conversion is that further
costs are involved for every new conversion project, whereas with
C2C++(TM) there is a single up-front investment. This makes
C2C++(TM) a serious economic consideration for all projects.
By ensuring an automated migration path from C to C++, C2C++(TM)
allows organizations to embark upon new object oriented projects
without throwing away their investment in C code. They can
achieve the same gains in application quality, development
productivity and maintenance productivity that are being
experienced by organizations already using C++.
_________________________________________________________________
15. Orders and Enquiries:
Post me a message on CompuServe including your FAX number and
CompuServe address. This will enable me to fax your order form or
liaise with you directly.
My CompuServe address is:
70732,3352
My international head office fax number is:
international-27-21-72-8005
Thankfully yours.
John Viveiros
_________________________________________________________________