www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Bug 31] New: Keyword 'function' and pointer test broken for IsExpression

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

           Summary: Keyword 'function' and pointer test broken for
                    IsExpression
           Product: D
           Version: 0.148
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: walter digitalmars.com
        ReportedBy: sean f4.ca


Given the documentation, I would expect all eight tests to pass, yet tests six
and eight both fail.


C:\code\d\bugs>type 149_1.d
import std.c.stdio;

template isPointer( T )
{
    const bool isPointer = is( T : T* );
}

void main()
{
    struct S {}
    union U {}
    class C {}
    interface I {}
    enum E { e }
    alias void function() fp;
    alias void delegate() dp;

    static if( is( S == struct ) ) printf( "1. struct passes\n" );
    static if( is( U == union ) ) printf( "2. union passes\n" );
    static if( is( C == class ) ) printf( "3. class passes\n" );
    static if( is( I == interface ) ) printf( "4. interface passes\n" );
    static if( is( E == enum ) ) printf( "5. enum passes\n" );
    static if( is( fp == function ) ) printf( "6. function passes\n" );
    static if( is( dp == delegate ) ) printf( "7. delegate passes\n" );
    static if( isPointer!(int*) ) printf( "8. pointer passes\n" );
}
C:\code\d\bugs>dmd 149_1.d
C:\bin\dmd\bin\..\..\dm\bin\link.exe 149_1,,,user32+kernel32/noi;

C:\code\d\bugs>149_1
1. struct passes
2. union passes
3. class passes
4. interface passes
5. enum passes
7. delegate passes

C:\code\d\bugs>


-- 
Mar 09 2006
next sibling parent reply Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

d-bugmail puremagic.com schrieb am 2006-03-10:
 Given the documentation, I would expect all eight tests to pass, yet tests six
 and eight both fail.


 C:\code\d\bugs>type 149_1.d
 import std.c.stdio;

 template isPointer( T )
 {
     const bool isPointer = is( T : T* );
 }

 void main()
 {
     struct S {}
     union U {}
     class C {}
     interface I {}
     enum E { e }
     alias void function() fp;
     alias void delegate() dp;

     static if( is( S == struct ) ) printf( "1. struct passes\n" );
     static if( is( U == union ) ) printf( "2. union passes\n" );
     static if( is( C == class ) ) printf( "3. class passes\n" );
     static if( is( I == interface ) ) printf( "4. interface passes\n" );
     static if( is( E == enum ) ) printf( "5. enum passes\n" );
     static if( is( fp == function ) ) printf( "6. function passes\n" );
     static if( is( dp == delegate ) ) printf( "7. delegate passes\n" );
     static if( isPointer!(int*) ) printf( "8. pointer passes\n" );
 }
 C:\code\d\bugs>dmd 149_1.d
 C:\bin\dmd\bin\..\..\dm\bin\link.exe 149_1,,,user32+kernel32/noi;

 C:\code\d\bugs>149_1
 1. struct passes
 2. union passes
 3. class passes
 4. interface passes
 5. enum passes
 7. delegate passes

Shouldn't isPointer be defined as: # template isPointer( T ){ # const bool isPointer = is( T : void* ); # } http://www.digitalmars.com/d/expression.html#IsExpression # is ( Type : TypeSpecialization ) # The condition is satisfied if Type is semantically correct and it is # the same as or can be implicitly converted to TypeSpecialization. Thus "is(T : T*)" is always false. Added to DStress as http://dstress.kuehne.cn/run/i/is_05_A.d http://dstress.kuehne.cn/run/i/is_05_B.d http://dstress.kuehne.cn/run/i/is_05_C.d http://dstress.kuehne.cn/run/i/is_05_D.d http://dstress.kuehne.cn/run/i/is_05_E.d http://dstress.kuehne.cn/run/i/is_05_F.d http://dstress.kuehne.cn/run/i/is_05_G.d http://dstress.kuehne.cn/run/i/is_05_H.d http://dstress.kuehne.cn/run/i/is_06_A.d http://dstress.kuehne.cn/run/i/is_06_B.d http://dstress.kuehne.cn/run/i/is_06_C.d http://dstress.kuehne.cn/run/i/is_06_D.d http://dstress.kuehne.cn/run/i/is_06_E.d http://dstress.kuehne.cn/run/i/is_06_F.d http://dstress.kuehne.cn/run/i/is_06_G.d http://dstress.kuehne.cn/run/i/is_06_H.d http://dstress.kuehne.cn/run/i/is_07_A.d http://dstress.kuehne.cn/run/i/is_07_B.d http://dstress.kuehne.cn/run/i/is_07_C.d http://dstress.kuehne.cn/run/i/is_07_D.d http://dstress.kuehne.cn/run/i/is_07_E.d http://dstress.kuehne.cn/run/i/is_07_F.d http://dstress.kuehne.cn/run/i/is_07_G.d http://dstress.kuehne.cn/run/i/is_07_H.d http://dstress.kuehne.cn/run/i/is_08_A.d http://dstress.kuehne.cn/run/i/is_08_B.d http://dstress.kuehne.cn/run/i/is_08_C.d http://dstress.kuehne.cn/run/i/is_08_D.d http://dstress.kuehne.cn/run/i/is_08_E.d http://dstress.kuehne.cn/run/i/is_08_F.d http://dstress.kuehne.cn/run/i/is_08_G.d http://dstress.kuehne.cn/run/i/is_08_H.d http://dstress.kuehne.cn/run/i/is_09_A.d http://dstress.kuehne.cn/run/i/is_09_B.d http://dstress.kuehne.cn/run/i/is_09_C.d http://dstress.kuehne.cn/run/i/is_09_D.d http://dstress.kuehne.cn/run/i/is_09_E.d http://dstress.kuehne.cn/run/i/is_09_F.d http://dstress.kuehne.cn/run/i/is_09_G.d http://dstress.kuehne.cn/run/i/is_09_H.d http://dstress.kuehne.cn/run/i/is_10_A.d http://dstress.kuehne.cn/run/i/is_10_B.d http://dstress.kuehne.cn/run/i/is_10_C.d http://dstress.kuehne.cn/run/i/is_10_D.d http://dstress.kuehne.cn/run/i/is_10_E.d http://dstress.kuehne.cn/run/i/is_10_F.d http://dstress.kuehne.cn/run/i/is_10_G.d http://dstress.kuehne.cn/run/i/is_10_H.d http://dstress.kuehne.cn/run/i/is_11_A.d http://dstress.kuehne.cn/run/i/is_11_B.d http://dstress.kuehne.cn/run/i/is_11_C.d http://dstress.kuehne.cn/run/i/is_11_D.d http://dstress.kuehne.cn/run/i/is_11_E.d http://dstress.kuehne.cn/run/i/is_11_F.d http://dstress.kuehne.cn/run/i/is_11_G.d http://dstress.kuehne.cn/run/i/is_11_H.d http://dstress.kuehne.cn/run/i/is_12_A.d http://dstress.kuehne.cn/run/i/is_12_B.d http://dstress.kuehne.cn/run/i/is_12_C.d http://dstress.kuehne.cn/run/i/is_12_D.d http://dstress.kuehne.cn/run/i/is_12_E.d http://dstress.kuehne.cn/run/i/is_12_F.d http://dstress.kuehne.cn/run/i/is_12_G.d http://dstress.kuehne.cn/run/i/is_12_H.d Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFEF+Hc3w+/yD4P9tIRAgIbAJ48xca4iWYt1eWGLX4PDQe/mo3TkwCgka6x f0HGCToN9r63VP1tHakuLaU= =m1gS -----END PGP SIGNATURE-----
Mar 15 2006
parent reply Sean Kelly <sean f4.ca> writes:
Thomas Kuehne wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
 d-bugmail puremagic.com schrieb am 2006-03-10:
 Given the documentation, I would expect all eight tests to pass, yet tests six
 and eight both fail.


 C:\code\d\bugs>type 149_1.d
 import std.c.stdio;

 template isPointer( T )
 {
     const bool isPointer = is( T : T* );
 }

 void main()
 {
     struct S {}
     union U {}
     class C {}
     interface I {}
     enum E { e }
     alias void function() fp;
     alias void delegate() dp;

     static if( is( S == struct ) ) printf( "1. struct passes\n" );
     static if( is( U == union ) ) printf( "2. union passes\n" );
     static if( is( C == class ) ) printf( "3. class passes\n" );
     static if( is( I == interface ) ) printf( "4. interface passes\n" );
     static if( is( E == enum ) ) printf( "5. enum passes\n" );
     static if( is( fp == function ) ) printf( "6. function passes\n" );
     static if( is( dp == delegate ) ) printf( "7. delegate passes\n" );
     static if( isPointer!(int*) ) printf( "8. pointer passes\n" );
 }
 C:\code\d\bugs>dmd 149_1.d
 C:\bin\dmd\bin\..\..\dm\bin\link.exe 149_1,,,user32+kernel32/noi;

 C:\code\d\bugs>149_1
 1. struct passes
 2. union passes
 3. class passes
 4. interface passes
 5. enum passes
 7. delegate passes

Shouldn't isPointer be defined as: # template isPointer( T ){ # const bool isPointer = is( T : void* ); # } http://www.digitalmars.com/d/expression.html#IsExpression # is ( Type : TypeSpecialization ) # The condition is satisfied if Type is semantically correct and it is # the same as or can be implicitly converted to TypeSpecialization. Thus "is(T : T*)" is always false.

Good point. However, this is inconsistent with the template specialization syntax, where "template foo( T : T* )" is completely valid. But perhaps that doesn't matter as IsExpression differs in other ways as well. I suppose that leaves 'function' then. By the way, this code: class C { void fn() {} } static if( is( typeof(C.fn) == function ) ) pragma( msg, "is function\n" ); static if( is( typeof(C.fn) == delegate ) ) pragma( msg, "is delegate\n" ); prints "is function" if compiled. Aren't non-static class functions actually delegates? Sean
Mar 15 2006
parent Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Sean Kelly schrieb am 2006-03-15:
 By the way, this code:

      class C { void fn() {} }
      static if( is( typeof(C.fn) == function ) )
          pragma( msg, "is function\n" );
      static if( is( typeof(C.fn) == delegate ) )
          pragma( msg, "is delegate\n" );


 prints "is function" if compiled.  Aren't non-static class functions 
 actually delegates?

Added to DStress as http://dstress.kuehne.cn/run/i/is_13_A.d http://dstress.kuehne.cn/run/i/is_13_B.d http://dstress.kuehne.cn/run/i/is_13_C.d http://dstress.kuehne.cn/run/i/is_13_D.d Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFEGIIo3w+/yD4P9tIRApHHAKCMeCKhln+R8zdriLdDSpoIXCewgwCfcrrh J90Jn3ukfw0vcbr6T894iR4= =9GBQ -----END PGP SIGNATURE-----
Mar 15 2006
prev sibling parent reply d-bugmail puremagic.com writes:
http://d.puremagic.com/bugzilla/show_bug.cgi?id=31


bugzilla digitalmars.com changed:

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




------- Comment #4 from bugzilla digitalmars.com  2006-04-26 13:43 -------
alias void function() fp;
static if( is( fp == function ) ) printf( "6. function passes\n" );

fp is not declared as a function, it is declared as a pointer to a function. If fp is declared as: alias void fp(); it will 'pass'.
template isPointer( T )
{
    const bool isPointer = is( T : T* );
}
static if( isPointer!(int*) ) printf( "8. pointer passes\n" );

Here, int* is passed as T to isPointer. The is(T:T*) is evaluated as is(int*:int**), and so it fails. To detect a pointer, use is(T:void*).
class C { void fn() {} }
     static if( is( typeof(C.fn) == function ) )
         pragma( msg, "is function\n" );
     static if( is( typeof(C.fn) == delegate ) )
         pragma( msg, "is delegate\n" );
prints "is function" if compiled.  Aren't non-static class functions 
actually delegates?

No. Class functions are functions. A delegate is a pointer to a class function. --
Apr 26 2006
parent reply Sean Kelly <sean f4.ca> writes:
d-bugmail puremagic.com wrote:
 alias void function() fp;
 static if( is( fp == function ) ) printf( "6. function passes\n" );

fp is not declared as a function, it is declared as a pointer to a function. If fp is declared as: alias void fp(); it will 'pass'.

So how do I test if T is a function pointer? Currently, I can test if T is a delegate via "if( is(T==delegate) )" but "if( is(T==function) )" clearly has a different meaning. For example: void delegate() dp; template isDelegate( T ) { const bool isDelegate = is( T == delegate ); } static assert( isDelegate!(dp) ); So far so good, but: void function() fp; template isFunctionPointer( T ) { const bool isFunctionPointer = ???; } static assert( isFunctionPointer!(fp) ); Currently, I'm examining the mangled name, which is a terrible hack: template isFunctionPointer( T ) { const bool isFunctionPointer= T.mangleof.length > 2 && T.mangleof[0] == 'P' && T.mangleof[1] == 'F'; } Sean
May 04 2006
next sibling parent Sean Kelly <sean f4.ca> writes:
Sean Kelly wrote:
 
 So how do I test if T is a function pointer?

By the way. If you're planning to eventually merge function pointers into delegates then I suppose there's no point in adding language support for this (assuming something doesn't already exist that I'm simply missing). I'd be content to use the workaround until then. Sean
May 04 2006
prev sibling parent Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Sean Kelly wrote:
 d-bugmail puremagic.com wrote:
 alias void function() fp;
 static if( is( fp == function ) ) printf( "6. function passes\n" );

fp is not declared as a function, it is declared as a pointer to a function. If fp is declared as: alias void fp(); it will 'pass'.

So how do I test if T is a function pointer? Currently, I can test if T is a delegate via "if( is(T==delegate) )" but "if( is(T==function) )" clearly has a different meaning. For example: void delegate() dp; template isDelegate( T ) { const bool isDelegate = is( T == delegate ); } static assert( isDelegate!(dp) );

I assume you mean isDelegate!(typeof(dp)).
 
 So far so good, but:
 
     void function() fp;
 
     template isFunctionPointer( T )
     {
         const bool isFunctionPointer = ???;
     }
 
     static assert( isFunctionPointer!(fp) );

Try: template declare(T) { T declare; } template isFunctionPointer(T) { const bool isFunctionPointer = is( typeof(*declare!(T)) == function); } /Oskar
May 05 2006