函数指针地址总是静态的吗?

时间:2018-06-10 03:24:00

标签: c function pointers

如果函数指针在用于另一个线程运行之前作用范围,指针是否无效?或者函数指针总是有效的,因为它们指的是不会移动的可执行代码"?

我认为我真正的问题是指针指向(函数)的内容是否会发生变化,或者在程序的整个生命周期中该值是否为静态

的伪代码:

static void func(void) { printf("hi\n"); }

int main(void)
{
    start_thread();
    {
        void (*f)(void) = func;
        // edit: void run_on_other_thread(void (*f)(void));
        run_on_other_thread(f); // non-blocking. 
    }
    join_thread();
}

2 个答案:

答案 0 :(得分:1)

在C基本语言中,函数指针的值永远不会变为无效。它们指向函数,并且函数在程序执行的整个时间内都存在。指针的值对整个程序有效。

包含指针的对象可能具有有限的生命周期。 (注意:问题提到范围,但范围是源代码中的 where ,标识符可见。生命周期在程序执行期间 时,对象存在。)在问题void (*f)(void) = func;中,f是具有自动存储持续时间的对象。一旦执行了块,它就在末尾定义,f不再存在,并且对它的引用具有未定义的行为。但是,分配给f仍然是有效值。例如,如果我们定义int x = 37;,并且x的生命周期结束,那么这并不意味着您不能再在程序中使用值37。在这种情况下,f所拥有的值(func的地址)仍然有效。在整个程序的执行过程中,func的地址可以继续使用。

Xypron’s answer中讨论的关于动态链接函数或动态创建函数的情况将是C语言的扩展。在这些情况下,它不是指针对象的生命周期,而是事实上函数本身被从内存中删除,导致指针不再是原始函数的有效指针。

答案 1 :(得分:0)

函数指针是否仍然有效取决于其用法。

如果它指向进程源代码中的函数,它将在进程的运行时期间保持有效。

如果使用函数指针指向动态链接库中的函数,则在卸载库时指针将变为无效。

可以编写重定位的代码。例如。当Linux内核启动时,它会重新定位自己,改变函数的地址。

你可以调用一个运行时编译器,它在程序执行期间在内存中创建函数,当对象超出范围时可能会重用内存。

正如所说的那样。