2016-11-02 47 views
8

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ść?

Odpowiedz

4

Prawdopodobnie jestem w najlepszej sytuacji, aby rozwiązać ten problem, ponieważ jestem tym, który to zrobił. I może ci się nie spodobać odpowiedź. :-)

Kiedy tworzyłem libC++ moim jedynym celem było macOS (OS X). To było tak, zanim libC++ było open-source. A moją główną motywacją do forsowania inline było kontrolowanie ABI dylib, który zostałby wypchnięty przez wydania OS. Wymuszona funkcja inline nigdy nie pojawiłaby się w dylib, a więc mogłem na nią liczyć wyłącznie w nagłówku (który miał inny system dostarczania niż wydania systemu operacyjnego).

Nigdy nie brałem pod uwagę dodatkowego atrybutu "ukrytego" w ramach tej decyzji, ponieważ było to po prostu niepotrzebne komplikacje dla mnie. Chciałem, aby funkcja żyła w nagłówku i nigdy nie została umieszczona w dylib i to było to. Więc twoja pierwsza kula jest zgodna z prawdą.

Jestem podekscytowany tym, że libC++ wykroczył poza swój pierwotny zakres i życzę dalszych starań. Chętnie udzielę wszelkich dodatkowych informacji, które mogą pomóc w osiągnięciu celu.

+0

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