Is it just me, or …
Re: Is it just me, or …
Vielleicht sollte man aufhoeren, MS VC als DEN Compiler zu sehen ;) Selbst der betagte gcc 4.3.3 bekommt es gebacken.
- Schrompf
- Moderator
- Beiträge: 5158
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Re: Is it just me, or …
Och naja... VC++ mag nicht DER Compiler sein, aber solange Visual Studio DEN Debugger hat, wird es kaum eine Diskussion geben :-)
Ich verfolge die gelegentlich auftauchenden Diskussionen über Compilerqualitäten... und soweit ich das beurteilen kann, produziert der GCC wirklich den besseren Code, teilweise drastisch schneller. Das tut allerdings auch der Intel-Compiler. Der AMD-Compiler taucht aus mir unerfindlichen Gründen bislang in keiner Diskussion auf. Der VC-Compiler hat allerdings einen großen Vorteil: er kompiliert schneller. Nach meinen subjektiven Einschätzungen durchaus Faktor 3 bis 5 schneller als der GCC.
Ich verfolge die gelegentlich auftauchenden Diskussionen über Compilerqualitäten... und soweit ich das beurteilen kann, produziert der GCC wirklich den besseren Code, teilweise drastisch schneller. Das tut allerdings auch der Intel-Compiler. Der AMD-Compiler taucht aus mir unerfindlichen Gründen bislang in keiner Diskussion auf. Der VC-Compiler hat allerdings einen großen Vorteil: er kompiliert schneller. Nach meinen subjektiven Einschätzungen durchaus Faktor 3 bis 5 schneller als der GCC.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
- Krishty
- Establishment
- Beiträge: 8346
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Is it just me, or …
In dem Augenblick, in dem ich 128 hinschriebe, würden beide Operanden als signed short behandelt, weil 128 zu groß für char ist.Alexander Kornrumpf hat geschrieben:P.P.S. Was soll überhaupt das dämliche = dort? 128 > x hätte es doch auch getan. Vielleicht kapiert der compiler das sogar besser.
Ich habe vor ein paar Monaten mal versucht, auf GCC umzusteigen … und so viel besser als VC ist der auch nicht. Den ersten Bug hatte ich – kein Witz – in der ersten Programmzeile: GCC #defined __cplusplus einfach zu 1 statt zum Datum des Sprachstandards. Von da an ging es dann weiter mit __builtins, die nicht existieren obwohl das komplette Internet das Gegenteil behauptet, einer Standardbibliothek wo die Hälfte (so ziemlich alles mit wchar_t) noch nicht implementiert ist und endet dann mit dem herrlichen online-Support, der schlicht und einfach nicht existiert (darüber, ob sie __cplusplus nun endlich standardkonform machen, flamen sie seit sieben Jahren). Irgendwie ist es da bequemer, von Zeit zu Zeit das VC-Kompilat gegenzutesten und hier und da von Hand zu optimieren. Und was Schrompf sagt kommt auch noch dazu.Jörg hat geschrieben:Vielleicht sollte man aufhoeren, MS VC als DEN Compiler zu sehen ;) Selbst der betagte gcc 4.3.3 bekommt es gebacken.
Nichtsdestotrotz benutze ich GCC einmal im Monat, um meinen Code zu parsen – fehlerhaften Template-Code oder nicht standardkonforme Syntaxkonstrukte findet er bedeutend häufiger als VC, das z.B. die Spezialisierung von Templates im class-Scope erlaubt. Wichtig insbesondere seit ich in VC nicht mehr die Language Extensions deaktivieren will, weil ich dann die C++0x-Features einbüßen würde.
Re: Is it just me, or …
So war's nicht gemeint, ging mir eher darum, dass man solche Dinge ja schnell mit einem "Zweitcompiler" beliebiger Wahl gegentesten kann. Wollte keinesfalls den Thread in einem Flamewar münden lassen. Und offensichtliche Unzulänglichkeiten sollte man natuerlich in einem Feature-Request formulieren, egal fuer welchen Compiler.
- Krishty
- Establishment
- Beiträge: 8346
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Is it just me, or …
Alles klar. Während der Stunde, die ich jetzt brauche um MinGW C++0x-tauglich zu machen, könnt ihr ja mal darüber nachdenken, warum VC ein Placement-new durch Move-Constructor mit einem nullptr-Check versieht:Kurz: Bevor die int verschoben wird, wird getestet, ob das Ziel nullptr ist. Falls das der Fall ist, wird die Bewegung einfach übersprungen (es dient also nicht dazu, einen Fehler zu melden oder so). Weder die Implementierung vom Placement-new noch von ::std::move tun irgendwas. Wo kommt dieser völlig überflüssige Check her und warum wird er nicht wegoptimiert? Das ist eine innere Schleife, raubt mir ein Register und macht mir die Funktion in der Summe zu lang, um geinlined zu werden.
Edit: Selbst, wenn ich per __assume(nullptr < &Array[Index]); direkt vor dem new den trust-me-on-this-one-Modus erzwinge – er testet weiter. Wtf?!?
Code: Alles auswählen
new (&Array[Index]) int(::std::move(Array[Index-1]));
xor ebx, ebx
lea eax,[edx+ecx*4]
cmp eax,ebx
je 0F21260h
mov edi,dword ptr [eax-4]
mov dword ptr [eax],edi
dec ecx // 0F21260h
Edit: Selbst, wenn ich per __assume(nullptr < &Array[Index]); direkt vor dem new den trust-me-on-this-one-Modus erzwinge – er testet weiter. Wtf?!?
Zuletzt geändert von Krishty am 13.06.2010, 20:34, insgesamt 1-mal geändert.
-
- Moderator
- Beiträge: 2151
- Registriert: 25.02.2009, 13:37
Re: Is it just me, or …
Was mich ehrlich gesagt in der These bestätigt, dass das ein bekloppter(das wäre zu zeigen) Randfall(das ist nun per Definition unstrittig) ist.In dem Augenblick, in dem ich 128 hinschriebe, würden beide Operanden als signed short behandelt, weil 128 zu groß für char ist.
Mal ehrlich, wieviele real-life Situationen fallen dir ein, in denen der Programmierer zwar denkt: "Mensch, bloß keine 128 schreiben, das passt nicht in char", aber dann nicht auch denkt "Hmm, Moment mal, der Vergleich an sich ist ja sinnlos", und das selbst wegoptimiert.
- Krishty
- Establishment
- Beiträge: 8346
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Is it just me, or …
Meine derzeitige Real-Life-Situation ist ein Parser:Du darfst den zweiten Vergleich dort nicht weglassen, weil die Existenz eines Vorzeichens in char implementation-defined ist. Der Compiler hingegen darf es schon, weil er im Gegensatz zu dir erkennen kann ob das Programmverhalten dadurch beeinträchtigt würde oder nicht.
Eine Mögliche Alternative wäre natürlich das explizite return (0x20 <= static_cast<signed char>(x));, da hast du Recht. Aber der Compiler soll ja gerade das optimieren, was ich nicht selber optimiere weil ich zu faul, schöngeistig oder dumm bin, darin liegt doch der Sinn eines Optimizers … und nachdem ich gestern gesehen habe, wie er eine Verzweigung aus Zuweisungen und bitweisen Manipulationen zu einem komplett sprungfreien Bithaufen optimiert hat, hätte ich sowas Einfaches eigentlich schon erwartet.
Code: Alles auswählen
bool IsNonControlASCII(char x) {
return (0x20 <= x) && (0x7F >= x);
}
Eine Mögliche Alternative wäre natürlich das explizite return (0x20 <= static_cast<signed char>(x));, da hast du Recht. Aber der Compiler soll ja gerade das optimieren, was ich nicht selber optimiere weil ich zu faul, schöngeistig oder dumm bin, darin liegt doch der Sinn eines Optimizers … und nachdem ich gestern gesehen habe, wie er eine Verzweigung aus Zuweisungen und bitweisen Manipulationen zu einem komplett sprungfreien Bithaufen optimiert hat, hätte ich sowas Einfaches eigentlich schon erwartet.
-
- Moderator
- Beiträge: 2151
- Registriert: 25.02.2009, 13:37
Re: Is it just me, or …
Point taken.
Allerdings hoffe ich auf den Tag wo ASCII an sich ein "bekloppter Randfall" wird. Es ist eine Zumutung wie oft man auch heute noch Encodingproblemen begegnet.
Allerdings hoffe ich auf den Tag wo ASCII an sich ein "bekloppter Randfall" wird. Es ist eine Zumutung wie oft man auch heute noch Encodingproblemen begegnet.
- TGGC
- Establishment
- Beiträge: 569
- Registriert: 15.05.2009, 18:14
- Benutzertext: Ich _bin_ es.
- Alter Benutzername: TGGC
- Echter Name: Ich _bin_ es.
- Wohnort: Mainz
- Kontaktdaten:
Re: Is it just me, or …
mea culpa. Bin wohl auf das gleiche wie Schromp reingefallen. f'`8k
Gruß, TGGC (der kostenlose DMC Download)
Gruß, TGGC (der kostenlose DMC Download)
- Krishty
- Establishment
- Beiträge: 8346
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Is it just me, or …
Bevor sie den Zeichensatz reformieren, sollten sie sich endlich mal auf vernünftige Line-Endings einigen ;)Alexander Kornrumpf hat geschrieben:Allerdings hoffe ich auf den Tag wo ASCII an sich ein "bekloppter Randfall" wird. Es ist eine Zumutung wie oft man auch heute noch Encodingproblemen begegnet.
Zurück zu dem Movement-Bug: Der Fehler scheint immer mit Placement-new aufzutreten, Move-Semantics haben nichts damit zu tun. Interessanterweise testet auch GCC 4.3.3 – allerdings nicht (wie VC 2010) die Zieladresse, sondern die Quelladresse. Aber genau wie VC springt er im Fall eines Nullzeigers einfach über die Konstruktion hinweg – kein Error-Handling, nichts. Da es beide Compiler tun, glaube ich nicht unbedingt an einen Fehler.
Hat jemand eine Idee, warum nach Placement-new und vor der Konstruktion absichtlich auf nullptr getestet werden sollte?
Hier mal ein Test:
Code: Alles auswählen
struct NonTrivialType {
int x;
NonTrivialType() : x(0) { }
NonTrivialType(NonTrivialType const & Ref) : x(Ref.x) { }
};
…
NonTrivialType * Array = new NonTrivialType[2];
new (&Array[0]) NonTrivialType(Array[1]);
Code: Alles auswählen
13F6E12DF test r11,r11
13F6E12E2 je 13F6E12EBh
13F6E12E4 mov eax,dword ptr [r11+4]
13F6E12E8 mov dword ptr [r11],eax
13F6E12EB …
Code: Alles auswählen
13F6E12E4 mov eax,dword ptr [r11+4]
13F6E12E8 mov dword ptr [r11],eax
Re: Is it just me, or …
Ich muss mich korrigieren, auch gcc testet das Ziel. Habe mit den Array-Indizees gespielt und bin durcheinander gekommen. placement-new muss wohl garantieren, auch im 0-Fall keine Exception zu werfen....ist natuerlich aergerlich, wenn man diesen per-se ausschliessen kann.
- Krishty
- Establishment
- Beiträge: 8346
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Is it just me, or …
Okay, Update:
Der C++-Standard sagt: Ist new mit throw() deklariert (wirft also keine Exceptions) und gibt nullptr zurück, darf keine Initialisierung stattfinden. Das gilt auch für das throw()-deklarierte Placement-new – dort liegt wahrscheinlich der Ursprung des Tests. Soweit, so gut.
Problematisch ist allerdings, dass der Compiler den Test nicht wegoptimiert, wenn die Adresse des Placements definitiv nicht nullptr ist … und das im Fall von VC sogar, wenn man es per __assume() zu erzwingen versucht. Das ist ein Bug im Optimizer.
Für GCC gibt es bereits einen entsprechenden Bug-Report, der 2005 gefiled wurde und immernoch offen ist. Für VC habe ich ihn gerade abgeschickt.
Der C++-Standard sagt: Ist new mit throw() deklariert (wirft also keine Exceptions) und gibt nullptr zurück, darf keine Initialisierung stattfinden. Das gilt auch für das throw()-deklarierte Placement-new – dort liegt wahrscheinlich der Ursprung des Tests. Soweit, so gut.
Problematisch ist allerdings, dass der Compiler den Test nicht wegoptimiert, wenn die Adresse des Placements definitiv nicht nullptr ist … und das im Fall von VC sogar, wenn man es per __assume() zu erzwingen versucht. Das ist ein Bug im Optimizer.
Für GCC gibt es bereits einen entsprechenden Bug-Report, der 2005 gefiled wurde und immernoch offen ist. Für VC habe ich ihn gerade abgeschickt.
- Krishty
- Establishment
- Beiträge: 8346
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Is it just me, or …
VCs Optimizer arbeitet auch ganz toll, wenn man eine float als int reinterpretieren möchte. Falls ihr mal so eine Funktion schreibt: Übergebt nicht float, sondern float const & – sonst wird die Gleitkommazahl aus einem SSE-Register auf den Stack geschoben, von dort zurück ins SSE-Register geladen, wieder zurück auf den Stack geschrieben, dann in ein Integer-Register geladen und erst dann weiterverarbeitet. Am besten pfeift ihr auch auf Aliasing und macht dann einfach return reinterpret_cast<int const &> – damit scheint der Compiler am besten zurecht zu kommen.
Übrigens sind Integer-Vergleiche locker 10 % schneller als Gleitkommavergleiche – wenn ihr also massiv auf Basis von Gleitkommazahlen brancht, konvertiert ihr Bitmuster zu Integers im Zweierkomplement und vergleicht die.
Übrigens sind Integer-Vergleiche locker 10 % schneller als Gleitkommavergleiche – wenn ihr also massiv auf Basis von Gleitkommazahlen brancht, konvertiert ihr Bitmuster zu Integers im Zweierkomplement und vergleicht die.
- Krishty
- Establishment
- Beiträge: 8346
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Is it just me, or …
Jeden Tag was Neues, Adam …
Hier gejammert und wenig später reproduziert: Der Linker entfernt unreferenzierte Compile-Time-constant-Arrays mal so, mal so aus der Exe. In meinem Programm hat er sie nur wegoptimiert, wenn sie in Zeigern lagen; beim Reproduzieren für den Bug-Report hat er sie nur entfernt, wenn sie in Arrays lagen.
Man kann sich also scheinbar nicht darauf verlassen, dass alles unreferenzierte Zeug rausfliegt – und es auch nicht wirklich erzwingen. Sollte das mal zum Problem werden (bei wirklich großen Datenmengen), sollte man sich vielleicht überlegen, ob man nicht per Präprozessor steuert, von welchen Symbolen der Compiler überhaupt weiß.
Hier gejammert und wenig später reproduziert: Der Linker entfernt unreferenzierte Compile-Time-constant-Arrays mal so, mal so aus der Exe. In meinem Programm hat er sie nur wegoptimiert, wenn sie in Zeigern lagen; beim Reproduzieren für den Bug-Report hat er sie nur entfernt, wenn sie in Arrays lagen.
Man kann sich also scheinbar nicht darauf verlassen, dass alles unreferenzierte Zeug rausfliegt – und es auch nicht wirklich erzwingen. Sollte das mal zum Problem werden (bei wirklich großen Datenmengen), sollte man sich vielleicht überlegen, ob man nicht per Präprozessor steuert, von welchen Symbolen der Compiler überhaupt weiß.
- kimmi
- Moderator
- Beiträge: 1412
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Is it just me, or …
Oder man checkt seinen Code mit so etwas wie Lint bzw. einem g++, der einem Warnungen für nicht referenzierte Symbole ausspuckt.
Gruß Kimmi
Gruß Kimmi
- Krishty
- Establishment
- Beiträge: 8346
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Is it just me, or …
Hmmm, interessantes Feature … kannst du mir genauer erklären, wie das funktioniert?
Was zum Beispiel passiert, wenn ich libpng einbinde um PNGs zu laden? Dann müsste doch ein Drittel der dortigen Symbole (nämlich die, die nur zum Schreiben da sind) als unreferenziert angezeigt werden … dann nochmal die Hälfte von zlib (alles, was nur zum Packen statt zum Entpacken da ist) inklusive endloser Listen von Lookup-Tables für Datenverarbeitung und Fehlernachrichten … und 90 % der Symbole der Laufzeitbibliothek sowieso?
Und, naja, wenn der Compiler (bzw. Linker) warnt, dass ein Symbol nicht genutzt wird, dann wird er ja auch in der Lage sein, es wegzulassen. Das bedeutet im Umkehrschluss, dass bei den Symbolen, die wegen dem Unvermögen des Compilers unnötig in der Executable landen, auch keine Warnung kommen würde.
Achja, noch was am Rande: Es scheint dem Optimizer auch einen Unterschied zu machen, ob meine Exception-Klasse einen Zuweisungsoperator hat oder nicht … Programmierung ist echt unberechenbar.
Was zum Beispiel passiert, wenn ich libpng einbinde um PNGs zu laden? Dann müsste doch ein Drittel der dortigen Symbole (nämlich die, die nur zum Schreiben da sind) als unreferenziert angezeigt werden … dann nochmal die Hälfte von zlib (alles, was nur zum Packen statt zum Entpacken da ist) inklusive endloser Listen von Lookup-Tables für Datenverarbeitung und Fehlernachrichten … und 90 % der Symbole der Laufzeitbibliothek sowieso?
Und, naja, wenn der Compiler (bzw. Linker) warnt, dass ein Symbol nicht genutzt wird, dann wird er ja auch in der Lage sein, es wegzulassen. Das bedeutet im Umkehrschluss, dass bei den Symbolen, die wegen dem Unvermögen des Compilers unnötig in der Executable landen, auch keine Warnung kommen würde.
Achja, noch was am Rande: Es scheint dem Optimizer auch einen Unterschied zu machen, ob meine Exception-Klasse einen Zuweisungsoperator hat oder nicht … Programmierung ist echt unberechenbar.
- Krishty
- Establishment
- Beiträge: 8346
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Is it just me, or …
Paralleles Thema: Gibt es eine Möglichkeit, den vector constructor iterator wegzuoptimieren?
Ich habe ein fixed-size-Array ([100]) eines User-Typs, dessen K’tor nichts anderes macht, als drei Member-Pointer auf 0 zu setzen. Anstatt nun 3×4×100 Bytes zu nullen, wird der vector constructor iterator aufgerufen und ruft den Konstruktor 100 Mal indirekt auf … erscheint mir irgendwie suboptimal :/
Ich habe ein fixed-size-Array ([100]) eines User-Typs, dessen K’tor nichts anderes macht, als drei Member-Pointer auf 0 zu setzen. Anstatt nun 3×4×100 Bytes zu nullen, wird der vector constructor iterator aufgerufen und ruft den Konstruktor 100 Mal indirekt auf … erscheint mir irgendwie suboptimal :/
- TGGC
- Establishment
- Beiträge: 569
- Registriert: 15.05.2009, 18:14
- Benutzertext: Ich _bin_ es.
- Alter Benutzername: TGGC
- Echter Name: Ich _bin_ es.
- Wohnort: Mainz
- Kontaktdaten:
Re: Is it just me, or …
Konstruktor schreiben, der nichts macht und dann den den Speicherblock mit memset fuellen. f'`8kKrishty hat geschrieben:Paralleles Thema: Gibt es eine Möglichkeit, den vector constructor iterator wegzuoptimieren?
Ich habe ein fixed-size-Array ([100]) eines User-Typs, dessen K’tor nichts anderes macht, als drei Member-Pointer auf 0 zu setzen. Anstatt nun 3×4×100 Bytes zu nullen, wird der vector constructor iterator aufgerufen und ruft den Konstruktor 100 Mal indirekt auf … erscheint mir irgendwie suboptimal :/
Gruß, TGGC (der kostenlose DMC Download)
-
- Moderator
- Beiträge: 2151
- Registriert: 25.02.2009, 13:37
Re: Is it just me, or …
Ich weiß nicht ob Kimmi die "Symbol defined but never used" Warnung meinte aber ich habe die immer so verstanden, dass der Gedanke dahinter ist dass der Programmierer sich vermutlich etwas dabei gedacht hat das Symbol zu definieren und es somit wahrscheinlich ein Irrtum des Programmieres ist dieses dann nicht zu benutzen. Der Charakter der Warnung war für mich immer "Du hast vergessen das Symbol zu benutzen" und nicht "Du hast eine Definition zuviel".Krishty hat geschrieben: Und, naja, wenn der Compiler (bzw. Linker) warnt, dass ein Symbol nicht genutzt wird, dann wird er ja auch in der Lage sein, es wegzulassen. Das bedeutet im Umkehrschluss, dass bei den Symbolen, die wegen dem Unvermögen des Compilers unnötig in der Executable landen, auch keine Warnung kommen würde.
- kimmi
- Moderator
- Beiträge: 1412
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Is it just me, or …
Teilweise kann es sogar unmöglich für den Compiler sein, nicht referenzierte Symbole wegzulassen: wenn über einen Header solche Dinge durch irgendwelche Kunstgriffe unbenutzte Symbole hinzukommen, die dann aber für andere Dlls wichtig sind. Und ja, das ist mir schon passiert :). Das setzt natürlich voraus, daß diese Symbole external linked sind. Bei Dlls hat das das selber ja in der Hand, bei Libs nur bedingt.
Mir ist es lieber, wenn der Compiler eine Warnung ausspuckt.
Gruß Kimmi
Mir ist es lieber, wenn der Compiler eine Warnung ausspuckt.
Gruß Kimmi
- Aramis
- Moderator
- Beiträge: 1458
- Registriert: 25.02.2009, 19:50
- Echter Name: Alexander Gessler
- Wohnort: 2016
- Kontaktdaten:
Re: Is it just me, or …
Man sollte einfach nicht vergessen dass ein Optimizer nichts ist, auf dass man sich 100% verlassen kann. Wenn absolut keine unreferenzierten Symbole drin sein duerfen, gibt es immer noch den Praeprozessor.
Fuer die allermeisten User spielt zudem Geschwindigkeit eine groessere Rolle als Groesse, daher duerfte die Entwicklung des MS-Linkers auch daraufhin ausgelegt sein.
Fuer die allermeisten User spielt zudem Geschwindigkeit eine groessere Rolle als Groesse, daher duerfte die Entwicklung des MS-Linkers auch daraufhin ausgelegt sein.
- Krishty
- Establishment
- Beiträge: 8346
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Is it just me, or …
Leider keine Option, da es kein PoD-Typ ist. Aber selbst, wenn ich es täte (ich habe es aus Verzweiflung gerade probiert) würde es nicht wegoptimiert – es würde in Schleife ein K’tor aufgerufen, der aus nichts als mov eax, ecx; ret bestünde.TGGC hat geschrieben:]Konstruktor schreiben, der nichts macht und dann den den Speicherblock mit memset fuellen.
Ich muss mich übrigens korrigieren, der Compiler benutzt den eh vector constructor iterator – und das wird auch der Knackpunkt sein: Ich vermute, dass der Compiler das tut, weil das Objekt unwindable ist (kein leerer Destruktor). Wahrscheinlich hat da irgendjemand angenommen, dass Objekte, sobald unwindable, auch ausnamesicher initialisiert werden müssen. Da der K’tor hier aber überhaupt keine Ausnahme auslösen kann (und der Compiler das auch korrekt erkennt, weil er an anderen Stellen entsprechenden Code weglässt) ist es hier auch überflüssig, ausnahmesicher zu initialisieren. Oder sehe ich das falsch?
Kann es sein, dass diese Warnung nur für den Quellcode der aktuellen Executable getriggert wird und nicht für alles, was zu ihr dazugelinkt wird?Alexander Kornrumpf hat geschrieben:Ich weiß nicht ob Kimmi die "Symbol defined but never used" Warnung meinte aber ich habe die immer so verstanden, dass der Gedanke dahinter ist dass der Programmierer sich vermutlich etwas dabei gedacht hat das Symbol zu definieren und es somit wahrscheinlich ein Irrtum des Programmieres ist dieses dann nicht zu benutzen. Der Charakter der Warnung war für mich immer "Du hast vergessen das Symbol zu benutzen" und nicht "Du hast eine Definition zuviel".
Ja, eine Warnung wäre mir auch lieb, aber der Compiler hält einfach nur die Klappe und packt die Symbole (wahllos!) mit rein. Achja, was wären das für Kunstgriffe?kimmi hat geschrieben:Teilweise kann es sogar unmöglich für den Compiler sein, nicht referenzierte Symbole wegzulassen: wenn über einen Header solche Dinge durch irgendwelche Kunstgriffe unbenutzte Symbole hinzukommen, die dann aber für andere Dlls wichtig sind. Und ja, das ist mir schon passiert :). Das setzt natürlich voraus, daß diese Symbole external linked sind. Bei Dlls hat das das selber ja in der Hand, bei Libs nur bedingt.
Mir ist es lieber, wenn der Compiler eine Warnung ausspuckt.
Wenn ich ihn geschrieben hätte, wäre das wohl anders. Aber vielleicht ändert es sich schon, wenn ich das Team weiterhin täglich mit Bug-Reports bombardiere … :)Aramis hat geschrieben:Man sollte einfach nicht vergessen dass ein Optimizer nichts ist, auf dass man sich 100% verlassen kann.
Es macht aber schon einen Unterschied, ob ein Linker einfach nur die Hälfte der Symbole weglässt, bei der er am schnellsten feststellen kann, dass sie unbenutzt sind oder ob er absolut gleichberechtigte Symbole ohne jedes nachvollziehbare Muster behält oder nicht. Das eine ist eine Optimierung, das andere imo ein Bug oder zumindest Nachlässigkeit.Aramis hat geschrieben:Fuer die allermeisten User spielt zudem Geschwindigkeit eine groessere Rolle als Groesse, daher duerfte die Entwicklung des MS-Linkers auch daraufhin ausgelegt sein.
- kimmi
- Moderator
- Beiträge: 1412
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Is it just me, or …
Zum Beispiel einen Int als volatile markieren, damit eine Variable nicht wegoptimiert wird. Oder man zaubert sich mit dem Präprozessor Symbole weg / Dummysymbole hin, um Linkprobleme in den Griff zu kriegen ( für Dummy-Wrapper beliebt, link mal F77, F90, C und C++ Libs zusammen, da kommt Freude auf ). Und ich hatte erst letztens ein Problem mit einem auf dem Heap generierten Objekt, daß unresolved symbols Fehler erzeugt hatte. Auf dem Stack kreiert waren die weg ( flgl heißt die Lib ). Ich hab den Fehler aus Zeitmangel nicht nachvollzogen.
Und wenn ich beim 2008'er das Warninglevel auf 4 stelle, kriege ich zumindest in meinem Code Warnungen für definierte, aber nicht referenzierte Symbole.
Gruß Kimmi
Und wenn ich beim 2008'er das Warninglevel auf 4 stelle, kriege ich zumindest in meinem Code Warnungen für definierte, aber nicht referenzierte Symbole.
Gruß Kimmi
- Krishty
- Establishment
- Beiträge: 8346
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Is it just me, or …
Wtf, ich kompiliere seit Jahren nur mit Warning Level 4. Ich bekomme Warnungen bei unreferenzierten Parametern, unreferenzierten lokalen Objekten – aber noch nie bei unreferenzierten Funktionen oder globalen Objekten. Jetzt muss ich aber mal einen Blick in die Compiler-Einstellungen werfen …kimmi hat geschrieben:Und wenn ich beim 2008'er das Warninglevel auf 4 stelle, kriege ich zumindest in meinem Code Warnungen für definierte, aber nicht referenzierte Symbole.
- kimmi
- Moderator
- Beiträge: 1412
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Is it just me, or …
Ops, sorry! Die Warnungen über nicht referenzierte Funktionen kriege ich von Lint! Ich hab die durch den Tüddel bekommen!
Gruß Kimmi
Gruß Kimmi
- Krishty
- Establishment
- Beiträge: 8346
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Is it just me, or …
Ah, okay! Microsofts statische Code-Analyse schmeißt vergleichbare Warnungen leider nicht. Dafür habe ich jetzt das Warning-Level WAll entdeckt, boah, da geht jedem Pedanten das Herz auf.
Es hat wohl einen Grund, warum diese Warnungen per default ausgeblendet werden.
Edit: DA!
Warning | 3081 | warning C4514: '_chgsignl' : unreferenced inline function has been removed | X:\Tools\VS2010\VC\include\math.h | 380
und direkt wieder herp derp:
Code: Alles auswählen
struct X {
enum {
A,
B,
NumValues,
}; // warning C4820: 'X' : '3' bytes padding added after data member 'NumValues'
int Members[NumValues];
};
Code: Alles auswählen
__assume(x <= 3); // warning C4557: '__assume' contains effect '='
Edit: DA!
Warning | 3081 | warning C4514: '_chgsignl' : unreferenced inline function has been removed | X:\Tools\VS2010\VC\include\math.h | 380
und direkt wieder herp derp:
Code: Alles auswählen
__declspec(noinline) void Foo(); // warning C4514: 'Foo' : unreferenced inline function has been removed
- Krishty
- Establishment
- Beiträge: 8346
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Is it just me, or …
Code: Alles auswählen
inline int Round(double const & Value) {
return ::_mm_cvtsd_si32(::_mm_load_sd(&Value));
}
…
int x = Round(1.0);
Code: Alles auswählen
movsd xmm0,mmword ptr [__real@3ff0000000000000]
movsd mmword ptr [SomeLocalAddress],xmm0
movsd xmm1,mmword ptr [SomeLocalAddress]
cvtsd2si edx,xmm1
- kimmi
- Moderator
- Beiträge: 1412
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Is it just me, or …
Wieso nimmst du da nicht einfach floor, der soll gemäß MS-Doku für alle Architekturen ein Intrinsic sein:
Das sieht dann auch etwas lesbarer aus und ist definitiv portabler. Keine Ahnung, was da an Assemblercode rausfällt. Außerdem gibst du einen int für einen Double zurück, wahrscheinlich für den absoluten Anteil des Doubles. Eventuell liegt da das Problem, weil double auf Int gecastet werden muß? Ich weiß nicht, wie das auf 64-Bit-Plattformen aussieht. KA!
Gruß Kimmi
Code: Alles auswählen
inline long floor(double val )
{
return (long)floor( val + 0.5 );
}
Gruß Kimmi
- Krishty
- Establishment
- Beiträge: 8346
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Is it just me, or …
Weil es nur für positive Zahlen funktioniert und um den Faktor 10 langsamer ist (floor ist zwar ein Intrinsic, aber nicht nur ein einziger Assembler-Befehl wie es cvtsd2si ist).kimmi hat geschrieben:Wieso nimmst du da nicht einfach floor
- kimmi
- Moderator
- Beiträge: 1412
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Is it just me, or …
Das mit dem Langsamer mag sein, aber floor gibt es für float und double. In Kombination mit dem ?-Operator und ceil klappts auch für negative :). Aber da bleibt natürlich das Performance-Problem.
Gruß Kimmi
Gruß Kimmi