Joel C. Salomon:

>http://plan9.bell-labs.com/sys/doc/comp.html<

Thank you for that link.
I can see some interesting things in that very C-like language:

>The #if directive was omitted because it greatly complicates the preprocessor, 
>is never necessary, and is usually abused. Conditional compilation in general 
>makes code hard to understand; the Plan 9 source uses it sparingly. Also, 
>because the compilers remove dead code, regular if statements with constant 
>conditions are more readable equivalents to many #ifs.<

Can the "static if" be removed from D then?

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

Variables inside functions can have any order, are D compilers too doing this?

>Unlike its counterpart on other systems, the Plan 9 loader rearranges data to 
>optimize access. This means the order of variables in the loaded program is 
>unrelated to its order in the source. Most programs don’t care, but some 
>assume that, for example, the variables declared by
int a;
int b;
will appear at adjacent addresses in memory. On Plan 9, they won’t.<


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

Plan 9 uses this strategy to solve endianess-induced troubles in integer I/O:

>Plan 9 is a heterogeneous environment, so programs must expect that external 
>files will be written by programs on machines of different architectures. The 
>compilers, for instance, must handle without confusion object files written by 
>other machines. The traditional approach to this problem is to pepper the 
>source with #ifdefs to turn byte-swapping on and off. Plan 9 takes a different 
>approach: of the handful of machine-dependent #ifdefs in all the source, 
>almost all are deep in the libraries. Instead programs read and write files in 
>a defined format, either (for low volume applications) as formatted text, or 
>(for high volume applications) as binary in a known byte order. If the 
>external data were written with the most significant byte first, the following 
>code reads a 4-byte integer correctly regardless of the architecture of the 
>executing machine (assuming an unsigned long holds 4 bytes):

ulong getlong(void) {
    ulong l;
    l = (getchar()&0xFF)<<24;
    l |= (getchar()&0xFF)<<16;
    l |= (getchar()&0xFF)<<8;
    l |= (getchar()&0xFF)<<0;
    return l;
}

Note that this code does not ‘swap’ the bytes; instead it just reads them in 
the correct order. Variations of this code will handle any binary format and 
also avoid problems involving how structures are padded, how words are aligned, 
and other impediments to portability. Be aware, though, that extra care is 
needed to handle floating point data.<

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

I don't fully understand this:

>the declaration
extern register reg;
(this appearance of the register keyword is not ignored) allocates a global 
register to hold the variable reg. External registers must be used carefully: 
they need to be declared in all source files and libraries in the program to 
guarantee the register is not allocated temporarily for other purposes. 
Especially on machines with few registers, such as the i386, it is easy to link 
accidentally with code that has already usurped the global registers and there 
is no diagnostic when this happens. Used wisely, though, external registers are 
powerful. The Plan 9 operating system uses them to access per-process and 
per-machine data structures on a multiprocessor. The storage class they provide 
is hard to create in other ways.<

Bye,
bearophile

Reply via email to