Das Problem mit C variadics ist, dass sie wirklich danach, nicht wirklich in die Sprache ausgelegt sind verschraubt. Das Hauptproblem ist, dass die variadischen Parameter anonym sind, sie haben keine Handles, keine Identifikatoren. Dies führt dazu, dass die unhandlichen VA-Makros Verweise auf Parameter ohne Namen generieren. Es führt auch dazu, dass man den Makros sagen muss, wo die variadische Liste beginnt und welchen Typ die Parameter haben sollen.
Alle diese Informationen sollten in der Sprache selbst in der richtigen Syntax codiert werden.
Zum Beispiel könnte eine vorhandene C-Syntax mit formalen Parametern nach dem Auslassungs verlängern, wie so
void foo (... int counter, float arglist);
Vereinbarungs der erste Parameter für das Argument Zahl sein könnte und die zweite für die Argumentliste. Innerhalb des Funktionskörpers könnte die Liste syntaktisch als Array behandelt werden.
Mit einer solchen Konvention wären die variadischen Parameter nicht mehr anonym. Innerhalb des Funktionskörper kann der Zähler wie jeder andere Parameter referenziert werden und die Listenelemente können referenziert werden, als ob sie Array-Elemente eines Arrays Parameter waren, wie so
void foo (... int counter, float arglist) {
unsigned i;
for (i=0; i<counter; i++) {
printf("list[%i] = %f\n", i, arglist[i]);
}
}
Mit einem solchen Merkmal in die Sprache selbst gebaut Jeder Verweis auf arglist[i]
würde dann in die entsprechenden Adressen auf dem Stapelrahmen übersetzt werden. Es wäre nicht notwendig, dies über Makros zu tun.
Darüber hinaus würde die Anzahl der Argumente automatisch vom Compiler eingefügt werden, wodurch die Möglichkeit für Fehler weiter reduziert wird.
Ein Aufruf
foo(1.23, 4.56, 7.89);
würde kompiliert werden, als ob es
foo(3, 1.23, 4.56, 7.89);
Innerhalb der Funktion Körper geschrieben worden war, keinen Zugang zu einem Element über die tatsächliche Anzahl der Argumente sein könnte tatsächlich weitergegeben überprüft zur Laufzeit und verursacht einen Kompilierungsfehler, wodurch die Sicherheit stark erhöht wird.
Zu guter Letzt werden alle Variadic-Parameter eingegeben und können zur Kompilierzeit wie bei nicht-variadischen Parametern überprüft werden.
In einigen Anwendungsfällen wäre es natürlich wünschenswert, alternierende Typen zu verwenden, beispielsweise beim Schreiben einer Funktion zum Speichern von Schlüsseln und Werten in einer Sammlung. Dies könnte auch einfach untergebracht werden, indem mehr formalen Parameter nach dem Auslassungszeichen ermöglicht, wie so
void store (collection dict, ... int counter, key_t key, val_t value);
könnte diese Funktion dann als
store(dict, key1, val1, key2, val2, key3, val3);
aber als kompilierte würde genannt werden, wenn es
geschrieben worden war
Die Arten der tatsächlichen Parameter würden Kompilierzeit gegen die entsprechenden variadischen formalen Parameter überprüft werden.
Im Körper der Funktion würde der Zähler wieder durch ihre Kennung, Schlüssel und Werte Bezug genommen werden würde referenziert werden, als ob sie Arrays waren,
key[i]
auf den Schlüssel des i-ten bezieht Schlüssel/Wert-Paar value[i]
bezieht sich auf den Wert des i-ten Wertepaars
und diese Referenzen würden zu ihren jeweiligen Adressen auf dem Stapelrahmen kompiliert werden.
Nichts davon ist wirklich schwer zu tun, noch war es jemals. Die Konstruktionsphilosophie von C ist diesen Funktionen jedoch nicht zuträglich.
Ohne wagen C-Compiler-Implementierer (oder C-Präprozessor Implementierer) die Führung übernehmen, dies zu implementieren oder eine ähnliche Regelung ist es unwahrscheinlich, dass wir jemals etwas von dieser Art in C. siehe
Das Problem ist, dass Leute, die sind an Typensicherheit interessiert und sind bereit, in die Arbeit zu investieren, um ihre eigenen Compiler zu bauen, um zu dem Schluss zu kommen, dass die C-Sprache nicht mehr zu retten ist und man gleich zu Beginn mit einer besser gestalteten Sprache beginnen kann.
Ich war selbst dort, beschloss schließlich, den Versuch aufzugeben, dann implementieren wir eine von Wirths Sprachen und fügte stattdessen typsichere Variablen hinzu. Ich bin seitdem auf andere Leute gestoßen, die mir von ihren eigenen abgebrochenen Versuchen erzählt haben. Richtige Art sichere variadics in C scheinen balanciert, um schwer zu bleiben.
Wenn alle Typen vom selben Typ sein müssen, haben Sie nur ein Array von ihnen übergeben? –
Kein natives Array in C89. Sie können zB "f ({1,2,3,0})" mit MS C Compiler nicht übergeben. – mikebloch
willst du etwas, das mit gcc oder MS C funktioniert? Bitte passend etikettieren. Mit C99 gibt es Lösungen, die typsicher sind. –