bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: gnulib and C++


From: John W. Eaton
Subject: Re: gnulib and C++
Date: Sat, 20 Feb 2010 09:26:19 -0500

On 20-Feb-2010, Bruno Haible wrote:

| And when I change the first line to
| 
| namespace system {
| #include <fcntl.h>
| }
| using namespace system;
| 
| then there is a different error message:
| 
| $ g++ -S foo.cc
| foo.cc: In function ‘int bar_uses_gnulib_implicitly()’:
| foo.cc:37: error: reference to ‘open’ is ambiguous
| foo.cc:12: error: candidates are: int (* const gnulib::open)(const char*, 
int, ...)
| /usr/include/fcntl.h:85: error:                 int system::open(const char*, 
int, ...)
| foo.cc:37: error: reference to ‘open’ is ambiguous
| foo.cc:12: error: candidates are: int (* const gnulib::open)(const char*, 
int, ...)
| /usr/include/fcntl.h:85: error:                 int system::open(const char*, 
int, ...)
| 
| Do you see a way to make it work?

Yesterday I was using a simplified example that I thought captured all
the necessary details, but I missed the original extern declaration of
the system function.

But how about the following example?  Does it have all the required
features?  It seems to work for me, but maybe I'm again missing
something.

It compiles and runs as I would expect with with GCC 3.3, 4.0, 4.1,
4.2, 4.3, and 4.4 with all the combinations of GNULIB_OPEN and
REPLACE_OPEN.

I renamed your "system" namespace to "gnulib_system_namespace" because
older versions of GCC (3.3 through 4.2) failed with

  bar.cc:3: error: 'namespace system { }' redeclared as different kind of symbol
  /usr/include/stdlib.h:666: error: previous declaration of 'int system(const 
char*)'
  bar.cc:38: error: 'system' is not a class or namespace

so I think the namespace that wraps the C/POSIX functions should
probably use a name that won't conflict.

jwe

#include <iostream>

namespace gnulib_system_namespace {
#include <fcntl.h>
}

extern "C" {
  extern int rpl_open (const char *filename, int flags, ...) __attribute__ 
((__nonnull__ (1)));
}

#define GNULIB_OPEN 1
#define REPLACE_OPEN 1

class foo
{
public:
  foo (void) { }
  void open (void) const;
};

#if GNULIB_OPEN
# if REPLACE_OPEN
#  ifndef __cplusplus
#   undef open
#   define open rpl_open
#  endif
# endif
#endif

#ifdef __cplusplus
namespace gnulib
{
  int (*const open) (const char *filename, int flags, ...) =
# if GNULIB_OPEN
#  if REPLACE_OPEN
    ::rpl_open;
#  else
    gnulib_system_namespace::open;
#  endif
# else
   gnulib_system_namespace::open;
# endif
}
using gnulib::open;
#endif

int
rpl_open (const char *filename, int flags, ...)
{
  std::cerr << "foo-i-hithere" << std::endl;
  return 42;
}

void
foo::open (void) const
{
  std::cerr << "foo::open" << std::endl;
}

int
main (void)
{
  int status = open ("/dev/null", O_RDWR);
  std::cerr << status << std::endl;
  foo x;
  x.open ();
  return 0;
}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]