June 16, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4251


Andrei Alexandrescu <andrei@metalanguage.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrei@metalanguage.com


--- Comment #10 from Andrei Alexandrescu <andrei@metalanguage.com> 2011-06-16 12:23:01 PDT ---
Yah, this has constantly puzzled starting C++ programmers - you can convert
char* to const(char*) but not char** to const(char*)*.

Generally, consider types P (permissive) and N (nonpermissive). Assume both types have the same structure, so there is no matter of converting representation. Generally you can't convert the address of a N to the address of a P even if you can actually convert a N to an P. This is because the address conversion would allow you subsequent P-specific operations directly against an N object.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 16, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4251



--- Comment #11 from Stewart Gordon <smjg@iname.com> 2011-06-16 13:18:31 PDT ---
(In reply to comment #10)
> Yah, this has constantly puzzled starting C++ programmers - you can convert
> char* to const(char*) but not char** to const(char*)*.

Do you mean char** to const(char)** ?

> Generally, consider types P (permissive) and N (nonpermissive). Assume both types have the same structure, so there is no matter of converting representation. Generally you can't convert the address of a N to the address of a P even if you can actually convert a N to an P. This is because the address conversion would allow you subsequent P-specific operations directly against an N object.

Well said.

Converting T* (N) to const(T)* (P) is safe.
The P-specific operation is rebinding it to an immutable(T).
So converting T** to const(T)** is unsafe.

Similarly,
Converting immutable(T)* (N) to const(T)* (P) is safe.
The P-specific operation is rebinding it to a mutable T.
So converting immutable(T)** to const(T)** is unsafe.

This is the principle that underlies all these proposed rules - whether the indirection is a pointer, dynamic array or other container type, and whether the N->P is a constancy change or a walk up the class hierarchy.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 17, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4251



--- Comment #12 from yebblies <yebblies@gmail.com> 2011-06-16 20:18:02 PDT ---
(In reply to comment #9)
> (In reply to comment #5)
> >>> immutable(T*)** => const(T*)** allowed, same number of mutable indirections
> 
> As it turns out, this is unsafe, as the following code shows:
> 

Good catch!  I'll get on it.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
June 22, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4251


yebblies <yebblies@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs@eml.cc


--- Comment #13 from yebblies <yebblies@gmail.com> 2011-06-22 00:31:47 PDT ---
*** Issue 6190 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 04, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4251


Brad Roberts <braddr@puremagic.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|patch                       |
                 CC|                            |braddr@puremagic.com


--- Comment #14 from Brad Roberts <braddr@puremagic.com> 2011-08-03 20:16:33 PDT ---
I've removed the patch keyword from this bug since the pull request was withdrawn.  I don't suppose you've had a chance to fix the issues with the first version of the patch, have you yebblies?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 04, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4251



--- Comment #15 from yebblies <yebblies@gmail.com> 2011-08-04 13:31:41 EST ---
(In reply to comment #14)
> I've removed the patch keyword from this bug since the pull request was withdrawn.  I don't suppose you've had a chance to fix the issues with the first version of the patch, have you yebblies?

Unfortunately no.  My patch was instantiating templates it shouldn't have, and I haven't had the time lately to fix the template deduction.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 17, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4251


timon.gehr@gmx.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |timon.gehr@gmx.ch
            Summary|Hole in the const system:   |Hole in the type system:
                   |immutable values can be     |Base type reference can be
                   |overwritten (const(T) is    |assigned to subtype
                   |appendable to const(T)[])   |reference (Super* is
                   |                            |treated as a supertype of
                   |                            |Sub*)


--- Comment #16 from timon.gehr@gmx.ch 2011-11-17 11:59:55 PST ---
Class references have the same problem.

class A{}
class B:A{}

void main(){
    B x;
    A* y=&x; // bad!
    *y=new A;
    Object o = x;
    assert(o is x && o && is(typeof(x)==B) && !cast(B)o);
}

I have generalized the title accordingly.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 18, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4251


Luther Tychonievich <lat7h@virginia.edu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Hole in the type system:    |Hole in the const system:
                   |Base type reference can be  |immutable values can be
                   |assigned to subtype         |overwritten (const(T) is
                   |reference (Super* is        |appendable to const(T)[])
                   |treated as a supertype of   |
                   |Sub*)                       |


--- Comment #17 from Luther Tychonievich <lat7h@virginia.edu> 2011-11-18 05:28:26 PST ---
(In reply to comment #16)
>     B x;
>     A* y=&x; // bad!
Everything you describe is supposed to happen. "A* y = &x" is the point of inheritance. What exactly is the problem you see in the above? All of your assert elements seem fine too…

Reverting title. This bug is about the const safety design of the language, not about inheritance. Even if there is a problem with inheritance, it should be a separate bug unless you can argue they have the same cause.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 18, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4251



--- Comment #18 from Steven Schveighoffer <schveiguy@yahoo.com> 2011-11-18 07:10:20 PST ---
(In reply to comment #17)
> (In reply to comment #16)
> >     B x;
> >     A* y=&x; // bad!
> Everything you describe is supposed to happen. "A* y = &x" is the point of inheritance. What exactly is the problem you see in the above? All of your assert elements seem fine too…

The example isn't illustrative enough.

Here's a better example:

class A {}
class B : A {void foo() {writeln("hello, B");} }

void main()
{
   B x;
   A* y = &x;
   *y = new A;
   x.foo(); // boom!  Call to invalid vtable entry
}

As I said in an earlier comment, this bug is really a dup of bug 2095, but it adds a different twist.  If we want to consolidate, we should close this as a duplicate of 2095.

> Reverting title. This bug is about the const safety design of the language, not about inheritance. Even if there is a problem with inheritance, it should be a separate bug unless you can argue they have the same cause.

It's somewhat the same thing.  const(T) is really a "base class" of T, since T
implicitly casts to const(T), but const(T) doesn't implicitly cast to T.

I won't revert the bug description again, because I think this case is already covered in 2095.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
November 18, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4251


Steven Schveighoffer <schveiguy@yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Hole in the const system:   |Hole in the const system:
                   |immutable values can be     |immutable(T)[] implicitly
                   |overwritten (const(T) is    |casts to ref const(T)[]
                   |appendable to const(T)[])   |


--- Comment #19 from Steven Schveighoffer <schveiguy@yahoo.com> 2011-11-18 07:12:53 PST ---
However, I just realized the title is not correct.  So I'll change the title to
reflect the actual problem (const(T) is perfectly legal to append to
const(T)[]).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------