Мои вопросы:
- Является ли равенство указателя функции гарантированным стандартом C?
- Если ответ (1) - да. Это дело независимо от того, какой указатель получен в разных конечных единицах компиляции (например, основной исполняемый файл и общая библиотека)?
- Как динамический загрузчик справляется с этим? (Я могу подумать о нескольких причинах, для которых это может быть сложно, все это связано с кодом PIC (например, таблицы 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;
}
shared.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