#define call_foo(...) \
do { \
int first; \
int second; \
int third; \
(__VA_ARGS__); \
foo(first, second, third); \
} while (0)
....
int main(void) {
call_foo(first=9, third=5, second=3);
}
Erste Rückgabewerte in einem nicht klobig Weise schwieriger ist.
Dies würde ermöglichen es Ihnen, sehr dumme Dinge zu tun (was ich hasse) wie Standardwerte für Ihre Argumente angeben:
#define call_foo(...) \
do { \
int first = default_first; \
int second; \
int third; \
(__VA_ARGS__); \
foo(first, second, third); \
} while (0)
Dies wird fehlschlagen, wenn Sie tun:
int first = 9;
call_foo(first=first, third=5, second=3);
weil in Die Makroerweiterung first=first
bedeutet, dass die lokale first
mit sich selbst initialisiert wird. Ich habe darüber nachgedacht, dies mit der Preprozessor-Verkettung zu umgehen, aber das wird komplizierter. Sie müssten die gleiche Anzahl von Makroparametern wie Funktionsparameter auflisten.
#define call_foo(x, y , z) \
do { \
int call_foo_first; \
int call_foo_second; \
int call_foo_third; \
call_foo_##x; \
call_foo_##y; \
call_foo_##z; \
foo(call_foo_first, call_foo_second, call_foo_third); \
} while (0)
Die call_foo_##x;
Linie würde in call_foo_first=first;
wenden, wenn im vorherigen Beispiel genannt, so dass jedes Symbol hat seinen eigenen einzigartigen Namen. Dies macht den Standard-Trick schwieriger, weil Sie etwas angeben müssen, um diesen Punkt in der Makroargumentliste zu füllen.
Wenn das Makro mit einem Standardargument für first
definiert wurden dann:
call_foo(first, third=7, second=8);
Dies zwingt Sie alle Parameter zur Liste (oder zumindest etwas, das in Rechts C führt - Sie zweimal zweite aufgeführt haben könnte, aber du hättest das trotzdem machen können) um dieses Makro zu benutzen.
Ich denke, Sie sollten in der Lage sein, die letzte Version dieses für Variable Argument gelisteten Makros/Funktionen zu erweitern, aber die optionalen Parameter müssten immer noch am Ende der Liste übergeben werden und Sie müssten alle davon verbrauchen die obligatorischen Stellen, bevor Sie zu den optionalen Argumenten kamen.
Ich mag das. Sehr kreativ und sauber. – nategoose
Beachten Sie jedoch, dass es mit dieser Methode unmöglich ist, ein Null/NULL-Argument von einem ausgelassenen Argument zu unterscheiden. – caf