Warum ist argc ein ‘int’ (und kein ‘unsigned int’)?

Lesezeit: 5 Minuten

Benutzeravatar von Catskul
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.

Benutzeravatar von mjv
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

Benutzeravatar von DigitalRoss
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

Benutzeravatar von John Bode
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

    – Eli Bendersky

    21. November 2009 um 6:56 Uhr

  • Sie sollten es umschreiben als for (size_t i = SIZE - 1; i < SIZE; i--) und voila. 😉 Quelle: <gustedt.wordpress.com/2013/07/15/…>

    – alx

    15. September um 14:52 Uhr

Benutzeravatar von Adam Goode
Adam Gut

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

    – Eli Bendersky

    21. November 2009 um 6:56 Uhr

  • Sie sollten es umschreiben als for (size_t i = SIZE - 1; i < SIZE; i--) und voila. 😉 Quelle: <gustedt.wordpress.com/2013/07/15/…>

    – alx

    15. September um 14:52 Uhr

Benutzeravatar von Greg Hewgill
Greg Hewgill

Als Lösung für Ihr Warnproblem könnten Sie so etwas tun, um die Warnungen zu unterdrücken:

const unsigned int uargc = (unsigned int) argc;

  • Richtig, da die Frage markiert war c Ich dachte, ich würde verwenden, was in beiden funktionieren würde.

    – Greg Hewgill

    21. November 2009 um 1:10 Uhr

1414980cookie-checkWarum ist argc ein ‘int’ (und kein ‘unsigned int’)?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy