Мои вопросы:
- Гарантируется ли равенство указателей функций стандартом C?
- Если ответ на (1) да. Так ли это, независимо от того, получен ли указатель в разных конечных единицах компиляции (например, в основном исполняемом файле и в общей библиотеке)?
- Как с этим справляется динамический загрузчик? (Я могу подумать о нескольких причинах, по которым это может быть сложно, все они связаны с кодом PIC (например, таблицы GOT в elf и любой эквивалентный 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
a == b
с помощью одной инструкции; можно свободно выполнять арифметические действия для преобразования каждого изa
иb
из любого формата, в котором они находятся, в полный уникальный адрес, а затем сравнивать полученные полные адреса. 20.02.2013FP_SEG
,FP_OFF
. 20.02.2013