Topic: Preprocessor


Author: "Ludwig Pumberger" <pumberger@direkt.at>
Date: Thu, 14 Mar 2002 03:51:45 GMT
Raw View
Hi,

If I have a headerfile like this:

#ifndef MY_HEADER
#define MY_HEADER

namespace myheader
{
    template <class FOO>
        void bar(FOO foo)
        {
            //do something
        }
}

#endif

everything seems to be okay. I don't pollute the global namespace and so I
don't have any problems with global names. This could be right if there were
no macros.

#define FOO ugly
#include "myheader.h"

Now we have a problem. The global macro FOO doesn't care about namespaces
and destroys my function. The STL uses names like _FWD to avoid this problem
because names beginning with an underscore are reserved, but I cannot use
them in my own headers.
But what about this:

#ifndef MY_HEADER
#define MY_HEADER

#locale
#undef FOO

namespace myheader
{
    template <class FOO>
        void bar(FOO foo)
        {
            //do something
        }
}

#end_locale

#endif

A locale block should be thought being an area where all #defines and
#undefs are just temporary. As soon as the preprocessor reaches #end_locale
all changes are lost:

#define ugly

#locale
#undef ugly
ugly //error there is no ugly
#end_locale

ugly //ok ugly is defined

#locale
#define ugly
ugly //ok
#end_locale

ugly //error

There could be also a directive #clear which should remove all global
symbols in the locale block.

        Ludwig Pumberger




---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Paul Mensonides" <pmenso57@attbi.com>
Date: Thu, 14 Mar 2002 16:20:28 GMT
Raw View
"Ludwig Pumberger" <pumberger@direkt.at> wrote in message
news:a6o140$ft3og$1@ID-133423.news.dfncis.de...
> Hi,
>
> If I have a headerfile like this:
>
> #ifndef MY_HEADER
> #define MY_HEADER
>
> namespace myheader
> {
>     template <class FOO>
>         void bar(FOO foo)
>         {
>             //do something
>         }
> }
>
> #endif
>
> everything seems to be okay. I don't pollute the global namespace and so I
> don't have any problems with global names. This could be right if there were
> no macros.
>
> #define FOO ugly
> #include "myheader.h"
>
> Now we have a problem. The global macro FOO doesn't care about namespaces
> and destroys my function. The STL uses names like _FWD to avoid this problem
> because names beginning with an underscore are reserved, but I cannot use
> them in my own headers.
> But what about this:

Actually it doesn't change it at all in this case.  Just renames the type
parameter.  I see you're point though.  I'd rather have a more general
macro-scoping mechanism though.

#region FOODEF
    #define FOO ugly
    #region NESTED
        #define FOO ugly
    #endreg
#endreg

typedef int ugly;

// myheader.h

#ifndef MY_HEADER_H
#define MY_HEADER_H

namespace myheader {
    template<class FOO> void bar(FOO foo) {
        // note:  no FOO defined in global region
    }
};

#endif

FOO@FOODEF x; // <- scoped macro
FOO@NESTED@FOODEF y;

Region names would not conflict with C++ names, of course, so you could have a
region as the same name.  E.g.

#region std
#define assert ...
#endreg

namespace std { }

If you did that, you could actually use the word assert somewhere else in the
program for something other than the standard library assert macro.

'std' by itself would mean nothing to the preprocessor, but

'macro_name@' followed by 'std' would.

assert@std(x < y);

Of course, you would also have to have some type of preprocessor using directive
to bring names in.

#region std
    // ...
#endreg

#region boost
#use @std // roughly equivalent to ::std
    // ...
#endreg

Paul Mensonides

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Thu, 14 Mar 2002 16:21:07 GMT
Raw View
In article <a6o140$ft3og$1@ID-133423.news.dfncis.de>, Ludwig Pumberger
<pumberger@direkt.at> writes
>Hi,
>
>If I have a headerfile like this:
>
>#ifndef MY_HEADER
>#define MY_HEADER
>
>namespace myheader
>{
>    template <class FOO>
>        void bar(FOO foo)
>        {
>            //do something
>        }
>}
>
>#endif

Well we are probably going to consider some such suggestion as the one
you make in your post, but why are you maximising the potential clash by
writing a non preprocessor identifier without any lowercase letters?
 From my perspective, that is asking for trouble. The reason
implementations of the standard library use one or more leading
underscores is to prevent clashes with user provided PREPROCESSOR
identifiers.



--
Francis Glassborow
Check out the ACCU Spring Conference 2002
4 Days, 4 tracks, 4+ languages, World class speakers
For details see: http://www.accu.org/events/public/accu0204.htm

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Paul Mensonides" <pmenso57@attbi.com>
Date: Thu, 14 Mar 2002 19:23:43 GMT
Raw View
"Ludwig Pumberger" <pumberger@direkt.at> wrote in message
news:a6o140$ft3og$1@ID-133423.news.dfncis.de...
> Hi,
>
> If I have a headerfile like this:
>
> #ifndef MY_HEADER
> #define MY_HEADER
>
> namespace myheader
> {
>     template <class FOO>
>         void bar(FOO foo)
>         {
>             //do something
>         }
> }
>
> #endif
>
> everything seems to be okay. I don't pollute the global namespace and so I
> don't have any problems with global names. This could be right if there were
> no macros.
>
> #define FOO ugly
> #include "myheader.h"
>
> Now we have a problem. The global macro FOO doesn't care about namespaces
> and destroys my function. The STL uses names like _FWD to avoid this problem
> because names beginning with an underscore are reserved, but I cannot use
> them in my own headers.
> But what about this:

Actually it doesn't change it at all in this case.  Just renames the type
parameter.  I see you're point though.  I'd rather have a more general
macro-scoping mechanism though.

#region FOODEF
    #define FOO ugly
    #region NESTED
        #define FOO ugly
    #endreg
#endreg

typedef int ugly;

// myheader.h

#ifndef MY_HEADER_H
#define MY_HEADER_H

namespace myheader {
    template<class FOO> void bar(FOO foo) {
        // note:  no FOO defined in global region
    }
};

#endif

FOO@FOODEF x; // <- scoped macro
FOO@NESTED@FOODEF y;

Region names would not conflict with C++ names, of course, so you could have a
region as the same name.  E.g.

#region std
#define assert ...
#endreg

namespace std { }

If you did that, you could actually use the word assert somewhere else in the
program for something other than the standard library assert macro.

'std' by itself would mean nothing to the preprocessor, but

'macro_name@' followed by 'std' would.

assert@std(x < y);

Of course, you would also have to have some type of preprocessor using directive
to bring names in.

#region std
    // ...
#endreg

#region boost
#use @std // roughly equivalent to ::std
    // ...
#endreg

Paul Mensonides



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news_comp.std.c++_expires-2002-05-01@nmhq.net (Niklas Matthies)
Date: Fri, 15 Mar 2002 17:07:44 GMT
Raw View
On Thu, 14 Mar 2002 19:23:43 GMT, Paul Mensonides <pmenso57@attbi.com> wrote:
[...]
>  I'd rather have a more general macro-scoping mechanism though.
>
>  #region FOODEF
>      #define FOO ugly
>      #region NESTED
>          #define FOO ugly
>      #endreg
>  #endreg
>
[...]
>
>  FOO@FOODEF x; // <- scoped macro
>  FOO@NESTED@FOODEF y;

Why not rather simply name it:

   #namespace std
   #  define dump_core_unless(cond) ...
   #endnamespace
   ...
   std::dump_core_unless(1.0 != 2.0);

Using :: would also have the benefit that stuff could be either
implemented through macros or through actual types/objects/functions
without the need to change client code.

Of course, a problem remains with

   #using namespace std

vs.

   using namespace std;

where the latter should really also imply the former, but the
preprocessor probably can't be made smart enough to recognize using
directives.

-- Niklas Matthies
--
Drive carefully; 90% of the people in the world are caused by accidents.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Paul Mensonides" <pmenso57@attbi.com>
Date: Sat, 16 Mar 2002 01:58:19 GMT
Raw View
> >  I'd rather have a more general macro-scoping mechanism though.
> >
> >  #region FOODEF
> >      #define FOO ugly
> >      #region NESTED
> >          #define FOO ugly
> >      #endreg
> >  #endreg
> >
> [...]
> >
> >  FOO@FOODEF x; // <- scoped macro
> >  FOO@NESTED@FOODEF y;
>
> Why not rather simply name it:
>
>    #namespace std
>    #  define dump_core_unless(cond) ...
>    #endnamespace
>    ...
>    std::dump_core_unless(1.0 != 2.0);

I would prefer to keep the prepreprocessor a separate mechanism.  So it only has
to worry about '@' for scoping issues.

> Using :: would also have the benefit that stuff could be either
> implemented through macros or through actual types/objects/functions
> without the need to change client code.
>
> Of course, a problem remains with
>
>    #using namespace std
>
> vs.
>
>    using namespace std;
>
> where the latter should really also imply the former, but the
> preprocessor probably can't be made smart enough to recognize using
> directives.

No, not C++ using directives, but it could recognize its own using directives.
The biggest reason to keep it separate, is that the preprocessor can make any
kind of C++ proper that you want it to.

i.e.

#define MAKE_NAMESPACE(A, B) namespace A ## B

Paul Mensonides

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: news_comp.std.c++_expires-2002-05-01@nmhq.net (Niklas Matthies)
Date: Sat, 16 Mar 2002 12:11:39 GMT
Raw View
On Sat, 16 Mar 2002 01:58:19 GMT, Paul Mensonides <pmenso57@attbi.com> wr=
ote:
> > >  I'd rather have a more general macro-scoping mechanism though.
> > >
> > >  #region FOODEF
> > >      #define FOO ugly
> > >      #region NESTED
> > >          #define FOO ugly
> > >      #endreg
> > >  #endreg
> > >
> > [...]
> > >
> > >  FOO@FOODEF x; // <- scoped macro
> > >  FOO@NESTED@FOODEF y;
> >
> > Why not rather simply name it:
> >
> >    #namespace std
> >    #  define dump_core_unless(cond) ...
> >    #endnamespace
> >    ...
> >    std::dump_core_unless(1.0 !=3D 2.0);
> =20
>  I would prefer to keep the prepreprocessor a separate mechanism.  So
>  it only has to worry about '@' for scoping issues.
[=B7=B7=B7]
>  The biggest reason to keep it separate, is that the preprocessor can
>  make any kind of C++ proper that you want it to.
> =20
>  i.e.
> =20
>  #define MAKE_NAMESPACE(A, B) namespace A ## B

I sure did mean #namespace and namespace to have separate semantics,
i.e. #namespace only applying to scoping of macros and leaving the
current 'namespace' as it is.

There are actually two seperate points I wanted to make.

First, Since the facility under discussion is effectively creating
namespaces for preprocessor identifiers (macros), why create new
terminology for it ("region") when "namespace" is already an established
term in C++? Better take advantage of what C++ programmers already know,
so you can tell them "it's like regular namespaces, only for the
preprocessor", and give the preprocessing directive the obvious name.

Secondly, it would be handy (arguably, there are a few pitfalls, like
Koenig lookup) for an implementor to have the choice of implementing
"namespaced" facilities either as macros or in the actual language.
For this to work, the syntax for accessing regular namespace scopes and
preprocessor namespace scopes would necessarily have to be compatible.
As a side-effect, this also would be easier on the user who wouldn't
have to remember yet another new syntax for doing stuff and having to
always have to take care which to use when, when in effect they do
conceptually the same thing.

Your example above,

  #define MAKE_NAMESPACE(A, B) namespace A ## B

would still work unchanged.
Breaking current usage would be unacceptable, no argument there.

-- Niklas Matthies
--=20
[X] <-- nail here for new monitor

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]