Null references redux + Cyclone

bearophile bearophileHUGS at lycos.com
Mon Sep 28 09:24:53 PDT 2009


Jeremie Pelletier:

> Not always true.

I agree, I'm using D also because it offers unions. Sometimes they are useful.

But beside normal C unions that I don't want to remove from C, it can be also useful to have safe automatic tagged unions of Cyclone. They are safer and give just a little less performance compared to C unions. In D they may be denoted with "record" or "tunion" or just "safe union" to save keywords. They always contain an invisible tag (that can be read with a special built-in union method, like Unioname.tagcheck). Such "safe unions" may even become the only ones allowed in SafeD modules!

The following is from Cyclone docs:
<<
The C Standard says that if you read out any member of a union other than the last one written, the result is undefined.
To avoid this problem, Cyclone provides a built-in form of tagged union and always ensures that the tag is correlated with the last member written in the union. In particular, whenever a tagged union member is updated, the compiler inserts code to update the tag associated with the union. Whenever a member is read, the tag is consulted to ensure that the member was the last one written. If not, an exception is thrown.

Thus, the aforementioned example can be rewritten in Cyclone like this:

@tagged union U { int i; int *p; };
void pr(union U x) {
  if (tagcheck(x.i))
    printf("int(%d)",x.i);
  else
    printf("ptr(%d)",*x.p);
}

The @tagged qualifier indicates to the compiler that U should be a tagged union. The operation tagcheck(x.i) returns true when i was the last member written so it can be used to extract the value.
>>


> Again, that's a lazy view on programming. High level constructs are 
> useful to isolate small and simple algorithms which are implemented at 
> low level.

Software is inherently multi-scale. Probably in 90-95% of the code of a program micro-optimizations aren't that necessary because those operations are done only once in a while. But then it often happens that certain loops are done an enormous amount of times, so even small inefficiencies inside them lead to low performance. That's why profiling helps.

This can be seen by how HotSpot (and modern dynamic language JITters work): usually virtual calls like you can find in a D program are quick, they don't slow down code. Yet if a dynamic call prevents the compile to perform a critical inlining or such dynamic call is left in the middle of a critical code, it may lead to a slower program. That's why I have Java code go 10-30% faster than D code compiled with LDC, not because of the GC and memory allocations, but just because LDC isn't smart enough to inline certain virtual methods.

------------------------------------

More quotations from the Cyclone documentation:

>In contrast, Cyclone's analysis extends to struct, union members, and pointer contents to ensure everything is initialized before it is used. This has two benefits: First, we tend to catch more bugs this way, and second, programmers don't pay for the overhead of automatic initialization on top of their own initialization code.<


This is right on-topic:
>This requires little effort from the programmer, but the NULL checks slow down getc. To repair this, we have extended Cyclone with a new kind of pointer, called a “never-NULL” pointer, and indicated with ‘@’ instead of ‘*’. For example, in Cyclone you can declare
int getc(FILE @);
indicating that getc expects a non-NULL FILE pointer as its argument. This one-character change tells Cyclone that it does not need to insert NULL checks into the body of getc. If getc is called with a possibly-NULL pointer, Cyclone will insert a NULL check at the call :<



>Goto C's goto statements can lead to safety violations when they are used to jump into scopes. Here is a simple example:

int z;
{ int x = 0xBAD; goto L; }
{ int *y = &z;
L: *y = 3; // Possible segfault
}

Cyclone's static analysis detects this situation and signals an error. A goto that does not enter a scope is safe, and is allowed in Cyclone. We apply the same analysis to switch statements, which suffer from a similar vulnerability in C.<

Bye,
bearophile



More information about the Digitalmars-d mailing list