Tag: programming

Friends and namespaces

There are C++ behaviors that may leave you a bit astonished, staring at the lines on the monitor and wondering why the code isn’t compiling, or doesn’t work as expected. Just stumbled in one of these cases.
I usually follow these steps to recover from the puzzled face. First I write a minimal example that reproduces the behavior. It should be a bunch of lines in a single file. Sometimes this could be a daunting task, but I have that it is always worth to grasp the problem.
In fact, once you have the minimal code, you can easily experiment, changing and twiddling bits to see how the behavior changes.
Then you have two options – you can ask your local C++ guru about the problem (if you have one), or you can google the Internet for a clever selection of keywords that describes your problem.
So what happened today?
I decide to move some code I developed into a namespace-constrained library. Everything compiled happily outside the namespace, but failed to do so in the namespace. After some headscraping, I started cutting and shaping a minimum file with the same odd behavior. Here you are:

/** prova.cc
 *
 * @author Massimiliano Pagani
 * @version 1.0
 * @date 24/04/2007
 *
 * @notes
 * @history
 *
*/

#if defined( USE_NAMESPACE )
namespace NS
{
#endif

    class A
    {
        public:
        private:
            struct B { int x; };
            friend bool fn( B const& b );
    };

#if defined( USE_NAMESPACE )
}

using namespace NS;

#endif

namespace NS
{

    bool fn( A::B const& b )
    {
        return b.x != 0;
    }
}

Now, if you compile it defining the symbol USE_NAMESPACE (e.g. via g++ -Wall -DUSE_NAMESPACE -c prova.cc), then you get the odd looking error:

prova.cc: In function 'bool fn(const NS::A::B&)':
prova.cc:21: error: 'struct NS::A::B' is private
prova.cc:31: error: within this context

While if you compile without the namespace everything works as expected. Since the error was quite meaningless to me, I started investigating on friend and namespace. After some mailing list browsing, I figure it out. And it was simpler than what appeared – just a case for a misleading error.
In fact the friend statement declares a function fn somewhere in the NS namespace, while actually fn is defined in the global namespace. In fact there is just a using statement. To fix the problem, just move the fn function into the NS namespace.
Well and I have figure it out alone, without the need of calling my uber-C++-guru friend Alberto.
On a completely unrelated topic, today is the 25th anniversary of the marvelous ZX Spectrum. Happy Birthday Dear Speccy.

Programming in Lua

(cover to the left here, refers to 4th edition of the book, I read the 1st edition). It is somewhat difficult, in writing this review, to distinguish the language from the book. The book teaches about Lua, so my opinions in favor or against this language could interfere with my opinions about the book. Anyway I’ll try to accomplish this hard task.When writing a book about a programming language you could follow either an hands-on approach or a more formal one. Both ways have their pros and cons. The first approach helps language novices to grasp quickly language fundamentals, while latter provide a convenient reference for those already using the language.
For example Bjarne Stroustrup’s “The C++ Language” belongs to the second set. It is very formal and descriptive; learning the language by this book it is definitely the hard way to do that (aside from the fact that C++ is a very complex and huge language). “Programming in Lua” is from the first camp. It features an easy to follow, example-ridden way into the language. It doesn’t pretend to give a thorough reference for the language or the library, demanding other books for this specific purpose.
I have to say that the writer does quite a good job. The text reads smoothly, examples are always fit to the chapter scope, prose is clean and clear. In theory I should have practiced with the language itself in order to state whether the book covers the matter adequately or not, but I have a limited amount of free time and no suitable project for a Lua application, not even a toy one.

Anyway while I didn’t fell in love with the language (quite the opposite as you may have read) I appreciated the book. Also I found an interesting reading the last chapters on how interfacing and extending lua with C code.
What I didn’t like is the author bias toward the language; I feel a vein of naivety. For example Lua supports only floating point values. Not the “float” kind, but the “double” variety. No integers, just doubles. The author advocates that there is no reason for integers since “double” works fine for just everything. Although I have not much experience with doubles (just floats), this appears quite a bold statement, at least from what I have skimmed through. The dumbest consideration I could think of is that doubles still have the usual precision problems that affect floating point arithmetic. It just depends on how many iterations you have to do.
On a whole I found this book a worth reading either if you want to learn a new programming language or you are just curious (like me). Just be sure to buy the 2nd edition that came out just few days after I ordered the book (I ordered the book few days after having read the, now disappeared, slashdot review… maybe you see a connection)… or to read the first one online for free.

Antipatterns at work

It is an odd sensation. I am puzzled about some decisions that are quite unanimously recognized in literature as bad, or, if you prefer the buzzword, as anti-patterns. Forests have been sacrificed for books on the matter. Given the current (poor) state of the planet I would urge management to read them, not just having them to preserving their libraries from dust.
You have this project late, the customer is coming screaming at you because you didn’t made it for the milestone, the product is still alpha quality when it ought be on the shelves. Sounds familiar? If not either you don’t work in any technologically advanced sector or you have been unbelievably lucky (or good… or both). So it is clear that the project needs extra time to achieve the goal set. I understand that there are contracts and politics involved, but for the sake of the project there is just to plan and move the milestone ahead WITHOUT adding new features. Leave them for another project. The customer could be disappointed from this refusal but she will be a lot more disappointed when you’ll told her that you didn’t made it another time.
Disclaimer: I have to be honest, this is not my project, I don’t know exactly what has been agreed on, the only thing I know is what a coworker told me in about a single line: milestone postponed, new features added. So basically I don’t know what I’m speaking of.

The Good, the Bad and the Ugly

Engineers are supposed to deal with systems, usually large and complex devices that are expected to work. They are expected to work at least, but the common expectation is that they keep working reliably under a wide set of circumstances and mostly regardless of the environment. Consider any system that results from an engineering process (say a TV set or a car) from this point of view – it is not enough that the device works fine only at the seller’s location. This should put under the right light one of the most used programmer defenses: “It works on my PC”.

For us, as programmers and programming team leaders, the point of concern is how to deliver such robust products that could reliably work even in non-clean room conditions. A lot of entropy has been sacrificed to this goal and I don’t want to start anything new or propose any existing process methodology, I’d just like to recall what a friend of mine reported from one of his senior coworkers (thanks Xté).

This is a quick analysis that allows you to understand how much in good shape your project (or task) is.
Consider two nearly binary variables – working and understanding. You can get four combinations that identify four states of the system composed of the object the engineer is working on and the engineer itself. Here we go to analyze the four states (I swear, I’ll be brief).

It doesn’t work and you don’t know why. This is the typical state of the project start, you have this black box not working as expected and you are supposed to fix or implement it. This is not so bad if you have enough time to study, ask other people, analyze, and get your knowledge on what you need to do to fix it. Summing it up, this can be fair or bad according to the time you have.

It doesn’t work and you know why. This is quite good. After all, knowledge is power. With the knowledge you can both devise strategies and solutions and figure out the time or the means you need. Moreover, you have plenty of facts to explain the situation to the management and ask for the most suitable resources you need to accomplish the task.

It works and you know why. Perfect, you achieved your goal. You fully understand your system, and why is it working so that you can predict to a good extent when and how it is going to work.

It works, but you don’t know why. This is the worst case of all. Unfortunately, the rush and the wrong assumption that if it works then who cares, can lead to this terrible situation. The real problem here is that you cannot make any assumption for when the system will cease to work, you have no clue how to deal with it both to repair, move, or change. You have no warrant that the system will continue to work.
The fact that it works usually leads the project management to consider it complete and to make pressure to move on. A false sense of security may affect the team cleaning the way for greater disasters.

There are some quick corollaries to this analysis. First, always try to understand what are you doing even if it may seem like a waste of time. Second, always include a learning time in your estimations. Third, poking randomly around to fix things is a dangerous way to further damage a system while creating the illusion of work.

Programmers strongly rely on tools, basically, there is direct contact with the matter we design and develop, our tools are our manipulators and probes into the hidden work of electrons. We have to know our tools by heart. We cannot go away with a rough understanding of the language we use because we cannot afford our ignorance would let something in.

The natural question that could arise is: “What is the extent required for the knowledge?”. Does programming require me to understand OS internals? Digital electronics? Semiconductor physics?

Well, it depends. Gone are the times when a single man could brace the whole human knowledge and art in his lifespan. Nowadays we have to stop at a given interface, taking for granted that what is going on behind us is good enough. I think that you have at least a good knowledge of the first interface you are using, be it OS system calls, environment libraries, or hardware if you are working closer to the metal. Anyway, an average knowledge up to the next barrier could only be good when you are hunting for problems since it could help you to better exploit the environment and to get helpful hints to get you out of trouble… troubles where engineers spend most of their time.

The Design and Evolution of C++

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.

Secrets and Lies

Some days ago I helped a coworker with an oddly behaving Makefile. I am a long-time user of this tool and am no longer surprised at ‘make’ doing the unexpected in many subtle ways. This time the problem was that a bunch of source files in a recursively invoked Makefile were compiled with the host C compiler rather than the cross-compiler as configured. Make, in an attempt to ease the poor programmer’s life, pre-defines a set of dependencies with a corresponding set of re-make rules. One of these implicit rules states how to build an object file (.o) from a C source file (.c). The rule is somewhat like this:

.o: %.c
    $(CC) -c $(CPPFLAGS) $(CFLAGS)

And by default, the CC variable is set to ‘cc’, i.e. the default C compiler on Unix systems. Bear in mind that this is a recursively invoked make, therefore it is expected to be hidden at least one level away from the programmer. In the other hand the build has configured the top-level make to use the cross-compiler arm-linux-gcc. The problem could also happen because ‘make’ has a local scope for variables, i.e. variables are not exported by default to the recursively invoked makefiles.

The hard part in spotting the problem is that everything works as expected, i.e. the build operation completes without a glitch a you are left wondering why your shared libraries are not loaded on the target system.

Once you know, the problem is easily fixed, but if you are an occasional Makefile user you may experience some bad hours seeking what the heck is going on.

Hiding isn’t always bad – you need to hide details for abstraction and consider complex objects as black boxes to simplify their handling. One of the three pillars of OOP is “encapsulation”, which basically translates as data opaqueness, the object user is not allowed to peek inside the used object.
The question arises – how much “hiding” is good and how much is wrong?

The C compiler is hiding away from the programmer the nits and bits of assembly programming so that he/she can think of the problem with a higher level set of primitives (variables instead of registers, struct instead of memory, and so on).

If you want to go up with the abstraction level you must accept two things:

  • you are losing control of details;
  • something will happen under the hood, beyond your (immediate) knowledge;

Going up another level we meet the C++ language, with a greater deal of things working below the horizon. For example, constructors implicitly call parent class constructors; destructors for objects instantiated as automatic variables (i.e. on the stack) are invoked when the execution leaves the scope where the objects had been instantiated.

If you are a bit fluent in C++ these implicit rules are likely not to surprise or to harm you. If you consider a traditional programming language such as C, Pascal, or even Basic (!), you will notice quite a difference. In traditional language, you cannot define code that is executed without an explicit invocation. C++ (and Java for that matter) is more powerful and expressive by hiding the explicit invocation.

In many scripting languages (such as Python, Lua, Unix shell, PHP… I think the list could go on for very long) you don’t have to declare variables. Moreover, if you use a variable that has not yet been assigned you get it initialized by default. Usually an empty string, a null value, or zero, depends on the language. This could be considered handy so that the programmer could save a bunch of keystrokes and concentrate on the algorithm core. I prefer to consider it harmful because it can hide one or more potential errors. Take the following pseudo-code as an example

# the array a[] is filled somewhere with numbers.
while( a[index] != 0 )
{
    total += a[index];
    index++;
}
print total;

If uninitialized variable values can be converted to number 0, then the script will correctly print the sum of the array content. But, what if some days later I add some code that uses a ‘total’ variable before that loop?

I will get a hard-to-spot error. Hard because the effect I see can be very far from the cause.
Another possible error is from mistyping. If the last line would be written as:

print tota1;

(where the last character of “tota1” is a one instead of a lowercase L)

I would get no parsing and no execution error, but the total would be always computed as zero (or with some variations in the code, could be the last non-zero element of the a[] array). That’s evil.

I think that one of the worst implicit variable definitions is the one made in Rexx. By default, Rexx variables are initialized by their name in upper case. At least 0 or nil is a pretty recognizable default value.

Time to draw some conclusions. You can recognize a pattern – evil hiding aims to help the programmer to save coding time but doesn’t scale, good hiding removes details that prevent the program from scaling up.

As you may have noticed lately, the world is not black or white, many are the shades and compromises are like the Force – they could yield both a light side and a dark side. E.g. C++ exceptions offer the error handling abstraction, at the cost of preventive programming nearly everywhere to avoid resource leaks or worse.

Knowing your tools and taking a set of well-defined idioms (e.g. explicitly initialize a variable, or use constructor/destructor according to the OOP tenets) are your best friends.

Frustrated programmers on Linux

Life is hard. Especially in the working hours. The more hard the more you have to do your job on linux for linux. If you think about it, that’s odd. Back in the Days, Unix was the result of a young team that sought a programming (and hacking) environment. At times they had very programmers-unfriendly environment and Unix was very successful in this respect – text editors, interpreters, advanced shells, programming tools and the like flourished in the Unix filesystems.
Today is like those days… well it is still like that, in the sense that the rest of the world, most notably Microsoft, caught up and overtook the Unix command line.
First, suppose you want a project aware C/C++ editor. In the Windows world, maybe you have not much choice, but the answer is easy, the latest Visual Studio is quite good, allowing you to do nearly everything in a comfortable way. Linux is lagging behind, there is vim, emacs and Eclipse. Eclipse is indeed good (considered the price), but its C/C++ editing capabilities are far inferior to the basic Visual Studio. Maybe you can get it working in the same way, but this requires a great effort for those that are not fluent in this developing environment.
Suppose now that you want to interface your application with audio. If you use the basic operating system functionalities (likely OSS) you can do it rather quickly at the price of audio exclusivity. If your application is running no one else can access it.
This is known problem and has a known solution – using a sound daemon that perform mixing from multiple audio applications. This is reasonable.
What is unreasonable is that Linux sports a wide variety of such deamons, everyone has his own. What is yet more unreasonable is that both Redhat/Fedora and Ubuntu use the eSound daemon that has no documentation.
So you are forced to not have a standard choice and, what is worse, the choice you are forced to has no documentation whatsoever.
Frustrating, isn’t it?

Searching (other people’s) code

You know, the better you know how to use Google the better you do your work. Be it searching, discovering, copying or taking inspiration Google is today as close as possible to the sixties idea of the omniscient computer. Just ask, it knows the answer. As a programmer I’m used to googling quite often, but it’s just today that I discovered a Google tool aimed at easing the programmer life. Google code search is a specialization of the best search engine to search through all the code available on Internet. It is impressive by itself allowing you to use regular expression, specifying language or license! The advance search shows a more usable form and allows you to specify negation and case sensitivity.
As this is a great tool for programmers, it is a great tool for those looking for vulnerabilities and security issues (be they the Good or the Bad boys). Have a look here to get a glimpse over what you can recover via Google code search.

Mysterious Hardware

After all, I am only a programmer. I know something about electronics, but that’s nearly all theory. I did some soldering when I was young, but my resources were too constrained to allow me a real understanding of the matter through experience. So, today I’m doing my programming job on a prototype hardware containing an ARM chip and some other almost invisible components. Working with prototype computers ranges from funny to entangling complicated. The reason is that it is very hard to understand and find where the software bug ends and where the hardware bug begins.
The funny part is usually when you understand that’s not your fault before banging your head against the wall too hard.
This board has about an entry-level-PC audio capabilities, so a mic-in line and a speaker output. For testing purpose I hooked the audio input to a PC continuously playing audio via a voltage divider. The speaker out is always connected to a… well, a speaker.
Now when no software is running the speaker is mute no matter what is coming in through the mike.
You can imagine my surprise when hooking the PC serial cable to the board I heard the music through the speaker! Remove the serial and the speaker mutes back. *Gosh*! That’s surely not my fault!
Another pretty fault as easy as astonishing is that a clicking noise in the sampled audio happens only when the board is battery operated. The audio is noise-clean when the board is tied to the AC power supply.
Nonetheless I am admired that such an engineering jewel is working (mostly) as expected. Kudos to my colleagues!

The Moon is the Limit

The first time I heard about the Lua programming language was back in 2003. My coworkers were working (quite hard) at porting FarCry to PlayStation 2. The game code and engine rely heavily on the Lua language.I am a sort of split about using script language to define game and character behaviors in a game. The good part is that an interpreted language offers several benefits like no need to recompile the whole engine (or a dll) for even a small change, gentler learning curve so that even non-programmers could write a piece of the higher level code of the game. Even if they cannot write it, at least they could get a clue of what the code is doing. Moreover if the language is tailored for the domain (Domain Specific Language) then coding with that language could be easier than using a general purpose one.
On the other hand I had usually bad experiences – the language interpreter itself it is usually not enough to develop code, a debugger is needed as well and creating a good debugger is not an easy task. Moreover integrating the script language with the engine could be either boring or error prone (usually both). The domain specific language tends to evolve into a general purpose one as soon as its users discovers that they need exactly the effect of that instruction only slightly different.
As soon as the barrier from Domain Specific to General Purpose is crossed, the nice and cute language turns into a wild beast ready to bite your back at the first oversight.
The lack of constraints, typical of scripting language, enables a quick prototyping or a quick development of small programs, but leave you alone when facing with mid-sized application. Coherence and consistency should be achieved by using rules, conventions and strict discipline.
So… how does lua stacks in those respects?
After reading about half the book Lua I should say that stacks pretty bad. According to the book, Lua is intended for solving problems with a few hundreds lines of code. And many of the language design choices are biased toward this direction. The first that comes to mind is that variables have a global scope by default. Actually this is a bad design decision since the global namespace tends to be polluted rather quickly and generally global variables are considered a bad programming practice.
One of the most confusing part is that list and multiple values are quite freely mixed with varying semantic. A function may return a multiple value, so that you can write something like:

a, b = f(x)

If f(x) returns two values then they are respectively assigned to ‘a’ and ‘b’. If f(x) returns one value then ‘a’ gets it, while ‘b’ is assigned with ‘nil’. If f(x) returns three or more values then ‘a’ and ‘b’ get the first pair other are silently discarded.
But it doesn’t hold true everytime. In fact if you write:

a, b = f(x), 1

then ‘1’ is assigned to ‘b’ and only the first returned value from f(x) is assigned to ‘a’. In other words the extra return values from f(x) are discarded. If f(x) doesn’t return any value then ‘a’ gets the ‘nil’ value. Frightening, isn’t it?
What if the result of a function is passed as argument to another function, as in ‘f(g())’ ?
Somewhat of a nightmare. If the function is the only argument then all the result values are passed as arguments to the outer function, if other arguments are given then just the first return value is taken.
Consider that a function can be invoked with more or less than the specified number of arguments without error and you get the whole creepy plot.
This approach could do for a very few hundred lines of code, crossing this boundary requires the application of strict rules and conventions in order to keep things working without falling into chaos.
The book I’m reading seems quite oriented to a prototype level of application, in fact shows with good detail how to load and save data as source code. This is fine with your home app, but it is what you don’t want to do in a real application if you even slightly care about security.
I found rather elegant the use of associative container (the table) as a mean both for structuring data and for implementing the concept of class (I haven’t yet touch the point that deals with inheritance). Although the (ab)use of syntactic sugar in the language is likely to lead to syntactic diabetes.
According to what I read around it took about 10 years to fully master a programming language. I could agree, even if I think that within a year and a good amount of code you should be proficient. So my considerations are based on the first impression and my understanding of the language is far even from a beginner. Nonetheless I daresay that Lua has some problems in scaling up.