[FIXED] Warum erlaubt eine Funktion in C (oder Objective C) ohne aufgelistete Argumente die Eingabe eines Arguments?

Ausgabe

Wenn Ceine Funktion so deklariert wird, dass void main();der Versuch, ein Argument einzugeben (als erstes und einziges Argument), keinen Kompilierungsfehler verursacht, und um dies zu verhindern, kann die Funktion wie deklariert werden void main(void);. Übrigens, ich denke, das gilt auch für Objective Cund nicht für C++. Mit Objective Cbeziehe ich mich auf die Funktionen außerhalb von Klassen. Warum ist das? Danke, dass Sie sich gemeldet haben. Ich stelle mir vor, dass es bei FortranVariablen, deren Namen mit i, j, k, l, m oder n beginnen, implizit vom integerTyp sind (es sei denn, Sie fügen ein hinzu implicit none).

Bearbeiten: Erlaubt Objective C dies aufgrund der größeren Kompatibilität mit C, oder ist es ein ähnlicher Grund wie der Grund, warum C dies hat, um dies zu haben?

Hinweis: Ich habe den Fehler in der Frage beibehalten, damit Antworten und Kommentare nicht geändert werden müssen.

Noch ein Hinweis: Wie von @Steve Summit und @matt ( hier ) hervorgehoben, ist Objective-C eine strikte Obermenge von C, was bedeutet, dass jeder C-Code auch gültiger Objective-C-Code ist und daher dieses Verhalten in Bezug auf Funktionen zeigen muss.

Lösung

In frühem C (vor ANSI) wurde eine korrekte Übereinstimmung von Funktionsargumenten zwischen der Definition einer Funktion und ihren Aufrufen nicht vom Compiler überprüft .

Ich glaube, dies geschah aus zwei Gründen:

  1. Es machte den Compiler erheblich einfacher
  2. C wurde immer für separate Kompilierung entwickelt, und die Überprüfung der Konsistenz über Übersetzungseinheiten hinweg (dh über mehrere Quelldateien hinweg) ist ein viel schwierigeres Problem.

In jenen frühen Tagen lag es also in der Verantwortung des Programmierers oder eines separaten Programms, sicherzustellen, dass die Aufrufe einer Funktion mit ihrer Definition übereinstimmten lint.

Die lockere Überprüfung von Funktionsargumenten machte auch varargs- Funktionen wie printfmöglich.

Jedenfalls im Original-C, als du geschrieben hast

extern int f();

, Sie sagten nichtf ” ist eine Funktion, die keine Argumente akzeptiert und zurückgibt int“. Sie sagten einfach ” fist eine Funktion, die zurückkehrt int“. Du hast nichts über die Argumente gesagt.

Im Grunde hatte das frühe C-Typ-System nicht einmal eine Möglichkeit, die von einer Funktion erwarteten Parameter aufzuzeichnen. Und das galt insbesondere dann, wenn eine separate Kompilierung ins Spiel kam, da der Linker externe Symbole praktisch nur anhand ihrer Namen auflöste.

C++ hat dies natürlich durch die Einführung von Funktionsprototypen geändert . Wenn Sie in C++ sagen extern int f();, deklarieren Sie eine Funktion, die explizit 0 Argumente akzeptiert. (Außerdem wurde ein Schema des „ Namensverstümmelns “ entwickelt, das es dem Linker unter anderem ermöglicht, zur Linkzeit einige Konsistenzprüfungen durchzuführen.)

Nun, das war alles ein gewisser Mangel im alten C, und die größte Änderung, die ANSI C eingeführt hat, war die Übernahme der Funktionsprototypnotation von C++ in C. Es war jedoch etwas anders: Um die Kompatibilität aufrechtzuerhalten, extern int f();musste das Sprichwort in C als interpretiert werden bedeutet “Funktion, intdie unspezifizierte Argumente zurückgibt und nimmt”. Wenn Sie ausdrücklich sagen wollten, dass eine Funktion keine Argumente hat, mussten (und müssen) Sie sagen extern int f(void);.

Es gab auch eine neue ...Notation, um eine Funktion explizit als Variablenargumente zu kennzeichnen, wie printf, und der Prozess, „implizit“ in Deklarationen loszuwerden int, wurde begonnen.

Alles in allem war es eine deutliche Verbesserung, obwohl es immer noch ein paar Löcher gibt. Insbesondere bleibt dem Programmierer immer noch eine gewisse Verantwortung, nämlich dafür zu sorgen, dass immer korrekte Funktionsprototypen vorhanden sind, damit der Compiler sie überprüfen kann. Siehe auch diese Frage .


Zwei zusätzliche Anmerkungen: Sie haben nach Objective C gefragt, aber ich weiß nichts über diese Sprache, daher kann ich diesen Punkt nicht ansprechen. Und Sie sagten, dass für eine Funktion ohne Prototyp “der Versuch, ein Argument (als erstes und einziges Argument) einzugeben, keinen Kompilierungsfehler verursacht”, aber tatsächlich können Sie eine beliebige Zahl oder Argumente an diese übergeben eine Funktion, ohne Fehler.


Beantwortet von –
Steve Summit


Antwort geprüft von –
Pedro (FixError Volunteer)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like

[FIXED] CIImage horizontal spiegeln

Ausgabe Ich versuche, mein CIImage horizontal zu spiegeln mit: image = [image imageByApplyingTransform:CGAffineTransformMakeScale(1, -1)]; image = [image imageByApplyingTransform:CGAffineTransformMakeTranslation(0,…