Reputation: 11232
I know it sounds a bit wierd but this is what I want to do: Lets say I have a function void f()
and I want to add tracing for this method. I want to trace the enrty of this function and the exit of the function by having trace messages such as "Entered function f" and "Exited function f". I don't want to add manual trace entries for the entry and exit as I might missout on some of return paths. So is possible to use the template magic at compile time and have these strings automatically generated. i.e. what I want to achieve is
void f()
{
some_template<magic>("f");
}
This should add a trace message "Entered function f" in constructor and "Exited function f" in destructor. I want it compile time and don't want to create any runtime objects. Is it possible in C++? any pointers where I can find more info if this can be achieved?
Upvotes: 4
Views: 336
Reputation: 12932
If you are really serious about this, using AspectC++ is one option. However, the threshold for doing so is quite high and I think you'll find yourself flooded with output if you do anything like this. A better option would be to use the debugger (setting breakpoints that print some output) or good ol' printf/cout wrapped in a class like DeadMG suggests. The ___FILE___
and ___LINE___
could be useful input to such a class.
Upvotes: 0
Reputation: 179779
All code is created at compile time anyway, so what's the problem with a class? The compiler will stick the constructor and destructor calls where they belong, and that's precisely what you want. The runtime cost is calling those functions, which is entirely unavoidable since it's your goal.
It may appear that saving "f"
would cost you a char const*
, but any decent optimizer will note that the string literal is a constant that doesn't change throughout the function, so it doesn't need to be stored but can be reloaded. Let the optimizer decide whether it's efficient to cache the pointer; I can't predict it.
Upvotes: 0
Reputation: 76778
The point at which the method is left is only known at runtime, since any kind of exception can happen at any point in your code (generally speaking). Hence, no compile-time solution is possible here.
Upvotes: 4
Reputation: 146910
You really need to ask your debugger or compiler to perform this job. There's no way that you can use RAII without creating an object, and in addition, no template can have access to the name of your function.
However, if you can accept an object, then it's no big deal.
class tracer {
std::string exit;
public:
tracer(std::string entry, std::string exit_)
: exit(exit_) {
std::cout << entry;
}
~tracer() { std::cout << exit; }
};
void f() {
tracer scope("Oh hai, I is entering f()", "Oh bai, I is leaving f()");
}
Upvotes: 4