New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[enh] Issue 5140 - Implement __FUNCTION__, __PRETTY_FUNCTION__ and __MODULE__ #1462
Conversation
Expression *FuncInitExp::semantic(Scope *sc) | ||
{ | ||
//printf("FuncInitExp::semantic()\n"); | ||
type = Type::tchar->invariantOf()->arrayOf(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type::tstring
I like |
If a function which has the bool func(string func = __FUNCTION__) { return true; }
enum b = func(); // CTFE in module scope
void main(){} |
Good point. I think in such a case |
But, it seems to me that is an exceptional behavior of the design of |
Other languages probably don't have to deal with this due to the lack of CTFE, it's why I forgot about this test-case. An empty string could be good. |
Since |
This is very useful for tracing and logging function calls, for example I use this kind of thing for error logging. I'm very hopeful this is approved! Does the proposed fix include a version that supplies the full function signature? The full function sig is required to distinguish which overloaded function was called, and what function template instantiation was called. This is rather important and should not be overlooked. |
Yes, but only when used in the parameter list. When used as a statement it returns the current function name.
No, however we could use a separate |
I reopened so github would update its diff view. I'll try to implement |
Nice. IMHO I think we should go with |
If we implement a version with full type signature it will be easier to use If we end up using |
If we issue that warning the natural question is, why didn't we name the bloody thing |
Yeah, it might also help with porting C and C++ code to D if we use the longer version. I'll revert back to using the longer version. |
I have a little bit of a problem. |
My thought is that we need to stop putting Though, yes, the unqualified version seems fine to me. |
Actually nevermind, I should simply use:
This is how GCC does it. |
Yes, I was going to suggest that. What does it do with class and struct function members? |
Update: Implemented |
@RobT2012 See the test-case, it's in the diff view. |
If If not it would probably be better to have a non-qualified |
Yah, |
@AndrejMitrovic @andralex |
I was just wondering how easy it is to figure the module from the qualified function name, i.e. if we have |
I think it would be difficult to tell, perhaps impossible due to nested levels. A person may be able to figure it out, but not an algorithm unless the algorithm has access to the module name. This does bring up a point: For logging purposes, we may not be able to tell which function was called when it's a nested function whose parent is overloaded or templated unless everything at levels above are fully qualified. |
We could figure module out via introspection, but that's arcane. I think |
Things are fine as they are. File and line belong together, but a template that wants to trace by module would take |
If we have auto full = __MODULE__ ~ __FUNCTION__;
auto part = __FUNCTION__;
//vs
auto full = __FUNCTION__;
auto part = __FUNCTION__[__MODULE__.length .. $]; |
Just consider that we should always try and avoid unnecessary memory allocations during runtime. For me, the primary use is for logging, so I would normally always append the full module name, and always use the full signature form of the function. Someone else however may have different needs. |
This crashes but only with mixin template T()
{
string fact()
{
mixin("return " ~ __FUNCTION__ ~ "();");
}
}
void main()
{
mixin T!() X; // __FUNCTION__ = test.main.T!().fact
} However it's unrelated to this pull, I've filed it as Issue 9303. |
I prefer to leave them fully-qualified to avoid bugs from any eventual abuse. Someone might end up using them in metaprogramming to issue function calls. I want them to get a compiler error if the function is wrongly-qualified rather than accidentally picking up some function that happens to be defined in the current scope.
|
I think a typical use case is: void fun(string caller = __FUNCTION__)(int x, double y) { ... } If |
Reopened after implementing template argument support. It didn't originally work as templates do not pass the right calling scope when issuing a call to Note that the reason |
__MODULE__ feature.
Fixed-up failure due to another pull affecting output, should be ready for a merge after green. |
Bump. It is rather useful addition. @andralex any final words about it? |
Sweet! I'll merge now. cc @WalterBright |
[enh] Issue 5140 - Implement __FUNCTION__, __PRETTY_FUNCTION__ and __MODULE__
Don't forget to add appropriate documentation for these changes. |
Yeah. Btw, we should have some kind of collective name for all these magic keywords so we know how to refer to them. What would be a good name for these? |
"Special constants" |
Excellent! I'll try using these new functions asap. Big thanks for the effort! |
I was going to suggest something along the lines of "reflection" or "introspection" but it doesn't really matter so long as there's a reasonable name for them. One question is where in the docs is best for this stuff? |
Well they're not really "constant" per say. I was just about to use "special keywords", but it can go either way. Edit: I mean "special tokens", this would sound nice. |
They're already in |
Argh I wanted to say "Special Tokens". |
Why in templates? These "special keywords" can be used in non-templated situations, in addition I would never think to look in a section about templates when looking for something like this. traits.html seems more appropriate to me. |
I think the're actually special constants. You can't e.g. do LINE++. |
Now that this is done, perhaps class Throwable and derivatives should be extended to include the function name? |
"Context expressions" |
http://d.puremagic.com/issues/show_bug.cgi?id=5140
__FUNCTION__
is a common feature found in other languages and compilers. C99 defines it as__function__
, although various compilers use their own naming (uppercase or lowercase, sometimes__func__
).List of compilers that I know of implementing the feature:
__FUNCTION__
will show the fully qualified name of the current function (when used as a statement in a function), or the calling function (when used in a parameter). If the function was called outside of a function scope (e.g. global enums initialized with CTFE), it returns an empty string.__PRETTY_FUNCTION__
is similar, except it also shows the function modifiers and parameters.__MODULE__
shows the fully qualified module name (which may be different from the file name). When used in a parameter it will show the fully qualified name of the module where the call was issued.