Saturday, June 05, 2010

Why a volatile is different in C/C++ and Java

The volatile keyword is highly subjective to the language and the platform it is implemented on. While Java provides a consistent behaviour of volatile across all architectures, this is not the case for languages that are directly compiled into the native machine platform, such as in the case of C/C++. Let's try to understand why this is the case.

Let a,  b be member of a set of program actions P, and v_{n} (a) be function that applies the volatility requirement to an action, where the subscript _n denotes the _n-th iteration in which a volatile action is applied, and \rightarrow be the precedes operator, which is explained previously. For all program actions, the following rules holds:

v_n(a) \rightarrow v_{n+1}(a)

a \rightarrow v_n(b)  \Rightarrow a \rightarrow v_{n+i}(b) where  i \in \mathbb{N}

Rule 1 says that all volatile functions enforce a total order, where the function v_{n} (a) always precedes v_{n+1} (a), where rule 2 says that if an action a precedes a volatile function on an action b on the _n-th iteration, then the action a must necessarily precede all subsequent volatile functions applied to b.

This is a very strong memory requirement in Java, in fact it is much stronger than compared to C/C++. The C/C++ language specification has no such restriction on memory ordering, and leaves it to the compiler implementation to decide how non-volatile actions are ordered around volatile actions.

Let's consider how the these rules affect program execution with a simple code sample:

int a = 0;
int b = 0;
volatile int count = 0;

a = 1;
count = 1;
b = 2;
count = 2;

In C/C++, the volatile keyword only guarantees that the count variable cannot be reordered against each other, ie. if count == 2, then count = 1 must necessarily precede it. However, there is neither a guarantee that a == 1, nor that b == 2.

In Java, given the stronger guarantee defined above, then if count == 1, then the assertion a == 1 must be true. Similarly, if count == 2 then assertion that a == 1 && b == 2 must be true. This is what is means by the strict memory guarantee that Java offers that C/C++ does not.

However this does not mean that C/C++ will not behave the same way Java does. Whether if it does so depends on (1) whether if the compiler performs any code reordering that may be in a surprising order, but legit order, and (2) whether if the underlying machine architecture upholds the same strict memory order, provided that the compiler does not perform any surprising code reordering.

For instance, compiling code on gcc with -O0 set on all x86 platforms will conform to (and is stricter than) Java's memory model, but other architectures such as the PowerPC, Alpha, Itanium all uphold a weaker memory model which can exhibit surprising program behaviours that a programmer may not expect. Caveat Lector!

Anyhow, if you are interested in more memory model consistency rules, you might want to watch Intel's explanation of the x86 memory model where the nuances of memory ordering is explained in good detail. Enjoy!

Java Hatred Is A Disease

When it comes to critising programming languages, Java seems to take the top spot for being the baddest. This is widely seen on the InterTubes, like here, and here.

But does a 'bad' language mean that it'll die a relatively quick death?

To find out, let's take a look at the etymology of an older computer language, C. C has been a systems programming language that has been around the last 40 years. The last revision to the C standard was 10 years ago, and even without moving with the times, the language is still going strong - last I heard, it is still the language of choice for 40% of Open Source developers.

Does that mean that people have stopped complaining about pointers, easy-to-write buffer overflow errors, memory leaks, having to declare all variables up front before code, etc, etc, and other quirks about the language?

I suspect not. So why still C?

Simple - it works. And I suspect the same can be said with Java.

Furthermore, it's silly to argue about Java's merits and drawbacks, because that's really missing the forest for the trees. While the most visible part about Java is the undoubtedly the language, but the true technology of Java is not in the language, but the virtual machine itself. The JVM as it stands today, is a fast, abstract machine that you can plug any languages into, and is able to operate at speeds comparable to natively compiled binaries.

Like most programmers, we do enjoy bitching about peculiarities of a language once in a while, but for people who hate Java with a passion, maybe you need to get your head checked. A language is merely a medium of expression; and a computer language is one specifically used to express program behaviour. Normally, the choices are either to learn it well and avoid the pitfalls, or find a better medium of expression.

So seriously, if you don't like Java, there is a cure. Stop. Using. It.

I'll let you in on a secret to programming languages; there are only two types of languages in this world - languages that people complain about, and languages that nobody uses (Stroustrup said so). So in an obtuse manner, the vast majority of people who criticises about Java are only reaffirming its popularity.

Which is precisely why I can't see Java going the way of dinosaurs. Raving incessantly against it, ironically only helps boost its reputation, albeit in a weird, backhanded-kind of way.