Topic: Avoiding macro name conflicts.


Author: Andy Vesper <avesper@wn.net>
Date: Tue, 31 Oct 2000 17:49:46 GMT
Raw View
David R Tribble wrote:

> The preprocessor is incredibly useful.  It's true that C++ has removed
> many of the former uses of the preprocessor, but C still relies on
> its capabilities a great deal.
>
> The two biggest areas I personally find macros useful are:
>
> 1. Porting code between different systems.
>  Is plain 'char' signed or unsigned?
>  Is the native character set ASCII or EBCDIC?
>  Is the native byte ordering big- or little- endian?
>  Is there a 'long long' supported type?
>  Which 'bool' type is it?

I would add:
    Better use of __LINE__ and __FILE__ (and __FUNC__ or is that
__FUNCTION__).
and the occasionally usage of # and ##.
--
Andy V (OpenGL Alpha Geek)
"In order to make progress, one must leave the door to the unknown ajar."
Richard P. Feynman, quoted by Jagdish Mehra in _The Beat of a Different
Drum_.

Paul Martz's OpenGL FAQ: http://www.opengl.org/About/FAQ/Technical.html


---
[ 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                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Mon, 30 Oct 2000 18:54:12 GMT
Raw View
David R Tribble <david@tribble.com> wrote:
>> I'm considering proposing a namespace facility for the preprocessor.

Roger Orr wrote:
> I'm interested in examples of where you consider this would be helpful
> - I don't find I use macros much in C++ since it provides better
> alternatives in many cases.
> [Especially given the number of people who say 'macros are evil' :) ]

Any language feature is evil when abused; it's just that some, like
'goto', are more easily abused than others.

The preprocessor is incredibly useful.  It's true that C++ has removed
many of the former uses of the preprocessor, but C still relies on
its capabilities a great deal.

The two biggest areas I personally find macros useful are:

1. Porting code between different systems.
 Is plain 'char' signed or unsigned?
 Is the native character set ASCII or EBCDIC?
 Is the native byte ordering big- or little- endian?
 Is there a 'long long' supported type?
 Which 'bool' type is it?

2. Combining code with multiple third-party libraries.
 This is probably the biggest reason C++ namespaces were invented.
 C, unfortunately, doesn't have namespaces (yet), and still suffers
 from name collisions when linking with multiple vendors' libraries.

Point (2) is a very important point.  Vendors *should* be using
unique affixes on all their macro, type, variable, function, and
constant identifiers, but so many don't or only do a half-baked job
of it.  Giving the client programmer a means of uniquifying a
vendor's poor choice of identifiers (i.e., specifying a #namespace
directive prior to #including the vendor's headers) would solve some
of these kinds of messes.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ 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                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Keith Thompson <kst@cts.com>
Date: Mon, 30 Oct 2000 19:02:00 GMT
Raw View
Just a reminder: this thread has been cross-posted to comp.std.c,
where it's off-topic.  Please watch the followups.

--
Keith Thompson (The_Other_Keith) kst@cts.com  <http://www.ghoti.net/~kst>
San Diego Supercomputer Center           <*>  <http://www.sdsc.edu/~kst>
Welcome to the last year of the 20th century.

---
[ 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                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: 2000/10/23
Raw View
David R Tribble wrote:
>> I'm considering proposing a namespace facility for the preprocessor.
>> Essentially, macro names would be allowed to have 'name::' prefixes
>> in order to make them unique.  Of course a big concern is to make
>> all of this new machinery work with existing code.
>>
>> Essentially, I would add the following directives:
>>
>>   #namespace <id>[::<id>]...
>>[...]
>>   #endnamespace
>>
>>     Closes the currently active pp-namespace.
>>
>>   #using <id>[::<id>]...
>>
>>     Adds a pp-namespace prefix to the list of implied prefixes to
>>     be considered when resolving macro names in subsequent source
>>     code.  Essentially, this allow the use of macro names that have
>>     been abbreviated by omitting one or more of their pp-namespace
>>     prefixes.
>>
>>     Multiple pp-namespace #using directives may be active at the
>>     same time.

Dennis Yelle wrote:
> Once we have a #using, how do we get rid of it?

The same way you get rid of the effects of a 'using' directive in C++
;-)

I modeled my pp-namespace proposal after the C++ namespace facility.
I assumed that once you've opened a namespace with 'using', you need
never close it.  At least, that's the case in C++.  I simply assumed
the same would be true of pp-namespaces.

But it would probably be more useful to be able to turn '#using'
namespaces on and off selectively.  I can see this would be useful
when defining prefixed macros and then #including existing headers.

> Do we have to use #endnamespace to do this?
> Or can we use #endusing ?

I would probably amend the proposal with another directive:

  #endusing <id>[::<id>]...

    Terminates implicit macro name matching using a specified
    pp-namespace prefix.  In other words, the given prefix is
    removed from the list of currently active pp-namespace prefixes
    that can be omitted in subsequent source code.

I would not use '#endnamespace' to accomplish this, because there are
two altogether different actions being done:

1. Defining macro names with [implicit] pp-namespace prefixes.
 This is accomplished with '#namespace' and '#endnamespace'.

2. Selecting a list of implicit pp-namespace prefixes that can be
 omitted in occurrences of macro names within program text.  (In
 particular, any #defines occuring within a '#using...#endusing'
 scope would not be affected by the scope.)
 This is accomplished with '#using' and '#endusing'.

>> [...]
>>     #endnamespace  // Foo

> I think it would be better to allow:
>
> #endnamespace Foo
>
> This would cause an error if the namespace being ended
> was NOT Foo.

This is probably a good idea.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ 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                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: 2000/10/23
Raw View
David R Tribble <david@tribble.com> writes:

| David R Tribble wrote:
| >> I'm considering proposing a namespace facility for the preprocessor.
| >> Essentially, macro names would be allowed to have 'name::' prefixes
| >> in order to make them unique.  Of course a big concern is to make
| >> all of this new machinery work with existing code.
| >>
| >> Essentially, I would add the following directives:
| >>
| >>   #namespace <id>[::<id>]...
| >>[...]
| >>   #endnamespace
| >>
| >>     Closes the currently active pp-namespace.
| >>
| >>   #using <id>[::<id>]...
| >>
| >>     Adds a pp-namespace prefix to the list of implied prefixes to
| >>     be considered when resolving macro names in subsequent source
| >>     code.  Essentially, this allow the use of macro names that have
| >>     been abbreviated by omitting one or more of their pp-namespace
| >>     prefixes.
| >>
| >>     Multiple pp-namespace #using directives may be active at the
| >>     same time.
|
| Dennis Yelle wrote:
| > Once we have a #using, how do we get rid of it?
|
| The same way you get rid of the effects of a 'using' directive in C++
| ;-)
|
| I modeled my pp-namespace proposal after the C++ namespace facility.
| I assumed that once you've opened a namespace with 'using', you need
| never close it.  At least, that's the case in C++.  I simply assumed
| the same would be true of pp-namespaces.

Well, in C++ you have the following construct which lets you emulate
the effect of closing a namespace:

 { // start a new block
  using namespace N;
  // ...
 }

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ 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                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: Mon, 30 Oct 2000 17:44:48 GMT
Raw View
David R Tribble <david@tribble.com> writes:

>I'm considering proposing a namespace facility for the preprocessor.
>Essentially, macro names would be allowed to have 'name::' prefixes
>in order to make them unique.
...
>  #using <id>[::<id>]...
>
>    Adds a pp-namespace prefix to the list of implied prefixes to
>    be considered when resolving macro names in subsequent source
>    code.  Essentially, this allow the use of macro names that have
>    been abbreviated by omitting one or more of their pp-namespace
>    prefixes.

Is this statically or dynamically scoped?
E.g. what would happen with something like this?

 int foo = 1;

 #namespace Foo
 #define foo 2
 #endnamespace Foo

 #namespace Bar
 #define foo 3
 #endnamespace Bar

 #namespace Baz
 #using Foo
 #define m1 foo
 #define m2(x) x
 #define concat(a,b) a##b
 #define m3 concat(f,oo)
 #end namespace Bar

 /* presumably we're not #using Foo anymore */

 #using Bar

 #include <stdio.h>
 int main() {
  printf("%d\n", foo);  // prints 3, I hope
  printf("%d\n", Bar::m1); // does this print 1 or 2?
  printf("%d\n", Bar::m2(foo)); // does this print 1, 2, or 3?
  printf("%d\n", Bar::m3); // does this print 1, 2, or 3?
 }

--
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3        |     -- the last words of T. S. Garp.

---
[ 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                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Bart" <bartkowalski@sympatico.ca>
Date: Sun, 15 Oct 2000 03:51:57 GMT
Raw View
In a recent thread on comp.lang.c++ the problem of macros conflicting with
other names was brought up. The C++ language has very good mechanisms for
reusing names, such as namespaces and overloading. However, macros that
conflict with existing names can very easily break code. When working with
legacy code or third party libraries, for example, it is sometimes difficult
to predict the effect of macros.

The standard [17.4.3.1.2] reserves certain names to the implementation,
apparently to prevent potential name conflicts. It seems odd, however, that
such an measure must be taken when so much effort has been put into allowing
name reuse. For this reason, I believe there should be a mechanism for
protecting code against accidents of this sort. Perhaps a #pragma directive
for disabling the preprocessor.

Any opinions?


Bart.

--
To reply by e-mail: bartkowalski at programmer dot net

---
[ 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                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: 2000/10/18
Raw View
Bart wrote [in news:comp.std.c++]:
> In a recent thread on comp.lang.c++ the problem of macros conflicting
> with other names was brought up. The C++ language has very good
> mechanisms for reusing names, such as namespaces and overloading.
> However, macros that conflict with existing names can very easily
> break code. When working with legacy code or third party libraries,
> for example, it is sometimes difficult to predict the effect of
> macros.
>
> The standard [17.4.3.1.2] reserves certain names to the
> implementation, apparently to prevent potential name conflicts. It
> seems odd, however, that such an measure must be taken when so much
> effort has been put into allowing name reuse. For this reason, I
> believe there should be a mechanism for
> protecting code against accidents of this sort. Perhaps a #pragma
> directive for disabling the preprocessor.
>
> Any opinions?

I'm considering proposing a namespace facility for the preprocessor.
Essentially, macro names would be allowed to have 'name::' prefixes
in order to make them unique.  Of course a big concern is to make
all of this new machinery work with existing code.

Essentially, I would add the following directives:

  #namespace <id>[::<id>]...

    Begins a new preprocessor namespace.  All #defined macro names
    have an implicit pp-namespace prefix.

    Macros defined outside of any pp-namespace have an implicit
    '::' prefix, also known as the global pp-namespace.

    pp-namespaces may be nested.  The name of a pp-namespace begun
    within another currently active pp-namespace is implicitly
    prepended with the name of the outer pp-namespace.

  #endnamespace

    Closes the currently active pp-namespace.

  #using <id>[::<id>]...

    Adds a pp-namespace prefix to the list of implied prefixes to
    be considered when resolving macro names in subsequent source
    code.  Essentially, this allow the use of macro names that have
    been abbreviated by omitting one or more of their pp-namespace
    prefixes.

    Multiple pp-namespace #using directives may be active at the
    same time.

Macro names would then be allowed to have pp-namespace prefixes.

An example of what I have in mind:

    #define BAD    0        // defines ::BAD

    #namespace Foo

    #define OKAY   0        // defines Foo::OKAY
    #define ERR    1        // defines Foo::ERR

    #namespace Buf
     #define SIZE   1024    // defines Foo::Buf::SIZE
    #endnamespace

    #endnamespace  // Foo

    int foo()
    {
        if (...)
            return Foo::OKAY;   // returns 0
        else
            return ::BAD;       // returns -1
    }

    #using Foo

    int bar(int n)
    {
        if (n < Buf::SIZE)      // uses Foo::Buf::SIZE, or 1024
            return BAD;         // returns ::BAD, or -1
        else
            return ERR;         // returns Foo::ERR, or 1
    }

In addition, the following pp-namespaces would be reserved for the
implmentation:

  std::   - reserved for the compiler and standard library
  STD::   - reserved for the compiler and standard library
  sys::   - reserved for the system and vendor library
  SYS::   - reserved for the system and vendor library

The main problem is drafting rules for resolving ambiguous macro
names within source code, which I haven't worked out fully yet.

There is also the problem of limiting the amount of look-ahead
required by the preprocessor for resolving (long) prefixed macro
names.  Perhaps simply requiring a minimum supported number of
pp-namespace prefixes (or, equivalently, a minimum number of
pp-namespace nesting levels) to, say, 64, is the answer.


This proposed facility provides the same capabilities as the
technique of using explicit unique prefixes on macro names, e.g.:

  #define Foo_OKAY  0

It goes beyond this simple technique, however, in allowing
abbreviated macro names (i.e., omitted prefixes and #using
directives).  This allows the facility to work with existing code.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com

---
[ 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                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Roger Orr <roger_orr@my-deja.com>
Date: 2000/10/19
Raw View
In article <39EDC992.8852C96C@tribble.com>,
  David R Tribble <david@tribble.com> wrote:
> I'm considering proposing a namespace facility for the preprocessor.

Dear David,
I'm interested in examples of where you consider this would be helpful
- I don't find I use macros much in C++ since it provides better
alternatives in many cases.
[Especially given the number of people who say 'macros are evil' :)  ]

Roger
--
MVP in C++ for Brainbench at http://www.brainbench.com


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Dennis Yelle <dennis51@jps.net>
Date: 2000/10/19
Raw View
David R Tribble wrote:
[...]
> I'm considering proposing a namespace facility for the preprocessor.
> Essentially, macro names would be allowed to have 'name::' prefixes
> in order to make them unique.  Of course a big concern is to make
> all of this new machinery work with existing code.
>
> Essentially, I would add the following directives:
>
>   #namespace <id>[::<id>]...
[...]
>   #endnamespace
>
>     Closes the currently active pp-namespace.
>
>   #using <id>[::<id>]...
>
>     Adds a pp-namespace prefix to the list of implied prefixes to
>     be considered when resolving macro names in subsequent source
>     code.  Essentially, this allow the use of macro names that have
>     been abbreviated by omitting one or more of their pp-namespace
>     prefixes.
>
>     Multiple pp-namespace #using directives may be active at the
>     same time.

Once we have a #using, how do we get rid of it?
Do we have to use #endnamespace to do this?
Or can we use #endusing ?
[...]

>     #endnamespace  // Foo

I think it would be better to allow:

#endnamespace Foo

This would cause an error if the namespace being ended
was NOT Foo.

Dennis Yelle
--
I am a computer programmer and I am looking for a job.
There is a link to my resume here:
http://table.jps.net/~vert/

---
[ 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                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]