www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 3646] New: Default values of function arguments are ignored when instantiating a template.

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

           Summary: Default values of function arguments are ignored when
                    instantiating a template.
           Product: D
           Version: 2.035
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: e.insafutdinov gmail.com


--- Comment #0 from Eldar Insafutdinov <e.insafutdinov gmail.com> 2009-12-25
01:02:49 PST ---
void foo(Fn)(Fn fn)
{
    fn();
}

void bar(int i = 22) {
    writeln("bar ", i);
}
void bam(int i) {
    writeln("bam ", i);
}

void baz() {
    foo(&bar);
    foo(&bam);
}

This code compiles while it should not. You cannot call bam() without any
arguments. If you switch the instantiations and call foo(&bam) first - it does
not compile.


pragma(msg, typeof(&bar).stringof);
pragma(msg, typeof(&bam).stringof);

outputs

void function(int i = 22)
void function(int i)


But it is not respected by the template.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 25 2009
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3646


Koroskin Denis <2korden gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |2korden gmail.com


--- Comment #1 from Koroskin Denis <2korden gmail.com> 2009-12-25 08:32:32 PST
---
This is a bit more tricky than it looks like.

The question here is, how many times should foo be instanciated?
DMD answers "just 1 time", and I agree with it, since bar and bam have same
signature and mangling.

Having only one instantiation means that code for it will also be generated
once.

When you call a function that has default argument without providing that
argument, the call is actually *rewritten to include that argument*. I.e.
bar(); is rewritten as bar(22);

Not lets see how foo!(bar) looks like after a rewrite:

void foo(Fn)(Fn fn)
{
    fn(22);
}

Now there is no wonder why dmd behaves like this.

But this only happens if foo!(bar) is instanciated before foo!(bam), because
when templates are instantiates on first use. When you instanciate foo!(bam)
first, it doesn't get rewritten and therefore fails to compile.

I guess the only fix for this issue would be to create an implicit trampoline
to invoke functions with default arguments, but only Walter can say for sure.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 25 2009
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3646



--- Comment #2 from Eldar Insafutdinov <e.insafutdinov gmail.com> 2009-12-26
12:51:57 PST ---
(In reply to comment #1)
 This is a bit more tricky than it looks like.
 
 The question here is, how many times should foo be instanciated?
 DMD answers "just 1 time", and I agree with it, since bar and bam have same
 signature and mangling.

 But this only happens if foo!(bar) is instanciated before foo!(bam), because
 when templates are instantiates on first use. When you instanciate foo!(bam)
 first, it doesn't get rewritten and therefore fails to compile.
 
 I guess the only fix for this issue would be to create an implicit trampoline
 to invoke functions with default arguments, but only Walter can say for sure.

Yeah, that was pretty much what I was thinking about. The issue cuts down to a question, should Foo be instantiated once or are the function types equal? For binary size and efficiency purposes I agree that there should be one instantiation. On the other hand for meta programming and code generation which is what I am doing I would like to have them as separate types, as I don't want to loose this information. Walter or Andrei would probably have to comment on this issue. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 26 2009
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=3646


Stewart Gordon <smjg iname.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |accepts-invalid, spec
                 CC|                            |smjg iname.com
            Version|2.035                       |1.051
             Blocks|                            |340
         OS/Version|Linux                       |All


--- Comment #3 from Stewart Gordon <smjg iname.com> 2010-01-03 08:53:39 PST ---
I've never heard of default arguments being part of the function type's
properties.  I'd probably guessed that the type is simply void function(int)
but default arguments are filled in on the caller side.  In which case the
functions are the same type, and so this isn't meant to work.  Either way, it's
certainly a bug that the code is accepted.

And it applies to D1 too, but the code needs changing a bit:
----------
import std.stdio;

void foo(Fn)(Fn fn) {
    fn();
}

void bar(int i = 22) {
    writefln("bar ", i);
}
void bam(int i) {
    writefln("bam ", i);
}

void main() {
    foo(&bar);
    foo(&bam);
}
----------

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