如何知道函数是否是从特定函数c ++调用的

时间:2012-04-11 23:19:24

标签: c++ callstack

我想知道是否有办法知道某个函数是否是从其他特定函数调用的。

doc(){
foo();
}

bar() {
doc();
}

foo() {
if (bar in the callStack ) { /* do this */}
}

谢谢!

5 个答案:

答案 0 :(得分:2)

如果不使用许多特定于平台的黑客攻击,则无法做到这一点。调试器会为您提供该信息,但一般情况下,如果不在C ++中使用ASM hackery,则无法访问堆栈。

如果你必须这样做,你的设计就会出错。你想做什么我们可以帮忙?

答案 1 :(得分:2)

这不是一个好主意或好的设计,但当然你可以使用另一个全球旗帜,如:

doc(){
   foo();
}

int inBar = 0;

bar() {
   inBar = 1;
   doc();
   inBar = 0;
}

foo() {
if (inBar) { /* do this */}
}

答案 2 :(得分:2)

您应该使用适合您的编译器的库。

对于海湾合作委员会,你可以想到Backtraces。这个基于GCC内置c/c++: call stack v.2

对于Visual C我听说过StackWalk64,但从未使用过它。

当然,你也可以制作自己的“痕迹”,但我认为这不是你想要的。

答案 3 :(得分:0)

您可以修改bar()以在输入时将全局bool设置为true,在退出时将false设置为false。 在foo()中测试bool会告诉你是否在bar()调用堆栈中。

namespace {
   bool test_bar = false;

}

void bar( ) {
   test_bar = true;

   // do stuff


   test_bar = false;
}

如果您需要以上工作在multi_threaded环境中,那么全局bool必须是线程本地的(使用类似boost :: thread_specific_ptr的东西) 这种构造只应该用于跟踪调试器中难以捕获的竞争条件,它是一个快速而肮脏的工具,其他用途表明设计很差。

答案 4 :(得分:0)

  

如何知道某个函数是否是从特定函数c ++

调用的

你做不到。但是,您可以将boolean参数添加到函数

foo(bool calledFromBar = false) {
     if (calledFromBar) { /* do this */}
}

并从bar设置此标志。但是,这将导致另一个问题 - 没有任何东西会阻止任何其他功能设置标志。

我认为这个(附加问题)可以通过这种方式修复:

class BarFlag{
private:
    bool flag;
protected:
    friend void doc();
    BarFlag(bool flag_)
    :flag(flag_){
    }
public:
    inline operator bool() const{
        return flag;
    }
    BarFlag()
    :flag(false){
    }
}

void foo(BarFlag flag = BarFlag()){
     if (flag){/*do it*/}        
}

//somewhere else
void doc(){
   foo(BarFlag(true));
}