www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 8640] New: Template struct/class member functions should compile conditionally

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8640

           Summary: Template struct/class member functions should compile
                    conditionally
           Product: D
           Version: unspecified
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: monarchdodra gmail.com



From the conversation here:
http://forum.dlang.org/thread/hgmloyopgeoxjzhfuyub forum.dlang.org

Not entirely sure if this is a bug, or an enhancement request (The answer I got
was "In this case I think D is working as designed")

Basically:
-------
struct S
{
  const int i;
}

struct C(T)
{
    private T val;
     property T front()
        {return val;}
     property void front(T value)
        {val = value;} //HERE
}

void main()
{
  C!S test;
}
--------

This creates a compilation error at "here". Problem: The non-compiling function
was never called.

I think that member functions of template structs/classes should be compiled
conditionally only when they are called.

Doing otherwise really burdens the developer with making implementation
conditions for *all* his functions.

Suggest that member functions only be compiled and validated when called.

This *should* be possible, because doing this bypasses the problem:
--------
struct C(T)
{
    private T val;
     property T front()() //Template specialization
        {return val;}
     property void front()(T value) //Template specialization
        {val = value;}
}
--------

//Technically, the first specialization is not needed, but there is currently a
limitation regarding template/non-template overloads.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 11 2012
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8640


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug yahoo.com.au



This is as designed. Doing otherwise would let a lot of bugs through.
In fact one of the oldest open rejects-valid bug reports is a request to make
the compiler check template functions even when they are NOT called.

There are strong reasons for the current behaviour.
* This request would interact badly with functions which return auto (the
compiler needs to compile them, to find out what the return type is).
* It's impossible for classes (you need to put the function into the vtable,
regardless of whether it is called or not), making a new, surprising difference
between classes and structs.

Generally in these cases I just turn the function into a template function.

 property void front(Dummy = void)(T value)
        {val = value;} //HERE

I never tested that with property functions though.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 11 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8640






Thanks for the reply.

 This is as designed. Doing otherwise would let a lot of bugs through.
 In fact one of the oldest open rejects-valid bug reports is a request to make
 the compiler check template functions even when they are NOT called.
 
 There are strong reasons for the current behaviour.
 * This request would interact badly with functions which return auto (the
 compiler needs to compile them, to find out what the return type is).
*Does* it need to compile them if no-one calls them? Who cares what the return value is, if there is no return value to be evaluated?
 * It's impossible for classes (you need to put the function into the vtable,
 regardless of whether it is called or not), making a new, surprising difference
 between classes and structs.
That is a good point, although arguably, it only holds for virtual vs final methods. So there is no reason for the same behavior to also apply to the final (non-virtual) methods of templated classes.
 Generally in these cases I just turn the function into a template function.
 
  property void front(Dummy = void)(T value)
         {val = value;} //HERE
 
 I never tested that with property functions though.
I had considered doing that, with the even simpler: property void front()(T value) {val = value;} However, as pointed out by bearophile, this approach means this: -------- struct C(T) { private T val; property void front()(T value) { val = value; } } void main() { C!int ci; auto f = &ci.front; //Should be &ci.front!() assert(ci.val == 0); f(1); assert(ci.val == 1); } -------- Ceases to work. So it does have client-side impacts :'( -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 11 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8640


Simen Kjaeraas <simen.kjaras gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |simen.kjaras gmail.com



PDT ---

 However, as pointed out by bearophile, this approach means this:
 --------
 struct C(T) {
     private T val;
      property void front()(T value) {
         val = value;
     }
 }
 void main() {
     C!int ci;
     auto f = &ci.front; //Should be &ci.front!()
     assert(ci.val == 0);
     f(1);
     assert(ci.val == 1);
 }
 --------
 Ceases to work. So it does have client-side impacts :'(
Indeed. Now, there is another way to do it, which clearly marks the code as 'may or may not work, depending on template parameters', and that involves static if. If the method does not work with some types, the correct way to state that is so that the compiler gives a sensible error message when someone tries to use your code, not when your code tries to use something else. In this case: static if (__traits(compiles, (T value){val = value;})) { property void front()(T value) { val = value; } } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 11 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8640


timon.gehr gmx.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |timon.gehr gmx.ch



I strongly object this change. It worsens expressiveness.

Open an enhancement request about implicitly instantiating function templates
if
they get their address taken instead.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 11 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=8640


monarchdodra gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID



Ty for the explanation.

This was mostly me being confused about "D doesn't work like C++".

I agree that it actually improves readability.

Will close.

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