Chcę napisać makro w C, które akceptuje dowolną liczbę parametrów, a nie określoną liczbę
przykład:
#define macro( X ) something_complicated( whatever( X ) )
gdzie X
jest dowolna liczba parametrów
Potrzebuję tego, ponieważ whatever
jest przeciążony i można go wywołać z 2 lub 4 parametrami.
Próbowałem zdefiniować makro dwa razy, ale druga definicja zastąpiła pierwszą!
Kompilator, z którym pracuję to g ++ (a dokładniej mingw)
c
g++
c-preprocessor
variadic
hasen
źródło
źródło
Odpowiedzi:
Sposób C99, obsługiwany również przez kompilator VC ++.
źródło
##
nie jest potrzebne i nie jest przenośne.#define FOO(...) printf(__VA_ARGS__)
wykonuje pracę w przenośny sposób;fmt
parametr może być pominięte z definicji.__VA_ARGS__
to standardowy sposób na zrobienie tego. Nie używaj hacków specyficznych dla kompilatora, jeśli nie musisz.Jestem naprawdę zirytowany, że nie mogę komentować oryginalnego postu. W każdym razie C ++ nie jest nadzbiorem C. Kompilowanie kodu C przy pomocy kompilatora C ++ jest naprawdę głupie. Nie rób tego, co robi Donny Don't.
źródło
class
zklass
celu umożliwienia kompilowania z C ++. Pamiętaj również, że istnieją pewne różnice, które Cię potkną; na przykład operator trójskładnikowy nie jest oceniany w ten sam sposób w obu językach, ainline
słowo kluczowe oznacza coś zupełnie innego (jak dowiedziałem się z innego pytania).Nie sądzę, żeby to było możliwe, można to sfałszować podwójnymi parenami ... tak długo, jak nie potrzebujesz pojedynczych argumentów.
źródło
Jeśli kompilator nie rozumie różnych makr, możesz także usunąć PRINT za pomocą jednego z poniższych:
lub
Pierwszy komentuje instrukcje PRINT, drugi zapobiega instrukcji PRINT z powodu warunku NULL if. Jeśli ustawiono optymalizację, kompilator powinien usuwać nigdy niewykonywane instrukcje, takie jak: if (0) print („hello world”); lub ((nieważny) 0);
źródło
if
wersja „nie rób tego”, która uwzględnia strukturę kodu, to:if (0) { your_code } else
średnik po zakończeniu rozwijania makraelse
. Dowhile
wygląda jak wersja:while(0) { your_code }
Problem zdo..while
wersji jest to, że koddo { your_code } while (0)
jest wykonywana raz, gwarantowane. We wszystkich trzech przypadkach, jeśliyour_code
jest pusty, jest to właściwedo nothing gracefully
.wyjaśniono tutaj dla g ++, chociaż jest to część C99, więc powinno działać dla wszystkich
http://www.delorie.com/gnu/docs/gcc/gcc_44.html
szybki przykład:
źródło
__VA_ARGS__
, chociaż są one obsługiwane przez kompilatory również we wcześniejszych wersjach, jako rozszerzenie.