algorithms.us - Blake McBride - Arahant.com
     
fader
   
Software Projects
: Dynace
: Extension to C

Dynace vs. C++

Please choose one of the following:

- Introduction
- Dynace Basics
- Code In Header Files
- Frequency Of Re-compiles
- Application Maintainability / Object Encapsulation
- Learning Curve / Code Complexity
- Code Re-usability
- Efficiency
- Compatibility With C
- Garbage Collection
- Class Library
- Conclusion

Dynace vs. C++ Introduction

The Dynace object oriented extension to the C language was created in order to solve many of the problems associated with C++ while retaining more backward compatibility with C than C++ and offering stronger object oriented facilities. This "white paper" discusses many of the shortcomings of C++ and how Dynace address them, as well as other important facts regarding Dynace.

[ Back to Top ]


Dynace Basics

Dynace stands for DYNAmic C language Extension and is pronounced like "dynasty" without the "t".

Dynace is a preprocessor, include files and a library which extends the C language with object oriented capabilities similar to CLOS and Smalltalk, including, multiple inheritance, true dynamic binding (using generic functions), metaobject based from the ground up, class library, automatic garbage collection and multiple threads. Because of the strong encapsulation features of Dynace, classes located in the middle of a class hierarchy may be modified without necessitating the recompilation of related classes. Dynace is written in C, is available in source form and applications are royalty free.

Dynace works on a wide variety of machines, comes with a 300 page manual and plenty of example programs.

[ Back to Top ]


Code In Header Files

C++ greatly encourages the movement of code and class definitions from source files (.c) to header files (.h). Because of its design, C++ requires this in order to support many of its compile time facilities. However, while enabling many compile time facilities, it is also the source of many of C++'s shortcomings. Dynace is able to offer similar compile time facilities (argument checking, ability to subclass a pre-existing class, etc.) while greatly encouraging movement of code from header files (.h) to source files (.c). In fact, all Dynace class definitions are entirely contained within source files. The consequences of these fundamental design differences will ripple throughout this paper.

C++ requires class definitions to be placed in header files and included by other source files for three main reasons. The first reason is so that when other files need to declare or create new instances of a given class, C++ needs to know the size of the instance at compile time.

The second reason is that C++ needs to know the entire structure of classes at compile time in order to create a new subclasses of them. The third reason is that C++ needs to know at compile time the names and locations of all externally accessible instance members (through public, protected and friend members).

Dynace is able to perform these facilities with an increased level of abstraction and code protection without any class definitions in header files.

[ Back to Top ]


Frequency Of Re-compiles

One very important consequence of placing class definitions in header files is that even very small changes in a class's definition necessitates the re-compilation of source files which implement the class, files which use the class and files which subclass that class. On large, real-life applications this can amount to several hours of time. And for applications in which a lot of development is being done, this may be required every thirty minutes. The net effect of this problem is that compile time quickly becomes the place where most of the development time is spent.

Dynace, on the other hand, places all class definition code in source (.c) files. With Dynace, you can have a massive application, take a class out of the middle of the class hierarchy and totally modify it, and so long as the pre-existing member functions (methods) retain their interface protocol (take the same arguments), only the one source file which implements that class would have to be re-compiled. Even if the member function's syntax changed, the only thing that would have to be modified and re-compiled were those modules who used the changed member function -- something which would have to be done in any environment. The net effect of Dynace's approach is that only the absolute minimum amount of time is waisted on compiles.

[ Back to Top ]


Application Maintainability / Object Encapsulation


One of the principal features of the object oriented paradigm is encapsulation. Encapsulation is the ability to combine code and data into a package such that the only external access provided is through a well defined interface. There are several important benefits associated with strong encapsulation.

At development time, strong encapsulation helps organize the design and breaks up the code into manageable size chunks. At debug time, strong encapsulation significantly limits the amount of code a programmer has to look at in order to locate the problem. After development, strong encapsulation makes code easier to understand by new programmers and limits the amount of code which must be checked and modified when a given module is changed. Strong encapsulation can have a major effect on the development, debug, and enhancement times associated with a project, not to mention reliability of the code.

C++ supports four types of encapsulation (protection) associated with members of a class: private, protected, public and friends. Of the four types, three of them (public, protected and friends) are ways to circumvent C++'s encapsulation features. And private members are only private from a narrow standpoint since it is declared in a publicly accessible header file.

Note that from a technical standpoint, there is never a reason for protected, public or friend members. Anything you could ever need to do can be done with private members and access functions. The net effect is that C++, for no apparent technical reason, does not encourage strong encapsulation, nor does it even have the facilities to support it.

Dynace, on the other hand, enforces strong encapsulation (private members) and places all member definitions in a source (.c) file. With this approach, all the benefits of strong encapsulation may be maximally achieved.

[ Back to Top ]


Learning Curve / Code Complexity

C++ is a large and complex language from a syntactical standpoint, especially when compared to the minimalist C language. There are two problems associated with this complexity. The first is that the learning curve associated with going from a proficient C programmer to a proficient C++ programmer is at least six months for most programmers. The second problem is that code written in C++ tends to be more complex and therefore harder for new programmers to understand and maintain. The bottom line is that C++ development tends to be much more expensive than C and employers end up being much more dependent on a few "experts".

Dynace, on the other hand, uses straight C syntax and only adds a few, easy to learn, constructs. The learning curve associated with Dynace is about one week (although you can actually use it the first day). Pre-existing C code can co-exist with Dynace code better than C++. And due to the simpler syntax and strong encapsulation features of Dynace, it is much easier for new programmers to pick up Dynace and the new application. This translates into real dollars saved.

[ Back to Top ]


Code Re-usability

C++ is a strongly typed language. This means that all type information associated with variables and function arguments must be completely specified at compile time. While attempting to create reusable code a programmer must create routines which are general purpose and can therefore be used in a variety of situations. The problem is that these two points are at odds with each other.

When creating general purpose (reusable) software components it is often desirable to have the routine handle a variety of data types, as is often needed in container classes. Strongly typed languages require that the potential data types be known at the compile time of the routine. This means that every time a new data type is used the "general purpose" routine would have to be modified and recompiled. How many books and articles have you seen which attempt to trick C++ into handling data in a generic fashion? This important feature of good software development (creating reusable software) is an up hill battle with C++.

Dynace, on the other hand, is a weakly typed language. This means that Dynace treats all objects (including classes) in a generic fashion. Creating generic (reusable) routines like container classes are trivial in Dynace. Dynace is also able to validate an object or its type at runtime.

[ Back to Top ]


Efficiency

Dynace is not an interpretive language. Dynace programs are compiled with a standard C compiler. The majority of the code is just standard compiled C code with no performance penalty. The only place Dynace incurs a runtime cost is at the point of method dispatch. Since C++ also incurs a runtime cost when using virtual functions, there is not much of a difference between the performance of Dynace programs when compared to C++. In addition, Dynace gives the ability to locally cache a method pointer in tight loops so as to totally dispense with the runtime overhead.

[ Back to Top ]


Compatibility With C

C++ is somewhat compatible with C, however, Dynace is entirely compatible with C. Code which uses Dynace classes is just plain C code. Code which defines new Dynace classes consists of standard C with a few added constructs to define classes and methods. This then goes through a Dynace preprocessor which emits straight C.

The two main points about this is that Dynace is more compatible with C than C++, and it's easier to incrementally add object oriented facilities to a pre-existing C application with Dynace.

[ Back to Top ]


Garbage Collection

While C++ will automatically dispose of some types of objects (automatic variables), it can not automatically dispose of those objects allocated from the heap. In a complex application most objects would be allocated from the heap, requiring explicit disposal in C++. Dynace's garbage collector handles all object reclamation automatically.

[ Back to Top ]


Class Library

C++ environments come with an absolute bare minimum of fundamental classes. Of course there are many C++ class libraries available, however, given the fundamental architecture of C++, these libraries are typically incompatible and difficult to understand, use and extend.

Dynace comes with a complete set of fundamental classes including classes to represent all the basic C types, a variety of container classes (sets, dictionaries, linked lists, associations, etc.), multi-dimensional dynamic arrays, threads, pipes and semaphores.

[ Back to Top ]


Conclusion

Dynace adds powerful object oriented capabilities in a simple, idealistic, theoretically pure way. Dynace has taken the best attributes of CLOS, Smalltalk and Objective--C and implemented it in a way which is natural to a C programmer. Dynace has no special syntax and is easy to learn. A Dynace program looks just like any other C program.

Dynace offers effective solutions to a variety of problems associated with software development, including reducing development time by segregating and organizing various application components, providing a powerful class library, making pre-written components maximally reusable, reducing language and application learning curves for new programmers, and making an application easy to debug, maintain and enhance.


[ Back to Top ]
 





.

.