Chciałbym zrozumieć, dlaczego makro widoczności libC++ dla funkcji inline używa __forceinline
lub __attribute__((__always_inline__))
jako część atrybutów skojarzonych z funkcjami śródliniowymi.Dlaczego libcxx stosuje __forceinline lub GCC odpowiadające już ukrytym funkcjom wstawianym?
Na tle patrz:
Jeśli te funkcje inline będą oznaczone jako __visibility__("hidden")
każdym razie, dlaczego jest to konieczne, aby dodatkowo zmusić kompilator je inline ?
myślałem o tym trochę, i mam kilka hipotez, ale nie wydaje mi się całkowicie zadowalające:
- To jest zapewnienie, że symbol nie przypadkowo stają się częścią ABI. Jeśli podczas budowania biblioteki kompilator zdecydował się nie wstawiać tej funkcji, może potencjalnie stać się zewnętrznym symbolem, a zatem częścią ABI. Ale czy atrybut
hidden
nie byłby wystarczający? Podobnie, czy nie byłoby konieczne tylko wymuszenie wbudowania funkcji podczas budowania biblioteki? Konsumenci nie powinni się przejmować. - Ma to zapewnić, że funkcja nigdy nie ma definicji, aby uniknąć problemów ODR, gdzie kompilator nie wybiera funkcji inline w samej bibliotece, i nie wybiera inline funkcji w kodzie generowanym przez klienta biblioteki, co daje dwie różne definicje. Ale czy nie jest to oczekiwany (i zaakceptowany) wynik użycia
visibility("hidden")
? - Jest to specyficzne dla projektu libC++ jako implementacja standardowej biblioteki.
Pytam o to, ponieważ pracuję nad budową biblioteki C++, dla której mam nadzieję pewnego dnia ujednolicić ABI, i używam libC++ jako przewodnika. Do tej pory działało to dobrze, ale ten problem spowodował pewne drapanie głowy.
W szczególności mieliśmy zgłoszenia użytkowników narzekających, że MSVC odmówił honorowania atrybutu __forceinline
, co prowadzi do ostrzeżeń. Proponowane przez nas rozwiązanie polega na rozszerzeniu naszego analogu do INLINE_VISIBILITY tylko o __forceinline
(lub równoważnik GCC) podczas budowania biblioteki, zakładając pierwsze wyjaśnienie powyżej.
Jednakże, ponieważ nie jesteśmy całkowicie pewni, że rozumiemy uzasadnienie zmuszając funkcji inline być __forceinline
lub __attribute__((__always_inline__))
na pierwszym miejscu, jesteśmy trochę niezdecydowany do przyjęcia tego rozwiązania.
Czy ktoś może udzielić ostatecznej odpowiedzi, dlaczego libC++ odczuwa potrzebę wymuszania wbudowanych funkcji liniowych, nawet jeśli są one już udekorowane jako ukryta widoczność?
Podoba mi się ta odpowiedź, a dzięki za poświęcenie czasu na odpowiedź. Wygląda na to, że prawdopodobnie możemy kontynuować i ponownie ocenić, czy nasze kultywowanie ładunku __forceinline jest niepotrzebne i powinno zostać usunięte. Wygląda na to, że tak może być. Ponadto, jeśli interesuje Cię podejście, jakie podejmujemy lub udzielamy informacji zwrotnych, biblioteka, o której mowa, to libmongocxx: https://github.com/mongodb/mongo-cxx-driver/tree/master – acm