6502's cornerC or C++ ?
2002-12-28
Index

Welcome!
Who am I
Demo
Documents
Small ones
Problems
Chess
Images
Music
My blog
Write me

Versione italiana 


C or C++ ?

A few years ago I decided to learn this new object oriente language (I was coming from Borland Pascal with objects and I was quite excited about this new way of thinking to programming).

Unfortunately my first experience was quite disappointing for a lot of reasons and so I thought that it wasn't worth to spend my time in something that I considered a bad tool.

Lately I've however decided to reconsider C++, trying to anaylize the language in the current condition. Nowdays the situation should be much more stamble and standardized.

Following the advice of a friend of mines that is way more expert than me in C++ I invested some money in the following titles:
  
The C++ programming language (third edition)

This is for sure the reference text for who wants to learn the C++ language in all its syntactic quirks and all its philosophical aspects. The author Bjarne Stroustrup is the creator of the language and this book surely can't be missing from the library of a C++ programmer.

The book is in my opinion quite well structured and written even if the father love of the author for the language makes him to lose objectivity when talking about evident problems or just ugly parts.

A point in which the book is as funny as a sitcom is when the absurd syntax of the typecast operators is explained as being a good point of C++ because: 1) this way typecasts are easy to find in your project; 2) typecasts are ugly from C++ philosophy and should be used only when really needed and so it's a good thing for them being ugly to write.

I've really to say about this that it rarely (if ever) happended to me to look for all typecasts in my 50K+ lines project and that following his reasoning probably Stroustrup thinks that a compiler that requires hex codes for inline assembly is better than one that allows the use of a good inline assembler.

This book is the only one i found in which templates with all their power and complexity where exlained in great detail. Templates are for sure one of the biggest new introduced with C++ and seems that Stroustrup is one of the most serious supporters of this kind of programing.

  
Effective C++ CD

This electronic book is the fusion of two best-sellers and a few very interesting articles on C++. Even the book used interface (based on HTML/Java) is quite well polished.

The book is substantially a collection of specific design and implementation problems analyzed in great detail and solved in C++. The book is entirely devoted to C++ and often it offers really clear and clever explanations about how this language can solve everyday problems that a programmer faces.

In the two books and in the articles collection there are also a few philosophical points about class hierarchies design analyzed in depth. This is surely not a book on object oriented design but some of the insight are quite useful to understand how C++ classes where meant to be used.

I only found a few disappointing parts, like the same discussion about how it's a good thing that typecast is ugly and some useless explanation about how to count all the instaces of objects of a specific class. Also a few complex problems like the initialization order problem for static instances were analyzed only partially.

  
C++ FAQs

This book has been written in the form of Frequently Asked Questions and this surely helped the authors. I must say however that this form of book made it alsto nice to read after all; it's a bit like taking a huge C++ thing in small self-contained pills easy to swallow.

This text is quite different from the other two becuse a lot of the discussions presented can be transported without any change to environments different from C++. A few advices are even appliable to non object oriented environments and are just related to the management of big projects. Quite interesting are also a few points about how software projects and human resources are seen in big companies (I can surely confirm that a big company thinks that programmers must be replaceable pawns in a working structure while the average time of a programmer in a position is longer than the average time of a coordinator; and so it should be more meaningful to try to be sure that coordinators remain replaceable).

The book contains no explanation of C++, but offers instead a vision about a specific way of using C++ in big projects. There's a fundamental distinction between what is "legal" in C++ and what is "moral" even if the morality boundaries are fuzzier and subjective. I must say however that most of the moral laws expressed in the book were already part of my C programmer background.

I found this book really really interesting. I got only a delusion in the CORBA/DCOM discussion that I found extremely superficial and quite not objective. I've ever caught myself thinking that it was a last-minute addition to make the book cover more interesting.

My opinion on C++

Since when i found object-oriented programming with Borland Pascal I've been intrgued by this kind of vision. Even when working in C i've always used an approach based on the subdivision of the problem in "thinking objects" implemented as structures. Simple inheritance was implemented placing a parent structure as the first member of the descendant so that every function writte to accept a pointer to the parent was also able to accept a pointer to the descendant. When polymorphism was needed i was normally setting function pointers in the instance passing the "this" pointer explicitly (without using VMT indirection).

My use of C++ wasn't much different from my use of C with the only big difference of using inheritance and polymorphism from the C++ compiler instead of my hand-crafted ones. To be more precise i kept the bad habit of having everything public with some (even a lot) of actions from the outside of a class directly on the data members of the class.

The "moral" use of C++ is completey different however and i'll try from my next big hi-level project to approach the problem in a cleaner and more moral way.

C++ is surely something DIFFERENT from C. It's not an extension or an addon: what it changes its the base philosophy. A C++ compiler does much more things than a C compiler (ever noted the much longer compile time ?) and this allows writing much more compact source code.

There are a few things that i really don't like about C++; i can cite in particular:
  
Syntax

C++ syntax is surely coincise enough but seems to me (at a first impression) really really "dirty". There's not simple set of rules to descibe the language but there are instead a lot of special cases that honestly would scare me if i would be called to being part in a C++ compiler development project.

In comparision, C syntax is surely simpler and nicer and I've to confess that even like a lot the choice made in C of demanding most of the rest to standard LIBRARIES instead of to the language (on embedded systems you often use C without any runtime library support).

This distinction between the language and the environment isn't so clear in C++. In other words C++ is more monolithic than C. After all this is consequential from the fact that C++ isn't C and that it's a language (environment) layered at an higher level.

  
Templates

I've to say that i found parametric programming quite interesting and i think that the template approach is much better than the limits of C preprocessor macros.

When i tried however to use templates for something just not completely trivial i've hit a few quite disturbing problems that can make template development really annoying. First of all are in my opinion the almost meaningless error messages that you get from a compiler when there's a syntax error. Of the complexity of template programming is surely aware even Stroustrup if in his book there's a strong advice in getting things working and bug free on concrete code before trying to use a template approach.

I just hope that compiler problems about templates are going to get solved in the future. My position is still quite contrary about big use of this tool that's surely powerful but difficult to dominate under several aspects.

To who would like to have some really good laugh I suggest to take a look at the standard template definitions and think what would be being in charge of maintenance of code like that after a few years working on something else.

  
STL and the standard library

C++ standard library is much bigger than the one available in C and in particular one can see the introduction of containers and algorithms that are now part of the ANSI standard.

Talking about containers i've to admit that you get a toolbox of basic tools that let you write small programs that would have required quite a lot of C coding. However I've also to say that there are a few really strange facts like the absence of an hash-map container and of a standard template for smart pointers with reference counting.

I'm much more confused about algorithms. The only text in which algorithms are explained to some detail is "The C++ programming language" and this makes me to think that algorithms are not being used often. Even if considering that the right direction (i'm not sure this is my position) i think that results is a bit too complex and unreadable. May be however that it's just that one needs time to get used to that look (even PERL syntax looks terrible but it's not so bad once you get over the first impression).

I/O handling of C++ is probably the thing of the language that I like less. Extensibility of I/O to classes could have been achieved even without making I/O primitives operators (a terrible decision in my opinion). I also think that formatting thru modifier is quit annoying and even "dirty" in an object-oriented approach. For I/O i would have surely preferred some "standard" member function receiving the output stream and the formatting as parameters. I've got the clear impression that most of this ugly interface is due to the decision to keep a consistent interface between classes and native types that are not classes (seems to me that trying to hide this distinction is behind a lot of C++ syntax troubles in general, and i'm not sure that trying to hide the distinction is The Right Thing to do).

  
Exceptions

Exception handling is sure one of the biggest differences between C and C++. I'm quite confused about this issue too, the reason being that in my opinion C++ is not enough "high-level" for using that approach.

I'll try to show my point.

I've personally written in the past an interpreter that uses an error handling very similar to C++ exceptions. The syntax of the language is similar to Pascal but adds the optional part "on error do <statement>" to begin/end blocks. When there is an error (either generated by the system or by an "error" statement from user code) the interpreter unwinds the stack until it founds a begin/end block with error handling.

Surely C++ exceptions are more sphisticated but the biggest difference in my opinion is that my interpreted language is typeless and entirely based on reference-counted pointers so the stack unwinding operation couldn't lead to any resource leak. Even files are for example handled in objects that when destroyed calls the operating system to properly release the allocated resources.

Moreover the language is purely procedural and, even if there may be a possible problem with global variables left in an unconsistent state, the stack unwinding operation can't do any serious damage. The language has been written for a context-free transaction server and so a few global variables are used just in the general part of the server and not in the implementation of the transactions (where most the code is).

In C++ we're in a completely different environment. In particular there are problems with either raw pointers (that are strongly discuraged exactly for this reason) and with object state. If a systematic use of auto_ptr or reference-counted pointers (that unfortunately aren't part of the standard library) can save you from the troubles deriving from resource leaks you've no support for the other problem of logical consistence of an object that has been left in the middle of a method because of stack unwinding caused by an exception.

In other words the presence of exceptions means that in any moment the normal flow of execution can be interrupted to "escape" out of the method. When this happens you must be sure of not losing resource (easy enough) and to not leave things messy (really difficult, especially if you consider that an exception may be raised in the middle of an expression in which the compiler can often play around with the order of evaluation).

As is well described in an article of "Effective C++ CD" the the problem is neither in who generates the exception (throw) nor in who handles it (catch) but in all the classes that the exception traverses almost asynchronously. Surely trivial cases are really elegant and compact; but i've the impression that this exception logic can't scale up to complex object oriented projects (unless you end up having a lot of 'catch' and '(re)throw' that are what the exception were thought to remove from programs written using the return-code C approach).

It would have been completely different if the compiler could give the user a "transaction" support similar to the ones present in relational databases; transactions that ensure that of a block of statements (for example a method implementation) either all get done correctly or nothing happens because the system is able to "rollback" all the changes made before the problem appeared. The interpreter i wrote was using exactly this approach wrapping the entire server transaction in a begin/end block with a database "rollback" in the on-error section.

Note:

After some thought I found C++ templates powerful enough to give you transactions on object modifications with just a few lines of code (with some restrictions). This of course costs in performance and has some other drawback.

Despite these limitations I decided to use exceptions with these transactions in a project I'll be developing in the next few months. One of the things I'm going to implement with this tecnique is a server for context-free businness transactions on a memory database held in a net data structure of C++ classes.

More details on this will be added soon.

Conclusions

I'm quite confused about this language; i think that the marriage between the clean and simple C with "++" isn't a perfect choice. The problem is that C strongest point was the complete control of the programmer about the code generated by the compiler (one can even imagine which assembler instruction are going to be generated by the compiler for a C code fragment). In C++ this control is really much weaker.

I've also got the impression that C++ supporters often see this language as a method to program without understanding what's happening behind the surface. I'm personally against this point of view and i think that object-oriented approach is a way to organize knowledge and not a way to avoid it. Using something without knowing (at least roughly) how it's implemented is asking for troubles. Soon or later one will make a big mistake in the usage, employing things one never understood well in a terrible way.

Still remaining a strong C supporter i've to admit that C++ gives some big help in object orientation. Also the strong-typed philosophy allows the use of object-orientation even when efficency is really important. I've to say that i'm for more "dynamic" views but the execution speed of a statically-typed language makes C++ a really valuable tool.

Even syntax asymmetries haven't been put there just to make things complex; they're all thought to ease the use of the language. Sure these make the language "dirty" and makes living difficult for compiler developers (few) but they make life easier for application programmers (many).

I find inexcusable the missing from the standard template of smart pointers: still understanding that the whole C++ model is based on the copy semantic, a standard smart pointer implementation would have been useful in all the cases where copy semantic fails (for example etherogeneus containers).

Now to get a better understanding i just need to work in "real" C++ on a project sized at least 100Klines (much better if part of a team of several programmers... at least this is the advice found in "C++ FAQs").

Someone said ...

- From the TAO OF PROGRAMMING -

In the beginning there was the machine language only.
  Then came assemblers.
    And then compilers.

And since then the languages grew every day
  populating our small world of logic.

Every language has his soul and his strenght.
  Every language has equal dignity in the Tao.

But if you can avoid it
  don't mess with COBOL.