Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Re: Including C Header in a namespace

Reply
Thread Tools

Re: Including C Header in a namespace

 
 
James Kanze
Guest
Posts: n/a
 
      05-29-2010
On May 28, 10:20 am, Markus Raab <(E-Mail Removed)> wrote:
> Victor Bazarov wrote:
> >> For struct, enum or typedefs there should be no problem at
> >> all, it should get a new name inside C++ and extern "C"
> >> should have no effect. Is this correct?


> > Any name that can have linkage will be affected.


> Is it possible that a struct or enum have linkage?


Formally, the answer is no. But I don't think this is what you
mean. Types, variables and functions don't have linkage; names
have linkage. And in C++, the name of a struct or an enum (or
any other type) can only have external linkage. That's one of
the reasons unnamed namespaces were introduced; so that you can
define a struct, enum or class that isn't accessible from
another translation unit.

This is one place where C and C++ differ.

> >> Did anyone ever put a C-Header file into a namespace?


> > Probably. It's very hard to prove a negative statement.


> >> Is this a good idea?


> > I don't think so. What would it accomplish?


> So that an existing C++ programs can have typedefs, enums and
> functions with the same names in the global namespace.


I'm not sure what the compiler is supposed to do with the names
introduced by typedef's or enums in an `extern "C"' namespace,
since they aren't visible in C. (A typedef isn't visible
outside the translation unit, period; a name defined by a
typedef declaration has internal linkage. But... a typedef is
nothing but an alias for a type, and the name of the type is
aliases has external linkage.)

> E.g. there is a program which has already a typedefs like:
> typedef struct InternalKey Key;
> or an enums like:
> enum {
> KEY_END=SDL_KEY_END,
> };


> And now I want to include a C-Header file which uses the same
> names (Key and KEY_END). My idea was to put this C-Header in a
> namespace to avoid such name-clashes.


Interesting idea. It should work, but I think it would be more
natural to do the reverse: put the C++ definitions in a
namespace.

Note that namespaces work as usual, and ignore linkage
specifications, during name lookup. However:

At most one function with a particular name can have C
language linkage. Two declarations for a function with C
language linkage with the same function name (ignoring
the namespace names that qualify it) that appear in
different namespace scopes refer to the same function.
Two declarations for an object with C language linkage
with the same name (ignoring the namespace names that
qualify it) that appear in different namespace scopes
refer to the same object.

In other words, given:

namespace A { extern "C" void f(); }

, the C++ compiler should treat the name of the function as
A::f. However, this A::f and a B::f declared identically in a
different translation unit refer to the same function.

> >> [..]

>
> >> Is there any difference between the next two lines?
> >> extern "C" { namespace yyy { }}
> >> namespace yyy { extern "C" { }}


> > The former looks wrong (although it probably isn't) <g>.
> > You need to keep in mind that 'extern "C"' removes the
> > namespace (yyy) in your case from the name. The namespaces
> > are *ignored* (see 7.5/6). I believe both are OK. The
> > names of anything inside the inner curly braces will *not*
> > have 'yyy::' as a part of it.


> Ohh, ok thank you. Does the standard says it is ignored in any
> case or only when there are problems at symbol level?


The standard says that it is not ignored at all. But that the
results might not be what you want.

Rather than trying to count the angels on the head of a pin in
the standard, wouldn't it be a better idea just to not do
either?

--
James Kanze
 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      05-29-2010
* James Kanze, on 29.05.2010 22:58:
> On May 28, 10:20 am, Markus Raab<(E-Mail Removed)> wrote:
>> Victor Bazarov wrote:
>>>> For struct, enum or typedefs there should be no problem at
>>>> all, it should get a new name inside C++ and extern "C"
>>>> should have no effect. Is this correct?

>
>>> Any name that can have linkage will be affected.

>
>> Is it possible that a struct or enum have linkage?

>
> Formally, the answer is no. But I don't think this is what you
> mean. Types, variables and functions don't have linkage; names
> have linkage. And in C++, the name of a struct or an enum (or
> any other type) can only have external linkage. That's one of
> the reasons unnamed namespaces were introduced; so that you can
> define a struct, enum or class that isn't accessible from
> another translation unit.
>
> This is one place where C and C++ differ.


Hm, I had to read the above 3 times. It's correct, but a hasty reading can yield
a false impression. So to summarize in clear-speech, in C++98 a struct type can
have external linkage or, if it is a local struct type (in a function), no
linkage. The latter can't be used as an actual template parameter since it
doesn't have linkage. As I recall this will be fixed in C++0x?


>>>> Did anyone ever put a C-Header file into a namespace?

>
>>> Probably. It's very hard to prove a negative statement.

>
>>>> Is this a good idea?

>
>>> I don't think so. What would it accomplish?

>
>> So that an existing C++ programs can have typedefs, enums and
>> functions with the same names in the global namespace.

>
> I'm not sure what the compiler is supposed to do with the names
> introduced by typedef's or enums in an `extern "C"' namespace,
> since they aren't visible in C. (A typedef isn't visible
> outside the translation unit, period; a name defined by a
> typedef declaration has internal linkage. But... a typedef is
> nothing but an alias for a type, and the name of the type is
> aliases has external linkage.)


It's a difficult thing to do. I once put a large part of <windows.h> in a
namespace 'win32', for code that did Windows security checking, handling ACLs
and doing impersonation and such, wrapped in an ActiveX control (i.e., it used a
pretty large part of the Windows API). It was fragile because Microsoft defines
a lot of things as macros, but the frequency of revisions of the wrapping
dropped to near zero as I coded away, so, it's doable. It was necessary to first
include all the standard headers that <windows.h> relies on. Happily it wasn't
more than 4 or 5, as I recall. I then got into a heated Usenet discussion with
the guy who introduced 'explicit' in the language. He maintained that what I did
was impossible...

Of course it broke a lot of language rules.

And I wouldn't do it today -- but although it was a braindead thing to do it
was a worthwhile exercise: I learned a lot (but most of it forgotten now).


[snip]


Cheers,

- Alf


--
blog at <url: http://alfps.wordpress.com>
 
Reply With Quote
 
 
 
 
Öö Tiib
Guest
Posts: n/a
 
      05-31-2010
On 31 mai, 21:21, Markus Raab <(E-Mail Removed)> wrote:
> James Kanze wrote:
> >> >> Is there any difference between the next two lines?
> >> >> extern "C" { namespace yyy { }}
> >> >> namespace yyy { extern "C" { }}

>
> >> > The former looks wrong (although it probably isn't) <g>.
> >> > You need to keep in mind that 'extern "C"' removes the
> >> > namespace (yyy) in your case from the name. *The namespaces
> >> > are *ignored* (see 7.5/6). *I believe both are OK. *The
> >> > names of anything inside the inner curly braces will *not*
> >> > have 'yyy::' as a part of it.

>
> >> Ohh, ok thank you. Does the standard says it is ignored in any
> >> case or only when there are problems at symbol level?

>
> > The standard says that it is not ignored at all. *But that the
> > results might not be what you want.

>
> > Rather than trying to count the angels on the head of a pin in
> > the standard, wouldn't it be a better idea just to not do
> > either?

>
> I would also be interested if the approach actually works in the major
> compilers. If it is not a good idea I will discard it. Maybe someone has
> another idea?


What about the "usual" idea to use prefixes in C names instead of
trying to use namespaces that C does not have?

IOW in C++ code write:

extern "C" { void yyy_f(); }

Instead of:

namespace yyy { extern "C" { void f(); }}
 
Reply With Quote
 
Öö Tiib
Guest
Posts: n/a
 
      06-01-2010
On Jun 1, 10:24*am, Markus Raab <(E-Mail Removed)> wrote:
> Öö Tiib wrote:
> > What about the "usual" idea to use prefixes in C names instead of
> > trying to use namespaces that C does not have?

>
> > IOW in C++ code write:

>
> > extern "C" { void yyy_f(); }

>
> > Instead of:

>
> > namespace yyy { extern "C" { void f(); }}

>
> They are already prefixed, but in some cases there could be still name
> clashes, e.g. KEY_END (KEY_ is the prefix).
>
> And of course there is lots of existing code already using the names as they
> are...


Yes. In C you can not have overloads. Namespaces do not help since
these are not part of C interface. 'extern "C"' means that what you
declare is C interface (so no namespaces apply).

The problem is that if you have different libraries where extern C
function names clash then you can not link them directly together and
expect that it works. You have to either rename the clashing functions
(add more prefixes) or enwrap them (i explain briefly) or avoid using
them in same program.

Enwrapping can be done for example with shared library module that
links with one bad library (with clashing names) but does not export
the clashing names. Then rest of the program links with that shared
library and not with the original bad library.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Including C Header in a namespace tan C++ 2 05-28-2010 06:45 PM
Re: Including C Header in a namespace Victor Bazarov C++ 0 05-28-2010 12:16 PM
Header files with "header.h" or <header.h> ?? mlt C++ 2 01-31-2009 02:54 PM
Including element from one schema namespace in another schema namespace mflll@wiu.edu XML 1 07-20-2006 06:48 AM
[XML Schema] Including a schema document with absent target namespace to a schema with specified target namespace Stanimir Stamenkov XML 3 04-25-2005 09:59 AM



Advertisments