www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - Major template bug??

reply David Medlock <amedlock nospam.org> writes:
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
Mar 28 2005
parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
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 +/
Mar 28 2005
parent reply David Medlock <nospam nospam.com> writes:
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
Mar 28 2005
parent reply Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
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 +/
Mar 28 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"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.
Mar 28 2005
parent Tom S <h3r3tic remove.mat.uni.torun.pl> writes:
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 +/
Mar 28 2005