www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Testing if a function is defined in a module

reply "Carlos Smith" <carlos-smith sympatico.ca> writes:
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
Feb 20 2007
parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
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
Feb 20 2007
next sibling parent "Carlos Smith" <carlos-smith sympatico.ca> writes:
"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.
Feb 20 2007
prev sibling next sibling parent reply Tyler Knott <tywebmail mailcity.com> writes:
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?
Feb 20 2007
parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
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.
Feb 21 2007
prev sibling parent reply "Carlos Smith" <carlos-smith sympatico.ca> writes:
"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...
Feb 21 2007
next sibling parent reply mario pernici <mario.pernici mi.infn.it> writes:
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)
Feb 21 2007
parent Kirk McDonald <kirklin.mcdonald gmail.com> writes:
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
Feb 21 2007
prev sibling parent mario pernici <mario.pernici mi.infn.it> writes:
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)
Feb 21 2007