Problem mit C-String (pointer)
-
supertux schrieb:
Man sollte kein strlen in der For Schleife Bedingung nutzen, denn dann wird strlen n Mal ausgeführt und die Schleife läuft dann in mind. O(n²)
falls der string in der schleife nicht verändert wird, sollte ein guter compiler das erkennen und nur einmal 'strlen' aufrufen.
aber, du hast natürlich recht, verlassen sollte man sich darauf nicht.
-
supertux schrieb:
Man sollte kein strlen in der For Schleife Bedingung nutzen, denn dann wird strlen n Mal ausgeführt und die Schleife läuft dann in mind. O(n²)
Versuche ich mir mal zu merken !
-
pale dog schrieb:
supertux schrieb:
Man sollte kein strlen in der For Schleife Bedingung nutzen, denn dann wird strlen n Mal ausgeführt und die Schleife läuft dann in mind. O(n²)
falls der string in der schleife nicht verändert wird, sollte ein guter compiler das erkennen und nur einmal 'strlen' aufrufen.
Gerade erst hab' ich gelesen, daß du ein guter Bit-Schubser bist;
mit Compilern kennst du dich aber überhaupt nicht aus.Woher soll denn der Compiler wissen, daß strlen nur
die Länge eines Strings berechnet und zurückliefert und
z.B. nicht mal schnell das Internet downloaded ().
Deine Aussage ist falsch, da kann nichts optimiert werden,;
auch nicht vom allergutesten Compiler!
-
Javaner schrieb:
Woher soll denn der Compiler wissen, daß strlen nur
die Länge eines Strings berechnet und zurückliefert und
z.B. nicht mal schnell das Internet downloaded ().
na, dieses 'strlen' ist doch eine bekannte standardfunktion.
ich könnte mir vorstellen, dass ein schlauer compiler die nicht einmal aufruft, wenn sich der string nicht ändert, sondern gleich einen festen wert einsetzt.
-
Da liegst du falsch!
Der Compiler erzeugt einfach immer Code,
der die Methode aufruft und die läuft auch immer
den String bis zum Ende ('\0') durch um die Länge
zu bestimmen.Ob das ne Standard-Methode ist oder nicht
darf den Compiler überhaupt nicht jucken.
-
Javaner schrieb:
Der Compiler erzeugt einfach immer Code,
der die Methode aufruft und die läuft auch immer
den String bis zum Ende ('\0') durch um die Länge
zu bestimmen.warum sollte er?
er kann doch auch code rausschmeissen. hauptsache das programm tut, was man von ihm erwartet.
-
Und woran sollte er erkennen, was sich hinter der Funktion verbirgt, die du da aufgerufen hast? (selbst wenn das Ding strlen() heißt, kann dir niemand garantieren, daß sich dahinter wirklich DIE strlen-Funktion aus dem ANSI-Standard verbirgt)
-
Der Compiler weissdoch
nicht was die Funktion strlen
macht. Du kannst dir ja schließlich
eine eigene Methode strlen schreiben,
die mal eben deine Festplatte formatiert
und dann das Internet downloadet.Was hindert dich daran?
Und woher soll der Compiler wissen,
was deine Funktion strlen
denn nun eigentlich macht?
-
CStoll schrieb:
Und woran sollte er erkennen, was sich hinter der Funktion verbirgt, die du da aufgerufen hast?
vielleicht, wenn ein '#include <string.h>' da ist, könnte er davon ausgehen, dass die standardfunktion gemeint ist.
wer weiss schon, was ausgebuffte compilermacher für optimiertricks drauf haben...
-
Klar ist das ein erster Anhaltspunkt, aber damit kann man sich recht schnell in die Nesseln setzen (und um solche Mikro-Optimierungen durchführen zu können, ohne das Programm unbrauchbar zu machen, brauchst du imho schon einen sehr intelligenten Compiler.
-
pale dog schrieb:
könnte er davon ausgehen, dass die standardfunktion gemeint ist.
Genau das darf der Compiler überhaupt nicht.
Erst der Linker bindet, nachdem der Compiler fertig ist,
strlen aus irgendeiner Bibliothek oder aus
einem .o-File ein; da ist es vollkommen egal ob die
Signatur von strlen nun aus string.h, sonstwo oder
nirgendwo herkommt.Probier's doch einfach mal aus, deine eigene
strlen-Funktion zu implementieren und dem
Compiler unterzujubeln.
-
Javaner schrieb:
pale dog schrieb:
könnte er davon ausgehen, dass die standardfunktion gemeint ist.
Genau das darf der Compiler überhaupt nicht.
wieso nicht? ein compiler darf doch schlauer sein als der mensch.
-
Hast du meinen letzten Post nicht zu Ende gelesen?
Dann geb' ich's auf!
-
Aber nicht schlauer als der ANSI-Standard vorschreibt. Beim Compilen ist überhaupt noch nicht bekannt, was für eine Funktion sich hinter diesem ominösen Namen "strlen()" später verbergen soll - das entscheidet erst der Linker. Und der Linker muß mit dem leben, was der Compiler zusammenoptimiert hat.
Das bedeutet, wenn der Compiler jetzt sagt "ich kenne strlen() und auf den selben char* angewendet liefert das immer das selbe Ergebnis" und daraufhin die regelmäßigen Funktionsaufrufe rausoptimiert, und der Linker später nicht die Standardbibliothek dazulinkt, sondern eine selbstgeschriebene (deren Version von strlen() nebenbei noch mitloggen soll, wann und wo es aufgerufen wurde), ist das herauskommende Porgamm falsch.
(davon abgesehen kann der Compiler - von einigen trivialen Fällen abgesehen - nicht einmal feststellen, ob sich der verwendete String zwischenzeitlich nicht doch verändert hat)
-
Genau! @CStoll.
Dann darf ich jetzt endlich eine
strlen-Funktion schreiben, die mir
das Internet downloadet?Dann mach ich mich gleich mal daran....
-
CStoll schrieb:
Aber nicht schlauer als der ANSI-Standard vorschreibt. Beim Compilen ist überhaupt noch nicht bekannt, was für eine Funktion sich hinter diesem ominösen Namen "strlen()" später verbergen soll - das entscheidet erst der Linker. Und der Linker muß mit dem leben, was der Compiler zusammenoptimiert hat.
wäre es nicht denkbar, dass ein compiler kenntnis von allen funktionen in allen files (.c, .lib, .obj, usw...) hat, und herausfinden kann, ob eine selbstdefinierte 'strlen'-funktion existiert oder nicht?
CStoll schrieb:
Das bedeutet, wenn der Compiler jetzt sagt "ich kenne strlen() und auf den selben char* angewendet liefert das immer das selbe Ergebnis" und daraufhin die regelmäßigen Funktionsaufrufe rausoptimiert, und der Linker später nicht die Standardbibliothek dazulinkt, sondern eine selbstgeschriebene (deren Version von strlen() nebenbei noch mitloggen soll, wann und wo es aufgerufen wurde), ist das herauskommende Porgamm falsch.
klar, man sieht manchmal im visual-c forum die frage: 'im debug-mode läuft mein programm, im release-mode nicht'. das hat doch bestimmt oft mit optimierungen zu tun, die im debugmodus nicht da sind.
-
Compilerbauer können gerne exzessive Optimierungen
in zusammenhängenden, nicht von Funktionsaufrufen
unterbrochenen, Code vornehmen lassen. Sie
düfen aber nicht vermuten, was ein Funktionsaufruf bewirkt.
-
pale dog schrieb:
wäre es nicht denkbar, dass ein compiler kenntnis von allen funktionen in allen files (.c, .lib, .obj, usw...) hat,
und herausfinden kann, ob eine selbstdefinierte 'strlen'-funktion existiert oder nicht?Braucht er doch gar nicht. Das erkennt er schon anhand des Quelltextes.
Der Kompiler muss nur dafür sorgen, dass eine selbstdefinierte "strlen ()" und die "strlen()" aus der Standardbibliothek dem Linker nicht unter dem gleichen Namen "bekanntgemacht" werden.
-
pale dog schrieb:
CStoll schrieb:
Aber nicht schlauer als der ANSI-Standard vorschreibt. Beim Compilen ist überhaupt noch nicht bekannt, was für eine Funktion sich hinter diesem ominösen Namen "strlen()" später verbergen soll - das entscheidet erst der Linker. Und der Linker muß mit dem leben, was der Compiler zusammenoptimiert hat.
wäre es nicht denkbar, dass ein compiler kenntnis von allen funktionen in allen files (.c, .lib, .obj, usw...) hat, und herausfinden kann, ob eine selbstdefinierte 'strlen'-funktion existiert oder nicht?
Nein, es sei denn er kann in die Zukunft sehen. Theoretisch arbeiten Compiler und Linker unabhängig voneinander (auch wenn die meisten modernen IDEs beide zusammenfassen), also könnte ich heute mein Programm compilieren, morgen eine neue Version der stdlib auf mein System laden und übermorgen beides zusammenlinken.
CStoll schrieb:
Das bedeutet, wenn der Compiler jetzt sagt "ich kenne strlen() und auf den selben char* angewendet liefert das immer das selbe Ergebnis" und daraufhin die regelmäßigen Funktionsaufrufe rausoptimiert, und der Linker später nicht die Standardbibliothek dazulinkt, sondern eine selbstgeschriebene (deren Version von strlen() nebenbei noch mitloggen soll, wann und wo es aufgerufen wurde), ist das herauskommende Porgamm falsch.
klar, man sieht manchmal im visual-c forum die frage: 'im debug-mode läuft mein programm, im release-mode nicht'. das hat doch bestimmt oft mit optimierungen zu tun, die im debugmodus nicht da sind.
Solche Probleme haben normalerweise nichts mit übereifrigen Optimierern zu tun, sondern damit, daß sich jemand auf undefiniertes Verhalten verlässt (ein Beispiel: Was in einem
int i;
steht, wird vom Standard nicht vorgeschrieben - im Debug-Modus könnte dort tatsächlich ein definierter (und zufällig richtiger) Wert eingetragen werden, im Release-Modus hast du nur ein zufälliges Bitmuster in der Hand).@merker: Compiler und Linker arbeiten unabhängig voneinander - und der Compiler kann den Linker auch nicht zwingen, eine bestimmte Bibliothek zu verwenden.
Edit: Und selbst mit dem originalen strlen() kann man nicht davon ausgehen, daß sich der Wert zwischen zwei Schleifendurchläufen nicht ändert