gpt4 book ai didi

c - C 中的函数指针相等

转载 作者:太空狗 更新时间:2023-10-29 16:34:09 25 4
gpt4 key购买 nike

我的问题:

  1. C 标准是否保证函数指针相等?
  2. 如果 (1) 的答案是肯定的。不管指针是在不同的最终编译单元(例如主可执行文件和共享库)中获得的,都是这种情况吗?
  3. 动态加载器如何处理这个问题? (我可以想到这可能很棘手的几个原因,所有原因都与 PIC 代码有关(例如 elf 中的 GOT 表以及 COFF 使用的任何等效表))。不管 (1) 和 (2) 是什么,linux 加载程序似乎都能保证这一点。

这是一个例子。上面的问题归结为 C 是否保证 main.c 打印的内容:"Function equality: 1""Function equality: 0",在第一种情况下,动态加载器如何实现这一点。

common.h:

extern void * getc_main;
extern void * getc_shared;
void assign_getc_shared();

main.c:

#include <stdio.h>
#include "common.h"

int main()
{
getc_main = (void*) getc;
assign_getc_shared();
printf("Function equality: %d\n", getc_main == getc_shared);
return 0;
}

共享.c:

#include <stdio.h>
#include "common.h"

void assign_getc_shared()
{
getc_shared = (void*) getc;
}

在 Unix 中,这将使用以下命令进行编译:

cc -shared -fPIC -o libshared.so shared.c
cc -o main main.c -L. -lshared

并执行:

LD_LIBRARY_PATH=. ./main

最佳答案

C 2011(N1570 委员会草案)6.5.9 6:“两个指针比较相等当且仅当......两者都是指向相同......功能......的指针。所以,是的,指向同一个函数的两个指针比较相等。

当一个函数的地址被取入两个不同的目标模块时,编译器会在目标代码中放置一个占位符。当对象模块在运行时链接到可执行文件或链接到动态库时,该占位符将被填充。

对于动态库,要么动态加载器根据需要填充可执行文件中的所有占位符,要么每个函数的地址实际上是一些跳转到实际函数的 stub 代码的位置,以及该 stub 中或由该 stub 使用的占位符代码由动态加载器填充。

此外,请注意一个可执行文件可以包含一个函数的多个实例。编译器可能会在几个地方内联插入函数,或者出于自身原因,可能会包含函数的特殊化版本和通用版本。但是,当取函数的地址时,编译器必须提供单个通用版本的地址。 (或者编译器必须确保程序的行为就好像已经完成了一样。例如,如果编译器可以检测到程序没有比较指针,那么理论上它可能能够为地址的某些实例使用不同的地址的功能。)

关于c - C 中的函数指针相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14985423/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com