2012-02-24 11 views
6

Właśnie odkryłem dyrektywę #pragma weak w GCC:Jak szeroko obsługiwane jest słabe pragma i czy przezwycięża problem używania atrybutu gcc?

6.57.9 Słaby pragma

Dla zgodności z SVR4, GCC obsługuje zestaw dyrektyw #pragma do deklarowania symbole być słabe, słabe i definiowania aliasów .

#pragma weak symbol

Ten symbol Pragma deklaruje się być słaby, jakby deklaracja miała atrybut o tej samej nazwie. Pragma może pojawić się przed lub po deklaracji symbolu. Nie jest błędem, aby symbol nigdy nie był zdefiniowany.

#pragma weak symbol1 = symbol2

Ten Pragma deklaruje symbol1 być słaby alias symbol2. Jest to błąd, jeśli symbol2 nie jest zdefiniowany w bieżącej jednostce tłumaczeniowej.

http://gcc.gnu.org/onlinedocs/gcc/Weak-Pragmas.html

Pomimo faktu, że deweloperzy GCC generalnie nie lubią #pragma i zachęcamy do korzystania z __attribute__ zamiast na wszelkiego rodzaju rzeczy, które mogłyby być pragma, jestem skłonny uwierzyć #pragma weak może faktycznie być lepsze podejście oparte na atrybut, który wygląda następująco:

extern __typeof(old_name) new_name __attribute__(weak, alias("old_name")) 

oprócz brzydoty wymagające __typeof (lub wymagając, aby wiedzieć, rodzaj i przeliterować exp nieważne, nawet jeśli jest to naprawdę złożony typ funkcji), największym problemem podejścia opartego na atrybutach jest to, że "old_name" musi zostać przekazany do gcc jako ciąg, który zostanie wklejony dosłownie do wygenerowanego zespołu. Jest to problematyczne, ponieważ różne systemy mają różne cechy znakowania nazw (najpopularniejsze są przedrostki podkreślenia wszystkich nazw symboli C lub w ogóle nie robią nic), a aby przekazać poprawny ciąg do atrybutu alias, musisz znać nazwę konwencja systemu, dla którego budujesz, która tak naprawdę nie jest wiedzą, która należy do biblioteki na poziomie aplikacji, gdzie przydatne mogą być słabe aliasy.

Wydaje się, że składnia #pragma weak new_name = old_name pozwala uniknąć tego problemu, posługując się obydwoma nazwami na poziomie kompilatora, gdzie t może je odpowiednio zmapować, chyba że się mylę.

Po zakończeniu wszystkich wstępnych pytań, moje aktualne pytania brzmią: Czy jestem w błędzie odnośnie do #pragma weak posiadania tej przewagi? i Czy wszystkie współczesne kompilatory w systemach typu unix (gcc, pcc, tinycc, icc, llvm/clang, itp.) Nadal obsługują tradycyjny SVR4 #pragma weak?

Jestem świadomy następującym podobne pytanie, ale nie wydaje się to samo, a odpowiedzi na nie zadowalająco rozwiązać moje pytanie:

How portable is weak linking? #pragma weak my_symbol

Odpowiedz

4

ani „#pragma weak” ani __attribute__ jest częścią standardu C, więc żadne z nich nie jest ściśle przenośne. Niektóre kompilatory C starają się być kompatybilne z większością rozszerzeń GCC do standardu C, inne nie.

Ogólnie mówiąc, jeśli jesteś już na poziomie mówienia o słabych symbolach i słabych aliasach, prawdopodobnie jesteś już w punkcie, w którym możesz napisać kod, który jest niezawodnie przenośny w kompilatorach. Nawet twój toolchain będzie tutaj problemem (w tym zwłaszcza linkerem) - nie sądzę, że możesz polegać na niczym bez dokładnego testowania.

Edytowane w celu dodania: Oryginalny plakat skomentował poniżej pytanie, czy pragmatycznie, #pragma jest nie mniej przenośna niż __attribute__.

Moje własne doświadczenie było następujące: dobrze jest móc ukryć wszystkie takie rzeczy wewnątrz makr lub innych wygenerowanych kodów, aby ułatwić przenoszenie. __attribute__ jest łatwiejsze do ukrycia w pliku nagłówkowym przenośności. Na przykład, co najmniej jedno jądro BSD ma cdefs.h, które używa __attribute__ wewnątrz makra, aby scentralizować sposób, w jaki słabe definicje są wykonywane w bazie kodu, aby umożliwić łatwiejsze zmiany w nowych kompilatorach. #pragma jest trudniejsze w użyciu w ten sposób. Takie makro może ukryć różnicę pomiędzy różnymi manglings nazwa za pomocą operatora CPP umieszczania („##”) itp

Jako przykład takiego zastosowania, patrz http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/sys/cdefs.h?rev=1.89.6.1&content-type=text/x-cvsweb-markup

+0

przypuszczać, że to rozwiązanie może być przydatne dla niektórych czytelników, ale nie dostarcza żadnych informacji, których jeszcze nie miałem. Moje pytanie brzmi w zasadzie, czy '#pragma weak' jest * bardziej przenośne niż *' __attribute __ ((słabe, alias)) lub przynajmniej * nie mniej przenośne *, włączając w to kwestię, czy mam rację, unikając wymieszania nazwy kwestia. –

+1

Żadne z przenośnych urządzeń nie jest przenośne. Jeśli chodzi o to, czy #pragma jest "nie mniej przenośna", sugeruję, że prawdopodobnie nie jest to dobry wybór, i wyjaśnię, dlaczego w powyższej edycji. – Perry

+1

Dlatego właśnie C99 dodało '_Pragma', które powinno działać zawsze, gdy' # pragma' działa ... –

Powiązane problemy