static — C ++ различаются между связыванием с .o и с .a файлом: другое поведение, почему?

Я ожидал, что:

связь с файлом .o и связь с файлом .a, заархивированным из файла .o, не должны иметь различий.

Но на самом деле это не так. У меня есть 2 исходных файла, каждый из которых объявляет 1class + 1 статический объект + 1 функцию и main.cpp, который вызвал одну из функций

$cat First.cpp
#include<stdio.h>
struct First{
First(){printf("First\n");}
};
void f1(){printf("f1\n");}//Not called in main
static First f_obj;

$cat Second.cpp
#include<stdio.h>
struct Second{
Second(){printf("Second\n");}
};
void f2(){printf("f2\n");}//Not called in main
static Second s_obj;

$cat main.cpp
void f2();
int main()
{
f2();
return 0;
}

$g++ -c First.cpp  -fPIC
$g++ -c Second.cpp -fPIC
$ar -rvs libmystatic.a  First.o Second.o
$g++ main.cpp -o MylinkSta -lmystatic -L.
$g++ main.cpp -o MyDirect First.o Second.o

$./MylinkSta
Second
f2

$./MyDirect
Second
First
f2

Так что вы можете видеть

(1) Результат выполнения MylinkSta не создает первый объект, но MyDirect делает.

(2) В то время как «Второй» объект всегда создается.

Я действительно не вижу никакой разницы между связыванием с двумя файлами ‘.o’ и связыванием с файлом ‘.a’, который заархивирован из этих двух файлов ‘.o’.

Почему они ведут себя по-разному? Я экспериментировал с gcc / clang на rhel / ubuntu, все показывают один и тот же результат. Интересно, есть ли какой-либо стандарт C ++ ABI, который говорит, когда должен быть действительно вызван созданный статический / глобальный объект, с помощью какой-либо опции связывания?

Откуда эта разница?

4

Решение

Это связано с семантикой статических библиотек. Компоновщик будет включать файлы из статической библиотеки только в том случае, если он содержит символ, на который ссылается какой-либо объектный файл, который предшествует ему в командной строке (например, main.cpp ссылается на f2 из Second, поэтому он включен). Вы можете изменить это поведение, окружив свою библиотеку

-Wl,--whole-archive -lmystatic -Wl,--no-whole-archive

но это не стандартно

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector