Why version() ?

Walter Bright newshound1 at digitalmars.com
Tue Feb 10 17:16:22 PST 2009


Derek Parnell wrote:
> On Tue, 10 Feb 2009 14:01:29 -0800, Walter Bright wrote:
> 
>> Derek Parnell wrote:
> 
>>>  ... it creates a new problem; code
>>> duplication.
>> I don't think that duplicating a small run of code is a problem.
> 
> 
> My apology. The problem is more than run-time performance issues. The more
> pressing problem, IMHO, is the one of maintenance costs. Duplicated code is
> a significant cost burden. Not only may each duplication require updating,
> but there is extra effort in analyizing every duplicate to see if it *does*
> need updating. And every act of updating increases the opportunity for
> introducing bugs.

Let's take an example, like the enum for O_XXXX in std.c.linux.linux. 
Some of those values are common between platforms, and some are unique 
to particular platforms. So you might be tempted to write:

enum
{
     O_RDONLY = 0,
     O_WRONLY = 1,
     O_RDWR = 2,
     O_CREAT = 0100,
version(OSX) O_SYMLINK   = 0x200000,
}

instead of:

version (linux)
{
   enum
   {
     O_RDONLY = 0,
     O_WRONLY = 1,
     O_RDWR = 2,
     O_CREAT = 0100,
   }
}
else version (OSX)
{
   enum
   {
     O_RDONLY = 0,
     O_WRONLY = 1,
     O_RDWR = 2,
     O_CREAT = 0100,
     O_SYMLINK   = 0x200000,
   }
}
else
{
     static assert(0); // need platform support
}

The first version is definitely shorter. But is it easier to maintain? I 
argue that it is *harder* and *buggier* to maintain. Let's say I am 
using linux and I need to add O_APPEND to it. I just stuff it in like:

enum
{
     O_RDONLY = 0,
     O_WRONLY = 1,
     O_RDWR = 2,
     O_CREAT = 0100,
     O_APPEND = 02000,
version(OSX) O_SYMLINK   = 0x200000,
}

and it works great for linux. Now I port my code to OSX, and it 
mysteriously dies. After much frustration, I discover that O_APPEND for 
OSX is 8, not 02000. (Yes, this kind of thing has happened to me. I only 
found it by suspecting the problem, and then going through every fscking 
definition comparing it to the one in the system .h file. Yeech.)

Now let's try the other way. I add O_APPEND to the linux branch, and 
linux works great. Now I port to OSX, and the compiler dies with 
"O_APPEND is undefined". I know immediately exactly what is wrong, look 
up the .h file, and insert the right O_APPEND into the OSX version of 
the declaration.

Furthermore, when I build a FreeBSD version, the compiler bings at me 
for every declaration that needs some porting attention, instead of 
silently using the wrong values.

This would be even better if the OSX and linux declarations were split 
into separate "personality" modules. That way you can develop happily on 
OSX without fear of accidentally breaking linux support. You can defer 
dealing with the linux version until you actually on the linux machine 
and are in an efficient position to take care of it.


> Coders need languages that help them do their job, and one way to help is
> to reduce the need for duplicated code.

I know there's a risk by getting in the way of programmers wanting to do 
things a particular way. To do it, I have to be pretty convinced that 
there is a better way. The C preprocessor is like crack, everyone knows 
it's bad but they snort it anyway because it feels so good <g>. C++ was 
supposed to get a bunch of features that obviate the preprocessor, but 
have a look at the premier C++ library - Boost - which uses the 
preprocessor heavily. Boost also uses every last iota of what the 
preprocessor can do, because if your cpp implementation is not 100% most 
of Boost will not compile (I know this from experience, DMC++ is 100% now).


>>> Duplicating (nearly all of a) source file is NOT, repeat NOT, a
>>> satisfatory solution.
>> I'm not insensitive to this as I do it myself in maintaining Phobos. It 
>> is a problem, but not a huge one. I find that the meld utility (on 
>> linux) makes this chore a snap.
> 
> Because of D's limited support for text macros, I am using third party
> tools to get me out of this problem too. 

meld is particularly nice. Andrei showed it to me:

http://www.linux.com/feature/61372



More information about the Digitalmars-d mailing list