Besser getch() od. cin.get() ?; bzw. wie beeinflusst eine include- eine *.exe-Datei

Rofi

Erfahrenes Mitglied

Hi,

weiß jemand wie die include-Dateien die Größe der ausführbaren *.exe-Dateien beeinflusst?

Damit das Dos-Fenster nach Ausführung des Programms nicht einfach geschlossen wird, setzt man ja für gewöhnlich ein „getch();“ oder „cin.get();“ an’s Ende der „main()“-Funktion.

Benutzt man „getch();“, muss die include-Datei „conio.h“ eingebunden werden.
Benutzt man „cin.get()“ braucht man dies nicht bzw. muss man keine zusätzliche Datei einbinden.

Zum Test habe ich einfach ein leeres Programm geschrieben.
Wird nun „getch();“ mit Einbindung von „conio.h“ benutzt und das Programm kompiliert ist die ausführbare *.exe-Datei bei mir 108KB groß.

Wird dagegen „cin.get()“ benutzt ohne zusätzliche Einbindung einer include-Datei, ist die *.exe-Datei paradoxerweise 224KB groß!

Heißt das etwa, dass der compiler nur das aus den include-Dateien übernimmt, was für das Programm gebraucht wird?

In beschriebenem Fall wäre die getch()-Routine also kleiner als cin.get() ?


Gruß, Rofi
Code:
#include <iostream>
#include <conio.h>
using namespace std;

int main()
{
	//cin.get();
	getch();
	return 0;
}
 
Zuletzt bearbeitet:
Re: Besser getch() od. cin.get() ?; bzw. wie beeinflusst eine include- eine *.exe-Dat

Hi!

Natürlich hängt es davon ab welche Funktionen du verwendest, wie groß deine ausführbare Datei letztendlich wird. Der Compiler setzt mal alles zusammen und der Linker holt dann nur diejenigen Teile aus den Bibliotheken, die referenziert werden.

Das bedeutet: Compiler stellt alles zusammen, Linker lässt alles weg, was nicht gebraucht wird, so siehts normal aus.

Je nach Einstellungen kann sogar Code aus deinem eigenen Programm weggelassen werden, z.B. wenn es innerhalb eines Moduls keine Referenz auf ein statisches Objekt gibt, wird dieses weggelassen.

lg
Johannes
 
Danke Johannes,
Das bedeutet: Compiler stellt alles zusammen, Linker lässt alles weg, was nicht gebraucht wird, so siehts normal aus.
Aha, so läuft das, "raffiniertes Kerlchen", dieser Linker! Ich sehe, es ist gar nicht schlecht, wenn man über solche Hintergründe Bescheid weiß. Wenn bei großen Programmen viele solcher Kleinigkeiten zusammen kommen, kann das sich mit Sicherheit auf die Größe auswirken. Ob’s sich aber auch auf die Ausführungsgeschwindigkeit auswirkt, hat sicher eher mit dem Optimierungsgrad der eingebunden Komponenten zu tun?
Je nach Einstellungen kann sogar Code aus deinem eigenen Programm weggelassen werden, z.B. wenn es innerhalb eines Moduls keine Referenz auf ein statisches Objekt gibt, wird dieses weggelassen.
Klar, leuchtet mir ein. So werden dann bestimmt auch die eigenen Kommentarzeilen entfernt. Damit kann das Programm ja auch nichts anfangen.

Gruss, Rofi
 
Moin moin,
Rofi hat gesagt.:
So werden dann bestimmt auch die eigenen Kommentarzeilen entfernt. Damit kann das Programm ja auch nichts anfangen.
das Ganze geht noch nen Stück weiter!

was Johannes meinte ist sowas.

Code:
void funktion()
{
int i;
float test;
i = 5;
i=6;
}
wenn du was zusammen bastelst und die Optimierungen einschaltest, wirst du beim Debuggen nur noch diese Zeilen beobachten können
Code:
void funktion()
{
int i;
i=6;
}
Der Rest wird einfach weggenommen, das hat erstmal nichts mit Kommentaren zu tun die killt der Linker sowieso.
Soviel zu dem Thema "Gute Programmierer dokumentieren nicht, weil Programm wird dann kleiner";-)

Das ganze wird bei eingeschalteter Oprimierung schneller, da für jeden Zeile C/C++ mehrer Zeilen Asm erstellt werden. Und die fallen dann natürlich auch weg.

Gruss Michael
 
Der Rest wird einfach weggenommen, das hat erstmal nichts mit Kommentaren zu tun die killt der Linker sowieso.

Das hat nichts mit den Linkern zu tun... Diese Aufgabe wird dem Scanner übertragen.
Der Scanner ist eine Phase eines Compilers. Dieser überliest nämlich
sämtliche Kommentrae Leerzeichen, Tabs und Zeilenvorschübe....


Gruß

RedWing
 
P.S.
Natürlich hängt es davon ab welche Funktionen du verwendest, wie groß deine ausführbare Datei letztendlich wird. Der Compiler setzt mal alles zusammen und der Linker holt dann nur diejenigen Teile aus den Bibliotheken, die referenziert werden.
Sollte man vielleicht noch hinzu erwähnen das das nur passiert wenn man
Bibliotheken statisch zum jewiligen Programm hinzulinkt.
Wenn man Bibliotheken dynamisch hinzulinkt ändert das nichts an der Größe
des Programms da die Funktion erst zur Laufzeit aus einer shred Library heraus
aufgerufen wird...
Siehe
http://de.wikipedia.org/wiki/Linker_(Programm)

btw sämtliche Codeoptimierungen kommen vom Compiler und nicht vom Linker nur um das
nochmal klar herauszustellen..

Gruß

RedWing
 
Hi,

Euren Kommentaren entnehme ich, dass da, sagen wir mal zusammenfassend „mehrere Mechanismen“ zum Einsatz kommen, welche als eine Art Vorfilter fungieren, um es dem endgültigen „Übersetzungsmechanismus“ mundgerecht zu verabreichen. Dieser „Mechanismus“ ist so ausgelegt, dass er dann den „bereinigten“ Quellcode in möglichst effizienten Maschinencode übersetzen kann. Was übrig bleibt, ist ausführbarer code, die ausführbare *.exe-Datei also, liege ich da in etwa richtig?

Welcher Unterschied besteht eigentlich zwischen einer *.exe-Datei, welche mit "release"- und einer, welche mit "debug" compiliert wurde? OK, die debug-Informationen sind nach einer release-Compilierung weg. Wie wirkt sich das aber auf die *.exe-Datei aus?


@codeFatal
Code:
void funktion()
{
int i;
float test;
i = 5;
i=6;
}
Verstehe:
float test; // wird entfernt, weil die Variable test nirgends mehr genutzt wird!
i=5; // wird entfernt, weil direkt danach i=6 kommt und so das erste i=5 nicht mehr relevant ist.

Der Rest wird einfach weggenommen, das hat erstmal nichts mit Kommentaren zu tun die killt der Linker sowieso.
Soviel zu dem Thema "Gute Programmierer dokumentieren nicht, weil Programm wird dann kleiner"
Hehe, das wäre damit auch geklärt! ;-]

@RedWing
Sollte man vielleicht noch hinzu erwähnen das das nur passiert wenn man
Bibliotheken statisch zum jewiligen Programm hinzulinkt.
Wenn man Bibliotheken dynamisch hinzulinkt ändert das nichts an der Größe
des Programms da die Funktion erst zur Laufzeit aus einer shred Library heraus
aufgerufen wird...
Sorry, Du bewegst Dich da bereits auf nem anderen Level :( . Bis ich da bin, dauert wohl noch’n Weilchen, glaube aber trotzdem zu verstehen, worauf Du hinaus willst.


A propos code-Optimierung:
Habe die kleine Version (ca.120,-€UR) des 2003er Microsoftcompilers. Der beherrscht aber noch keine code-Optimierung, dafür benötigt es doch die teureren Versionen, oder habe ich was falsch verstanden? Beherrscht die kleine 2005er-Version vielleicht code-Optimierung?

Gruss und Danke, Rofi

PS. Habe hier was zur code-Optimierung von Visual C++ 2003 gefunden:
http://www.microsoft.com/germany/msdn/library/net/cplusplus/CodeoptimierungMitVisualCPlusPlus.mspx
 
Zuletzt bearbeitet:
Re: Besser getch() od. cin.get() ?; bzw. wie beeinflusst eine include- eine *.exe-Dat

Hallo,
Euren Kommentaren entnehme ich, dass da, sagen wir mal zusammenfassend „mehrere Mechanismen“ zum Einsatz kommen, welche als eine Art Vorfilter fungieren, um es dem endgültigen „Übersetzungsmechanismus“ mundgerecht zu verabreichen. Dieser „Mechanismus“ ist so ausgelegt, dass er dann den „bereinigten“ Quellcode in möglichst effizienten Maschinencode übersetzen kann. Was übrig bleibt, ist ausführbarer code, die ausführbare *.exe-Datei also, liege ich da in etwa richtig?
Genau
Siehe: http://de.wikipedia.org/wiki/Übersetzer_(Compiler)
Sorry, Du bewegst Dich da bereits auf nem anderen Level . Bis ich da bin, dauert wohl noch’n Weilchen, glaube aber trotzdem zu verstehen, worauf Du hinaus willst.

das glaub ich nicht ;)
Vielleicht hab ich mich auch nur etwas umständlich ausgedrückt.
Wenn statisch gelinkt wird heißt das das der Programmcode der jeweiligen Funktion die
du in deinem Programm aufrufst mit an dein Binary gebunden wird.
Wenn man dynamisch linkt heißt das das sämtliche Funktionsnamen bzw Variablennamen
die du in deinem Programm nutzt nicht mit zum Programmcode hinzugefügt werden. Sondern
diese werden erst zur Laufzeit aufgelöst. =>
Vorteil: Dein Binary bleibt klein
Nachteil: Die zugehörige Bibliothek in deren die Funktion enthalten ist muss auf dem
Zielsystem installiert sein, damit dein Programm den entsprechenden Funktionsaufruf
zur Laufzeit auflösen kann...
Aber das steht alles in dem obigen Link(vorheriger Post) ganz prima erklärt ;)

Gruß

RedWing
 
Zuletzt bearbeitet:
Re: Besser getch() od. cin.get() ?; bzw. wie beeinflusst eine include- eine *.exe-Dat

RedWing hat gesagt.:
P.S.

Sollte man vielleicht noch hinzu erwähnen das das nur passiert wenn man
Bibliotheken statisch zum jewiligen Programm hinzulinkt.

Danke für die Ergänzung, ich bin erstmal davon ausgegangen, dass statisch gelinkt wird. Bei DLLs kommt natürlich einiges an Mechanismen hinzu.

RedWing hat gesagt.:
btw sämtliche Codeoptimierungen kommen vom Compiler und nicht vom Linker nur um das
nochmal klar herauszustellen..

Klar kann der Compiler damit, wie er verschiedene Code-Trees verarbeitet und umsetzt, bzw. wenn er z.B. Schleifen oder Rekursionen auflöst und entsprechend verpackt sehr große Unterschiede in der Größe der Ausführbaren Datei herbeiführen.

Die Links zu Wikipedia sind sehr empfehlenswert für Einsteiger in die Materie des Programmierens allgemein, da auf einmal ein wenig Licht in die "Black-Box" Compiler kommt ;)

lg
Johannes
 
Re: Besser getch() od. cin.get() ?; bzw. wie beeinflusst eine include- eine *.exe-Dat

Das was RedWing hier Scanner nennt, heißt offiziell Präprozessor, der liest auch die Include Files ein etc. Beim Gnu C Compiler bzw. G++ lässt sich der Präprozessor auch per Hand mit cpp aufrufen (C PreProcessor) Die Ausgabedateien kann man sich dann ansehen, meistens sind sie jedoch 10 KB größer :-) Include Dateien werden nämlich direkt eingefügt.
EDIT: Ich habe mal ein Hello-World Programm "preprozessed"
test.c.txt => Vorher
test.ppd.c.txt => Nachher :-)
 

Anhänge

Zuletzt bearbeitet:
Zurück