extern(C++, ns)

Walter Bright via Digitalmars-d digitalmars-d at puremagic.com
Sun Jan 3 08:18:13 PST 2016


On 1/3/2016 3:25 AM, Manu via Digitalmars-d wrote:
> On 3 January 2016 at 18:03, Walter Bright via Digitalmars-d
> <digitalmars-d at puremagic.com> wrote:
>>
>> C++ doesn't have a module structure,
>
> It's called the filesystem ;) .. People use folders and filenames to
> describe what would be 'modules' in C, if C was said to have modules.
> Sometimes they make namespaces that match the filesystem ;)

I know how C++ name scoping works, after all, I implemented a C++ compiler. C++ 
doesn't have modules, and doesn't even have a semantic notion of files. You can 
pretend it has them, but when you talk about "edge cases not working", they 
aren't going to work in spades here.


>> and the way you propose cannot work in
>> D, since D does not have a global scope. If I implemented your method, the
>> first bug report from you will be:
>>
>>      ---
>>      int x;
>>      extern (C++, ns) { char x; }
>>      ---
>>      error: multiple definition of x
>
> This!!! You're on to it!!
> That's exactly what I want; I ***REALLLY*** want the compiler to emit
> that error message in that exact situation!
> Please, please can we have that? :)

No. If D is to support C++ namespaces, it has to support declaring the same 
identifier for different purposes in different namespaces. C++ namespaces have 
different scopes in C++. Doing anything else would make it impossible to connect 
to perfectly legitimate C++ programs. The WHOLE POINT of C++ namespaces is to 
support declaring the same identifier in different namespaces.


> This would solve a lot of awkward issues.

It'd be a river of bug reports, because sure as shootin', people are going to 
try to interface to this C++ code:

   namespace ns1 { int identifier; }
   namespace ns2 { int identifier; }

And why shouldn't they? It's correct and legitimate C++ code.


> Oh yeah, I just remembered another great case, I had this in C++:
>    namespace delegate {}
> 'delegate' is not a valid identifier in D, I was going to come in here
> and bang the drum again, and also suggest that the namespace needs to
> be a string, ie extern(C++, "delegate")
> D takes a lot more names from the namespace than C++ does.
>
> The user has _no control_ over what they name the C++ namespace; by
> definition, it already exists. It's for binding purposes. It might not
> even be a name that's a valid D identifier.
> It's just for mangling.

Please file an enhancement request for that. Though you can probably make it 
work by writing a C++ wrapper for it.


> But this is it, please help me get this C++ binding working.

The 2 bugzilla issues filed already are enough to make progress with. You 
needn't do anything more on this at the moment.


> One involves more complex inheritence; we have typical C++
> 'interfaces', ie, classes populated only with abstract virtuals, and
> multiple inheritence of those. Does extern(C++) currently support
> inheriting multiple interfaces?

Only if they have no fields, i.e. they mirror COM inheritance.

> I also expect I'll need a way to express a class instance. I noticed that in:
>
> extern(C++)
> {
>    class C {}
>    struct S(T) {}
> }
> S!C x;
>
> I noticed in one case like this that 'x' seemed to mangle as C++
> S<C*>, where the '*' in the mangled name seems to be implicit in D
> (presumably because D's classes are always references?).
> If that is indeed the case, we'll need a way to express a symbol name
> that is just the instance 'C', not 'C*'. But these will be advanced
> problems, with possible work-arounds when basic problems are solved.

D doesn't support "Shimmer" aggregates ("Is it a floor wax or a dessert 
topping?") You may need to write C++ wrappers for the problematic C++ types, and 
then interface to the wrappers.


More information about the Digitalmars-d mailing list