extern(C++, ns)
Manu via Digitalmars-d
digitalmars-d at puremagic.com
Sun Jan 3 03:25:37 PST 2016
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 ;)
> 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? :)
> You'll say "but it is in a different namespace, so I should be able to
> declare another x!" and you would be right.
No. No I wouldn't!
They're both symbols with the same name in the same scope! extern(C++)
means nothing, it should just change how it mangles.
Let the D module system handle symbol lookup as usual.
I want the error message you said above.
> It will also be impossible to
> connect to C++ code that defines the same identifier in different
> namespaces.
...put it in a different module? Just like any normal D code.
---- ns1.cpp ----
namespace ns1 {
int identifier;
}
---- ns2.cpp ----
namespace ns2 {
int identifier;
}
---- ns1.d ----
module ns1;
extern(C++, ns1) int identifier;
---- ns2.d ----
module ns2;
extern(C++, ns2) int identifier;
It's beautiful!
This would solve a lot of awkward issues.
Also consider that my top level package has the same name as the C++
namespace. That's really awkward, and I also anticipate this would be
the common case (why would the qt package be called anything other
than 'qt'? sadly, this matches the C++ namespace)
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.
>> There was a binary decision made; as far as I know, the decision was made
>> on a
>> whim, there was no design committee, a decision was simply chosen.
>> I know of no argument that demonstrates that the current state is correct,
>> but I
>> have months of wasted time and energy that prove that it's wrong. Why do I
>> need
>> to now take even more time to construct an elaborate suite of examples to
>> demonstrate my argument?
>
>
> Producing cases that fail should have been a byproduct of the production of
> code that failed. In any case, without examples that illustrate the
> problem(s) you're having, I cannot help.
It's I can't reasonably zip the project and email it 100 times a day.
I'd need to involve management the moment I wanted to do that.
These problems emerge in non-trivial situations.
>> I can't get work done. I've spent all the free time I have trying, and I'd
>> rather write code than spend my time reducing test cases.
>> Try and bind to a reasonably complex C++ project and you will discover the
>> same
>> thing... or don't, I've honestly already done that work for you!
>
>
> I appreciate that you've done the work for me, but I'd have to start over
> from scratch because you don't provide examples that don't work, and I'd
> have to guess what you were trying to do, which never works out very well.
I don't own the code I write >_<
This is an eternal problem of mine. This project is 30 files, almost
all of them have extern(C++) in them, and they interact...
It's extremely difficult and time consuming to reduce.
I suspect the forward referencing issues may be flagging false
positives when I'm debugging, that should be first.
But this namespace thing is the cause of problems at scale.
>> Please don't make me waste endlessly more of my time, I don't have energy
>> left
>> to spare. This is precisely what's driving me away from D. I can't take it
>> anymore, everything hits brick walls, I am so frustrated, I just want to
>> have a
>> **SINGLE** win, where I can complete a single real-world project and say I
>> have
>> written something that works!
>
>
> I hope that you'll come here and ask for help before you've expended endless
> hours beating your head :-(
This isn't the first time I've had this rant ;)
But this is it, please help me get this C++ binding working.
I already anticipate a new class of error emerging as soon as I can
reach a state where foundational stuff isn't causing me grief...
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?
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.
I was pondering a solution for class instances like:
struct ByVal(C) if(is(C == class))
{
alias get this;
// magic to stitch up constructors and stuff
private:
void[__traits(classInstanceSize, C)] instance;
@property C get() { return cast(C)instance.ptr; }
}
Something like that would express C++ style class aggregation... Is
there something like that in the std library? If so, it should be
special-cased so that extern(C++) will mangle it as C rather than the
usual C*.
S!(ByVal!C) x; // -> S<C>, instead of S<ByVal<C*>>
More information about the Digitalmars-d
mailing list