Jammer-Thread

Hier kann über allgemeine Themen diskutiert werden, die sonst in kein Forum passen.
Insbesondere über Szene, Games, Kultur, Weltgeschehen, Persönliches, Recht, Hard- und Software.
Benutzeravatar
Krishty
Establishment
Beiträge: 8244
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: Jammer-Thread

Beitrag von xq »

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.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4856
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Schrompf »

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.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: Jammer-Thread

Beitrag von Spiele Programmierer »

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.
Benutzeravatar
Krishty
Establishment
Beiträge: 8244
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: Jammer-Thread

Beitrag von Spiele Programmierer »

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. ;)
Benutzeravatar
Krishty
Establishment
Beiträge: 8244
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: Jammer-Thread

Beitrag von Spiele Programmierer »

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.
Benutzeravatar
Krishty
Establishment
Beiträge: 8244
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

 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!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8244
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8244
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

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!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8244
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

Kann jemand ein Gemälde von mir im Rennaissance-Stil malen, wie ich nackt mit Visual C++ ringe?

Bild

So etwa?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

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 [...]
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. :|
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Jammer-Thread

Beitrag von kimmi »

Eure Sogen möchte ich haben :). Ich arbeite mit vxWorks von WIndows aus. Visual-Studio zu benutzen wäre ein Traum!

Kimmi
antisteo
Establishment
Beiträge: 854
Registriert: 15.10.2010, 09:26
Wohnort: Dresdem

Re: Jammer-Thread

Beitrag von antisteo »

Krishty 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.
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 :P
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
Benutzeravatar
Krishty
Establishment
Beiträge: 8244
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

antisteo hat geschrieben:
Krishty 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.
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 :P
Ja, sowas passiert tatsächlich, wenn auch nur lesend statt schreibend:
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.
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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Alexander Kornrumpf
Moderator
Beiträge: 2113
Registriert: 25.02.2009, 13:37

Re: Jammer-Thread

Beitrag von Alexander Kornrumpf »

Krishty hat geschrieben:Ja, sowas passiert tatsächlich, wenn auch nur lesend statt schreibend:
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.
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.
Dazu mal zwei Fragen.

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?
Helmut
Establishment
Beiträge: 237
Registriert: 11.07.2002, 15:49
Wohnort: Bonn
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Helmut »

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.
Ich denke es kommt nicht darauf an, wie groß die Firma ist, sondern wie verbreitet die Software ist.
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?
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
Moderator
Beiträge: 2113
Registriert: 25.02.2009, 13:37

Re: Jammer-Thread

Beitrag von Alexander Kornrumpf »

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.
Danke. Hatte ich nicht verstanden. Jetzt ergibt alles einen Sinn.
Benutzeravatar
Krishty
Establishment
Beiträge: 8244
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

Helmut hat geschrieben:
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.
Ich denke es kommt nicht darauf an, wie groß die Firma ist, sondern wie verbreitet die Software ist.
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).

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).
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Alexander Kornrumpf
Moderator
Beiträge: 2113
Registriert: 25.02.2009, 13:37

Re: Jammer-Thread

Beitrag von Alexander Kornrumpf »

Krishty hat geschrieben:Für XP gab es wohl einen Chart mit Programmen, die funktionieren MUSSTEN (und in den Top 10 war Deer Hunter).
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.
Benutzeravatar
Krishty
Establishment
Beiträge: 8244
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

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 :)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Jonathan
Establishment
Beiträge: 2369
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Jonathan »

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.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Krishty
Establishment
Beiträge: 8244
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

Hat die OpenGL-Funktion denn identische Parameter? Normalerweise müsste sich das Problem durch Überladung erledigen …
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Jonathan
Establishment
Beiträge: 2369
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Jonathan »

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/
Benutzeravatar
Schrompf
Moderator
Beiträge: 4856
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Schrompf »

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.)
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
antisteo
Establishment
Beiträge: 854
Registriert: 15.10.2010, 09:26
Wohnort: Dresdem

Re: Jammer-Thread

Beitrag von antisteo »

Krishty hat geschrieben:
antisteo hat geschrieben:
Krishty 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.
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 :P
Ja, sowas passiert tatsächlich, wenn auch nur lesend statt schreibend:
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.
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.
Woah, was ich als Scherz gemeint hab, entpuppt sich als tatsächlich geschehene Gruselgeschichte.

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.
Benutzeravatar
Krishty
Establishment
Beiträge: 8244
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8244
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

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 … ;)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Jonathan
Establishment
Beiträge: 2369
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Jonathan »

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:

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)
(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.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Antworten