-fPIC (Position Independent Code) - это флаг компилятора GCC/Clang, который генерирует позиционно-независимый код. Такой код может быть загружен и выполнен по любому адресу в памяти без модификации.
Основные применения:
// Пример кода до компиляции с -fPIC
extern int global_var;
int foo() {
return global_var + 42;
}
После компиляции с -fPIC (упрощенно):
foo:
mov eax, [rip + global_var@GOTPCREL] # Доступ через GOT
add eax, 42
ret
Характеристика | PIC-код (-fPIC) | Не-PIC код |
---|---|---|
Размер | Больше (на 10-20%) | Меньше |
Производительность | Немного медленнее | Быстрее |
Гибкость | Можно загружать по любому адресу | Фиксированный адрес |
Безопасность | Поддержка ASLR | Уязвим к атакам |
g++ -fPIC -c mylib.cpp -o mylib.o
g++ -shared mylib.o -o libmylib.so
При попытке создать shared-библиотеку без -fPIC:
g++ -c mylib.cpp -o mylib.o
g++ -shared mylib.o -o libmylib.so
# Ошибка: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object
Современные CPU (x86-64, ARM) имеют специальные оптимизации для PIC:
Это уменьшает накладные расходы PIC-кода до 1-3%.
-fPIC критически важен для:
Основные компромиссы:
В современной разработке рекомендуется всегда использовать -fPIC для библиотек, так как преимущества перевешивают небольшие потери производительности.
Для максимальной производительности в критичных участках можно:
__attribute__((visibility("hidden")))
)