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
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

Artificial Mind hat geschrieben:
CodingCat hat geschrieben:Fazit: Ich brauche über kurz oder lang auch noch eine eigene Stringklasse. :-/
Es gibt ja nicht schon genug string-Klassen ... (auch wenn ich deinen Punkt verstehe)
Ganz genau, deshalb freue ich mich schon so drauf ... Was solls, ich werde wohl einfach einen unique_ptr wrappen. Veränderliche C-Strings braucht ohnehin kein Mensch.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Krishty
Establishment
Beiträge: 8260
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

CodingCat hat geschrieben:
Krishty hat geschrieben:signed __int64 foo = …;
signed __int64 bar = …;
if(foo > 0 && bar > 0) {
    auto x = foo / bar;
}


VS 2010 begreift bei der Division nicht, dass die Typen unsigned sind. [...]
Hier hätte man sich gewünscht, dass sie den HLSL-Compiler, der ja offensichtlich aus MSVC6 hervorgegangen sein muss, auch wieder so weit zurückportiert hätten, dass die Wertebereiche zu jedem Zeitpunkt vollständig bekannt sind.
Ich bin mir sogar sicher, dass Visual Studio das kann – zum einen für die statische Analyse, die sie ja seit geraumer Zeit pushen; zum anderen ist __assume() dafür da, Wertebereiche zu verklickern, wenn keine passenden ifs in der Nähe sind (z.B., wenn man aus Attributen liest). Ich denke, dass sie schlicht und einfach übersehen / vergessen / auf später verschoben haben, dass sie den Wertebereich für schnellere Multiplikation und Division nutzen können.

Nachtrag: VS 2012 kann es ebenfalls nicht.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
AyJayKay
Beiträge: 88
Registriert: 01.05.2012, 20:13

Re: Jammer-Thread

Beitrag von AyJayKay »

unity-javascript ungleich javascript
class.clone() ist ganz einfach nicht da..... den constructor mit ganz viel "this." zu füllen sieht so falsch aus :D
"Es gibt 10 Arten von Menschen, die die Binär verstehen und die die es nicht tun."
"Hier gibts Code zum Auskommentieren. Wo ist der Praktikant? Hmpf, so müssen sich Lehrer beim Kontrollieren von Arbeiten fühlen..."
antisteo
Establishment
Beiträge: 854
Registriert: 15.10.2010, 09:26
Wohnort: Dresdem

Re: Jammer-Thread

Beitrag von antisteo »

AyJayKay hat geschrieben:den constructor mit ganz viel "this." zu füllen sieht so falsch aus :D
Ist es aber nicht.

Und wo bitteschön ist .clone definiert? Es gibt kein "clone" in Javascript. Es gibt nur Funktionen, die dieses Verhalten haben und bei Object.prototype eingeschleust werden - vielleicht von irgendeiner Erweiterung.
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
AyJayKay
Beiträge: 88
Registriert: 01.05.2012, 20:13

Re: Jammer-Thread

Beitrag von AyJayKay »

hmpf... *such und das mit der Erweiterung bestätigt bekomm*
gut, stimmt, dass es kein standard ist... jetzt sieht es schon gar nicht mehr so falsch aus... danke.
Tja, manchmal ist es gar nicht so schlecht, das Rad neu zu erfinden... for educational use natürlich ;)
"Es gibt 10 Arten von Menschen, die die Binär verstehen und die die es nicht tun."
"Hier gibts Code zum Auskommentieren. Wo ist der Praktikant? Hmpf, so müssen sich Lehrer beim Kontrollieren von Arbeiten fühlen..."
Alexander Kornrumpf
Moderator
Beiträge: 2116
Registriert: 25.02.2009, 13:37

Re: Jammer-Thread

Beitrag von Alexander Kornrumpf »

Krishty führt ein Doppelleben als fefe:

http://blog.fefe.de/?ts=ae3606aa
Psycho
Establishment
Beiträge: 156
Registriert: 16.09.2002, 14:23

Re: Jammer-Thread

Beitrag von Psycho »

Ist wohl die erste Anwendung, die er reverse-engineered.
j.klugmann
Establishment
Beiträge: 201
Registriert: 07.07.2010, 13:00
Kontaktdaten:

Re: Jammer-Thread

Beitrag von j.klugmann »

Alexander Kornrumpf hat geschrieben:Krishty führt ein Doppelleben als fefe:

http://blog.fefe.de/?ts=ae3606aa
Genau das war auch mein Gedanke, als ich das gelesen habe.
Imaging-Software und bald auch Middleware: http://fd-imaging.com
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

Ich glaube kaum, dass Krishty derart unüberlegt drauf los geschrieben hätte. ;) Der ganze Sinn der C++-Klassenbibliotheken ist doch genau, diesen Code für den Anwendungsprogrammierer zu generieren. Insofern ist die Aussage "Nicht mal 1% des Binaries sind die Anwendung." reine Ansichtssache. Wenn die Anwendung von Strings, I/O etc. Gebrauch macht, dann ist diese Funktionalität eben auch Teil der Anwendung. Natürlich ist es möglich und sehr wahrscheinlich, dass die Anwendung auch geschickter hätte programmiert werden können. Genauso ist es richtig, dass STL, Boost & Co. gerne mal mehr Code generieren, als einem lieb ist. Schlussendlich ist es aber gerade ein Vorteil von C++, dass dieser Code direkt in die Anwendung integriert wird/werden kann und so mit Inlining auch wesentlich aggressivere Optimierung erlaubt. Java Code wäre wegen JIT vermutlich wesentlich leichter zu reverse-engineeren, aber wer will schon Java programmieren. ;)

Ich stimme zu, dass die String- und IO-Funktionalität in der STL/Boost gnadenlos overengineered ist, und man hier ggf. einen wesentlich weniger Template-lastigen Ansatz mit weniger Inline-Code hätte wählen sollen - Performancevorteile durch Inlining sind bei deren umständlichen Entwurf ohnehin nicht zu erwarten. Allerdings geht es hier auch wieder um Flexibilität, die weder die C-Runtime noch die Java Runtime bieten - die Frage ist, inwieweit diese Flexibilität bei einem derart undurchschaubaren (unbrauchbaren?) Entwurf überhaupt noch relevant ist.

Schlussendlich ist es klar, dass sich all das immer durch minimale Funktionalität Marke Eigenbau ersetzen ließe - da Reverse Engineering jedoch kein klassischer Anwendungsfall ist, sollte man auch bedenken, dass "Diese ganze Komplexität, die man sich da in seine Programme reinzieht" nicht nur überflüssig ist, und eigene Basteleien bei einem Großteil der Programmierer sehr leicht in wesentlich suboptimalere und fehlerhaftere Lösungen ausarten können. C++ hat hier schlicht eine andere Philosophie als andere Sprachen - wo andere Sprachen auf geteilte zugelinkte Module setzen, setzt C++ auf weitestgehend eigenständigen Code und Duplikation. Dass dabei wesentlich größere Binaries rauskommen, ist kaum verwunderlich.

Fazit: Ich werde high-level C++ nicht gegen Java eintauschen, nur damit fefe meine Anwendungen in Zukunft besser reverse-engineeren kann.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Alexander Kornrumpf
Moderator
Beiträge: 2116
Registriert: 25.02.2009, 13:37

Re: Jammer-Thread

Beitrag von Alexander Kornrumpf »

CodingCat hat geschrieben:Java Code wäre wegen JIT vermutlich wesentlich leichter zu reverse-engineeren, aber wer will schon Java programmieren. ;)
[...]
Ich werde high-level C++ nicht gegen Java eintauschen, nur damit fefe meine Anwendungen in Zukunft besser reverse-engineeren kann.
Ich gehe davon aus, dass sein Kommentar "warum nehmen die nicht gleich Java" sich eher darauf bezog dass Java ebenfalls / noch mehr aufgebläht ist und daher ein in seinen Augen vergleichbares Übel. Daher war der Vorschlag vermutlich nicht ernst gemeint.

Ganz abgesehen davon dass ich zwischen Krishtys struggle Boost, STL und weiß der Himmel was noch loszuwerden und der dort geäußerten Kritik auch nach deinem Kommentar noch Parallelen sehe :)
Benutzeravatar
Krishty
Establishment
Beiträge: 8260
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

Oberflächlich zu bemängeln wäre eine allgemeine Anspruchslosigkeit: es fängt mit der CPU an, die jeden Code frisst. Es geht weiter mit dem Compiler, der bloß ein halbwegs fehlerfreies Kompilat ausspucken soll. Die Programmiersprachen sind überfrachtet und gewuchert, aber Umgewöhnen wäre eben anstrengend. Programmierern ist egal, wie groß der Zustandsraum einer Funktion ist, so lange sie ihren Zweck erfüllt. Dem Management zählt keine Qualität, so lange noch Features reinpassen. Und der Kunde kauft sowieso alles.

Genauer betrachtet ist diese Anspruchslosigkeit aber nicht allgemein, sondern ein Kompromiss – und so ist eben die ganze Welt. Die Programme sind zu fett weil die CPUs zu viel Leistung liefern? Selbst euer Körper mit seiner über zwei Milliarden Jahre perfektionierten, jederzeit optimal angepassten und maximal abgespeckten Bionik wird fett und krank, wenn die Burger von alleine in seinen Mund hüpfen! Dafür ist er glücklich, so lange das Herz noch pocht.

Und so gibt es eben Leute, die mit ihrer produktiven Ignoranz dafür sorgen, dass wir nicht in einer wunderschön-perfekten Steinzeit leben; und andere, die den ganzen Tag in blinder Wut wettern, dass alles falsch und fett und scheiße ist („Leute“ = ich). Unterm Strich ist es dadurch aber weder so Effizient wie es sein könnte, noch so katastrophal, wie es sein müsste.

Wenn ihr es besser könnt, dann macht es besser – ich kann das und tue es auch. Aber falls euer Programm nicht fertig wird, und von niemandem benutzt wird weil ihr bis in alle Ewigkeit Cache-Zugriffsmuster optimiert, ist es wertlos. Ebenso die investierte Zeit; die nötige Hard- und Software; Strom, Gas und Kalorien während der Entwicklung; sogar die Leben der Kinder, die in Bürgerkriegen erschossen wurden von dem Geld, das der Kauf der Elektronik, die ihr benutzt, in die Kassen der Warlords spült. Schade, dass zwei Ausnahmebehandlungsroutinen zu viel in mein Kompilat gekrochen sind.

Leute wie Fefe und ich jammern eben weiter über Komplexität und explodierende Zustandsbäume; und andere wissen nicht, was das ist, und stecken Boost mit MFC zusammen. Imo ist der für alle beste Weg jedoch, sich klar zu werden, welcher Teil des Ganzen man ist, und das, was man tun muss, weiterzumachen, so gut es geht.


P.S.: Java ist scheiße.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Alexander Kornrumpf
Moderator
Beiträge: 2116
Registriert: 25.02.2009, 13:37

Re: Jammer-Thread

Beitrag von Alexander Kornrumpf »

Toller Beitrag!
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4261
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Jammer-Thread

Beitrag von Chromanoid »

Find ich auch!

P.S. :)
coffee%25252Ccup%25252Clove%25252Cspoon-943bafb5697af450cd7cd970f0e48eba_h[1].jpg
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:Die Programmiersprachen sind überfrachtet und gewuchert, aber Umgewöhnen wäre eben anstrengend.
Viel gravierender ist doch, dass es im Moment nichts zu geben scheint, auf das man sich guten Gewissens umgewöhnen könnte, wenn man denn wollte. Denn noch anstrengender als das Umgewöhnen ist das Mitgestalten. Eine ordentliche neue Sprache vergleichbarer Reife und Umfang zu erschaffen, ohne diese mangels Erfahrung gleich selbst wieder an anderen Stellen dem Wucherwachstum zu überlassen oder zu überfrachten, erscheint ein ziemlich aussichtsloses Unterfangen. Und so oft wir hier über das Schneckentempo der Standardisierung schimpfen, alleine dass nach unzähligen Jahren des Leids noch ein Modulsystem den Weg in C++ finden soll, ist eine ganz beachtliche Leistung, betrachtet man die Vielzahl der gestaltenden Interessengruppen und die Handvoll Freiwilliger, die sich der mühsamen Kompromissbildung unter all diesen Gruppen annehmen.
Krishty hat geschrieben:Leute wie Fefe und ich jammern eben weiter über Komplexität und explodierende Zustandsbäume; und andere wissen nicht, was das ist, und stecken Boost mit MFC zusammen.
Hier bezweifle ich etwas, dass Fefe in dieselbe Richtung denkt. So unschön es für das Reverse Engineering sein mag, die vielen Konstruktor- und Destruktoraufrufe sprechen grundsätzlich für ein recht gut strukturiertes und insbesondere zustandsarmes Programm. Komplexität wiederum verhält sich außerhalb von Spielzeuganwendungen ohnehin nicht proportional zum eingebundenen Code - auch komplexe eingebundene Systeme können komplexitätsreduzierend wirken, wenn sie in sich abgeschlossen sind und den entsprechenden Anwendungscode von dieser Komplexität befreien. Insofern verschweigt der Satz "Diese ganze Komplexität, die man sich da in seine Programme reinzieht, überblickt ja schon lange niemand mehr.", dass in zwangsläufig komplexen Anwendungen diese Komplexität alternativ unweigerlich in der Anwendung stecken müsste, wodurch diese kaum überblickbarer werden dürfte. Geringe Komplexität und Zustandsarmut sind wünschenswert, lassen sich in anforderungsbedingt zustandsreichen und komplexen Anwendungen aber nur eingeschränkt erreichen. Selbst großes Können hilft dann nur soweit, die Komplexität der Anwendung auf die Komplexität der Anforderungen herunterzubringen. Entscheidend ist, dass auch der eingebundene Code Komplexität und Zustandsraum nach Möglichkeit minimiert, was zweifelsohne schon bei STL und Boost nicht konsequent gegeben ist, von MFC, Qt und etlichen Java-Libraries ganz zu schweigen.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
antisteo
Establishment
Beiträge: 854
Registriert: 15.10.2010, 09:26
Wohnort: Dresdem

Re: Jammer-Thread

Beitrag von antisteo »

Die Android-API ist so inkonsistent.

Buttons gebe ich direkt Listenern.
Will ich aber ein Event eines Kontextmenüs behandeln, muss ich einen Listener in meine Activity einbauen und mit Eventhandler-Switching und IDs arbeiten, um herauszufinden, wo der User hinklicken wollte.
Warum kann man nicht alles mit Closures bauen, wie es in JavaScript schon seit Ewigkeiten üblich ist?
http://fedoraproject.org/ <-- freies Betriebssystem
http://launix.de <-- kompetente Firma
In allen Posts ist das imo und das afaik inbegriffen.
TDK
Beiträge: 54
Registriert: 06.04.2012, 11:15

Re: Jammer-Thread

Beitrag von TDK »

Ich will... darf aber nicht.

Warum bekomme ich es nicht gebacken, jeweils eine devIL DLL für x86, x64, jeweils als AVX und jeweils kombiniert als Debug-Runtime zu kompilieren? Nur weil diese API auf ein paar andere Bibliotheken aufbaut, die wieder auf Bibliotheken aufbauen. Warum bekomme ich nicht mit dieser Idiotensicheren Anleitung eine *.lib, mit der ich wenigstens arbeiten könnte?

Ich habe heute keinen Bock mehr. Soll die Welt am 21.12.2012 doch verbrennen... dann verbrennt das nicht lauffähige devIL gleich mit. Und Java auch.

Beim nächsten mal drücke ich einfach nur F12, wenn Visual Studio läuft.

Bild
Benutzeravatar
Krishty
Establishment
Beiträge: 8260
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

CodingCat hat geschrieben:So unschön es für das Reverse Engineering sein mag, die vielen Konstruktor- und Destruktoraufrufe sprechen grundsätzlich für ein recht gut strukturiertes und insbesondere zustandsarmes Programm.
Naja; man kann daraus weder auf geringe noch auf hohe Komplexität schließen. Wenn ich 30 verschachtelte Funktionen habe und ganz unten eine Ausnahme losschieße, wird der Compiler mindestens 30 Ausnahme-Handler erzeugen. Ob die Funktionen darüber komplex sind oder nicht ist absolut egal.

Was das Thema angeht vergessen imo übrigens die meisten Leute, dass Computer deterministisch sind. Für ein Programm, das keine externen Bibliotheken aufruft, kann ich genau sagen, was die Ausgabe für eine bestimmte Eingabe ist; und falls ich auf dem Weg dahin auf das Halteproblem stoße, weiß ich, dass ich was falsch gemacht habe. Wirklich zustandsreich wird der Kram erst durch externe Abhängigkeiten wie das Betriebssystem.

Dementsprechend bin ich dazu übergegangen, alles zu laden, und dann möglichst nichts mehr außerhalb meines selbstverfassten Quellextes anzufassen. Ich finde es idiotisch, bei Speicherallokationen auf Fehler gefasst zu sein, weil ich weiß, wie viel virtueller Adressraum dem Prozess zur Verfügung steht und vorrechnen kann, dass auch bei stundenlangem Gedrückthalten der Feuertaste nicht so viele Objekte durch das Programm fliegen können, dass der aufgebraucht ist.

Spätestens seit ich mich auf Festkomma-Integer-Berechnung stütze bin ich dazu übergegangen, den Algorithmus für alle möglichen Klassen von Eingaben zu testen und nirgends auch nur einen Furz auf Fehlerbehandlung zu geben, weil Fehler schlicht nicht auftreten können. (Könnt ihr den Ursprung eurer Szene 10 km wegbewegen, ohne, dass die Spielmechanik kollabiert? Ich kenne meine Grenzen jetzt exakt.)

Aber STL, CRT und Boost behandeln trotzdem jede String-Zuweisung als würde das Überleben der Menschheit an korrektem Stack Unwinding hängen. Das kotzt mich an, weil es zeigt, wie weit wir uns von diesem Idealbild entfernt haben, dass es schon quasi zwecklos ist, es bloß zu versuchen.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8260
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

Gestern hat das CERN UN-Beobachterstatus erhalten, und jetzt drehen sie Zombiefilme.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8260
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

Integerarithmetik und Vektormathematik kombiniert ist furchtbar. Ich muss meinen Vektoren nun sechs Template-Parameter übergeben, weil jede Komponente je nach Berechnung individuell viele Bits erhalten könnte.

Soll die Deklaration meines Kreuzprodukts jetzt so aussehen?!
template <
    unsigned integerBitsLeftX, unsigned fractionBitsLeftX,
    unsigned integerBitsLeftY, unsigned fractionBitsLeftY,
    unsigned integerBitsLeftZ, unsigned fractionBitsLeftZ,
    unsigned integerBitsRightX, unsigned fractionBitsRightX,
    unsigned integerBitsRightY, unsigned fractionBitsRightY,
    unsigned integerBitsRightZ, unsigned fractionBitsRightZ
> auto crossProductOf(
    Vector<
        integerBitsLeftX, fractionBitsLeftX,
        integerBitsLeftY, fractionBitsLeftY,
        integerBitsLeftZ, fractionBitsLeftZ
    > const & a,
    Vector<
        integerBitsRightX, fractionBitsRightX,
        integerBitsRightY, fractionBitsRightY,
        integerBitsRightZ, fractionBitsRightZ
    > const & b
) -> Vector<
    decltype(a.y * b.z - a.z * b.y)::integerBits, decltype(a.y * b.z - a.z * b.y)::fractionBits,
    decltype(a.z * b.x - a.x * b.z)::integerBits, decltype(a.z * b.x - a.x * b.z)::fractionBits,
    decltype(a.x * b.y - a.y * b.x)::integerBits, decltype(a.x * b.y - a.y * b.x)::fractionBits
> const;


(Das ist aufgeräumt; tatsächlich haben meine Zahlen andere (mehr!) Parameter)

Ich habe gerade echt Lust, meine Programmiersprache weiterzumachen; und dort Integerartihmetik zu implementieren, weil der Compiler alles, was ich damit erreichen will, eigentlich von selber können sollte.
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 »

Was spricht dagegen, das zu verpacken?

Code: Alles auswählen

template <unsigned int integerBits, unsigned int fractionBits>
struct ComponentType; // Optional Inhalt ...

template <class X, class Y, class Z> // X, Y, Z vom Typ ComponentType<i,f>, ließe sich per static_assert erzwingen
struct VectorType; // Optional Inhalt ...

template <class LVT, class RVT>
auto crossProductOf(Vector<LVT> const & a, Vector<RVT> const & b)
 -> Vector< VectorType<
       decltype(a.y * b.z - a.z * b.y),
       decltype(a.z * b.x - a.x * b.z),
       decltype(a.x * b.y - a.y * b.x)
    > >;
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Krishty
Establishment
Beiträge: 8260
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

Dass er dann damit durcheinanderkommt, dass ich noch Vector<float> und Vector<double> habe. Die Template-Parameter müssen absolut typsicher sein; fucking Concept-loses C++ …
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:Dass er dann damit durcheinanderkommt, dass ich noch Vector<float> und Vector<double> habe. Die Template-Parameter müssen absolut typsicher sein; fucking Concept-loses C++ …
Wie Vector<float> und Vector<double>? Du kannst doch mit deinen 6 Ints das Template erst recht nicht spezialisieren, geschweige denn überladen? Mit Verpacken ginge das sogar über Spezialisierungen:

Code: Alles auswählen

template <class Type>
struct Vector { ... Float, Double und so };

template <class X, class Y, class Z>
struct Vector< VectorType<X, Y, Z> > { Int ... };
Viel weiter kämst du mit Concepts wohl auch nicht?
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Krishty
Establishment
Beiträge: 8260
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

Wartewarte. Nimm den Prototyp von oben:

Code: Alles auswählen

template <class LVT, class RVT>
auto crossProductOf(Vector<LVT> const & a, Vector<RVT> const & b)
 -> Vector< VectorType<
       decltype(a.y * b.z - a.z * b.y),
       decltype(a.z * b.x - a.x * b.z),
       decltype(a.x * b.y - a.y * b.x)
    > >;
Dieses Template würde nicht nur für die int-Vektoren aufgerufen werden, sondern auch für mein existierendes „normales“ Vektor-Template Vector<float>, wo alle drei Komponenten denselben Typ haben. Dabei würde dann als Ergebnis der komplett falsche Typ Vector<VectorType<float, float, float>> rauskommen statt Vector<float>, und mein float-Kreuzprodukt würde aufhören zu funktionieren.

Die Parameter einer einzelnen Komponente zu Typen zu machen und wegzukapseln ist eine gute Idee; damit wären meine Parameter von 12, 18 oder 24 runter auf höchstens 6. Aber auf 2 reduzieren geht nicht ohne Concepts, die garantieren, dass für Vector<Vector_Type> ein anderes Template genommen wird als für Vector<float> – und so muss ich für Vector<VectorType<X, Y, Z>> spezialisieren, womit ich wieder bei den 6 Parametern wäre, die ich auch ohne VectorType direkt hinschreiben könnte.
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 »

Wartewarte. Wie definierst du gleichzeitig ein Vector<Type>-Template und ein Vector<int, ....>-Template?! Da muss doch mindestens ein Namespace dazwischen sein, und dann sehe ich absolut keinen Weg, wie da irgendetwas durcheinander kommen sollte?! Selbst mit Concepts bezweifle ich, dass derlei Klassen-Template-Overloading jemals funktionieren/erlaubt sein wird.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Krishty
Establishment
Beiträge: 8260
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

Du hast absolut recht; ja! Ich war im ADL-Dschungel verloren … und ich brauche eine App, die ZFX für 24 Stunden sperrt, sobald meine Promille über 1,5 klettern.

P.S.: ZFX’ Uhr geht falsch, oder? (10 Minuten vor)
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 »

Wie sorge ich dafür, dass ein String noch vor der dynamischen Initialisierung in folgendem Objekt landet?!

Code: Alles auswählen

struct ComponentType { const char *const Name; };
const ComponentType FooType = { "foo" }; // Zum Zeitpunkt der dynamischen Initialisierung noch NULL ?!
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Krishty
Establishment
Beiträge: 8260
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Jammer-Thread

Beitrag von Krishty »

Kann ich nicht nachvollziehen. So lange das POD ist, wird die Instanz statisch initialisiert … VS2012 macht das bei mir sogar im Debug-Modus.
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 »

Ich bin in VC10, und haltet euch fest: Es ist das const.

Code: Alles auswählen

struct ComponentType { const char *const Name; }; // non-POD
struct ComponentType { const char * Name; }; // POD
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Jammer-Thread

Beitrag von CodingCat »

Kommt niemals auf die Idee, Typen in größeren Reflection-Systemen "vorläufig" via String zu identifizieren. Ich habe heute den ganzen Tag mühsam jeden String einzeln rauspfriemeln müssen, bis die Typen nun endlich überall verlässlich über statische TypeName::GetComponentType()-Methoden angegeben werden, welche eine eindeutige ComponentType*-Adresse zurückgeben. 91 geänderte Dateien im Commit, das war kein Spaß.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
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:Aber STL, CRT und Boost behandeln trotzdem jede String-Zuweisung als würde das Überleben der Menschheit an korrektem Stack Unwinding hängen. Das kotzt mich an, weil es zeigt, wie weit wir uns von diesem Idealbild entfernt haben, dass es schon quasi zwecklos ist, es bloß zu versuchen.
Das ärgert mich auch schon lange, deshalb folgendes Experiment:

Code: Alles auswählen

_declspec(noinline) const char* test()
{
	try
	{
		int *p = new int;
	}
	catch (...)
	{
		return "except";
	}

	return "noexcept";
}
Resultiert in:

Code: Alles auswählen

_declspec(noinline) const char* test()
{
00AA1270  push        ebp  
00AA1271  mov         ebp,esp  
00AA1273  push        0FFFFFFFFh  
00AA1275  push        0AA2350h  
00AA127A  mov         eax,dword ptr fs:[00000000h]  
00AA1280  push        eax  
00AA1281  push        ecx  
00AA1282  push        ebx  
00AA1283  push        esi  
00AA1284  push        edi  
00AA1285  mov         eax,dword ptr ds:[00AA4018h]  
00AA128A  xor         eax,ebp  
00AA128C  push        eax  
00AA128D  lea         eax,[ebp-0Ch]  
00AA1290  mov         dword ptr fs:[00000000h],eax  
00AA1296  mov         dword ptr [ebp-10h],esp  
	try
	{
		int *p = new int;
00AA1299  push        4  
00AA129B  mov         dword ptr [ebp-4],0  
00AA12A2  call        dword ptr ds:[0AA30C4h]  
00AA12A8  add         esp,4  
	}

	return "noexcept";
00AA12AB  mov         eax,0AA31B4h  
}
00AA12B0  mov         ecx,dword ptr [ebp-0Ch]  
00AA12B3  mov         dword ptr fs:[0],ecx  
00AA12BA  pop         ecx  
00AA12BB  pop         edi  
00AA12BC  pop         esi  
00AA12BD  pop         ebx  
00AA12BE  mov         esp,ebp  
00AA12C0  pop         ebp  
00AA12C1  ret  
	}
	catch (...)
	{
		return "except";
00AA12C2  mov         eax,0AA12C8h  
00AA12C7  ret  
$LN7:
00AA12C8  mov         eax,0AA31ACh  
}
00AA12CD  mov         ecx,dword ptr [ebp-0Ch]  
00AA12D0  mov         dword ptr fs:[0],ecx  
00AA12D7  pop         ecx  
00AA12D8  pop         edi  
00AA12D9  pop         esi  
00AA12DA  pop         ebx  
00AA12DB  mov         esp,ebp  
00AA12DD  pop         ebp  
00AA12DE  ret  
Aber new wirft praktisch nie!

Code: Alles auswählen

// neu
void* operator new(std::size_t size) throw(); // für C++11 Compiler noexcept statt throw()

_declspec(noinline) const char* test()
{
	try
	{
		int *p = new int;
	}
	catch (...)
	{
		return "except";
	}

	return "noexcept";
}
Aufgemerkt:

Code: Alles auswählen

	try
	{
		int *p = new int;
00BF1270  push        4  
00BF1272  call        dword ptr ds:[0BF30C4h]  
00BF1278  add         esp,4  
	}
	catch (...)
	{
		return "except";
	}

	return "noexcept";
00BF127B  mov         eax,0BF31ACh  
Eine entsprechende globale Operator-Deklaration sollte auch die STL beeinflussen (Array-New-Operator nicht vergessen!). In Nichtspielzeuganwendungen sollten diese Operatoren dann natürlich zusätzlich durch eine echt nichtwerfende eigene Implementierung ersetzt werden. (Denn ich bezweifle, dass die hier gezeigte reine Deklaration standardkonform ist. Wäre sie es, so würde auch ein nichtfehlschlagender New-Handler genügen.)

Mit dieser minimalen Modifikation könnte sich ein großer Teil unnötigen Exception Handlings abschalten lassen. Wie sich das auf eine größere Codebasis auswirkt, werde ich testen.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Antworten