🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #2797

Re: Any interest in feature-specific macros?

#2797
From: J. Kanze
Date: Fri, 01 Dec 1995 16:04
137 lines
6101 bytes
Sean A Corfield (sean@corf.demon.co.uk) wrote:
|> In article <xg3pwecl774.fsf@marsh.cacs.usl.edu>,
|> akv@cacs.usl.edu (Anil Vijendran) wrote:

|> |> I shudder to think of such ifdef's in the code. It would be a
|> |> maintenance nightmare -- think of having dynamic stuff like exceptions
|> |> and casting in such ifdef's. 

|> I would go further and say that it would simply be unworkable. Suppose you
|> want to write code that uses exceptions if they are available. What does it
|> do if they aren't? Some horrendous pseudo-exception hack, perhaps? RTTI
|> also affects the core of the way you design/build systems.

It depends on what level you are programming.  At the application level,
I agree.  An application must be designed to use exceptions, or not to
use them; it cannot do both.  At a library level, however, I would like
to write code which allows the user to use exceptions if they are
present, but also allows him not to use them, whether they are present
or not.

Most of the defines encompass smaller issues, however.  Things like
bool.  And the resulting ifdef's are limited to a header file which
makes other defines, for example:

    #if GB_HASBOOL
    typedef bool        GB_bool ;
    #define GB_true     true
    #define GB_false    false
    #else
    typedef int         GB_bool ;
    #define GB_true     1
    #define GB_false    0
    #endif

    #if GB_HASNEWCAST
    #define GB_CONSTCAST( t , o )       (const_cast< t >(o))
    #define GB_STATICCAST( t , o )      (static_cast< t >(o))
    #define GB_REINTERPRETCAST( t , o ) (reinterpret_cast< t >(o))
    #else
    #define GB_CONSTCAST( t , o )       ((t)(o))
    #define GB_STATICCAST( t , o )      ((t)(o))
    #define GB_REINTERPRETCAST( t , o ) ((t)(o))
    #endif

    #if GB_HASMUTABLE
    #define GB_MUTABLE  mutable
    #define GB_MUTABLECAST( t , o )     (o)
    #else
    #define GB_MUTABLE
    #define GB_MUTABLECAST( t , o )     GB_CONSTCAST( t , o )
    #endif

Even with regards to exceptions, I will occasionally use something like
the following in library code:

    GB_BEGIN_TRY
        //  .. Some operations
    GB_CATCH( ... )
        //  .. Any necessary cleanup
        GB_RETHROW ;
    GB_END_TRY

The definition of the macros is as follows:

     #if GB_HASEXCEPTIONS
     #define GB_BEGIN_TRY            try {
     #define GB_END_TRY              }
     #define GB_CATCH( cond )        } catch( cond ) {
     #define GB_RETHROW              throw
     #else
     #define GB_BEGIN_TRY            if ( 1 ) {
     #define GB_END_TRY              }
     #define GB_CATCH( cond )        } else if ( 0 ) {
     #define GB_RETHROW
     #endif

If the implementation doesn't support exceptions, of course, I don't
have to worry about cleaning up when an exception is thrown.

|> Smaller issues are slightly easier to workaround -- simply don't use new
|> features if your target is portability!

How do I avoid using namespaces if my compiler library puts iostream in
namespace std?  Once again, GB_USE( std::ios ) (or GB_USE_NS( std )) to
the rescue (and of course, GB_USE and GB_USE_NS are defined
conditionally).

And let's not forget GB_SYSINCLUDE(iostream), which expands to
<iostream.h>, or <iostream.hpp>, or <iostream>, or in fact, anything
else you might need to get the works (including, perhaps "myiostream.h"
for the perverse cases).

|> And then there are more subtle issues:

|>   enum E { a, b, c };
|>   void f(E);
|>   void f(int);

|> Or, even more so:

|>   struct T { static void f(); };
|>   T* g();
|>   g()->f();

|> Depending on how close to the draft your compiler is, the first may fail to
|> compile and the second may, or may not, cause 'g()' to actually be called.

|> The best approach to stuff like this is simply to avoid the changed areas
|> unconditionally -- feature-specific macros are not the way to go, IMO

I agree with avoiding the new stuff when you can.  I would never write
code which actually uses namespaces or RTTI, for example, except in an
application for a specific compiler where I knew that they were
available.  And I write my for loops so that it doesn't matter which
scope rules are used.  But you simply cannot always avoid the
differences.

This is nothing new.  Alert readers will have already noticed that
defining GB_SYSINCLUDE(iostream) to generate <iostream.h> or
<iostream.hpp> has nothing to do with new features in the standard.  And
we've always had to deal with int's being different sizes, plain char
being maybe signed and a number of other variables.  (My code still has
conditional definitions to handle ctype functions that don't work for
values greater than 127, and my programs don't expect tolower to work
unless isupper is true, ISO 9899 not withstanding.)

I must admit, however, that the evolving C++ standard has raised this
sort of compiler dependancy handling to a new level.
-- 
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils, études et réalisations en logiciel orienté objet --
              -- A la recherche d'une activité dans une region francophone

[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Technical Details
Message-ID: <49mkqg$bat@gabi.gabi-soft.fr>
Path: arc1-ca.pugleaf.net!engnews1.Eng.Sun.COM!taumet!clamage
References: <4957mt$idp@fido.asd.sgi.com> <xg3pwecl774.fsf@marsh.cacs.usl.edu> <ACE1ED709668A68DC@corf.demon.co.uk>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!engnews1.Eng.Sun.COM!taumet!clamage
From: kanze@gabi-soft.fr (J. Kanze)
Newsgroups: comp.std.c++
Subject: Re: Any interest in feature-specific macros?
Date: 1 Dec 1995 16:04:43 GMT
Organization: GABI Software, Sarl.
Approved: clamage@eng.sun.com (comp.std.c++)
Message-ID: <49mkqg$bat@gabi.gabi-soft.fr>
References: <4957mt$idp@fido.asd.sgi.com> <xg3pwecl774.fsf@marsh.cacs.usl.edu> <ACE1ED709668A68DC@corf.demon.co.uk>
NNTP-Posting-Host: taumet.eng.sun.com
Content-Type: text
X-Newsreader: TIN [version 1.2 PL2]
Content-Length: 5149
X-Lines: 133
Originator: clamage@taumet