Thread overview
Major template bug??
Mar 28, 2005
David Medlock
Mar 28, 2005
Tom S
Mar 28, 2005
David Medlock
Mar 28, 2005
Tom S
Mar 29, 2005
Walter
Mar 29, 2005
Tom S
March 28, 2005
import std.stdio;

template Print(T)
{
  void Print( T[16] matrix )
  {
    writefln("\nMatrix:\n" );
    for( int i=0; i<4; i++ )
      writefln("<%s,%s,%s,%s>", matrix[i], matrix[i+4], matrix[i+8], matrix[i+12] );
  }
}


void main( char[][] arg )
{
    double[16] matrix;
    Print!(double).Print( matrix );
}

dmd 0.119 on WinXP:
argbug.d(18): function argbug.Print!(double).Print (double[16]) does not  match argument types ()


If you replace the Print function with:
  void Print( T[16] matrix )
  {
    double total = 0;
    for( int i=0; i<4; i++ ) total = total + matrix[i];
  }

You get the same bug, BUT if you move the double total = 0; outside the function(but still inside the template), it compiles just fine.

This bug _ONLY_ seems to occur when the function is the same name as the template.

Am I missing something here??

-DavidM

March 28, 2005
David Medlock wrote:
> import std.stdio;
> 
> template Print(T)
> {
>   void Print( T[16] matrix )
>   {
>     writefln("\nMatrix:\n" );
>     for( int i=0; i<4; i++ )
>       writefln("<%s,%s,%s,%s>", matrix[i], matrix[i+4], matrix[i+8], matrix[i+12] );
>   }
> }
> 
> 
> void main( char[][] arg )
> {
>     double[16] matrix;
>     Print!(double).Print( matrix );
> }
> 
> dmd 0.119 on WinXP:
> argbug.d(18): function argbug.Print!(double).Print (double[16]) does not  match argument types ()
>
> <snip />
> 
> Am I missing something here??
> 
> -DavidM
> 

It's not a bug, it's a feature :D
In the docs about templates, there's a section "Implicit Template Properties" which says:
"If a template has exactly one member in it, and the name of that member is the same as the template name, that member is assumed to be referred to in a template instantiation:

	template Foo(T)
	{
	    T Foo;	// declare variable Foo of type T
	}

	void test()
	{
	    Foo!(int) = 6;	// instead of Foo!(int).Foo
	}"

Which means that you should use this syntax:

Print!(double)(matrix);


-- 
Tomasz Stachowiak  /+ a.k.a. h3r3tic +/
March 28, 2005
Tom S wrote:
> David Medlock wrote:
> 
>> import std.stdio;
>>
>> template Print(T)
>> {
>>   void Print( T[16] matrix )
>>   {
>>     writefln("\nMatrix:\n" );
>>     for( int i=0; i<4; i++ )
>>       writefln("<%s,%s,%s,%s>", matrix[i], matrix[i+4], matrix[i+8], matrix[i+12] );
>>   }
>> }
>>
>>
>> void main( char[][] arg )
>> {
>>     double[16] matrix;
>>     Print!(double).Print( matrix );
>> }
>>
>> dmd 0.119 on WinXP:
>> argbug.d(18): function argbug.Print!(double).Print (double[16]) does not  match argument types ()
> 
>  >
> 
>> <snip />
>>
>> Am I missing something here??
>>
>> -DavidM
>>
> 
> It's not a bug, it's a feature :D
> In the docs about templates, there's a section "Implicit Template Properties" which says:
> "If a template has exactly one member in it, and the name of that member is the same as the template name, that member is assumed to be referred to in a template instantiation:
> 
>     template Foo(T)
>     {
>         T Foo;    // declare variable Foo of type T
>     }
> 
>     void test()
>     {
>         Foo!(int) = 6;    // instead of Foo!(int).Foo
>     }"
> 
> Which means that you should use this syntax:
> 
> Print!(double)(matrix);
> 
> 

That is , as I understand it, a shortcut feature to save extraneous typing.  The syntax I posted should be valid.

-David
March 28, 2005
David Medlock wrote:
> Tom S wrote:
> 
>> David Medlock wrote:
>>
>>> import std.stdio;
>>>
>>> template Print(T)
>>> {
>>>   void Print( T[16] matrix )
>>>   {
>>>     writefln("\nMatrix:\n" );
>>>     for( int i=0; i<4; i++ )
>>>       writefln("<%s,%s,%s,%s>", matrix[i], matrix[i+4], matrix[i+8], matrix[i+12] );
>>>   }
>>> }
>>>
>>>
>>> void main( char[][] arg )
>>> {
>>>     double[16] matrix;
>>>     Print!(double).Print( matrix );
>>> }
>>>
>>> dmd 0.119 on WinXP:
>>> argbug.d(18): function argbug.Print!(double).Print (double[16]) does not  match argument types ()
>>
>>
>>  >
>>
>>> <snip />
>>>
>>> Am I missing something here??
>>>
>>> -DavidM
>>>
>>
>> It's not a bug, it's a feature :D
>> In the docs about templates, there's a section "Implicit Template Properties" which says:
>> "If a template has exactly one member in it, and the name of that member is the same as the template name, that member is assumed to be referred to in a template instantiation:
>>
>>     template Foo(T)
>>     {
>>         T Foo;    // declare variable Foo of type T
>>     }
>>
>>     void test()
>>     {
>>         Foo!(int) = 6;    // instead of Foo!(int).Foo
>>     }"
>>
>> Which means that you should use this syntax:
>>
>> Print!(double)(matrix);
>>
>>
> 
> That is , as I understand it, a shortcut feature to save extraneous typing.  The syntax I posted should be valid.

Yeah, it's a shortcut, but when the conditions "a template has exactly
one member in it, and the name of that member is the same as the
template name" are met, that shortcut is the only way to access the
template's insides.

By writing:
Print!(double).Print( matrix );

You'd mean:
"Call the Print function with no parameters (as a property) and
access the return type's member function 'Print' and call it with the 'matrix' argument"  // Explanation follows

This:
Print!(double).Print( matrix );
Translates to:
Print!(double)().Print( matrix );

Hence the error "function argbug.Print!(double).Print (double[16]) does
 not match argument types ()"

Even if it matched the function, you'd still get an error indicating
that void does not have a property named 'Print'.

That's how I understand it, debug me if I'm wrong.

// -------------------------------------------------

Ok, now something I seriously don't understand. Why does the following program print the maximal value of uint instead of crashing ?

import std.stdio;

uint foo()
{
	throw new Exception("crash !");
	return 0;
}

void main()
{
	uint a = foo().max;
	writefln(a);
	getchar();
}


Does the compiler quietly assume that foo() doesn't have any side effects ? I'm confused...



-- 
Tomasz Stachowiak  /+ a.k.a. h3r3tic +/

March 29, 2005
"Tom S" <h3r3tic@remove.mat.uni.torun.pl> wrote in message news:d2a3jh$3pq$1@digitaldaemon.com...
> Ok, now something I seriously don't understand. Why does the following program print the maximal value of uint instead of crashing ?
>
> import std.stdio;
>
> uint foo()
> {
> throw new Exception("crash !");
> return 0;
> }
>
> void main()
> {
> uint a = foo().max;
> writefln(a);
> getchar();
> }
>
>
> Does the compiler quietly assume that foo() doesn't have any side
> effects ? I'm confused...

Because the .max property looks at the type of the expression of the left side of the ., it does not attempt to evaluate it.


March 29, 2005
Walter wrote:
> Because the .max property looks at the type of the expression of the left
> side of the ., it does not attempt to evaluate it.

Assuming that it's the desired behavior:
Isn't it a possible source of bugs ? What are the downsides of evaluating the expression ?


-- 
Tomasz Stachowiak  /+ a.k.a. h3r3tic +/