Nie, nie ma na to przenośnego sposobu. Z drugiej strony, w ogóle nie ma przenośnych sposobów używania #pragma. Z tego powodu wiele kompilatorów C / C ++ definiuje własne metody robienia rzeczy podobnych do pragmy i często można je osadzać w makrach, ale potrzebujesz innej definicji makra na każdym kompilatorze. Jeśli chcesz iść tą drogą, często kończysz na takich rzeczach:
#if defined(COMPILER_GCC)
#define Weak_b
#define Weak_e __attribute__((weak))
#elif defined(COMPILER_FOO)
#define Weak_b __Is_Weak
#define Weak_e
#endif
#define DEFINE_DELETE_OBJECT(type) \
Weak_b void delete_ ## type_(int handle) Weak_e; \
Weak_b void delete_ ## type(int handle) Weak_e;
W przypadku, gdy nie jest to oczywiste, chcesz zdefiniować Weak_b
i Weak_e
jako konstrukcje nawiasów rozpoczynających i kończących, ponieważ niektóre kompilatory, takie jak GCC, dodają atrybuty jako uzupełnienie do podpisu typu, a niektóre, jak MSC, dodają go jako przedrostek (a przynajmniej tak kiedyś minęły lata, odkąd używałem MSC). Posiadanie konstrukcji w nawiasach pozwala zdefiniować coś, co zawsze działa, nawet jeśli musisz przekazać całą sygnaturę typu do konstrukcji kompilatora.
Oczywiście, jeśli spróbujesz przenieść to do kompilatora bez wymaganych atrybutów, nie możesz nic zrobić, ale pozostawić makra rozwinięte do niczego i mieć nadzieję, że twój kod nadal działa. Jest to prawdopodobne w przypadku pragm czysto ostrzegawczych lub optymalizujących. W innych przypadkach nie tak bardzo.
Aha, i podejrzewam, że faktycznie musiałbyś zdefiniować Weak_b i Weak_e jako makra, które przyjmują parametry, ale nie chciałem czytać dokumentacji, aby dowiedzieć się, jak utworzyć słabą definicję tylko dla tego przykładu. Zostawiam to jako ćwiczenie dla czytelnika.