Hi John, Ralf proposes: > I suggest you could > produce a helper header to #undef them again; you could even do that > automatically during bootstrap with above. Then only a portability > layer would need to avoid using these symbols in another namespace.
This would only be a makeshift. Your example > class foo > { > public: > ... > int open (some, args); > ... > }; > int foo::open (some, args) { ... } clearly indicates that in C++, one should minimize the use of preprocessor defines for lowercase identifiers. C++ has its own, idiosyncratic, ways of aliasing and overriding functions. If we were to change gnulib's fcntl.h like this: *** lib/fcntl.in.h.orig Thu Feb 18 23:44:21 2010 --- lib/fcntl.in.h Thu Feb 18 23:31:02 2010 *************** *** 79,87 **** #if @GNULIB_OPEN@ # if @REPLACE_OPEN@ ! # undef open ! # define open rpl_open ! extern int open (const char *filename, int flags, ...) _GL_ARG_NONNULL ((1)); # endif #elif defined GNULIB_POSIXCHECK # undef open --- 79,89 ---- #if @GNULIB_OPEN@ # if @REPLACE_OPEN@ ! # ifndef __cplusplus ! # undef open ! # define open rpl_open ! # endif ! extern int rpl_open (const char *filename, int flags, ...) _GL_ARG_NONNULL ((1)); # endif #elif defined GNULIB_POSIXCHECK # undef open *************** *** 111,116 **** --- 113,132 ---- } #endif + #ifdef __cplusplus + namespace gnulib + { + # if @GNULIB_OPEN@ + int (*const open) (const char *filename, int flags, ...) = + # if @REPLACE_OPEN@ + rpl_open; + # else + open; + # endif + # endif + } + #endif + /* Fix up the FD_* macros, only known to be missing on mingw. */ #ifndef FD_CLOEXEC Then you can use the identifier 'gnulib::open' on any platform. On platforms where REPLACE_OPEN = 1, calls to 'gnulib::open' will be automatically inlined to calls to 'rpl_open', on the other platforms to calls to the C function 'open'. Here are some code that compiles fine with this modified gnulib fcntl.h: // A class 'foo' can have a member 'open' without any problem. class foo { int open (const char *arg); }; // This function invokes the global C function 'open'. int bar_uses_global () { return open ("/dev/null", O_RDWR); } // Does not work, leads to // error: reference to ‘open’ is ambiguous // /usr/include/fcntl.h:85: error: candidates are: int open(const char*, int, ...) // foo.cc:9: error: int (* const gnulib::open)(const char*, int, ...) //using namespace gnulib; // This function invokes the global C function 'rpl_open' or 'open', depending on platform. int bar_uses_gnulib () { return gnulib::open ("/dev/null", O_RDWR); } Additionally, there is some talk about a future standard namespace called 'posix'. [1][2] You can already forward-adapt your code by using posix:: in place of gnulib:: // Compatibility with future C++1X: namespace posix = gnulib; int bar_uses_gnulib_via_posix () { return posix::open ("/dev/null", O_RDWR); } Bruno [1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2667.htm [2] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2733.html