On 3 January 2016 at 18:03, Walter Bright via Digitalmars-d <digitalmars-d@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*>>