Re: const(Class) is mangled as Class const* const

2017-03-28 Thread Walter Bright via Digitalmars-d

On 3/28/2017 11:12 AM, Jacob Carlborg wrote:

As far as I understand, D can link with C++ templates if they're instantiated on
the C++ side. It would link with the instantiated template not the actual 
template.


Recall that dmd itself connected to C++ templates when the front end was not 
full in D.




Re: const(Class) is mangled as Class const* const

2017-03-28 Thread Jacob Carlborg via Digitalmars-d

On 2017-03-28 00:30, kinke wrote:


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)?


As far as I understand, D can link with C++ templates if they're 
instantiated on the C++ side. It would link with the instantiated 
template not the actual template.


--
/Jacob Carlborg


Re: const(Class) is mangled as Class const* const

2017-03-28 Thread kinke via Digitalmars-d

On Tuesday, 28 March 2017 at 14:11:16 UTC, deadalnix wrote:
I understand you point and showed you why it isn't a mangling 
problem at all, and gave you direction you may want to dig in 
to make a proposal that may

actually get traction.

If you really did get my point, it should be clear that I don't 
see a necessity for differentiating between `const T` and 
`const(T)` on the D side in general, transitive const hasn't been 
an issue for my D/C++ interop use cases yet, but the 
const(Object) issue the OP arises would definitely be a show 
stopper at some point and, unlike a more general solution, can be 
trivially remedied.


Re: const(Class) is mangled as Class const* const

2017-03-28 Thread deadalnix via Digitalmars-d

On Tuesday, 28 March 2017 at 13:18:57 UTC, kinke wrote:
You don't seem to get my point, I don't know why it's 
apparently that hard.


It's hard because you assume I did not understood you point and 
you keep repeating the same thing. I understand you point and 
showed you why it isn't a mangling problem at all, and gave you 
direction you may want to dig in to make a proposal that may 
actually get traction.


But you can chose to entrench yourself in a position were nobody 
understands your genius. You won't get any result, but depending 
on your personality, it may make you feel good, which is already 
something.




Re: const(Class) is mangled as Class const* const

2017-03-28 Thread kinke via Digitalmars-d

On Tuesday, 28 March 2017 at 12:55:02 UTC, deadalnix wrote:

On Tuesday, 28 March 2017 at 08:30:43 UTC, kinke wrote:
What I don't get is why it's considered important to have a 
matching C++ mangling for templates across D and C++ - what 
for? I only care about mangling wrt.


If you still think this is a mangling problem, please reread my 
first response in this thread.


You don't seem to get my point, I don't know why it's apparently 
that hard. I don't want to be able to express both `const T* 
const` AND `const T*` in C++, I only want D's const(Object) 
mangling to express solely the former instead of the latter, as 
there's no use for the double-const, except maybe for templates 
as Walter pointed out, but there's no template interop between D 
and C++ anyway.


I absolutely don't care that it's inconsistent to what a D 
const(Object) reference actually is (both pointer and class 
const) when passing such a thing BY VALUE to C++. As I said, 
there's no C++ analogon for D object references, so why not have 
it be a special case in the C++ mangler...


Re: const(Class) is mangled as Class const* const

2017-03-28 Thread deadalnix via Digitalmars-d

On Tuesday, 28 March 2017 at 08:30:43 UTC, kinke wrote:
What I don't get is why it's considered important to have a 
matching C++ mangling for templates across D and C++ - what 
for? I only care about mangling wrt.


If you still think this is a mangling problem, please reread my 
first response in this thread.


Re: const(Class) is mangled as Class const* const

2017-03-28 Thread kinke via Digitalmars-d

On Tuesday, 28 March 2017 at 02:14:25 UTC, Jonathan M Davis wrote:
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.


I know that. I'm just arguing for this tiny change in 
C++-mangling of D const object references as a remedy for this 
one particular issue out of many wrt. C++ interop.


What I don't get is why it's considered important to have a 
matching C++ mangling for templates across D and C++ - what for? 
I only care about mangling wrt. interop if I wanna link to some 
foreign code, and with templates I can't, so I see absolutely no 
problem with a D template `extern (C++) void foo()(const(Object) 
arg)` being mangled slightly differently (arg as `const Object*`) 
than a C++ template `template  void foo(const T arg)` 
with `T = const Object*` (arg as `const Object* const`).


Don't get me wrong, I don't advocate C++-mangling a D `const(S*)` 
for some struct S as `const S*` at all - we're talking 
specifically about D class references here, which don't have a 
direct C++ analogon, so choosing to C++-mangle them in a special 
way sounds absolutely feasible to me.





Re: const(Class) is mangled as Class const* const

2017-03-27 Thread Jonathan M Davis via Digitalmars-d
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



Re: const(Class) is mangled as Class const* const

2017-03-27 Thread Walter Bright via Digitalmars-d

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.


Re: const(Class) is mangled as Class const* const

2017-03-27 Thread kinke via Digitalmars-d

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)?


Re: const(Class) is mangled as Class const* const

2017-03-27 Thread Walter Bright via Digitalmars-d

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.


Re: const(Class) is mangled as Class const* const

2017-03-27 Thread kinke via Digitalmars-d

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...


Re: const(Class) is mangled as Class const* const

2017-03-27 Thread Walter Bright via Digitalmars-d

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.



Re: const(Class) is mangled as Class const* const

2017-03-27 Thread deadalnix via Digitalmars-d

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.




Re: const(Class) is mangled as Class const* const

2017-03-27 Thread kinke via Digitalmars-d

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'.


Re: const(Class) is mangled as Class const* const

2017-03-27 Thread Walter Bright via Digitalmars-d

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.


Re: const(Class) is mangled as Class const* const

2017-03-27 Thread Walter Bright via Digitalmars-d

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  to . 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.


Re: const(Class) is mangled as Class const* const

2017-03-27 Thread kinke via Digitalmars-d

On Sunday, 26 March 2017 at 17:41:57 UTC, Benjamin Thaut wrote:
There are thousands of C++ libraries out there that can't be 
bound to D because they use const Class* instead of const 
Class* const. So in my eyes there is definitly something wrong 
with the C++ mangling of D.


I agree that C++-mangling a const D object reference as `const T 
*const` isn't helpful although it would be consistent with D 
semantics. As deadalnix pointed out, the const for the pointer 
itself only concerns the callee and not the caller. I sometimes 
use `void foo(const T *bla); ... void foo(const T *const bla) { 
... }` if I find it useful to make clear that `bla` won't change 
in my foo() implementation, but I never use the second const in 
the function declaration in the header as it's just useless 
clutter for the caller.


Having said that, you can only declare a C++ type as D class if 
it's exclusively passed and returned as pointer (at least in the 
parts you are going to interface with via D). This was true for 
the C++-based DMD front-end and would also be true for some types 
used in LLVM. But as soon as you want to interface with a C++ 
function taking an object as `[const] T&`, afaik you're f*cked 
and need to declare it as D struct. So I'm quite skeptical that 
I'll often be able to use D classes to represent C++ types.


Re: const(Class) is mangled as Class const* const

2017-03-26 Thread Jonathan M Davis via Digitalmars-d
On Sunday, March 26, 2017 18:31:52 Jerry via Digitalmars-d wrote:
> On Sunday, 26 March 2017 at 15:29:02 UTC, Jonathan M Davis wrote:
> > Personally, I don't think that the fact that you can't use
> > const for head-const in D is really a loss, since it's almost
> > never what you want. Tail-const is _way_ more useful. But it is
> > true that by making D's const fully transitive, there are
> > variations of constness that C++ can do that D can't. immutable
> > pretty much forces that though, and it does simplify the
> > language.
>
> There are quite a few things wrong with const, it's so bad phobos
> isn't even const-correct when it should be. In cmp() for example,
> if you pass a lambda that takes the parameters by reference. You
> will be modifying temporary values that cmp() created on the
> stack. These should be const, but then what if it is a pointer?
> It is a different situation and you don't really want const cause
> you are going to be modifying the correct struct (the one pointed
> to). It is just easier to not use const in D cause it makes your
> code more difficult to actually use. That's exactly what Phobos
> does, it ignores const for the most part because it is easier not
> to use it.

There are significant pros and cons when comparing C++ and D's const, but
they usually relate to the ability to get around const in C++ and the lack
of ability to do so in D. The ability to create a const pointer to a mutable
element is occasionally something that someone wants to do, but in my
experience, it's pretty useless. I'm not sure that I've ever used it in C++
(and I've programmed professinally primarily in C++), and when I was
learning Java and found out that that's what Java's final did, I decided
that all it was good for was constants of built-in types, and I think that
that's mostly what I've seen other folks do with it. Having a
pointer/reference that can't change while what it points to can just isn't
very useful. It's having a mutable pointer to const that's useful.

Now, as for const in D in general and how it compares to C++, that's a
rather difficult question and highly debatable (and it's been debated here
on many occasions). C++'s const is little more than documentation. It
prevents accidental mutation, but there are so many ways around it that it's
borderline meaningless. It only works as well as it does, because it's a
convention that programmers _usually_ hold to. But it gurantees almost
nothing. For instance, it's perfectly possible to have a class where all of
its members are const but where all of them mutate the state of the object.
The fact that that doesn't normally happen is simply because fortunately,
programmers normally choose to behave themselves with mutable and casting
away const. But they don't have to, and the compiler doesn't enforce it.

D's const, on the other hand, has strong guarantees about something that's
const never being mutated unless something elsewhere in the code has access
to a mutable reference and changes the data that way. The const reference is
never able to change the data without violating the type system. So, D's
const actually means something. It provides real guarantees. But the reality
of the matter is that that's so restrictive that pretty quickly you simply
can't use const. There are too many idioms that require backdoors to const -
mutexes, memory management, lazy initializaiton, etc.

So, the end result is that in C++, you don't have much in the way of
guarantees, but you're able to use what you do have all over the place.
Accidental mutation is prevented and programmer intention is conveyed, but
not much of anything is really guaranteed. Whereas with D, you have the
strong guarantees, and you can use const in certain circumstances, but
you're quickly forced to use it in only very restricted circumstances -
especially if user-defined types or templates are involved. Too much simply
doesn't work with true const. What most code really needs is logical const,
and the compiler can't guarantee that.

As to whether C++ or D did a better job with const, I really don't know. I
find C++'s const to be pretty terrible from the standpoint of what it really
protects, and I only recall one time in my entire programming career that
it's actually caught a bug for me, but it's still nice to be able to
indicate that a function doesn't mutate its arguments, even if it's not
actually guaranteed, since it's usually true. The fact that D's const
provides the stronger guarantees is fantastic, but it's also so restrictive
that it borders on useless. So, ultimately, I'm not very happy with either
solution, and I don't know what the best one would be.

Arguably, immutable is what's truly useful - though obviously, code has to
be written with it in mind, because a lot of code won't work with it without
that - but for it to do its job, D's const pretty much has to be the way it
is. Even if we wanted C++'s const in D, we couldn't have it unless it didn't
interoperate 

Re: const(Class) is mangled as Class const* const

2017-03-26 Thread Jerry via Digitalmars-d

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. I see a lot of people in D 
say similar things about it. Saying it is a bug, saying it's a 
good thing that a const pointer with mutable type isn't in D. Yet 
they always tend to be the people that have never actually used 
C++. As is indicative of not even knowing the correct syntax to 
use in C++. A common matter in C++ is to use templates, you may 
have seen it, it's a really common pattern, `const T&`. The magic 
that makes this work is that you read it like this: `T const &`. 
They both mean the samething but I find makes more sense, 
conceptually to read it like that. Now substitute a type for T, 
`int* const &`. You see here that int is mutable for this 
template. You can see my other post about cmp(), and how Phobos 
avoids usages of const as it just makes writing generic code 
difficult.


Re: const(Class) is mangled as Class const* const

2017-03-26 Thread deadalnix via Digitalmars-d

On Sunday, 26 March 2017 at 17:41:57 UTC, Benjamin Thaut wrote:

On Sunday, 26 March 2017 at 14:30:00 UTC, deadalnix wrote:


It's consistent. D's const is transitive, and D doesn't allow 
you to specify const on the indirection of a reference type. 
So there is no problem on the C++ mangling side of things, 
but, arguably, there is one in D's sementic, that isn't new.


I disagree. When binding C++ code to D I don't care about D's 
const rules. I care about the C++ const rules. There are 
thousands of C++ libraries out there that can't be bound to D 
because they use const Class* instead of const Class* const. So 
in my eyes there is definitly something wrong with the C++ 
mangling of D.


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.


Re: const(Class) is mangled as Class const* const

2017-03-26 Thread Jerry via Digitalmars-d

On Sunday, 26 March 2017 at 15:29:02 UTC, Jonathan M Davis wrote:
Personally, I don't think that the fact that you can't use 
const for head-const in D is really a loss, since it's almost 
never what you want. Tail-const is _way_ more useful. But it is 
true that by making D's const fully transitive, there are 
variations of constness that C++ can do that D can't. immutable 
pretty much forces that though, and it does simplify the 
language.



There are quite a few things wrong with const, it's so bad phobos 
isn't even const-correct when it should be. In cmp() for example, 
if you pass a lambda that takes the parameters by reference. You 
will be modifying temporary values that cmp() created on the 
stack. These should be const, but then what if it is a pointer? 
It is a different situation and you don't really want const cause 
you are going to be modifying the correct struct (the one pointed 
to). It is just easier to not use const in D cause it makes your 
code more difficult to actually use. That's exactly what Phobos 
does, it ignores const for the most part because it is easier not 
to use it.




Re: const(Class) is mangled as Class const* const

2017-03-26 Thread Benjamin Thaut via Digitalmars-d

On Sunday, 26 March 2017 at 14:30:00 UTC, deadalnix wrote:


It's consistent. D's const is transitive, and D doesn't allow 
you to specify const on the indirection of a reference type. So 
there is no problem on the C++ mangling side of things, but, 
arguably, there is one in D's sementic, that isn't new.


I disagree. When binding C++ code to D I don't care about D's 
const rules. I care about the C++ const rules. There are 
thousands of C++ libraries out there that can't be bound to D 
because they use const Class* instead of const Class* const. So 
in my eyes there is definitly something wrong with the C++ 
mangling of D.





Re: const(Class) is mangled as Class const* const

2017-03-26 Thread Jonathan M Davis via Digitalmars-d
On Sunday, March 26, 2017 14:51:28 Namespace via Digitalmars-d wrote:
> On Sunday, 26 March 2017 at 14:30:00 UTC, deadalnix wrote:
> > On Sunday, 26 March 2017 at 10:43:11 UTC, Benjamin Thaut wrote:
> >> As you see from the above example D mangles the getClassConst
> >> as a "Class const * const" instead of a "Class const *"
> >> ("YAQEBV" vs "YAPEBV"). Is this expected behavior?
> >
> > It's consistent. D's const is transitive, and D doesn't allow
> > you to specify const on the indirection of a reference type. So
> > there is no problem on the C++ mangling side of things, but,
> > arguably, there is one in D's sementic, that isn't new.
> >
> > Something like differentiating "const(C) i" and "const C i" may
> > be a good idea.
>
> After reading your post, I wonder: How could I translate the
> following C++ code to D?
>
> 
> int a = 2;
> int* const p = 
> 

You don't. Once part of a type is const, everything inside it is const. So,
if a pointer is const, everything it points to is const. You can have the
outer part be mutable with the inner part be const, but not the other way
around. D's const can do tail-const, but it can't do head-const.

Now, while you can't use const to make the pointer const and what it points
to mutable, you _can_ make the the pointer read-only while still having what
it points to be fully mutable by putting it in a struct which restricts
write-access to the pointer. I believe that that's essentially what
std.experimental.typecons.Final is supposed to do.

Personally, I don't think that the fact that you can't use const for
head-const in D is really a loss, since it's almost never what you want.
Tail-const is _way_ more useful. But it is true that by making D's const
fully transitive, there are variations of constness that C++ can do that D
can't. immutable pretty much forces that though, and it does simplify the
language.

- Jonathan M Davis



Re: const(Class) is mangled as Class const* const

2017-03-26 Thread Namespace via Digitalmars-d

On Sunday, 26 March 2017 at 14:30:00 UTC, deadalnix wrote:

On Sunday, 26 March 2017 at 10:43:11 UTC, Benjamin Thaut wrote:
As you see from the above example D mangles the getClassConst 
as a "Class const * const" instead of a "Class const *" 
("YAQEBV" vs "YAPEBV"). Is this expected behavior?


It's consistent. D's const is transitive, and D doesn't allow 
you to specify const on the indirection of a reference type. So 
there is no problem on the C++ mangling side of things, but, 
arguably, there is one in D's sementic, that isn't new.


Something like differentiating "const(C) i" and "const C i" may 
be a good idea.


After reading your post, I wonder: How could I translate the 
following C++ code to D?



int a = 2;
int* const p = 



Re: const(Class) is mangled as Class const* const

2017-03-26 Thread deadalnix via Digitalmars-d

On Sunday, 26 March 2017 at 10:43:11 UTC, Benjamin Thaut wrote:
As you see from the above example D mangles the getClassConst 
as a "Class const * const" instead of a "Class const *" 
("YAQEBV" vs "YAPEBV"). Is this expected behavior?


It's consistent. D's const is transitive, and D doesn't allow you 
to specify const on the indirection of a reference type. So there 
is no problem on the C++ mangling side of things, but, arguably, 
there is one in D's sementic, that isn't new.


Something like differentiating "const(C) i" and "const C i" may 
be a good idea.


const(Class) is mangled as Class const* const

2017-03-26 Thread Benjamin Thaut via Digitalmars-d

Consider the following C++ and D source:

class Class
{
virtual ~Class(){}
};

// mangles as ?getClass@@YAPEAVClass@@XZ
Class * getClass() { return nullptr; }

// mangles as ?getClassConst@@YAPEBVClass@@XZ
const Class * getClassConst() { return nullptr; }

// mangles as ?getClassConstConst@@YAQEBVClass@@XZ
const Class * const getClassConstConst() { return nullptr; }

extern(C++)
{
  class Class
  {
void _cppDtor() {}
  }

  // Mangles as ?getClass@@YAPEAVClass@@XZ
  Class getClass() {return null;}

  // Mangles as ?getClassConst@@YAQEBVClass@@XZ
  const(Class) getClassConst() {return null;}
}

As you see from the above example D mangles the getClassConst as 
a "Class const * const" instead of a "Class const *" ("YAQEBV" vs 
"YAPEBV"). Is this expected behavior? The core problem is that D 
can not express one of the two. Either const(Class) becomes 
"Class const *" or "Class const * const". I've never seen C++ 
code that returns const pointers to const classes so I think the 
default should be "Class const *". Either way its rather bad that 
we can only represent one or the other. Sooner or later someone 
will hit this problem again wanting the other option or both. Any 
idea how we can avoid changing C++ source code in order to bind 
it to D? Using pragma(mangle,) works but is kind of ugly. 
Especially because the string to pragma(mangle,) can't be 
genearted using CTFE.


Should I open a bug for this?