Hey Leute,
ich hab folgendes problem bei einer Aufgabe und zwar geht es darum zu
erkennen wo ein Fehler liegt und ob dieser vom Compiler oder vom Linker
erkannt wird.
Im Anhang sind zwei unterschiedliche programme i) und ii)
Der Compiler gibt ja Fehlermeldungen aus wenn z.B ein Syntaxfehler
vorliegt oder eine nicht eingeführte Variable benutzt wird. Er geht
dabei ja jede Datei einzel durch wenn also kein Syntaxfehler vorliegt
ist alles gut und er spuckt keine Fehler aus.
Beim Linker hingegen geht es ja darum fehlerhafte verweise zu finden
oder wenn zwei Funktionen mit dem gleichen Namen existieren etc.
Keine Ahnung ob ich das richtig verstanden habe, trotzdem erkenne ich
bei den Programmabschnitten jetzt nicht wo die Compiler/Linker-fehler
vorliegen.
Wäre cool wenn mir da jemand auf die Sprünge helfen könnte.
Wo liegt der Unterschied zwischen den Programmen und welchen Einfluss
könnte er haben?
Warum tippst du das nicht einfach mal in einen Computer ein und schaust,
was passiert? Anhand der real auftauchenden Fehlermeldung kannst du ja
feststellen, ob der Compiler oder Linker ein Problem haben.
Und die Dateiendung .cpp deutet darauf hin, daß das C++ ist, kein C.
Auch wenn’s gleich aussieht, ist das bei der Fragestellung schon
entscheidend.
Oliver
Steht aber C Programmierung drüber. Nicht definierte Funktionen sind dem
Compiler egal, nicht definierte Variablen interessieren ihn. Grund:
Funktionen muss man nur aufrufen, da muss man nix drüber wissen. Aber
Variablen könnten unpassende Typen haben.
Da prog2 nicht kompiliert, wird sich der linker bei prog1 über das nicht
gefundene addx beschweren.
Ausprobieren tut nicht weh.
nfet schrieb:> Steht aber C Programmierung drüber.
Und in der Aufgabenstellung steht .cpp.
Wer sagt, dass der TO die Aufgabe verstanden hat?
Man könnte man zumindest mal drüber nachdenken, ob das was am Problem
ändert.
Oliver
nfet schrieb:> Nicht definierte Funktionen sind dem Compiler egal, nicht definierte> Variablen interessieren ihn. Grund: Funktionen muss man nur aufrufen, da> muss man nix drüber wissen. Aber Variablen könnten unpassende Typen> haben.
Das gilt für beides, deshalb ist beides in C egal. Er nimmt int an. Als
variable, als Funktionsparameter, als Rückgabewert, ...
Wenn die Datei .cpp heißt, dann wird doch garantiert mit C++ kompiliert.
Da wäre dann prog1.cpp in B richtig. (In C wären die Version in A und B
OK.)
prog2.cpp ist weder in C++ noch in C vollständig. Da fehlt eine Zeile.
Bis auf .cpp deutet alles auf C hin.
Aber egal, dann eben einmal die Antwort für C und einmal für C++:
C:
Programm A:
prog1.cpp kompiliert: https://godbolt.org/z/28PT2P
prog2.cpp kompiliert nicht (error: 'x' undeclared)
https://godbolt.org/z/a9c5wh
Da prog2 nicht kompiliert, gibt es nichts, womit man prog1 linken
könnte. Wenn man also ein executable erstellen wöllte, würde der Linker
sich beschweren mit einer Meldung wie "undefined reference to `addx'"
(https://godbolt.org/z/7CeJya)
Für Programm B gilt genau das gleiche wie für Programm A.
C++:
Programm A:
prog1.cpp kompiliert nicht ( error: 'addx' was not declared in this
scope): https://godbolt.org/z/k3WlNV
prog2.cpp kompiliert nicht (error: 'x' undeclared)
https://godbolt.org/z/JVny_3)
Damit gibt es absoult nix, was man linken könnte.
Programm B:
prog1.cpp kompiliert (https://godbolt.org/z/ceLkgO)
Für prog2.cpp gilt das gleiche wie bei A.
Da prog2 nicht kompiliert, gibt es nichts, womit man prog1 linken
könnte. Wenn man also ein executable erstellen wöllte, würde der Linker
sich beschweren mit einer Meldung wie "undefined reference to
`addx(int)'" (siehe link davor)
Fassen wir zusammen:
Meine Aussage von oben hat absoult bestand, wer mir nicht glaubt, möge
es bei sich selbst einfach testen, soviel ist das nicht zum tippen.
nfet schrieb:> Steht aber C Programmierung drüber. Nicht definierte Funktionen sind dem> Compiler egal, nicht definierte Variablen interessieren ihn. Grund:> Funktionen muss man nur aufrufen, da muss man nix drüber wissen. Aber> Variablen könnten unpassende Typen haben.
Selbstverständlich können auch Funktionen unpassende Typen haben. Es
gibt schließlich so Dinge wie Parameter und einen Return-Typ. Wenn das
nicht passt, kracht's gegebenenfalls.
In C ist es lediglich so, dass der Compiler beim Aufruf einer Funktion
mehr oder weniger rät, von welchem Typ sie ist, wenn er sie nicht kennt.
Das ist letztendlich der Kompatibilität zu den Anfängen von C
geschuldet, als es Prototypen noch nicht gab.
In dem hier gezeigten Fall würde der Compiler zufällig das richtige
raten, da er als Parameter einen int annimt, weil ein solcher übergeben
wurde und als return-Typ ebenfalls int, weil das implizit immer
angenommen wird.
In C++ ist dagegen erforderlich, dass der Compiler den Typ der Funktion
kennt. Das ergibt sich schon alleine daraus, dass man Funktionen
überladen kann.
Rolf M. schrieb:> In C ist es lediglich so, dass der Compiler beim Aufruf einer Funktion> mehr oder weniger rät, von welchem Typ sie ist, wenn er sie nicht kennt.
Er gibt aber eine Warnung aus. Und sauber geschriebene Programme
erzeugen keine Warnungen.
Rufus Τ. F. schrieb:> Er gibt aber eine Warnung aus.
Und sollte bei C99 oder C11 eigentlich eine Fehlermeldung ausgeben, da
es die implizite Deklaration da nicht mehr gibt.
gcc nimmt zwar defaultmässig C99, gibt aber trotzdem nur eine Warnung
aus.
Mit -pedantic-errors wirds dann zur Fehlermeldung.
Oliver
Rufus Τ. F. schrieb:> In C ist es lediglich so, dass der Compiler beim Aufruf einer Funktion> mehr oder weniger rät, von welchem Typ sie ist, wenn er sie nicht kennt.
Der Compiler rät nicht!
sondern geht von einem Interger aus.
GEKU schrieb:> Rufus Τ. F. schrieb:> In C ist es lediglich so, dass der Compiler beim Aufruf einer Funktion> mehr oder weniger rät, von welchem Typ sie ist, wenn er sie nicht kennt.>> Der Compiler rät nicht!> sondern geht von einem Interger aus.
Sorry leider falsch zitiert.
nfet schrieb:> Steht aber C Programmierung drüber. Nicht definierte Funktionen sind dem> Compiler egal, nicht definierte Variablen interessieren ihn. Grund:> Funktionen muss man nur aufrufen, da muss man nix drüber wissen.
LoL
so wie Du nichts über Deklaration und Definition in C weisst!
A. S. schrieb:> nfet schrieb:>> Nicht definierte Funktionen sind dem Compiler egal, nicht definierte>> Variablen interessieren ihn. Grund: Funktionen muss man nur aufrufen, da>> muss man nix drüber wissen. Aber Variablen könnten unpassende Typen>> haben.>> Das gilt für beides, deshalb ist beides in C egal. Er nimmt int an. Als> variable, als Funktionsparameter, als Rückgabewert, ...
In welchem C - Standard wurde denn die implizite Typendeklaration
eingeführt?
Muss ich wohl verpasst haben :-(
Walter K. schrieb:> In welchem C - Standard wurde denn die implizite Typendeklaration> eingeführt?
Das war im fossilen "K&R-C" so, der C-"Standard" vor C89.
Der kannte keine Funktionsprototypen und damit auch keine
Typüberprüfungen bei Funktionsaufrufen.
Bei Funktionen, die ohne Rückgabetyp deklariert wurden, wurde implizit
von int als Rückgabetyp ausgegangen.
Glücklicherweise findet man nur noch sehr, sehr selten Sourcecode, der
für diesen fossilen C-Dialekt geschrieben ist.
Rufus Τ. F. schrieb:> Das war im fossilen "K&R-C" so, der C-"Standard" vor C89.
C89 führte die Funktionsprototypen ein, aber erst in C99 sind die
impliziten Funktionsdeklarationen nicht mehr enthalten.
Oliver
Walter K. schrieb:> LoL>> so wie Du nichts über Deklaration und Definition in C weisst!
Naja, nichts würde ich das nun nicht nennen. Ich habe genau dargelegt,
was Compiler und was Linkerfehler produziert.
Ich habe das auch mithilfe eines online Compilers gezeigt.
Meine Begründung kann man als zu ungenau kritisieren, aber (Achtung
reine Behauptung meinerseits) ich behaupte, genau das wird der Grund
gewesen sein, warum man in den Anfängen von C keinen entscheidenden
Mehrwert in der Deklaration von Funktionen gesehen hat.
A. S. schrieb:> Das gilt für beides, deshalb ist beides in C egal. Er nimmt int an. Als> variable, als Funktionsparameter, als Rückgabewert, ...
Das halte ich für eine gewagte Behauptung, mein Link oben zeigt dass
Gegenteil:
https://godbolt.org/z/JVny_3