At Thu, 17 Dec 2009 10:02:41 +0100, Jonathan Schleifer <js%webkeks.org@localhost> wrote: Subject: Re: NetBSD macros > > Am 14.12.2009 um 20:43 schrieb Greg A. Woods: > > > I wasn't referring to __NetBSD__ alone -- I would include > > <sys/param.h>'s __NetBSD_Version__ as well of course. > > So you'd already have: > > #ifdef __NetBSD__ > #include <sys/param.h> > #if __NetBSD_Version__ ?ôó¦ > ?ôó¦ > #else > ?ôó¦ > #endif > > Ok, now you covered NetBSD. Now you have to do the same for: No, actually you don't, usually -- and that's my point. You only use the system-specific identification macros for system-specific features, i.e. those features found _only_ on one(1) type of system. If the feature is found on multiple types of systems, but not all, and for some reason you must still use it, then you should identify it by a unique identifier and find some other way to enable that identifier, other than messing about with system-specific identifiers. As I said: > > Neither should be used blindly either of course -- it's horrid to see > > long trails of "#if defined(__NetBSD__) || defined(__FreeBSD__) || > > defined(__OpenBSD__) || defined(__DragonFly__) || defined(__Darwin__)" > > (with the only missing one being __Linux__ or whatever!) > > Although this is already long, it's wrong as it does not check versions. Irrelevant! :-) Don't do that in the first place if possible! :-) (However, BTW, often the version checking is irrelevant because the feature is, for this example say, a common BSD feature that was found in the original code from which all the various modern variants have been derived -- a wee bit of history goes a long way!) Also, all that said, I'd rather see a few snarly #ifdef lines in one header file that can sort out a few necessary conflicting features than to have to use Autoconf. > Can you please elaborate? While I agree that most configure.ac files > are too big because they are written by people who don't know what > they're doing, you can to very much in autoconf with very little code. Most configure.ac files are large and result in huge scripts with many tests because if you truly wish to use Autoconf properly to make your code as ultra-portable as possible then you really must include a very large number of tests (and also all the necessary #ifdef's in your code), even for quite simple programs. I.e. they often do know what they're doing -- it's just futile to do it sometimes. That's the problem with doing feature tests and relying on them solely to keep your code portable. I do agree that some people do write too many feature tests, but unless you're able to go out and re-test the program on every platform it has already been tested on, it's sometimes really difficult to prove that any given feature test can be safely removed. Not always, but sometimes! > For the time consuming part, I couldn't disagree more: It's much more > time consuming to write a check yourself when it's just a single line > in autoconf. If you were reffering to the time needed to run the > generated configure script, this is again because many write stupid > configure.ac files that check for stuff they don't even need. The right way to do things is to write code that's portable in the first place. Don't ever make use of _any_ system-specific features unless absolutely necessary! Use template header files to adapt to the few features which often do vary between systems. There are of course classes of programs which must make use of features which are not standardised sufficiently and thus they must have alternate implementations to supplement systems without, etc. Writing good portable code does require one to be a good historian of the relevant systems and standards, and also to know when supporting a given system, or class of systems, or even a standard, has become irrelevant. I suppose a first-time programmer who knows little beyond the system he or she is initially working with, can achieve some degree of portability of their early code by simply following the Autoconf guide and/or book. However even that can come later -- if they simply write good clean code that works properly on the one system they have access to, but which is as much as possible written to use the _standard_ APIs that their system happens to support (POSIX, ISO C, etc.), then any issues with porting to another system can be addressed at a later time, perhaps with the help of someone more experienced in porting code. I.e. I would not recommend one try to make one's first big/largish program portable by immediately starting with the likes of GNU Autoconf! > There's nothing wrong with doing the checks again, as the system can > have changed. If it would cache it, how would it know the system > changed? The point is that the system does not (usually) change! Every test that you do twice or more is a waste of resources. IFF the system does change, eg. you upgrade to a new version, and IFF the system's APIs have changed incompatibly, then you need to throw away the cache and start fresh. You know when you've changed the system, so you know how to manage your cache file! Ideally Autoconf would come with a standard boiler-plate configure.ac file which could be run once on a target system to generate a cache for all standard tests. > This is why abstraction was invented - and as most GUI applications > use Qt or GTK, they come with a framework as well that takes care of > portability for you. I would claim that's not why many abstractions were invented, especially not for GUIs. They are not primarily portability layers -- though sometimes they can be made to do that job as well. Even those which did start out as simple portability layers have almost always gone well beyond that level. Most abstraction layers are designed to hide complexity and to (hopefully) share common code. -- Greg A. Woods Planix, Inc. <woods%planix.com@localhost> +1 416 218 0099 http://www.planix.com/
Attachment:
pgp0ziqWM1Z9X.pgp
Description: PGP signature