[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: gnulib and C++
From: |
Bruno Haible |
Subject: |
Re: gnulib and C++ |
Date: |
Thu, 18 Feb 2010 23:57:15 +0100 |
User-agent: |
KMail/1.9.9 |
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
Re: gnulib and C++,
Bruno Haible <=
Re: gnulib and C++, Bruno Haible, 2010/02/19
Re: gnulib and C++, Ralf Wildenhues, 2010/02/20