version and debug statements

Sean Kelly sean at f4.ca
Thu May 11 14:26:43 PDT 2006


Walter Bright wrote:
> Sean Kelly wrote:
>> For what it's worth, I think it would be useful for the 'Posix' 
>> version to be added, so any system supporting POSIX would have version 
>> 'Posix' automatically specified in addition to any OS version 
>> identifier.  This would be similar to how Windows platforms also have 
>> either 'Win32' or 'Win64' defined.  While a good bit of POSIX 
>> declarations are indeed implementation dependent, an equally large 
>> amount are not, and I believe it would be useful for a version 
>> identifier to reflect this.
> 
> Having large parts of Posix be implementation dependent kinda shoots the 
> whole idea of a standard in the foot.

It's kind of silly, but I think the reason was to allow basically any 
system to be Posix compliant, so a good portion of Posix is broken into 
individually optional subsets of features, such as threading.  For the 
required stuff, function declarations will obviously be consistent, but 
the contents and layout of structs and the value of constants is likely 
to change from OS to OS.

For what it's worth, I've found it's far simpler to work completely from 
the spec for determining what should be defined and then looking for 
those definitions in the header files than to simply try and convert the 
headers en masse.  This made implementing the C99 headers a breeze and 
is really the only workable option for Posix support.

>> As much as I like the version idea, I'm beginning to feel that the 
>> C/C++ #ifdef method may actually be preferable in some situations.  
>> For example, some portions of Posix are common and others are not, so 
>> I am faced with a few options:
>>
>> - Define a separate set of Posix headers for each OS and have the user 
>> import the proper set manually.
>>
>> - Define a separate set of Posix headers for each OS and do some fancy 
>> versioning in a common area to publicly import the proper set 
>> automatically.
>>
>> - Define a common set of modules, each of which contains version 
>> blocks for each OS and may potentially result in multiple declarations 
>> of the same symbol occuring in the file (this is what I'm doing now 
>> for the Ares Posix headers as it's  the most readable, but I think it 
>> may become difficult to deal with when support for more OSes is added)
>>
>> - Define a common set of modules with centralized logic for 
>> determining various things and use 'static if' in place of 'version' 
>> in a manner similar to #ifdef in C/C++
>>
>> - Define a common set of modules but specify version identifiers in 
>> the makefile or via other means and move the complicated logic out of 
>> code and into a configure script or something similar
> 
> I suggest another possibility:
> 
> - Define a set of modules for each operating system, each in its own 
> package
> - Define an "os configuration module" that is edited by the user to 
> import the correct os modules
> 
> I.e.:
>     windows.foo.bar;
>     linux.foo.bar;
>     bsdunix.foo.bar;
> 
> and:
> 
>     foo.bar
> 
> the contents of foo.bar.d are:
> 
>     import windows.foo.bar;
>     //import linux.foo.bar;
>     //import bsdunix.foo.bar;
> 
> No version statements needed.

Hrm, so similar to option 2, but with the user manually choosing which 
set of headers to use.  That works, I suppose.

>> While preprocessor logic has proven to be an aboslute nightmare in 
>> terms of readability and maintainability in some cases, I truly 
>> believe that this is more attributable to a lack of programmer skill 
>> than anything else.
> 
> Over time, I've been rewriting my use of #ifdef's in C++ to use the D 
> style, and the results are worth it.

I'll trust you on this.  I simply haven't had enough need for them yet 
to have formed a solid opinion.

>> Yup, but doing this in every module isn't particularly desirable if 
>> such settings may be common for an entire package.
> 
> True, but the way to do that is to create an import such as foo.bar 
> above that imports or aliases the correct configuration. I think these 
> will work out better than the usual C technique of having gobs of 
> command line #defines. Just today, I have been having a miserable time 
> attempting to compile the Boost test suite, and am being stymied trying 
> to figure out which wretched set of #define's have to go on the command 
> line just to get the freakin' default to work.

Boost is an absolute nightmare of preprocessor code and workarounds for 
compiler support.  Between this and the complexity of implementation for 
some of the utilities, I'm not terribly inclined to use much of Boost in 
production applications.

Regarding the import idea, I think it's a good one.  I did recently have 
reason to need something akin to #ifdef in D (to have the value of an 
assignment contingent on whether a constant was defined--darned Posix), 
but I suspect this is a rare case.  And I suppose an alternative would 
be to declare this constant on non-supporting platforms to a "safe" 
default value.

> <flame on>
> C++ was supposed to reduce the use of the preprocessor. Boost is 
> peer-reviewed and written by the best and the brightest C++ developers. 
> So why does even the simplest Boost code *heavily* rely on complex, 
> obtuse, layer after layer of preprocessor macros?
> <flame off>

It's interesting to see how Boost components have evolved over time. 
For example, the implementation of shared_ptr used to be extremely 
straightforward--it comprised maybe 100 lines of code with nary a macro 
to be seen.  Now it's spread across multiple files, contains dense and 
complicated code, and has more features than I care to list.  In some 
respects this reminds me of what I call the "Microsoft Word" syndrome. 
That being that everyone wants a very small subset of features in a 
product, but all of those people want *different* features.

Another factor may be that while it's quite difficult to write an easily 
usable library, it's far more difficult to do so using simple, 
straightforward code or to maintain this simplicity across maintenance 
cycles.  shared_ptr started out clean and compact, but it certainly 
didn't stay that way.  Perhaps there's simply more pressure to get 
improvements done than to do so in a clearly readable manner, or perhaps 
it's an issue of too many fingers spoiling the soup?  I suppose it also 
doesn't help that the best and brightest may occasionally lack 
perspective on what's understandable to the average person, or perhaps 
there's simply no perceived need for users to be able to make sense of 
the code.


Sean



More information about the Digitalmars-d mailing list