Warum ist argc ein ‘int’ (und kein ‘unsigned int’)?
Lesezeit: 5 Minuten
Katzenkul
Warum ist die Anzahl der Befehlszeilenargumente variabel (traditionell argc) ein int statt ein unsigned int? Gibt es dafür einen technischen Grund?
Ich habe es immer einfach ignoriert, als ich versucht habe, alle meine signierten nicht signierten Vergleichswarnungen loszuwerden, aber nie verstanden, warum es so ist, wie es ist.
mjv
Die Tatsache, dass die ursprüngliche C-Sprache so war, dass durch Standardmäßig wurde jede Variable oder jedes Argument als Typ int definiert, ist wahrscheinlich ein weiterer Faktor. Mit anderen Worten, Sie könnten Folgendes haben:
main(argc, char* argv[]); /* see remark below... */
statt
int main(int argc, char *argv[]);
Bearbeiten: effektiv, wie Aaron uns erinnerte, wäre die sehr ursprüngliche Syntax so etwas wie gewesen
main(argc, argv) char **argv {... }
Da die „Prototypen“ erst später vorgestellt wurden. Das kam ungefähr, nachdem jeder mindestens 10 Stunden damit verbracht hatte, subtilen (und nicht so subtilen) typbezogenen Fehlern nachzujagen
Eigentlich wäre es `main(argc,argv) char* argv { } gewesen, da die Inline-Parameterdeklaration und Prototypen erst mit ANSI C eingeführt wurden (ahh – die guten alten Zeiten … ich bin so froh, dass sie weg sind)
– Aaron
20. November 2009 um 23:58 Uhr
@richtig, Aaron! Ich vergaß… Wir sollten besser aufhören, bevor wir unser Alter zu sehr zeigen 😉
– mjv
21. November 2009 um 0:07 Uhr
@Aaron Hatte nicht gesehen main(argc, argv) char **argv {... } Funktionsdefinition im alten Stil, aber gesehen / verwendet main(argc, argv) int argc; char* argv; { ... }
– chux – Wiedereinsetzung von Monica
29. Juli 2015 um 20:56 Uhr
DigitalRoss
Ein paar Gründe:
weil es egal ist
weil C die ursprünglich nicht hatte unsigned Stichwort bzw vorzeichenlose Integer-Typen
weil C ursprünglich keine Parametertypen überprüfte und nicht einmal Prototypen hatte. Infolgedessen war es üblich, nicht einmal zu deklarieren int Typen, da dies die Vorgabe war.
Weil int war damals gewissermaßen wichtiger. Alles war ein int. C entwickelte sich teilweise aus einer Sprache, die nicht einmal Typen hatte. Jede einzelne Variable war a wordwelches ist was int ursprünglich verwendet wurde für.
AKTUALISIEREN: Jason S fragte nach Quellen. Ich denke, Sie können das alles (außer “es spielt keine Rolle”) aus einem Papier ausgraben dmr was online ist: Die Entwicklung der C-Sprache. Möglicherweise müssen Sie die früheren Sprachen BCPL und B an den üblichen Stellen nachschlagen.
Weil C alt ist und von Anfang an so entworfen wurde. Es ist zu spät, es jetzt zu ändern.
C ist alt. Es war von Anfang an so konzipiert. Aber ich muss diesem letzten Satz widersprechen (nicht genug, um ihn abzulehnen). ISO könnte ganz einfach eine dritte Prototyp-Definition für main mit wenig Auswirkungen hinzufügen. Tatsächlich steht es Implementierern auch frei, andere Hauptprototypen hinzuzufügen – dies wird ausdrücklich im Standard erwähnt.
– paxdiablo
21. November 2009 um 0:18 Uhr
@paxdiablo stimmte zu, Standards können und sollten weiterentwickelt und geändert werden [with care]. Wie hilft dieses unsignierte Argc-Ding in diesem speziellen Fall jedoch beim Weltfrieden?
– mjv
21. November 2009 um 0:34 Uhr
@mjv Weniger Leute, die sich über Dinge beschweren, die im Internet nicht genau korrekt sind, bedeuten weniger Leute, die sich im Allgemeinen beschweren, was bedeutet, dass es welche geben wird etwas mehr Weltfrieden als zuvor.
– Dai
19. Mai 2017 um 21:54 Uhr
Johannes Bode
Hier ist eine Geschichte der Programmiersprache C in dmrs eigenen Worten. Es wird nicht ausdrücklich angegeben (zumindest nicht aus dem kurzen Überfliegen, das ich ihm gegeben habe), aber die frühesten Versionen von C unterstützten keine unsignierten Typen. mjvs Punkt zur impliziten Eingabe von to int ist auch relevant.
BEARBEITEN
Der Bell Labs-Link ist seit einiger Zeit unterbrochen: Hier ist ein alternativer Link zum gleichen Artikel.
Ein weiterer Grund könnte sein, dass vorzeichenlose Typen für die Iteration unpraktisch sein können. Zum Beispiel dieses Snippet, das nach unten iteriert:
for (size_t i = SIZE - 1; i >= 0; --i)
...
Ist in der Tat ein Bug. Wenn i in der letzten Iteration 0 erreicht, geht es direkt weiter zu 4294967295 (auf einem 32-Bit-Rechner) und die Schleife wird nicht beendet.
Aus diesem Grund finde ich persönlich plain ints bequemer für die Iteration. Sie müssen nicht besonders vorsichtig sein, wenn Sie a wechseln for Schleife vom Aufwärts- zum Abwärtszählen bei Verwendung von ints.
Das liegt daran, dass C++ kein geeignetes for_each-Konstrukt hat. Ich habe das gleiche Problem mehrmals ausgeführt, aber ich bin immer froh, wenn ich die std-Container mit geeigneten Iteratoren verwenden kann.
– xtofl
21. November 2009 um 6:44 Uhr
vereinbart, aber in C-Schleifen ist alles, was Sie haben
Das Google C++ Styleguide schlägt vor, niemals zu verwenden unsigned int Typen, es sei denn, Sie arbeiten mit tatsächlichen Bitmustern. Ihre Begründung gilt auch für C. Kurze Zusammenfassungszeile:
… Das Type-Promotion-Schema von C bewirkt, dass sich vorzeichenlose Typen anders verhalten, als man erwarten könnte. … Verwenden Sie keinen vorzeichenlosen Typ.
Das war wahrscheinlich nicht in den Köpfen der ursprünglichen Schöpfer von C, aber wer weiß‽
Das liegt daran, dass C++ kein geeignetes for_each-Konstrukt hat. Ich habe das gleiche Problem mehrmals ausgeführt, aber ich bin immer froh, wenn ich die std-Container mit geeigneten Iteratoren verwenden kann.
– xtofl
21. November 2009 um 6:44 Uhr
vereinbart, aber in C-Schleifen ist alles, was Sie haben