Thread overview
How to get a function name (string) @ compile time
Nov 02, 2008
Denis Koroskin
Nov 03, 2008
Denis Koroskin
Nov 03, 2008
Simen Kjaeraas
Dec 09, 2018
Andrew Pennebaker
Dec 09, 2018
Stanislav Blinov
November 02, 2008
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

November 02, 2008
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);
}
November 03, 2008
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

November 03, 2008
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.
November 03, 2008
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
December 09, 2018
On Monday, 3 November 2008 at 12:29:16 UTC, Simen Kjaeraas wrote:
> 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.

Er, when I try to use either foo.stringof, or __trait(identifier, foo), I always get that binding name, rather than the original function name, sad panda.

I can only print out the current variable name, but I want to print the name of the function declaration, no matter how deeply I pass that first function pointer into different calls :/
December 09, 2018
On Sunday, 9 December 2018 at 03:29:27 UTC, Andrew Pennebaker wrote:

> Er, when I try to use either foo.stringof, or __trait(identifier, foo), I always get that binding name, rather than the original function name, sad panda.
>
> I can only print out the current variable name, but I want to print the name of the function declaration, no matter how deeply I pass that first function pointer into different calls :/

You're confusing function pointer with the function symbol. This will not give you the function name:

import std.stdio;

void wrap(F)(F f) { writeln(__traits(identifier, f)); }
int foo() { return 0; }
void main() { wrap(&foo); }

But this will:

import std.stdio;

auto wrap(alias f, Args...)(auto ref Args args) {
    import std.functional : forward;
    writeln("Calling ", __traits(identifier, f));
    return f(forward!args);
}

int foo() { return 42; }
size_t bar(string x) { return x.length; }

void main() {
    assert(wrap!foo == 42);
    assert(wrap!bar("hello") == 5);
}

December 10, 2018
On Sunday, 9 December 2018 at 03:29:27 UTC, Andrew Pennebaker wrote:
> On Monday, 3 November 2008 at 12:29:16 UTC, Simen Kjaeraas wrote:
>> On Mon, 03 Nov 2008 12:33:05 +0100, Denis Koroskin <2korden@gmail.com> wrote:
>>
>>> [...]
>>
>> 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.
>
> Er, when I try to use either foo.stringof, or __trait(identifier, foo), I always get that binding name, rather than the original function name, sad panda.
>
> I can only print out the current variable name, but I want to print the name of the function declaration, no matter how deeply I pass that first function pointer into different calls :/

You may want to look at https://forum.dlang.org/post/yxobqahkvfcpcvidqppo@forum.dlang.org