C++ language despite of the powerful mechanisms supported is not a language for the faint hearted. Two forces drive its peculiar concept of friendliness (it is not unfriendly, just very selective) the backward compatibility with C and the effort to not getting in the way to performances. This book, written by the language father, presents and analyzes the language history and the design decisions. And, given the writer, the perspective you get reading the book is very interesting and more than once helps to shred some lights in the dark corners of the language.
The history is very interesting since it details how the language genesis and marketing went from the AT&T labs to the academy and industry.
C++ design principles are presented and the most notable is that of ease of teach-ability. Several time proposed/existing features had been modified or dropped entirely because they were not easy to teach.
Another very interesting principle is the “you don’t pay what you don’t use”, meaning that features added to the C language in order to define the C++ language were designed so that the programmer would not incur in any penalties if not using them. That’s why if a class has no virtual method, then the pointer to the virtual methods table is not included, saving the pointer space from the class instance memory footprint.
Aside from answering to many questions, the book opens up a bunch of new ones. For example, the very first implementation of C++ has been developed practically around a threading library. Now more than 30 years later, in a world with an increasing presence of multi-core machines, the C++ standard still lacks of a multithreading / multiprocessing facility.
Also Stroustrup asserts more than once that a Garbage Collection way of managing memory could be add by a specific implementation. But fails to explain how this non-deterministic way of terminating dynamic memory life could deal with the deterministic needs of destructors. Likely I’m just to dumb to figure out myself.
The big miss I found in the book had been a comparison with Java language. Basically one of the great contenders for the title of most widely used programming language. Java, on its side, has some interesting approach to language design that conflicts with those of C++ (e.g. the C compatibility issue). Therefore it would have been nice listen from Bjarne voice his thoughts about. In his defense it has to be noted that by the date of this book hit the streets, Java hype had just been started.
Last complain about the book is the lack of conclusions. The book seems cut a couple of chapters before the real end. Aside from stylistic point of view, some words about the future evolution and perspective would have been at their place at the end of the book.
Adventure in cross compiling land
If you have a C background you may find correct and appropriate that filenames are case sensitive. After all ‘a’ is different from ‘A’ as much as 65 is different from 97. If you have a BASIC background you may equally find correct and appropriate that filenames are case insensitive. It doesn’t matter how you write it, it is always the same character.
Every approach has its strengths and good arguments. The problem arise when one of the parties blindly ignores the rest of the world.
Well this may sounds like gibberish until you try to compile the linux kernel on windows. In this impressive set of source there are a bunch of files in the same directory that have the same name case-insensitive-wise. Moreover, if you untar the sources you get no warning sign since the tar command silently overwrites existing files. You get some hint of the problem when you copy sources with the windows GUI from a samba share to you local disk.
The problem is not so hard indeed, but if you don’t want to tamper source file structure it is better to rely on a case sensitive filesystem. That means that you cannot use Windows.
So I switched to Linux. After all FreeScale gives you the ready made cross compiler for Linux, so it is a clear sign of the way to go.
At workplace I installed the recently released Fedora Core 5. (Yes, I just completed a satisfactory configuration of the FC4 on my laptop 🙁 ). I must admit that Fedora Core, at last, has an original look. And a good look. Apparently they stopped following Redmond and Cupertino and started to set their own trend. Well done, I like it.
On the other hand having FC5 seamlessly working in a Windows environment is not something for the faint hearted. Be prepare to a good amount of swearing before you can resolve names, browse windows shares and access files there contained. Once done it works very well.
Back to Linux kernel compilation. Despite of what you may think by a look at my desk, I like cleanness and order, at least in files. So I want to store in the versioning system nothing that can be derived, just primary sources. With Kernel source this is a little fuzzy. In fact you download sources that are ‘distclean’ed. I.e. no kernel configuration is set. First you configure the kernel either by issuing one of ‘make menuconfig’, ‘make oldconfig’, ‘make xconfig’ or by picking up one of the precanned configuration by typing something like ‘make xyz_config’.
Anyone of these performs some operations – a file ‘.config’ is placed in the kernel source root, some symlinks and some files are created. So far so good. A file named ‘autoconf.h’ is required in order to build the kernel. This file is just the C version of the ‘.config’ file. In other words and simplifying a bit, in ‘.config’ you find something like ‘VALUE=y’ and in ‘autoconf.h’ you find ‘#define VALUE 1’.
Now I would expect that ‘autoconf.h’ is created from ‘.config’ somewhere in the Makefile. This is not true. The only way to create ‘autoconf.h’ (I found so far) is to interact with the system using one of the ‘make *config’. This is bad to me, since it prevents a fully automatic build.
On the other hand it is true that the configuration changes quite seldom, so you don’t have to ‘make distclean’ a lot and the ‘.config’ file you generate will be with you for long.
Maybe I didn’t search enough, but I have to do some actual work and produce some results beside googling for answers trying to bend universe to my personal view.
Cross compiling
Have you ever tried to build a cross compiler under cygwin? Today I tried to do exactly this. Well I quite underestimate the complexity. After all many Unix programs can be happily compiled without much effort under cygwin, why gcc should be different?A cross-compiler is somewhat convoluted, in fact you have first to build a bootstrapping version of the compiler in order to compile the standard C library. Before compiling the compiler you need the binary tools compiled for the intended target. The library needs some information from the operating system. Since my goal was to produce a cross compiler for embedded Linux running on ARM 9, I had to do something with the Linux kernel.
When you successfully compiled the compiler and the library, you have to compile the final compiler.
Luckily today there is internet and google ready to help you. I found many pages and advices, but I haven’t yet achieved my goal. Moreover it is not clear to me whether the cross compiler supports by default all instruction mode that an ARM920 makes available – native, thumb and jazelle. More on this in the next days.
90% of Research
According to a recent tv-ad 90% of research is funded by pharmaceutical corporations. Maybe this data is a little overestimated, nonetheless it is still astonishing. In other words the research for health and cure is privately founded. I wonder to which extent this is good. I mean the logic driving the research for health preservation and recovering is the logic of the Return of Investment, the dividend and share logic. The same logic that led one of the German pharmaceutical giant during the WWII to produce (and sell to the government) the infamous zyklon-B gas used to kill millions of people in concentration camps.
If you google around in internet for these terms you’ll find more than one reason to be concerned. Even if trusting the human nature, it is not possible to not doubt whether such research could find inexpensive treatments for any disease. What if something could be simply let pass, or just a spoonful of water and sugar is fine?
Leaving aside these gloomy thoughts, the link of the day is to Sibling Rivalry: C and C++ a pdf paper from B. Stroustrup detailing the source of incompatibilities between C99 and C++89 and the parallel evolution of these languages that aimed to be one.
Enjoy
The news of the day is that I implemented the comment preview. So before leaving a comment, you have a chance to reread it and make corrections if needed. I trust that this won’t reduce the number of comments just because you have more chances to change your mind in the process 🙂 Also, let me know if anything’s wrong with the new version.
The link of the day is The Development of the C Language. This is a document written by Dennis M. Ritchie about the birth and evolution of the C language. Dating back to the days of the PDP-7 and Multics. The document explains the genesis of the C language and many of its quirks. If you (like me before reading this) believe that the “++” operator was introduced because it mapped on a specific assembly instruction you should read it.
Ok, you have no time, so the answer is – the PDP-7 had no pre/post increment/decrement assembly instruction. Instead, it had just 8k of 18 bits word of memory. So keeping things small was an urgent need. And x++ saves a bunch of bits with respect to x=x+1.
C++ To Gui or Not To Gui?
One of the most missing feature of the C and C++ standards is, at least for us everyday programmers, the standardisation of the GUI. What a bless could be a single approach to the GUI programming. Tools companies may focus their efforts to provide wonderful tools, programmers could stop wasting time in #ifdeffing around, and so on. Anyway looking at Java language maybe that ISO/ANSI committee were not so wrong in taking such a conservative approach. At only some 10 years after the language debut, Java, although strictly controlled by Sun, has 4 different (and incompatible) GUI toolkits (JWT, AWT, Swing, SWT) plus the J2ME GUI interface.
News from C++0x
Hello there, I’m back from holidays. Refreshing (actually a bit more colder than refreshing 🙂 holidays.I found this article from Stroustrup providing a quick glimpse on the next C++ standard. I know you’re holding your breath for my review of Design and Evolution of C++ and since I don’t want to loose any one of you two, you can start reading this. I found here the same guiding spirit and ideas that lined through all the book.
My favorite quotes:
– In my opinion, C++ has become too “expert friendly”
– Finally, C++ is so large, is used in so many application areas, and there are so many useful C++ design techniques, that we are all “novices” much of the time.
– I hope that after looking a bit at this example, your reaction will be “How simple!” rather than “How clever! How advanced!”
C++98 took several years, mainly because of a wealth of new things not existing before. This huge effort resulted in a large language and equally overwhelming library, capable of coping with most of daily uses of most of the C++ programmers. Unfortunately the effort hadn’t been equally spent on making things simple. The learning curve of the most advanced features of the language (e.g. the algorithm library, or the metaprogramming) is rather steep.
It seems that one of the main objective of the C++0x (where x is expected to be ‘9’) is teachability and simplification, so there are good chances that we’ll see definitive advances in these directions.
Humble programmer, this time for real
Sometimes even the most skilled programmer like me lose their humbleness and blame the compiler. Luckily for him (or her) reality is ready the put them back at their places. This is what happened to me today. It was afternoon and after some thick coding with containers and containers of containers I was rather tired, maybe in need of a break. I don’t believe in break so I went on and wrote the destructor.
Pretty simple stuff a for loop iterating through all the container elements and basically deleting them one by one.
So far so good, then I wrote the test case (I do believe in test cases) and I got a rather surprising behavior on the destruction of an empty container. My code was supposed to skip the destruction loop and get out of the destructor cleanly, instead what actually happened was that the loop code was executed once causing exception and exception dialog popping all around.
Puzzled I stared at the code without a clue. It was a for loop as thousands other I wrote.
So I composed a small source to test just that behavior (I do believe in small source test, too, they usually help you a lot understanding stuff). And I got it perfectly right. The code was doing what I expected. So I cut and pasted some types from the project into my test. Maybe after all it had something to do with the complex types I used.
But once more the small test code run perfectly.
I was quite astonished and tempted to blame the compiler. So I went for the assembly window just to have the confirmation that the code was actually different and that the project code compiled to execute the loop once.
My personal C++ GURU was away so I had to handle it all by myself. At this point I tried to do some more cut & paste to understand were the problem arise and… I got it… There was, right after the closing bracket of the for statement and before the opening curly bracket… there a SEMICOLON!
Feeling dumb would have been an giant leap upward respect to that I felt. I knew that very seldom the compiler is to blame, so despite of appearance I was the culprit. Also I should believe some more in breaks, just a few minutes to get from ‘fused’ back to ‘bright’. And … yes C++ (or C, in this case it is a common pitfall) is a loaded gun ready to shot into your feet by default… but, what the heck! A little warning from the compiler would have saved me quite a time.
In fact my personal programming style is to always use the curly brackets even when the block is empty. I found this to be more readable and less error prone. It would be nice to instruct the compiler to emit a warning when this rule is broken. If the programmer is so smart to do everything in the for parenthesis and doesn’t need to specify a loop body, then she could spend part of the saved time writing a pair of curly brackets.
Don’t fear, it’s only C++
One thing I’m sure about C++ is that it had a troubled history. It sprang to life in mid 80s as a C with classes, a language aimed to bring the then new object oriented paradigm to C programmers. The standardization was far ahead, but the language when arrived to the first programmers outside AT&T was quite stable: single and multiple inheritance, late binding, function and operator overload.
But quite stable isn’t as stable as stable, so the first addenda to the language arrived by the beginning of 90s: exceptions and templates.
The standardization arrived quite late (late 90s) in the history of C++ and rather than codifying the existing practice, as it had been the case for C, took the way of empowering the language. The committee added many features to the language, one for all the STL. The standardization of the C++ language had been an impressive result, if for anything else at least for being a result. With the heavy load of new features it would have been easy to get lost on the way killed by the committee overhead.
Today, by admission of the language creator himself, Bjarne Stroustrup, it is unlikely for a single programmer to have a perfect knowledge of the whole language (considered as both the core language and the library).
With this troubled history, compiler vendors had their hard time to keep up with improvement first and standard later. The standard presented for sure a hard challenge. Being compliant could be a too ambitious goal when you have actually to develop a product and put it on the shelves.
Incompatibilities, non-compliancies, misbehavior were only part of the problem that programmers had to deal with, the part was the increased level of complexity: whole new concepts in the template field, tons of components and functions in the library. Also from the development battlefields new concern arose. Exceptions which had considered an elegant way to deal with errors and anomalies turned out to be if not a false friend, at least a very difficult one. If not carefully planned and the code actually being written with exceptions in mind, the exception mechanism would yield no benefits and the problems caused by misuse are more or less the same you would have without using exceptions and ignoring anomalies.
Another pretty impressive result from the battlefield was the meta-programming. Templates were intended to describe a set of classes or functions that performed the same algorithm on different types. In order to do this some business have to be done at compile time. It was discovered, from a programmer, that this kind of business could be used to perform non-trivial computation at compile time. If generating a set of prime numbers at compile time could be not much interesting, the matter changes when the result of the generation is a parser or an optimal evaluation of complex expressions.
With this sort of history it is pretty natural that many programmers are scared by the new features of C++ (if not by the whole language itself). As any kind of fear, this too deserves to be analyzed and addressed. There no point in avoiding everything that hide some side effect, because this is the main mechanism behind abstraction – ignoring details of the lower levels. Instead the programmer should develop an approach that let her avoid pitfalls and undesired effects of the use and abuse of the language.
Also, nowadays most of the compilers are reasonably compliant with the standard. Even Microsoft Visual C++ is now a pretty good compiler by standard… standards. Therefore even from this point of view, programmers could stop worrying and start using the language to its full potential. And C++ has a huge potential being nearly the only language that allows the programmer to properly choose the right amount of abstraction to employ.
For sure C++ isn’t for the faint hearted, stealing someone words, C++ is like a gun loaded, ready to shot and aimed straight to your feet by default. I’m sure it’s what you want when there are grizzly around.
C++ Standard Library
(picture refers to the cover of a later version of the book) My approach to C++ was of unbound enthusiasm, until I started using it intensively. Then I got a more fair perspective on the language. Although it is still my language of choice (and it will likely be for a while) it is far from the elegance and simplicity that were the hallmark of the C language.After learning the ins and outs of the standardized C++, you’ll discover that the modern C++ language is a complex, heterogeneous, large pile of different bits and stuff patched together. The standardization process did no good to this and when you go in details of the standard C++ library all the mismatching comes to light.
Covering the whole standard C++ library is a daunting task, but this book does an excellent job. The aim of the book is to provide both a reference and a tutorial. Despite of these two, somewhat opposite, goals the result is very good. When you read it as a tutorial you can skim over the reference parts, glancing through tables and summaries since you just read the real stuff. When you use it as a tutorial you’ll find plenty of cross-reference both to descriptions and examples.
The only lacking in the book, by admission of the author himself, is about the io/stream section of the library which is not discussed in fine details. Anyway I found it very complete covering all the common and a good deal of the not-so-common usage of the everyday usage.
If you are going the C++ way and you’re already a programmer I strongly recommend this book along with “The C++ Language” by Stroustrup.