home *** CD-ROM | disk | FTP | other *** search
- 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
-
- _________________________________________________________________
-
-