March 27, 2017
On 3/26/2017 3:43 AM, Benjamin Thaut wrote:
> Should I open a bug for this?

It's not a bug, it was intended that way.

The trouble is that D cannot express a <const pointer> to <mutable>. Whichever way it is mangled will gore someone's ox. D went with the simplest mangling solution, which is to mangle all C++ const pointers as "head const".

The obvious solution is to implement "head const" in D, but that is a major change to the type system and the philosophy of D.

I suggest a simpler way - declare the C++ side of the D interface in a way that matches the way D mangles it. It's always been true that in order to interface D with C++ you'll need to be a bit flexible on the C++ side.
March 27, 2017
On 3/26/2017 3:29 PM, deadalnix wrote:
> Note that using const Class* in C++ is essentially useless. The class remains
> mutable and the reference is local the the callee anyway, so it doesn't change
> anything for the caller. Such a pattern is most likely indicative of a bug on
> the C++ side, or at least of code that do not do what the author intend to.

Ironically, because C++ const is not transitive, most programmers use const in C++ as if it was transitive. This is most evident in templates where:

   const T

is used.
March 27, 2017
On Monday, 27 March 2017 at 20:09:35 UTC, Walter Bright wrote:
> Whichever way it is mangled will gore someone's ox. D went with the simplest mangling solution, which is to mangle all C++ const pointers as "head const".
> [...]
> I suggest a simpler way - declare the C++ side of the D interface in a way that matches the way D mangles it. It's always been true that in order to interface D with C++ you'll need to be a bit flexible on the C++ side.

Unfortunately, it's almost always the other way around - D code trying to interop with one of the gazillions existing C++ libs, and nobody wants to maintain his own fork with D-compatible glue interfaces. How often did you use `const T *const` vs. `const T *` in your C++ headers? ;) I think this would be a tiny change for D, breaking almost no code and well worth the reduction in required 'flexibility on the C++ side'.
March 27, 2017
On Sunday, 26 March 2017 at 22:56:59 UTC, Jerry wrote:
> On Sunday, 26 March 2017 at 22:29:56 UTC, deadalnix wrote:
>> It is clear that you won't be able to express 100% of C++ in D, that would require to important all the weird parts of C++ into D, but if we are doing so, why use D in the first place ?
>>
>> Note that using const Class* in C++ is essentially useless. The class remains mutable and the reference is local the the callee anyway, so it doesn't change anything for the caller. Such a pattern is most likely indicative of a bug on the C++ side, or at least of code that do not do what the author intend to.
>
>
> For `const Class*` the Class is not mutable. It is the case of `Class* const` that Class is mutable.

You are correct. See my first post for an explanation of this specific case.

March 27, 2017
On 3/27/2017 1:41 PM, kinke wrote:
> Unfortunately, it's almost always the other way around - D code trying to
> interop with one of the gazillions existing C++ libs, and nobody wants to
> maintain his own fork with D-compatible glue interfaces. How often did you use
> `const T *const` vs. `const T *` in your C++ headers? ;) I think this would be a
> tiny change for D, breaking almost no code and well worth the reduction in
> required 'flexibility on the C++ side'.

It's made to work with:

   const T

which is the norm with C++ templates.

March 27, 2017
On Monday, 27 March 2017 at 22:04:55 UTC, Walter Bright wrote:
> On 3/27/2017 1:41 PM, kinke wrote:
>> Unfortunately, it's almost always the other way around - D code trying to
>> interop with one of the gazillions existing C++ libs, and nobody wants to
>> maintain his own fork with D-compatible glue interfaces. How often did you use
>> `const T *const` vs. `const T *` in your C++ headers? ;) I think this would be a
>> tiny change for D, breaking almost no code and well worth the reduction in
>> required 'flexibility on the C++ side'.
>
> It's made to work with:
>
>    const T
>
> which is the norm with C++ templates.

Okay, so how exactly do I bind D code to a C++ header-only-template library? I thought that in that case you need a full D translation anyway...
March 27, 2017
On 3/27/2017 3:12 PM, kinke wrote:
>> It's made to work with:
>>
>>    const T
>>
>> which is the norm with C++ templates.
>
> Okay, so how exactly do I bind D code to a C++ header-only-template library? I
> thought that in that case you need a full D translation anyway...

C++ templates are always header-only. I don't really understand your question.
March 27, 2017
On Monday, 27 March 2017 at 22:24:26 UTC, Walter Bright wrote:
> On 3/27/2017 3:12 PM, kinke wrote:
>>> It's made to work with:
>>>
>>>    const T
>>>
>>> which is the norm with C++ templates.
>>
>> Okay, so how exactly do I bind D code to a C++ header-only-template library? I
>> thought that in that case you need a full D translation anyway...
>
> C++ templates are always header-only. I don't really understand your question.

Yep, so there are no libs my D code can link to, so how am I supposed to use C++ templates from D (as you're using that as argument for the `const T *const` mangling)?
March 27, 2017
On 3/27/2017 3:30 PM, kinke wrote:
> On Monday, 27 March 2017 at 22:24:26 UTC, Walter Bright wrote:
>> On 3/27/2017 3:12 PM, kinke wrote:
>>>> It's made to work with:
>>>>
>>>>    const T
>>>>
>>>> which is the norm with C++ templates.
>>>
>>> Okay, so how exactly do I bind D code to a C++ header-only-template library? I
>>> thought that in that case you need a full D translation anyway...
>>
>> C++ templates are always header-only. I don't really understand your question.
>
> Yep, so there are no libs my D code can link to, so how am I supposed to use C++
> templates from D (as you're using that as argument for the `const T *const`
> mangling)?

There's still a miscommunication here, as header-only template libraries are not linked to.
March 27, 2017
On Monday, March 27, 2017 20:41:51 kinke via Digitalmars-d wrote:
> On Monday, 27 March 2017 at 20:09:35 UTC, Walter Bright wrote:
> > Whichever way it is mangled will gore someone's ox. D went with
> > the simplest mangling solution, which is to mangle all C++
> > const pointers as "head const".
> > [...]
> > I suggest a simpler way - declare the C++ side of the D
> > interface in a way that matches the way D mangles it. It's
> > always been true that in order to interface D with C++ you'll
> > need to be a bit flexible on the C++ side.
>
> Unfortunately, it's almost always the other way around - D code trying to interop with one of the gazillions existing C++ libs, and nobody wants to maintain his own fork with D-compatible glue interfaces. How often did you use `const T *const` vs. `const T *` in your C++ headers? ;) I think this would be a tiny change for D, breaking almost no code and well worth the reduction in required 'flexibility on the C++ side'.

Realistically, unless D fully supports C++ (which pretty much means that it has to become C++ on some level), you're almost always going to be stuck with some sort of glue layer between D code and C++ code. There's no reasonable way around that. We can work to improve the situation so that more C++ stuff just works when hooking up to D, but we'll never get all the way there, because that would mean dragging C++ into D, which we really don't want. There was talk at one point of trying to declare some sort of extern(C++) const that worked more like C++'s const, but even just that would be a huge mess and would further complicate the already overly complicated situation with const in D.

And for that matter, even though D is highly compatible with C code, you still have to worry about maintaining all of the bindings. So, even then, you're still basically dealing with a glue layer to maintain, even if it's just there to tell D about the symbols in C land rather than adding any real code.

Any time that D interacts with another language, _someone_ is going to have to maintain some sort of glue layer, even if it's a very thin layer, and to a great extent, I think that eliminating that layer is a pipe dream, though I do agree that improvements to make it thinner would certainly be nice (assuming that the cost isn't too high).

Now, as for this particular case with const, I really don't know what should be done. What's currently done _is_ the most correct, but it's also something that really isn't what would be done normally in C++ - at least not outside of templated code. Pointers to const are _very_ prevalent, but const pointers to const really aren't. But I'd also be worried about what quirks and problems we'd end up with if we tried to mangle extern(C++)'s const with semantics that didn't match D's semantics, even if in most cases, it wouldn't matter.

Also, in general, unless a C++ function was written to be called from D, I don't know how likely it is to work very well. It definitely _can_ work, but from what I've seen thus far, you tend to need to create C++ wrappers to interact with D code anyway, and if you do that, you just write the C++ functions with the correct constness, and it's no longer a problem.

- Jonathan M Davis