Thread overview
Testing if a function is defined in a module
Feb 21, 2007
Carlos Smith
Feb 21, 2007
Kirk McDonald
Feb 21, 2007
Carlos Smith
Feb 21, 2007
Tyler Knott
Feb 21, 2007
Frits van Bommel
Feb 21, 2007
Carlos Smith
Feb 21, 2007
mario pernici
Feb 21, 2007
Kirk McDonald
Feb 21, 2007
mario pernici
February 21, 2007
Hi!

say i have defined a function (or i dont):

int YYUSERINIT( )
{
   ...
}


How can i test (statically), later in the module
if that function have been defined ?

if yes, code using the function will
be compiled.

Thanks


February 21, 2007
Carlos Smith wrote:
> Hi!
> 
> say i have defined a function (or i dont):
> 
> int YYUSERINIT( )
> {
>    ...
> }
> 
> 
> How can i test (statically), later in the module
> if that function have been defined ?
> 
> if yes, code using the function will
> be compiled.
> 
> Thanks
> 
> 

There are a few ways of phrasing this, but here's one:

static if (is(typeof(&YYUSERINIT))) {
    // Do stuff with the function
}

However, I can't help but wonder what situation you're in where you need to check this directly. I'm just guessing, here, but you'd probably be better off using a version flag:

version (WithTheFunction) int YYUSERINIT() {}

// Later...
    version (WithTheFunction) {
        // Use the function
    }
// ...

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org
February 21, 2007
"Kirk McDonald" <kirklin.mcdonald@gmail.com> wrote in
message news:erggra$lc1
: static if (is(typeof(&YYUSERINIT))) {
:     // Do stuff with the function
: }
: However, I can't help but wonder what situation you're in
where you need
: to check this directly. I'm just guessing, here, but you'd
probably be
: better off using a version flag:

I am trying to add D support to flex. Without completly rewriting it.

GNU programs use the preprocessor a lot, and in ways
not easy to translate to D.

Given a grammar, flex generate a C lexer for that grammar. The user can define a macro YYUSERINIT. That macro will be expanded if the test:

#ifdef YYUSERINIT
    YYUSERINIT();
#endif

is satisfied. flex does not know, and does need to know
if YYUSERINIT is defined.

But, he [the user] may also not define it, and everything
will compile
ok.

Your first suggestion is exactly what i am looking for.

That can be also used to generate a default version for
a function, in the case the user does not define his own.

eg:
int yywrap( ) { return 1;}


Thanks a lot.

February 21, 2007
Kirk McDonald wrote:
> Carlos Smith wrote:
>> Hi!
>>
>> say i have defined a function (or i dont):
>>
>> int YYUSERINIT( )
>> {
>>    ...
>> }
>>
>>
>> How can i test (statically), later in the module
>> if that function have been defined ?
>>
>> if yes, code using the function will
>> be compiled.
>>
>> Thanks
>>
>>
> 
> There are a few ways of phrasing this, but here's one:
> 
> static if (is(typeof(&YYUSERINIT))) {
>     // Do stuff with the function
> }
> 
> 

Thanks for the solution.  I was grappling with a similar problem myself.  Would you mind explaining why this works?  I'm a bit fuzzy on IsExpression syntax. I'm guessing it's because you can't take the type of an undeclared symbol, making the Type invalid and the IsExpression return 0, correct?
February 21, 2007
Tyler Knott wrote:
> Kirk McDonald wrote:
>> Carlos Smith wrote:
>>> How can i test (statically), later in the module
>>> if that function have been defined ?
>>
>> There are a few ways of phrasing this, but here's one:
>>
>> static if (is(typeof(&YYUSERINIT))) {
>>     // Do stuff with the function
>> }
> 
> Thanks for the solution.  I was grappling with a similar problem myself.  Would you mind explaining why this works?  I'm a bit fuzzy on IsExpression syntax. I'm guessing it's because you can't take the type of an undeclared symbol, making the Type invalid and the IsExpression return 0, correct?

In this case it's taking the type of an expression that tries to take the address of an undefined symbol (note the &), but other than that your guess is right.
February 21, 2007
"Kirk McDonald" <kirklin.mcdonald@gmail.com> wrote

: There are a few ways of phrasing this, but here's one:
:
: static if (is(typeof(&YYUSERINIT))) {
:     // Do stuff with the function
: }

Just tried with dmd 1.007, in a program
defining int a=0;

  static if( is(typeof(main) == function ) )
    ...
  static if( is(typeof(yymain) == function ) )
    ...
  static if( is(typeof(a) == int ) )
    ...
  static if( is(typeof(a) == float ) )
    ...

All 4 tests gives what they suggest.
Ie: main is a function, yymain is not.
a is an int and not a float.

Great !

Looks like D wont miss the C preprocessor...

February 21, 2007
Carlos Smith Wrote:

> 
> "Kirk McDonald" <kirklin.mcdonald@gmail.com> wrote
> 
> : There are a few ways of phrasing this, but here's one:
> :
> : static if (is(typeof(&YYUSERINIT))) {
> :     // Do stuff with the function
> : }
> 
> Just tried with dmd 1.007, in a program
> defining int a=0;
> 
>   static if( is(typeof(main) == function ) )
>     ...
>   static if( is(typeof(yymain) == function ) )
>     ...
>   static if( is(typeof(a) == int ) )
>     ...
>   static if( is(typeof(a) == float ) )
>     ...
> 
> All 4 tests gives what they suggest.
> Ie: main is a function, yymain is not.
> a is an int and not a float.
> 
> Great !
> 
> Looks like D wont miss the C preprocessor...
> 


Nice. I Tried to install dmd 1.007 for Linux, but the link is still for 1.006.

One can check the return type of the function with
 static if(is(typeof(YYUSERINIT))) {
    if( typeid(typeof(&YYUSERINIT)).toString() == "int()*")
      writefln("YYUSERINIT is a int()*");
  }

but it works independently of the arguments of the function,
int YYUSERINIT()
or
int YYUSERINIT(int a, int b)


February 21, 2007
Carlos Smith Wrote:

> 
> "Kirk McDonald" <kirklin.mcdonald@gmail.com> wrote
> 
> : There are a few ways of phrasing this, but here's one:
> :
> : static if (is(typeof(&YYUSERINIT))) {
> :     // Do stuff with the function
> : }
> 
> Just tried with dmd 1.007, in a program
> defining int a=0;
> 
>   static if( is(typeof(main) == function ) )
>     ...
>   static if( is(typeof(yymain) == function ) )
>     ...
>   static if( is(typeof(a) == int ) )
>     ...
>   static if( is(typeof(a) == float ) )
>     ...
> 
> All 4 tests gives what they suggest.
> Ie: main is a function, yymain is not.
> a is an int and not a float.
> 
> Great !
> 
> Looks like D wont miss the C preprocessor...
> 


Nice. I Tried to install dmd 1.007 for Linux, but the link is still for 1.006.

One can check the return type of the function with
 static if(is(typeof(YYUSERINIT))) {
    if( typeid(typeof(&YYUSERINIT)).toString() == "int()*")
      writefln("YYUSERINIT is a int()*");
  }

but it works independently of the arguments of the function,
int YYUSERINIT()
or
int YYUSERINIT(int a, int b)


February 21, 2007
mario pernici wrote:
> Carlos Smith Wrote:
> 
> 
>>"Kirk McDonald" <kirklin.mcdonald@gmail.com> wrote 
>>
>>: There are a few ways of phrasing this, but here's one:
>>: : static if (is(typeof(&YYUSERINIT))) {
>>:     // Do stuff with the function
>>: }
>>
>>Just tried with dmd 1.007, in a program
>>defining int a=0;
>>
>>  static if( is(typeof(main) == function ) )
>>    ...   static if( is(typeof(yymain) == function ) )
>>    ...
>>  static if( is(typeof(a) == int ) )
>>    ...
>>  static if( is(typeof(a) == float ) )
>>    ...
>>
>>All 4 tests gives what they suggest.
>>Ie: main is a function, yymain is not.
>>a is an int and not a float.
>>
>>Great !
>>
>>Looks like D wont miss the C preprocessor...
>>
> 
> 
> 
> Nice. I Tried to install dmd 1.007 for Linux, but the link is still for 1.006.
> 
> One can check the return type of the function with
>  static if(is(typeof(YYUSERINIT))) {
>     if( typeid(typeof(&YYUSERINIT)).toString() == "int()*")
>       writefln("YYUSERINIT is a int()*");
>   }
> 
> but it works independently of the arguments of the function, int YYUSERINIT()
> or
> int YYUSERINIT(int a, int b)
> 
> 

Or one can use the IsExpression to derive the return type more sanely:

static if (is(typeof(&YYUSERINIT) Ret == return)) {
    writefln(typeid(Ret));
}

This is neatly wrapped by Phobos in the form of the std.traits.ReturnType template:

writefln(typeid(ReturnType!(YYUSERINIT)));

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org