www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to get a function name (string) compile time

reply Daniel Ribeiro Maciel <daniel.maciel gmail.com> writes:
How do we get a function name (string)   compile time?

I need to do stuff like (in C)

#include <stdio.h>

#define HELLO( func ) \
  printf( "calling " #func "\n" ); \
  func();

void foo()
{
	printf( " foo" );
}

int main()
{
	HELLO( foo );
	printf( "\n" );
}

The output is:
calling foo
 foo

Thanks in advance,
Daniel
Nov 02 2008
parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 03 Nov 2008 01:59:56 +0300, Daniel Ribeiro Maciel  
<daniel.maciel gmail.com> wrote:

 How do we get a function name (string)   compile time?

 I need to do stuff like (in C)

 #include <stdio.h>

 #define HELLO( func ) \
   printf( "calling " #func "\n" ); \
   func();

 void foo()
 {
 	printf( " foo" );
 }

 int main()
 {
 	HELLO( foo );
 	printf( "\n" );
 }

 The output is:
 calling foo
  foo

 Thanks in advance,
 Daniel

Just in case you know little D here is the source code, explanation and comparison to C++: import std.stdio; // this is used to import writefln() - a function similar to printf (but typesafe) // this is a template function that takes almost anything (close to C++ templates and C macros) void print(alias functionName)() { // stringof is used to take a string representation of the identifier writefln("Calling ", functionName.stringof); // let's invoke it! This will succeed if functionName is a function, pointer to function, // delegate or an object that have overloaded opCall() (similar to C++ operator()) functionName(); } void foo() { writefln(" foo"); // same as printf(" foo); } void main() { // foo is a global (free) function. it is passed to the template function. // In C++ you would do print<foo>(); (but C++ doesn't support specializing // templates with functions nor does it have .stringof) print!(foo); }
Nov 02 2008
next sibling parent Daniel Ribeiro Maciel <daniel.maciel gmail.com> writes:
Denis Koroskin Wrote:

 On Mon, 03 Nov 2008 01:59:56 +0300, Daniel Ribeiro Maciel  
 <daniel.maciel gmail.com> wrote:
 
 How do we get a function name (string)   compile time?

 I need to do stuff like (in C)

 #include <stdio.h>

 #define HELLO( func ) \
   printf( "calling " #func "\n" ); \
   func();

 void foo()
 {
 	printf( " foo" );
 }

 int main()
 {
 	HELLO( foo );
 	printf( "\n" );
 }

 The output is:
 calling foo
  foo

 Thanks in advance,
 Daniel

Just in case you know little D here is the source code, explanation and comparison to C++: import std.stdio; // this is used to import writefln() - a function similar to printf (but typesafe) // this is a template function that takes almost anything (close to C++ templates and C macros) void print(alias functionName)() { // stringof is used to take a string representation of the identifier writefln("Calling ", functionName.stringof); // let's invoke it! This will succeed if functionName is a function, pointer to function, // delegate or an object that have overloaded opCall() (similar to C++ operator()) functionName(); } void foo() { writefln(" foo"); // same as printf(" foo); } void main() { // foo is a global (free) function. it is passed to the template function. // In C++ you would do print<foo>(); (but C++ doesn't support specializing // templates with functions nor does it have .stringof) print!(foo); }

Thanx a lot! It worked for some functions. I found a problem though. If we change foo to: void foo( double i ) { writefln(" foo ", i ); } the compiler yields an error: test.d(30): function app.sandbox.main.foo (double i) does not match parameter types () test.d(30): Error: expected 1 arguments, not 0] line 30 is this: writefln("Calling ", functionName.stringof); Is this supposed to be a bug? Best regards, Daniel
Nov 02 2008
prev sibling next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Mon, 03 Nov 2008 04:11:20 +0300, Daniel Ribeiro Maciel  
<daniel.maciel gmail.com> wrote:

 Denis Koroskin Wrote:

 On Mon, 03 Nov 2008 01:59:56 +0300, Daniel Ribeiro Maciel
 <daniel.maciel gmail.com> wrote:

 How do we get a function name (string)   compile time?

 I need to do stuff like (in C)

 #include <stdio.h>

 #define HELLO( func ) \
   printf( "calling " #func "\n" ); \
   func();

 void foo()
 {
 	printf( " foo" );
 }

 int main()
 {
 	HELLO( foo );
 	printf( "\n" );
 }

 The output is:
 calling foo
  foo

 Thanks in advance,
 Daniel

Just in case you know little D here is the source code, explanation and comparison to C++: import std.stdio; // this is used to import writefln() - a function similar to printf (but typesafe) // this is a template function that takes almost anything (close to C++ templates and C macros) void print(alias functionName)() { // stringof is used to take a string representation of the identifier writefln("Calling ", functionName.stringof); // let's invoke it! This will succeed if functionName is a function, pointer to function, // delegate or an object that have overloaded opCall() (similar to C++ operator()) functionName(); } void foo() { writefln(" foo"); // same as printf(" foo); } void main() { // foo is a global (free) function. it is passed to the template function. // In C++ you would do print<foo>(); (but C++ doesn't support specializing // templates with functions nor does it have .stringof) print!(foo); }

Thanx a lot! It worked for some functions. I found a problem though. If we change foo to: void foo( double i ) { writefln(" foo ", i ); } the compiler yields an error: test.d(30): function app.sandbox.main.foo (double i) does not match parameter types () test.d(30): Error: expected 1 arguments, not 0] line 30 is this: writefln("Calling ", functionName.stringof); Is this supposed to be a bug? Best regards, Daniel

Yes, it is. For some reason it tries to evaluate function first and *then* take the stringof property (that is of the returned value), i.e. it rewrites it as "functionName().stringof". I have written about this bug 4 months ago ("Omittable parens is an evil" thread) but it is not fixed yet.
Nov 03 2008
prev sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Mon, 03 Nov 2008 12:33:05 +0100, Denis Koroskin <2korden gmail.com>  
wrote:

 On Mon, 03 Nov 2008 04:11:20 +0300, Daniel Ribeiro Maciel  
 <daniel.maciel gmail.com> wrote:

 Denis Koroskin Wrote:

 On Mon, 03 Nov 2008 01:59:56 +0300, Daniel Ribeiro Maciel
 <daniel.maciel gmail.com> wrote:

 How do we get a function name (string)   compile time?

 I need to do stuff like (in C)

 #include <stdio.h>

 #define HELLO( func ) \
   printf( "calling " #func "\n" ); \
   func();

 void foo()
 {
 	printf( " foo" );
 }

 int main()
 {
 	HELLO( foo );
 	printf( "\n" );
 }

 The output is:
 calling foo
  foo

 Thanks in advance,
 Daniel

Just in case you know little D here is the source code, explanation and comparison to C++: import std.stdio; // this is used to import writefln() - a function similar to printf (but typesafe) // this is a template function that takes almost anything (close to C++ templates and C macros) void print(alias functionName)() { // stringof is used to take a string representation of the identifier writefln("Calling ", functionName.stringof); // let's invoke it! This will succeed if functionName is a function, pointer to function, // delegate or an object that have overloaded opCall() (similar to C++ operator()) functionName(); } void foo() { writefln(" foo"); // same as printf(" foo); } void main() { // foo is a global (free) function. it is passed to the template function. // In C++ you would do print<foo>(); (but C++ doesn't support specializing // templates with functions nor does it have .stringof) print!(foo); }

Thanx a lot! It worked for some functions. I found a problem though. If we change foo to: void foo( double i ) { writefln(" foo ", i ); } the compiler yields an error: test.d(30): function app.sandbox.main.foo (double i) does not match parameter types () test.d(30): Error: expected 1 arguments, not 0] line 30 is this: writefln("Calling ", functionName.stringof); Is this supposed to be a bug? Best regards, Daniel

Yes, it is. For some reason it tries to evaluate function first and *then* take the stringof property (that is of the returned value), i.e. it rewrites it as "functionName().stringof". I have written about this bug 4 months ago ("Omittable parens is an evil" thread) but it is not fixed yet.

That's not the only error here. Your template function also calls foo with no arguments on the line below that bug. Fixing that would probably include the ParameterTypeTuple and ReturnType templates. -- Simen
Nov 03 2008