how to include a c struct in C++ namespace

E

ethan.liuyi

Hi,

I am trying to wrap c functions with some exception handling, for
example, wrap the socket bind in A::Bind

a.h
namespace A {
int Bind(int fd, struct sockaddr *addr, socklen_t addrlen) throw
(inet_error);
}

a.cc
namespace A {
int Bind(int fd, struct sockaddr *addr, socklen_t addrlen) throw
(inet_error) {
/* if error, throw; otherwise return; */
}
}

The problem is this generates link error,
error: reference to ‘sockaddr’ is ambiguous....

it seems the compiler think I define a new struct, with the same name
"sockaddr" in name space A, I tr
ied to remove the struct keyword, and it wouldn't compile.

in A, I have to reference to the global C struct, sockaddr etc.
in main(), I have to use those global C structs together with
functions I defined in A.

I am a bit confused here, I didn't define any new struct in A.

so I guess my question is, is there a simple and clean way to use a C
struct within a user defined namespace in C++?
 
V

Victor Bazarov

Hi,

I am trying to wrap c functions with some exception handling, for
example, wrap the socket bind in A::Bind

a.h
namespace A {
int Bind(int fd, struct sockaddr *addr, socklen_t addrlen) throw
(inet_error);
}

a.cc
namespace A {
int Bind(int fd, struct sockaddr *addr, socklen_t addrlen) throw
(inet_error) {
/* if error, throw; otherwise return; */
}
}

The problem is this generates link error,
error: reference to ‘sockaddr’ is ambiguous....

it seems the compiler think I define a new struct, with the same name
"sockaddr" in name space A, I tr
ied to remove the struct keyword, and it wouldn't compile.

in A, I have to reference to the global C struct, sockaddr etc.
in main(), I have to use those global C structs together with
functions I defined in A.

I am a bit confused here, I didn't define any new struct in A.

so I guess my question is, is there a simple and clean way to use a C
struct within a user defined namespace in C++?

You can always qualify the type-id from outside of the namespace:

namespace A {
int Bind(int, ::sockaddr*, ::socklen_t) throw(ine_error);
}

That should disambiguate the names of the types.

V
 
J

James Kanze

I am trying to wrap c functions with some exception handling,
for example, wrap the socket bind in A::Bind
a.h
namespace A {
int Bind(int fd, struct sockaddr *addr, socklen_t addrlen) throw
(inet_error);
}
a.cc
namespace A {
int Bind(int fd, struct sockaddr *addr, socklen_t addrlen) throw
(inet_error) {
/* if error, throw; otherwise return; */
}
}

The problem is this generates link error,
error: reference to \u2018sockaddr\u2019 is ambiguous....
it seems the compiler think I define a new struct, with the
same name "sockaddr" in name space A, I tried to remove the
struct keyword, and it wouldn't compile.

Did you include the header which defines sockaddr (sys/socket.h
under Unix)? If not, without the struct, the compiler doesn't
know what it is, and with the struct, you're declaring a new
struct in the function declaration---the struct itself is in
namespace A, but the scope (and thus the visibility) is just the
declaration, so when you provide the definition (a second
declaration), there is a conflict: because sockaddr isn't in
scope, the compiler can't see it, and so it must be a
declaration of a new type, but when the compiler goes to insert
this new type in namespace A, it finds that there is already a
type with the same name.
in A, I have to reference to the global C struct, sockaddr etc.
in main(), I have to use those global C structs together with
functions I defined in A.
I am a bit confused here, I didn't define any new struct in A.

If you didn't include the necessary headers, you did.
so I guess my question is, is there a simple and clean way to
use a C struct within a user defined namespace in C++?

Well, since it is C, it's never really clean:). But I have no
problems in my code, provided I've included the correct headers.

If you've included <sys/socket.h> before any use of sockaddr,
and are still having problems, please post a complete example of
what you're feeding the compiler.
 
E

ethan.liuyi

You can always qualify the type-id from outside of the namespace:

    namespace A {
       int Bind(int, ::sockaddr*, ::socklen_t) throw(ine_error);
    }

That should disambiguate the names of the types.

V

hi, thank you very much for the reply. at one moment, I thought I was
enlightened,

the program compiled and linked well using gcc 4.3.2 on Fedora 10. in
the main file, I just say "using namespace A", then I can use my
wrapper function without causing any ambiguity on those C structs.

but today I tried to compile in cygwin gcc 3.4.4
it complained about this line: (enclosed in namespace A, as above)

int Connect(int sockfd, const ::sockaddr_in *serv_addr, socklen_t len)
throw (inet_error);

"error: expected unqualified-id before * token".

now I am confused again. isn't this supposed to be a valid syntax/
semantic rule of C++?
 
V

Victor Bazarov

hi, thank you very much for the reply. at one moment, I thought I was
enlightened,

the program compiled and linked well using gcc 4.3.2 on Fedora 10. in
the main file, I just say "using namespace A", then I can use my
wrapper function without causing any ambiguity on those C structs.

but today I tried to compile in cygwin gcc 3.4.4
it complained about this line: (enclosed in namespace A, as above)

int Connect(int sockfd, const ::sockaddr_in *serv_addr, socklen_t len)
throw (inet_error);

"error: expected unqualified-id before * token".

now I am confused again. isn't this supposed to be a valid syntax/
semantic rule of C++?

Uh... Do you think it might be worth your while to upgrade the compiler
to something more recent? Without seeing all the sources (and I don't
want to encourage you to post them, I'm not going to try compiling them)
it's kind of hard to tell you exactly what else might be contributing to
the error. Did you remember to include the definition of 'sockaddr_in'
struct? AFAICT, the following should compile except for the line in the
'main':

struct S1 {};
namespace A { struct S1 {}; }

using namespace A;

void foo(const ::S1 * ptr);

int main() {
A::S1 a;
foo(&a); // error here, not above
}

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top