2011-09-08 66 views
12

如果我存储一个指向函数的指针,然后在我的程序执行期间的某个时间点,将它与同一函数的地址进行比较,两个地址是否保证相等。C函数是否保证有固定的内存地址?

E.g.

int foo(void){return 0;} 
int (*foo_p)(void) = &foo; 

assert(foo_p == &foo); 

在上面的代码中,断言总是保证成功吗?是否有任何的情况下函数的地址可以改变?

回答

17

每6.5.9:

两个指针比较相等当且仅当两者都是空指针,两者都指向同一对象(包括一个指向对象和子对象在其开始)或函数,它们都是指向同一个数组对象的最后一个元素之后的指针,或者是指向一个指向一个数组对象末尾的指针,另一个指向不同数组对象开始的指针碰巧紧跟着地址空间中的第一个数组对象。

(黑体字为补充强调。)

0

函数的地址,永远不会改变。许多程序都是围绕回调的概念构建的,如果函数的地址可能发生变化,则这些程序将不起作用。

如果假设函数的位置发生了变化,例如通过自修改程序,则对该函数的所有调用都会导致段错误或非常不确定的行为。编辑:澄清 - 函数符号就像指针一样,如果指针指向的内存不会将实际的指针变量归零,它仍会指向那里,就像函数调用仍然指向旧的被移动的位置一样功能。

虽然自修改程序是非常大的例外,但在这些日子里,二进制的代码段是写保护的,非常非常困难。