Jammer-Thread
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Also wenn vorher deine Klasse ein std::vector- und ein HANDLE-Attribut hatte, muss jedes Übersetzungsmodul, das irgendwie deine Klasse benutzt, <vector> und <Windows.h> einbinden, denn die gehören zur Definition der Klasse, und die brauchst du, um Methoden aufzurufen.
Mit der freien Funktion hingegen liegt die Definition der Klasse in einem einzigen Übersetzungsmodul, und andere Module sehen nichts anderes als die öffentliche Schnittstelle in Form der freien Funktionen, die du in einen gemeinsamen Header geschrieben hast (oder rumkopiert hast, wenn du mehr Schreibarbeit haben willst). Wenn nun irgendwas deine Klasse benutzt, muss es kein <vector> oder <Windows.h> mehr einbinden.
So rutschen die #include-Zeilen von Hunderttausenden runter auf eine Handvoll, und statt exponentiellem „alles braucht alle Definitionen von allem womit es arbeitet und alle Definitionen, die darin vorkommen“ hast du weit weniger fettes „alles braucht nur Deklarationen von allem womit es arbeitet“. Und die Deklarationen kann man sorgar durch struct vor der Erwähnung in Funktionsdeklarationen machen.
Das geht natürlich nicht mit etwas, das lokal instanziert werden muss. Aber die meisten Klassen werden nur über die öffentliche Schnittstelle angesprochen oder auf dem Heap allokiert statt lokal instanziert, und das sind meist auch die mit den fetten Abhängigkeiten. Die sind dann superschnell und wolkig-leicht.
Mit der freien Funktion hingegen liegt die Definition der Klasse in einem einzigen Übersetzungsmodul, und andere Module sehen nichts anderes als die öffentliche Schnittstelle in Form der freien Funktionen, die du in einen gemeinsamen Header geschrieben hast (oder rumkopiert hast, wenn du mehr Schreibarbeit haben willst). Wenn nun irgendwas deine Klasse benutzt, muss es kein <vector> oder <Windows.h> mehr einbinden.
So rutschen die #include-Zeilen von Hunderttausenden runter auf eine Handvoll, und statt exponentiellem „alles braucht alle Definitionen von allem womit es arbeitet und alle Definitionen, die darin vorkommen“ hast du weit weniger fettes „alles braucht nur Deklarationen von allem womit es arbeitet“. Und die Deklarationen kann man sorgar durch struct vor der Erwähnung in Funktionsdeklarationen machen.
Das geht natürlich nicht mit etwas, das lokal instanziert werden muss. Aber die meisten Klassen werden nur über die öffentliche Schnittstelle angesprochen oder auf dem Heap allokiert statt lokal instanziert, und das sind meist auch die mit den fetten Abhängigkeiten. Die sind dann superschnell und wolkig-leicht.
- xq
- Establishment
- Beiträge: 1589
- Registriert: 07.10.2012, 14:56
- Alter Benutzername: MasterQ32
- Echter Name: Felix Queißner
- Wohnort: Stuttgart & Region
- Kontaktdaten:
Re: Jammer-Thread
Elediges Rumgeficke mit Variadic Templates. Dafür kann ich jetzt beliebige C++-Funktionen aufrufen, deren Argumentliste aus dem Lua-Stack gefüttert wird. Und das ist ziemlich cool.
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…
Programmiert viel in Zig und nervt Leute damit.
Programmiert viel in Zig und nervt Leute damit.
- Schrompf
- Moderator
- Beiträge: 5050
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Re: Jammer-Thread
Gerade wegen Linux-Portierung, Encoding und Pfaden wieder in die Tiefen von locales abgetaucht - grmpf. Global State wherever you go, überflüssige Verzeichnisstrukturen mit genau je einem File drin und nicht so ganz genau spezifizierte Encodings quer durch's Programm.
Würde gern alles in UTF8 machen, aber dazu müsste ich selbst anfangen, Pfade zu zerlegen und zusammenzusetzen.
Oder ich mach alles im jeweiligen Native Encoding, wie boost::filesystem es tut, aber dann müsste ich jeden Pfad von irgendwo in ein Makro wrappen. Grmpf. Und wenn Dateinamen und Pfade aus XML_Dateien kommen, muss man *auf machen* Plattformen manuell konvertieren.
Würde gern alles in UTF8 machen, aber dazu müsste ich selbst anfangen, Pfade zu zerlegen und zusammenzusetzen.
Oder ich mach alles im jeweiligen Native Encoding, wie boost::filesystem es tut, aber dann müsste ich jeden Pfad von irgendwo in ein Makro wrappen. Grmpf. Und wenn Dateinamen und Pfade aus XML_Dateien kommen, muss man *auf machen* Plattformen manuell konvertieren.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
-
- Establishment
- Beiträge: 426
- Registriert: 23.01.2013, 15:55
Re: Jammer-Thread
Ich verwende überall bei mir grundsätzlich UTF-8 und konvertiere nur speziell auf Windows System Calls vorher nach UTF-16. Das funktioniert bei mir hervorragend. Warum musst dafür denn Pfade zerlegen und zusammensetzen? Das verstehe ich gerade nicht so ganz.
Von "locale" lasse ich inzwischen die Finger. Ich erwarte einfach das ein deutscher Benutzer meines Programmes anstatt eines Kommas einen Punkt schreibt. Verglichen damit wie viel Software schon ihren Dienst versagt hat, weil zum Beispiel lokalisierte Werte in Dateien gespeichert werden, kein großer Verlust. Ist vielleicht aber nicht in jeder Software möglich.
Von "locale" lasse ich inzwischen die Finger. Ich erwarte einfach das ein deutscher Benutzer meines Programmes anstatt eines Kommas einen Punkt schreibt. Verglichen damit wie viel Software schon ihren Dienst versagt hat, weil zum Beispiel lokalisierte Werte in Dateien gespeichert werden, kein großer Verlust. Ist vielleicht aber nicht in jeder Software möglich.
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Ich persönlich bin Verfechter des Native Encodings, wie hier besprochen: http://zfx.info/viewtopic.php?f=4&t=297 ... =30#p37656
Klar, dann muss das, was aus den XML-Dateien kommt, auf einer der Plattformen konvertiert werden. Aber IMHO besser als auf allen Plattformen alles zu konvertieren.
Klar, dann muss das, was aus den XML-Dateien kommt, auf einer der Plattformen konvertiert werden. Aber IMHO besser als auf allen Plattformen alles zu konvertieren.
-
- Establishment
- Beiträge: 426
- Registriert: 23.01.2013, 15:55
Re: Jammer-Thread
Kann ich persönlich so nicht voll unterstützen. Deine Umsetzung ist zwar auch eine Lösung, behebt aber nur einen Bruchteile der Probleme. Außer dem ideellen Wert, dass man eine Operation weniger macht, ist nicht wirklich etwas gewonnen. Eine Konvertierung kann sehr schnell gehen und sehr viel schneller als jeder Systemaufruf oder selbst "std::string" wenn die SSO nicht anschlägt. Dein Ansatz funktioniert angefangen von externen Bibliotheken, XML oder interne String-Operationen nur mit Mehraufwand. Überhaupt, sind doch die meisten Strings nicht hardcoded.
Man kann außerdem auch so argumentieren, dass UTF-8 Strings durchschnittlich nur halb soviel Speicherplatz benötigen und damit generell im Programm zu bevorzugen sind. ;)
Man kann außerdem auch so argumentieren, dass UTF-8 Strings durchschnittlich nur halb soviel Speicherplatz benötigen und damit generell im Programm zu bevorzugen sind. ;)
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Was denn jetzt, Mehraufwand oder eine Operation weniger?
Wer sagt, dass externe Bibliotheken zwingend alles mit UTF-8 machen? Man *spart* doch eher Aufwand, wenn die Bibliothek zufällig dieselbe Kodierung nutzt (wie es eben boost::filesystem tut), oder? Und ich denke, dass eine Konvertierung weniger kein ideeller Wert, sondern reduzierte Ausführungskomplexität ist.
Wer sagt, dass externe Bibliotheken zwingend alles mit UTF-8 machen? Man *spart* doch eher Aufwand, wenn die Bibliothek zufällig dieselbe Kodierung nutzt (wie es eben boost::filesystem tut), oder? Und ich denke, dass eine Konvertierung weniger kein ideeller Wert, sondern reduzierte Ausführungskomplexität ist.
-
- Establishment
- Beiträge: 426
- Registriert: 23.01.2013, 15:55
Re: Jammer-Thread
Mehraufwand für mich als Programmierer.
Ich muss schließlich von Hand eine Konvertierung durchführen. Wenn einfach alle APIs UTF-8 nutzen, hat man weniger Arbeit.
Ich weiß ja nicht mit welchen Bibliotheken du so arbeitest: Ich für meinen Teil habe die Erfahrung gemacht, dass fast alle der von mir genutzten Bibliotheken auch aus der Welt der freien Betriebssysteme kommen und dann logischerweise sowieso nur UTF-8 nutzen.
Wie gesagt, müsste ich ohnehin die meisten Strings konvertieren. Besitzt eine Unicode-Konvertierungsroutine eine hohe Ausführungskomplexität? Meiner Meinung nach nein. Allerdings sehe ich darin schon auch einen ideellen Wert. Vielleicht weiß ich damit aber auch einfach nicht, was du genau meinst. Praktische Werte sind für mich zum Beispiel Geschwindigkeit, Speicherverbrauch, Wartbarkeit oder Korrektheit.
Wenn man eine Anwendung speziell für Windows, WinAPI und DirectX Plattform schreibt, kann man natürlich die Sache schon vereinfachen, grundsätzlich bei UTF-16 zu bleiben. Ich für meinen Teil arbeite "meistens" weniger mit Windows-spezifischen APIs und sehe keinen Sinn darin, für meine paar zur Plattformunabhänigkeit gewrappten WinAPI Funktionen jetzt einen neuen String-Typen einzuführen.
Ich muss schließlich von Hand eine Konvertierung durchführen. Wenn einfach alle APIs UTF-8 nutzen, hat man weniger Arbeit.
Ich weiß ja nicht mit welchen Bibliotheken du so arbeitest: Ich für meinen Teil habe die Erfahrung gemacht, dass fast alle der von mir genutzten Bibliotheken auch aus der Welt der freien Betriebssysteme kommen und dann logischerweise sowieso nur UTF-8 nutzen.
Wie gesagt, müsste ich ohnehin die meisten Strings konvertieren. Besitzt eine Unicode-Konvertierungsroutine eine hohe Ausführungskomplexität? Meiner Meinung nach nein. Allerdings sehe ich darin schon auch einen ideellen Wert. Vielleicht weiß ich damit aber auch einfach nicht, was du genau meinst. Praktische Werte sind für mich zum Beispiel Geschwindigkeit, Speicherverbrauch, Wartbarkeit oder Korrektheit.
Wenn man eine Anwendung speziell für Windows, WinAPI und DirectX Plattform schreibt, kann man natürlich die Sache schon vereinfachen, grundsätzlich bei UTF-16 zu bleiben. Ich für meinen Teil arbeite "meistens" weniger mit Windows-spezifischen APIs und sehe keinen Sinn darin, für meine paar zur Plattformunabhänigkeit gewrappten WinAPI Funktionen jetzt einen neuen String-Typen einzuführen.
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
1 | char * copyAndAppendZero(
2 | char * toDestination,
3 | char const * toSource,
4 | char const * toEndOfSource
5 | ) {
6 | auto const length = size_t(toEndOfSource - toSource);
7 | __movsb((unsigned char *)toDestination, (unsigned char const *)toSource, length);
8 | toDestination += length;
9 | *toDestination++ = '\0';
10 | return toDestination;
11 | }
Die Addition in Zeile 8
sie produziert tatsächlich Code
mit einem zusätzlichen Register
und lädt dafür sogar toDestinations Originalwert vom Stack
wie kann man so dumm sein und seinem Compiler ein Intrinsic hinzufügen, das ein Ergebnis in einem Register hinterlässt, und das einfach wegschmeißen?! Ich meine: Wofür überhaupt ein Intrinsic, wenn nicht wegen der Leistung?! Nein, sie machen es void!
2 | char * toDestination,
3 | char const * toSource,
4 | char const * toEndOfSource
5 | ) {
6 | auto const length = size_t(toEndOfSource - toSource);
7 | __movsb((unsigned char *)toDestination, (unsigned char const *)toSource, length);
8 | toDestination += length;
9 | *toDestination++ = '\0';
10 | return toDestination;
11 | }
Die Addition in Zeile 8
sie produziert tatsächlich Code
mit einem zusätzlichen Register
und lädt dafür sogar toDestinations Originalwert vom Stack
wie kann man so dumm sein und seinem Compiler ein Intrinsic hinzufügen, das ein Ergebnis in einem Register hinterlässt, und das einfach wegschmeißen?! Ich meine: Wofür überhaupt ein Intrinsic, wenn nicht wegen der Leistung?! Nein, sie machen es void!
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Erinnert ihr euch noch, wie ich vor Jahren gemeldet habe, dass Visual C++ besser optimiert, wenn Klassen keine Destruktoren haben?
Offenbar optimiert es auch schlecht, wenn Konstruktoren default-Deklariert sind.
Können wir jetzt bitte Clang haben?
Offenbar optimiert es auch schlecht, wenn Konstruktoren default-Deklariert sind.
Können wir jetzt bitte Clang haben?
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Visual C++ 2013 vergisst die Initialisierung eines Members, wenn dessen Konstruktor keinen Parameter hat und ein Template ist und der umgebende Konstruktor geinlinet wird oder so. Von Hand hinschreiben oder Optimierungen abschalten geht. Boah echt jetzt. Jedes Mal, wenn ich ins scheiß Disassembly gucke, geht irgendwas kaputt.
Nachtrag: Es ist schon echt bezeichnend, dass hier eine Warnung fliegt:
bool const changeTexture = ...;
UnsignedInt originalTexture;
if(changeTexture) {
originalTexture = bar(...);
}
foo();
if(changeTexture) {
bar(originalTexture); // warning C4701: potentially uninitialized local variable 'originalTexture' used
}
Visual C++ x64 geht auf höchster Optimierungsstufe davon aus, dass sich der Wert einer lokalen Variable ändert, wenn ein Funktionsaufruf OHNE DIE VARIABLE stattfindet. Es wäre niedlich, wenn es nicht so nerven würde.
Nachtrag 2: Jetzt ist mein Debug-Fenster voller Fragezeichen. Vielleicht ist ja doch nicht der Compiler kaputt, sondern ein wilder Zeiger hat den Syntaxbaum überschrieben oder so. Macht ja auch keinen Unterschied mehr!
Nachtrag: Es ist schon echt bezeichnend, dass hier eine Warnung fliegt:
bool const changeTexture = ...;
UnsignedInt originalTexture;
if(changeTexture) {
originalTexture = bar(...);
}
foo();
if(changeTexture) {
bar(originalTexture); // warning C4701: potentially uninitialized local variable 'originalTexture' used
}
Visual C++ x64 geht auf höchster Optimierungsstufe davon aus, dass sich der Wert einer lokalen Variable ändert, wenn ein Funktionsaufruf OHNE DIE VARIABLE stattfindet. Es wäre niedlich, wenn es nicht so nerven würde.
Nachtrag 2: Jetzt ist mein Debug-Fenster voller Fragezeichen. Vielleicht ist ja doch nicht der Compiler kaputt, sondern ein wilder Zeiger hat den Syntaxbaum überschrieben oder so. Macht ja auch keinen Unterschied mehr!
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Jammer-Thread
Außerdem vergisst Visual C++ 2013 auch ohne Warnung oder Fehlermeldung sämtliche Inline-Nonstatic-Member-Initialisierungen wenn die umgebende Klasse keinen Namen hat - weil solche Klassen ja ehemals keine handgeschriebenen C'toren haben durften und VC++ wohl einfach einen handgeschriebenen C'tor aus diesen Initialisierungen baut. Als der Fehler auftrat habe ich nicht mal 10 s gebraucht, um das Problem zu erkennen - so sehr denkt man nach einigen Jahren wie VC++' Compiler-Team, dass man auf der Stelle die schlechtestmögliche Umsetzung mit den meisten Sonderfallbehandlungen und Problemen erkennt, annimmt und bestätigt findet. :|Krishty hat geschrieben:Visual C++ 2013 vergisst die Initialisierung eines Members, wenn dessen Konstruktor keinen Parameter hat und ein Template ist und der umgebende Konstruktor geinlinet wird oder so [...]
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- kimmi
- Moderator
- Beiträge: 1405
- Registriert: 26.02.2009, 09:42
- Echter Name: Kim Kulling
- Wohnort: Luebeck
- Kontaktdaten:
Re: Jammer-Thread
Eure Sogen möchte ich haben :). Ich arbeite mit vxWorks von WIndows aus. Visual-Studio zu benutzen wäre ein Traum!
Kimmi
Kimmi
Re: Jammer-Thread
Ist doch logisch: Die aufgerufene Funktion könnte doch anhand ihres Stack-Pointers den Zeiger der darüberliegenden Variablen herausfunden und ihren Inhalt verändern. Vielleicht gibt es ja Software in der Industrie, die das wirklich so macht ;) Deshalb kann Microsoft das Verhalten nicht ändern :PKrishty hat geschrieben:Visual C++ x64 geht auf höchster Optimierungsstufe davon aus, dass sich der Wert einer lokalen Variable ändert, wenn ein Funktionsaufruf OHNE DIE VARIABLE stattfindet. Es wäre niedlich, wenn es nicht so nerven würde.
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Ja, sowas passiert tatsächlich, wenn auch nur lesend statt schreibend:antisteo hat geschrieben:Ist doch logisch: Die aufgerufene Funktion könnte doch anhand ihres Stack-Pointers den Zeiger der darüberliegenden Variablen herausfunden und ihren Inhalt verändern. Vielleicht gibt es ja Software in der Industrie, die das wirklich so macht ;) Deshalb kann Microsoft das Verhalten nicht ändern :PKrishty hat geschrieben:Visual C++ x64 geht auf höchster Optimierungsstufe davon aus, dass sich der Wert einer lokalen Variable ändert, wenn ein Funktionsaufruf OHNE DIE VARIABLE stattfindet. Es wäre niedlich, wenn es nicht so nerven würde.
Die richtige Lösung wäre aber in diesem Fall, den Fake Stack volatile zu deklarieren anstatt Optimierungen für alle lokalen Variablen in jedem Windows-Programm der Welt abzuschalten.The Old New Thing — When programs grovel into undocumented structures... hat geschrieben:A certain software company decided that it was too hard to take the coordinates of the NM_DBLCLK notification and hit-test it against the treeview to see what was double-clicked. So instead, they take the address of the NMHDR structure passed to the notification, add 60 to it, and dereference a DWORD at that address. If it's zero, they do one thing, and if it's nonzero they do some other thing.
It so happens that the NMHDR is allocated on the stack, so this program is reaching up into the stack and grabbing the value of some local variable (which happens to be two frames up the stack!) and using it to control their logic.
For Windows 2000, we upgraded the compiler to a version which did a better job of reordering and re-using local variables, and now the program couldn't find the local variable it wanted and stopped working.
I got tagged to investigate and fix this. I had to create a special NMHDR structure that "looked like" the stack the program wanted to see and pass that special "fake stack".
I think this one took me two days to figure out.
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Jammer-Thread
Dazu mal zwei Fragen.Krishty hat geschrieben:Ja, sowas passiert tatsächlich, wenn auch nur lesend statt schreibend:Die richtige Lösung wäre aber in diesem Fall, den Fake Stack volatile zu deklarieren anstatt Optimierungen für alle lokalen Variablen in jedem Windows-Programm der Welt abzuschalten.The Old New Thing — When programs grovel into undocumented structures... hat geschrieben:A certain software company [...]
For Windows 2000, we upgraded the compiler to a version which did a better job of reordering and re-using local variables, and now the program couldn't find the local variable it wanted and stopped working.
I got tagged to investigate and fix this. I had to create a special NMHDR structure that "looked like" the stack the program wanted to see and pass that special "fake stack".
I think this one took me two days to figure out.
Erstens: WIe groß muss "a certain software company" sein, dass Microsoft durch den Reifen springt. Wenn meine Programme nicht laufen kann ich nicht bei Microsoft anrufen und fordern, dass sie was am Betriebssystem oder Compiler ändern.
Zweitens: Es ist ja bekannt, dass die Abwärtskompatibilität von Windows extrem wichtig ist. In dem Zusammenhang kann ich aber "For Windows 2000, we upgraded the compiler to a version" nicht parsen. Abwärtskompatibilität bezieht sich doch darauf, dass das alte Kompilat auf dem neuen Betriebssystem noch läuft und nicht, so dachte ich zumindest, dass ein Programm, das undokumentiertes (?) Verhalten eines bestimmten Kompilers ausnutzt auch dann noch läuft, wenn man es einem anderen Kompiler neu baut. Wie ist das also gemeint? Habe ich einen Bug in meiner Vorstellung der Aufgabenverteilung zwischen Kompiler und Betriebssystem?
Re: Jammer-Thread
Ich denke es kommt nicht darauf an, wie groß die Firma ist, sondern wie verbreitet die Software ist.Alexander Kornrumpf hat geschrieben: Erstens: WIe groß muss "a certain software company" sein, dass Microsoft durch den Reifen springt. Wenn meine Programme nicht laufen kann ich nicht bei Microsoft anrufen und fordern, dass sie was am Betriebssystem oder Compiler ändern.
Das fehlerhafte Programm wurde ja nicht neu kompiliert. Microsoft hat den Sourcecode ja garnicht. Das Programm hat auf interne Variablen von Windowsfunktionen zugegriffen.Alexander Kornrumpf hat geschrieben: Zweitens: Es ist ja bekannt, dass die Abwärtskompatibilität von Windows extrem wichtig ist. In dem Zusammenhang kann ich aber "For Windows 2000, we upgraded the compiler to a version" nicht parsen. Abwärtskompatibilität bezieht sich doch darauf, dass das alte Kompilat auf dem neuen Betriebssystem noch läuft und nicht, so dachte ich zumindest, dass ein Programm, das undokumentiertes (?) Verhalten eines bestimmten Kompilers ausnutzt auch dann noch läuft, wenn man es einem anderen Kompiler neu baut. Wie ist das also gemeint? Habe ich einen Bug in meiner Vorstellung der Aufgabenverteilung zwischen Kompiler und Betriebssystem?
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Jammer-Thread
Danke. Hatte ich nicht verstanden. Jetzt ergibt alles einen Sinn.Helmut hat geschrieben: Das fehlerhafte Programm wurde ja nicht neu kompiliert. Microsoft hat den Sourcecode ja garnicht. Das Programm hat auf interne Variablen von Windowsfunktionen zugegriffen.
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Ja genau. Es gibt alte Geschichten, dass sie für Windows 95 den lokalen Software-Discounter leergekauft und die Software an alle Mitarbeiter verteilt haben. Für XP gab es wohl einen Chart mit Programmen, die funktionieren MUSSTEN (und in den Top 10 war Deer Hunter).Helmut hat geschrieben:Ich denke es kommt nicht darauf an, wie groß die Firma ist, sondern wie verbreitet die Software ist.Alexander Kornrumpf hat geschrieben: Erstens: WIe groß muss "a certain software company" sein, dass Microsoft durch den Reifen springt. Wenn meine Programme nicht laufen kann ich nicht bei Microsoft anrufen und fordern, dass sie was am Betriebssystem oder Compiler ändern.
Man darf auch nicht vernachlässigen, dass Kompatibilität für ein bestimmtes Programm als Nebenwirkung auch andere Programme funktionieren lässt, die den selben Hack benutzen. Ich kann mir durchaus vorstellen, dass sie heute nicht nach bestimmten Software-Produkten, sondern nach Fehlerklasse arbeiten (Heap-double-Free-Bugs betreffen hunderttausende Programme, also hat Kompatibilität dort Priorität vor irgendwelchen obskuren Dateisystem-Bugs).
-
- Moderator
- Beiträge: 2138
- Registriert: 25.02.2009, 13:37
Re: Jammer-Thread
Was aber gleich viel wenige kurios klingt wenn man sich klar macht, dass Deer Hunter für einen kurzen Moment der Geschichte das war was heute meinetwegen Minecraft ist. Und andererseits zum Nachdenken anregt was die Frage angeht ob Phänomene wie eben z. B. Minecraft in 15 Jahren noch da sein werden.Krishty hat geschrieben:Für XP gab es wohl einen Chart mit Programmen, die funktionieren MUSSTEN (und in den Top 10 war Deer Hunter).
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Ja, absolut. Wobei ich finde, dass sich Deer Hunter einfach in den Simulationswahn um die 2010er herum weiterentwickelt hat und deshalb gar nicht so tot ist wie man erstmal denkt.
Weil ich gerade so kurz angebunden war, hier nochmal die Quellen auf The Old New Thing: und mein persönlicher Favorit sind die letzten beiden Fragen dieses Artikels:Jetzt verlassen wir aber langsam den Jammer-Thread :)
Weil ich gerade so kurz angebunden war, hier nochmal die Quellen auf The Old New Thing: und mein persönlicher Favorit sind die letzten beiden Fragen dieses Artikels:Jetzt verlassen wir aber langsam den Jammer-Thread :)
Re: Jammer-Thread
windows.h :(
(Ich habe irgendwie das Gefühl, dass ich so viele meiner Probleme mit einem einzigen Wort beschreiben kann. Neulich kam ich nach einer langen Debugsession zu meinem Kollegen ins Zimmer und sagte nur: "std::ios::binary")
Aber vielleicht kann mir ja wer helfen: Ich kam leider in die Situation einen zusätzlichen Header inkludieren zu müssen (um Zeit zu sparen zieh ich jetzt mal nicht über das vollkommen kaputte Buildsystem von C++ her), der irgendwo einen OpenGL Header inkludierte, der irgendwo die windows.h Funktion inkludierte. Und jetzt ist meine GetKeyState Funktion doppelt definiert. Das schöne an Windows.h Makros ist, dass man sie wegdefinieren kann, aber GetKeyState ist eine Funktion.
Vielleicht könnte ich mit viel Mühe meine Header überarbeiten um die Abhängigkeit zu vermeiden, aber gibt es nicht eine Allzweck Strategie um die ganzen Drecks-Definitionen aus der Windows.h nicht in den globalen Namespace zu schmeißen? Der entsprechende OpenGL Header ist übrigens mit GlLoadGen generiert.
(Ich habe irgendwie das Gefühl, dass ich so viele meiner Probleme mit einem einzigen Wort beschreiben kann. Neulich kam ich nach einer langen Debugsession zu meinem Kollegen ins Zimmer und sagte nur: "std::ios::binary")
Aber vielleicht kann mir ja wer helfen: Ich kam leider in die Situation einen zusätzlichen Header inkludieren zu müssen (um Zeit zu sparen zieh ich jetzt mal nicht über das vollkommen kaputte Buildsystem von C++ her), der irgendwo einen OpenGL Header inkludierte, der irgendwo die windows.h Funktion inkludierte. Und jetzt ist meine GetKeyState Funktion doppelt definiert. Das schöne an Windows.h Makros ist, dass man sie wegdefinieren kann, aber GetKeyState ist eine Funktion.
Vielleicht könnte ich mit viel Mühe meine Header überarbeiten um die Abhängigkeit zu vermeiden, aber gibt es nicht eine Allzweck Strategie um die ganzen Drecks-Definitionen aus der Windows.h nicht in den globalen Namespace zu schmeißen? Der entsprechende OpenGL Header ist übrigens mit GlLoadGen generiert.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Hat die OpenGL-Funktion denn identische Parameter? Normalerweise müsste sich das Problem durch Überladung erledigen …
Re: Jammer-Thread
Ja, meine Funktion hat auch einen int als Parameter. (d.h. über den OpenGL Header kommt die Windows.h rein, und deren GetKeyState kollidiert dann mit meinem GetKeyState-Wrapper für GLFW). Meine war in einem Input:: namespace, weswegen es halt geht wenn ich ihn explizit davor schreibe. Aber es nervt einfach, wenn der globale Namespace zugemüllt wird und ich in meiner cpp-Datei, die nunmal Input verarbeitet kein using namespace Input; benutzen kann.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/
- Schrompf
- Moderator
- Beiträge: 5050
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas
- Wohnort: Dresden
- Kontaktdaten:
Re: Jammer-Thread
CMake. Ich kriege echt Assimp nicht mehr gebaut, weil die generierten Projekte ihre eigens gebauten Libs nicht mehr finden. Wenn man das manuell korrigiert und den DLL-Quatsch ausmacht, bekommt man immernoch ein Rudel Linkerfehler von vermissten Funktionen, die ganz eindeutig da sind.
Leider muss man inzwischen diesen CMake-Schachsinn mitmachen, weil dabei irgendwelche Header generiert werden, die man ja leider nicht einfach beilegen kann, weil sie eine VERSIONSNUMMER enthalten! Boah. Ich könnte mich schon wieder aufregen. Das war mal ne praktische Lib, die alle notwendigen Sachen schön lokal bei sich gehalten hat und problemfrei baute. Inzwischen ist es ein Monster, das sich nach irgendwelchen Linux-Guidelines Für Header Am Sonntag Nach Mitternacht Bei Vollmond über 20 Verzeichnisse verteilt und darob dann natürlich 40 zusätzliche Verzeichnisreferenzen zum Bauen braucht.
(Ja, ich weiß, dass das unfair ist, weil sowas nunmal rauskommt, wenn man es allen Leuten und ihren jeweiligen Distributionsvorstellungen recht machen will. Kotzt mich trotzdem an, weil genau bei diesem Rechtmachen der statistische Standardfall Visual Studio irgendwie hinten runtergefallen ist.)
Leider muss man inzwischen diesen CMake-Schachsinn mitmachen, weil dabei irgendwelche Header generiert werden, die man ja leider nicht einfach beilegen kann, weil sie eine VERSIONSNUMMER enthalten! Boah. Ich könnte mich schon wieder aufregen. Das war mal ne praktische Lib, die alle notwendigen Sachen schön lokal bei sich gehalten hat und problemfrei baute. Inzwischen ist es ein Monster, das sich nach irgendwelchen Linux-Guidelines Für Header Am Sonntag Nach Mitternacht Bei Vollmond über 20 Verzeichnisse verteilt und darob dann natürlich 40 zusätzliche Verzeichnisreferenzen zum Bauen braucht.
(Ja, ich weiß, dass das unfair ist, weil sowas nunmal rauskommt, wenn man es allen Leuten und ihren jeweiligen Distributionsvorstellungen recht machen will. Kotzt mich trotzdem an, weil genau bei diesem Rechtmachen der statistische Standardfall Visual Studio irgendwie hinten runtergefallen ist.)
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Re: Jammer-Thread
Woah, was ich als Scherz gemeint hab, entpuppt sich als tatsächlich geschehene Gruselgeschichte.Krishty hat geschrieben:Ja, sowas passiert tatsächlich, wenn auch nur lesend statt schreibend:antisteo hat geschrieben:Ist doch logisch: Die aufgerufene Funktion könnte doch anhand ihres Stack-Pointers den Zeiger der darüberliegenden Variablen herausfunden und ihren Inhalt verändern. Vielleicht gibt es ja Software in der Industrie, die das wirklich so macht ;) Deshalb kann Microsoft das Verhalten nicht ändern :PKrishty hat geschrieben:Visual C++ x64 geht auf höchster Optimierungsstufe davon aus, dass sich der Wert einer lokalen Variable ändert, wenn ein Funktionsaufruf OHNE DIE VARIABLE stattfindet. Es wäre niedlich, wenn es nicht so nerven würde.Die richtige Lösung wäre aber in diesem Fall, den Fake Stack volatile zu deklarieren anstatt Optimierungen für alle lokalen Variablen in jedem Windows-Programm der Welt abzuschalten.The Old New Thing — When programs grovel into undocumented structures... hat geschrieben:A certain software company decided that it was too hard to take the coordinates of the NM_DBLCLK notification and hit-test it against the treeview to see what was double-clicked. So instead, they take the address of the NMHDR structure passed to the notification, add 60 to it, and dereference a DWORD at that address. If it's zero, they do one thing, and if it's nonzero they do some other thing.
It so happens that the NMHDR is allocated on the stack, so this program is reaching up into the stack and grabbing the value of some local variable (which happens to be two frames up the stack!) and using it to control their logic.
For Windows 2000, we upgraded the compiler to a version which did a better job of reordering and re-using local variables, and now the program couldn't find the local variable it wanted and stopped working.
I got tagged to investigate and fix this. I had to create a special NMHDR structure that "looked like" the stack the program wanted to see and pass that special "fake stack".
I think this one took me two days to figure out.
Warum stellt Microsoft dem entsprechenden Kunden nicht einfach die 2 Arbeitstage in Rechnung?
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Das sind keine „Kunden“. Keine Firma kommt zu Microsoft und fragt, „Unser Programm läuft nicht unter Windows Vista, könnt ihr da was tun?“. Viel mehr ist Microsoft angeschissen, wenn der Kunde auf Windows Vista aktualisiert und Pinball nicht mehr läuft, denn dann heißt es „Scheiß Vista hat mein Pinball kaputtgemacht“, und nicht „Scheiß Pinball hat sich auf veraltetes FPU-Rounding verlassen“.
Und in den meisten Fällen, die Microsoft-Mitarbeiter bearbeiten, existiert die entsprechende Firma gar nicht mehr oder hat die Lizenzen längst abgetreten.
Darum bauen sie still und leise eine Kompatibilitätsoption ein (das Programm selber dürfen sie ja nicht verändern) und stellen die zwei Tage den Kunden – den Windows-Usern – in Rechnung.
Und in den meisten Fällen, die Microsoft-Mitarbeiter bearbeiten, existiert die entsprechende Firma gar nicht mehr oder hat die Lizenzen längst abgetreten.
Darum bauen sie still und leise eine Kompatibilitätsoption ein (das Programm selber dürfen sie ja nicht verändern) und stellen die zwei Tage den Kunden – den Windows-Usern – in Rechnung.
- Krishty
- Establishment
- Beiträge: 8316
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Jammer-Thread
Mein PC und alle meine virtuellen Maschinen scheitern am DNS-Lookup. ZFX ist die einzige Seite, die noch gefunden wird. Weiß nicht, ob es an meiner Hardware oder meiner Software liegt, und gehe deshalb einfach schlafen.
Falls aber noch andere das Problem haben sollten: Respekt vor Seraph! Der Server-Umzug geht zwar nicht ohne Ausfall, aber so lange bloß das gesamte Internet außer ZFX ausfällt … ;)
Falls aber noch andere das Problem haben sollten: Respekt vor Seraph! Der Server-Umzug geht zwar nicht ohne Ausfall, aber so lange bloß das gesamte Internet außer ZFX ausfällt … ;)
Re: Jammer-Thread
CMake. :evil:
:evil: :evil: :evil:
Es ist unglaublich, wie ein einziges Programm es schafft, dass ich jedesmal kurz vor einem Wutanfall stehe, wenn ich es benutzen muss. Warum ist das ver********* Buildsystem von C++ nur so ver***** ver***, dass jedesmal wenn ich eine neue Lib benutzen will, ein halber Tag dafür draufgehen muss?
Es ist JEDESMAL das selbe. Man lädt irgendetwas runter, und in den allermeisten Fällen liegt eine CMake Datei bei. Manchmal funktioniert die sogar. Aber meistens eben nicht. Dann muss ich erst CMake-Code debuggen, bevor ich überhaupt die Chance hätte, in meinem Code Fehler zu machen, die ich dann debuggen könnte.
Das Problem ist ja nicht einmal, dass die 'Sprache' das mit Abstand schlimmste ist, was ich je irgendwo als formale Sprache gesehen hätte. Das Hauptproblem sind die tausende Benutzer die keine Ahnung haben, was sie da tun. Da hat man eine FindCMake für irgendeine Abhängigkeit, lädt diese runter, kompiliert sie, so wie die Bibliothek es vorsieht und dann kommt das find-Skript nicht mit dem Standard-Ordner-layout klar. Wie ******* muss man eigentlich sein, um soetwas zu programmieren? Oder irgendwelche Deppen, die noch nichtmal so tun als würden sie versuchen es richtig zu machen und einfach sowas schreiben:
(Entschuldigt die Kraftausdrücke, aber statt sowas hätte man auch einfach in eine leere Datei "Fick dich und mach es selber" schreiben können, das hätte beiden Seiten Zeit gespart...)
Wieso kann man nicht einfach mal ein paar vernünftige Standards durchsetzen? Warum muss eine CMake-Datei 830 Zeilen haben? Das ganze wurde doch irgendwann mal eingeführt, um das kompilieren einfacher zu machen, aber stattdessen ist es nur auf eine andere Art kompliziert geworden. Und weil es so **** schwierig ist, auch nur eine einzige Bibliothek zu kompilieren, hat dann jede Bibliothek 37 Schalter um optionale Abhängigkeiten zu modellieren, was dann noch so 3 Stufen weiter geht.
:evil: :evil: :evil:
Es ist unglaublich, wie ein einziges Programm es schafft, dass ich jedesmal kurz vor einem Wutanfall stehe, wenn ich es benutzen muss. Warum ist das ver********* Buildsystem von C++ nur so ver***** ver***, dass jedesmal wenn ich eine neue Lib benutzen will, ein halber Tag dafür draufgehen muss?
Es ist JEDESMAL das selbe. Man lädt irgendetwas runter, und in den allermeisten Fällen liegt eine CMake Datei bei. Manchmal funktioniert die sogar. Aber meistens eben nicht. Dann muss ich erst CMake-Code debuggen, bevor ich überhaupt die Chance hätte, in meinem Code Fehler zu machen, die ich dann debuggen könnte.
Das Problem ist ja nicht einmal, dass die 'Sprache' das mit Abstand schlimmste ist, was ich je irgendwo als formale Sprache gesehen hätte. Das Hauptproblem sind die tausende Benutzer die keine Ahnung haben, was sie da tun. Da hat man eine FindCMake für irgendeine Abhängigkeit, lädt diese runter, kompiliert sie, so wie die Bibliothek es vorsieht und dann kommt das find-Skript nicht mit dem Standard-Ordner-layout klar. Wie ******* muss man eigentlich sein, um soetwas zu programmieren? Oder irgendwelche Deppen, die noch nichtmal so tun als würden sie versuchen es richtig zu machen und einfach sowas schreiben:
Code: Alles auswählen
SET(HAVE_LAPACK 1 CACHE BOOL "Do we have LAPACK/BLAS?")
# the directory where the lapack/blas/f2c libraries reside
SET(LAPACKBLAS_DIR "/usr/lib" CACHE PATH "Path to lapack/blas libraries")
SET(NEED_F2C 1 CACHE BOOL "Do we need either f2c or F77/I77?")
SET(HAVE_PLASMA 0 CACHE BOOL "Do we have PLASMA parallel linear algebra library?")
IF(HAVE_PLASMA)
SET(PLASMA_DIR "/usr/local/PLASMA" CACHE PATH "Path to PLASMA root")
ENDIF(HAVE_PLASMA)
Wieso kann man nicht einfach mal ein paar vernünftige Standards durchsetzen? Warum muss eine CMake-Datei 830 Zeilen haben? Das ganze wurde doch irgendwann mal eingeführt, um das kompilieren einfacher zu machen, aber stattdessen ist es nur auf eine andere Art kompliziert geworden. Und weil es so **** schwierig ist, auch nur eine einzige Bibliothek zu kompilieren, hat dann jede Bibliothek 37 Schalter um optionale Abhängigkeiten zu modellieren, was dann noch so 3 Stufen weiter geht.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
https://jonathank.de/games/