开发者

Compile time RAII type of behavior using C++

开发者 https://www.devze.com 2023-03-09 17:58 出处:网络
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 th

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?


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.


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()");
}


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号