Vor allem ist das Problem nicht die if
; wie Sie gesehen haben, gcc
sieht durch die if
und schafft es, 30
direkt an printf
übergeben.
Nun tut gcc
eine gewisse Logik haben auf Sonderfälle von printf
handhaben (insbesondere, tut es printf("something\n")
optimieren und sogar printf("%s\n", "something")
zu puts("something")
), aber es ist sehr spezifisch und nicht viel weiter geht; printf("Hello %s\n", "world")
wird zum Beispiel so belassen wie es ist. Noch schlimmer ist, dass eine der Varianten über ohne eine nachlaufende Zeilenschaltung unberührt bleibt, selbst wenn sie in umgewandelt werden könnten.
Ich kann mir vorstellen, dass dies auf zwei Hauptprobleme kommt:
die beiden oben genannten Fälle sind extrem einfache Muster zu implementieren und sehr oft passieren, aber für den Rest der Mühe ist es wahrscheinlich selten wert; Wenn die Zeichenkette konstant ist und die Leistung wichtig ist, kann sich der Programmierer leicht darum kümmern - wenn die Leistung von printf
kritisch ist, sollte er sich nicht auf diese Art der Optimierung verlassen, die bei der geringsten Änderung des Formats brechen kann Zeichenfolge.
Wenn Sie mich fragen, auch nur die puts
Optimierungen oben sind bereits "für die Stil Punkte gehen", werden Sie wirklich keine ernsthafte Leistung in nichts als künstliche Testfälle gewinnen.
Wenn Sie beginnen, außerhalb des Bereichs von %s\n
zu gehen, ist printf
ein Minenfeld, da es eine starke Abhängigkeit von der Laufzeitumgebung hat; insbesondere sind viele printf
Spezifizierer (leider) vom Gebietsschema betroffen, außerdem gibt es eine Aufzählung von implementierungsspezifischen Macken und Spezifizierern (und gcc
kann mit printf
von glibc, musl, mingw/msvcrt arbeiten, ...- und zur Kompilierzeit können Sie die Ziel-C-Laufzeit nicht aufrufen - denken Sie beim Cross-Compilieren nach.
Ich stimme zu, dass diese einfache %d
Fall wahrscheinlich sicher ist, aber ich kann sehen, warum sie wahrscheinlich beschlossen, zu vermeiden, übermäßig schlau zu sein und nur die dümmsten und sichersten Optimierungen hier durchzuführen.
Für den neugierigen Leser, here ist, wo diese Optimierung tatsächlich umgesetzt wird; Wie Sie sehen können, passt die Funktion zu einer begrenzten Anzahl von sehr einfachen Fällen (und GIMPLE beiseite, hat sich nicht viel geändert, seit this nice article sie beschrieben wurde). Übrigens erklärt die Quelle tatsächlich, warum sie die fputs
-Variante für den Nicht-Newline-Fall nicht implementieren konnten (es gibt keinen einfachen Weg, die stdout
global in dieser Kompilierungsstufe zu referenzieren).
'gcc' kann nicht (kann nicht ..?) Die' printf' Ausgabe vorhersagen. – LPs
@LPs AFAIK, ändert er Aufrufe von printf() mit Aufrufen von puts() und putchar() wo möglich. – Mitsos101
@ Mitsos101 nur mit * bekannten Kompilierzeitkonstanten *. Was Sie in Ihrem Code sehen, kann nur durch Ausführen ermittelt werden. Einfach für Sie in Ihrem Kopf - weniger einfach für einen Compiler. – adelphus