Anti-Jammer-Thread
- Aramis
- Moderator
- Beiträge: 1458
- Registriert: 25.02.2009, 19:50
- Echter Name: Alexander Gessler
- Wohnort: 2016
- Kontaktdaten:
Re: Anti-Jammer-Thread
Es nutzt Assimp :-)
-
- Establishment
- Beiträge: 467
- Registriert: 18.04.2002, 15:31
Re: Anti-Jammer-Thread
Yeah, mein new/delete und new[]/delete[] Ersatz in pre C++ 11 ( siehe http://zfx.info/viewtopic.php?p=34605#p34605 ) nimmt jetzt beliebige Kontruktoren, solange diese nicht mehr als 10 Parameter haben:
Haupteffekt:
Ich kann meinen eigenen MemoryManager, der auf dem Testsytem 30 mal so schnell dynamischen Speicher bereit stellt, wie malloc es tut, mit allen Vorteilen, die new über malloc hat, benutzen, ohne new global überschreiben zu müssen oder auf Klassenherarchien, welche new überschreiben, beschränkt zu sein.
Genialer Nebeneffekt:
Damit lassen sich jetzt sogar Arrays mit Non-Default Konstruktoren konstruieren!
PS:
Dank geht an die programmierende Katze für ihre sehr nützliche Hilfe bei der Lösung des Problems
Code: Alles auswählen
#ifdef __MEMORY_MANAGER
#define DEFINITION_ALLOCATE(...) \
{ \
Ftype* p = reinterpret_cast<Ftype*>(MALLOC(sizeof(Ftype))); \
new(p) Ftype(__VA_ARGS__); \
return p; \
}
#define DEFINITION_ALLOCATE_ARRAY(count, ...) \
{ \
size_t* pRaw = reinterpret_cast<size_t*>(MALLOC(sizeof(Ftype)*count+sizeof(size_t))); \
*pRaw = count; \
Ftype* p = reinterpret_cast<Ftype*>(pRaw+1); \
for(size_t i=0; i<count; ++i) \
new(p+i) Ftype(__VA_ARGS__); \
return p; \
}
template<typename Ftype > Ftype* allocate(void) DEFINITION_ALLOCATE()
template<typename Ftype, typename P1> Ftype* allocate(P1 p1) DEFINITION_ALLOCATE(p1)
template<typename Ftype, typename P1, typename P2> Ftype* allocate(P1 p1, P2 p2) DEFINITION_ALLOCATE(p1, p2)
template<typename Ftype, typename P1, typename P2, typename P3> Ftype* allocate(P1 p1, P2 p2, P3 p3) DEFINITION_ALLOCATE(p1, p2, p3)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4> Ftype* allocate(P1 p1, P2 p2, P3 p3, P4 p4) DEFINITION_ALLOCATE(p1, p2, p3, p4)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5> Ftype* allocate(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) DEFINITION_ALLOCATE(p1, p2, p3, p4, p5)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> Ftype* allocate(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) DEFINITION_ALLOCATE(p1, p2, p3, p4, p5, p6)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7> Ftype* allocate(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) DEFINITION_ALLOCATE(p1, p2, p3, p4, p5, p6, p7)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8> Ftype* allocate(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) DEFINITION_ALLOCATE(p1, p2, p3, p4, p5, p6, p7, p8)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9> Ftype* allocate(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) DEFINITION_ALLOCATE(p1, p2, p3, p4, p5, p6, p7, p8, p9)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10> Ftype* allocate(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) DEFINITION_ALLOCATE(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
template<typename Ftype > Ftype* allocateArray(size_t count) DEFINITION_ALLOCATE_ARRAY(count)
template<typename Ftype, typename P1> Ftype* allocateArray(size_t count, P1 p1) DEFINITION_ALLOCATE_ARRAY(count, p1)
template<typename Ftype, typename P1, typename P2> Ftype* allocateArray(size_t count, P1 p1, P2 p2) DEFINITION_ALLOCATE_ARRAY(count, p1, p2)
template<typename Ftype, typename P1, typename P2, typename P3> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3, P4 p4) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3, p4)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3, p4, p5)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3, p4, p5, p6)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3, p4, p5, p6, p7)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3, p4, p5, p6, p7, p8)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3, p4, p5, p6, p7, p8, p9)
template<typename Ftype, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10> Ftype* allocateArray(size_t count, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) DEFINITION_ALLOCATE_ARRAY(count, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
template<typename Ftype>
void deallocate(const Ftype* p)
{
if(!p)
return;
p->~Ftype();
FREE(const_cast<Ftype*>(p));
}
template<typename Ftype>
void deallocateArray(const Ftype* p)
{
if(!p)
return;
size_t* pRaw = (reinterpret_cast<size_t*>(const_cast<Ftype*>(p))-1);
for(size_t i=*pRaw; i-->0;)
p[i].~Ftype();
FREE(pRaw);
}
#endif
Ich kann meinen eigenen MemoryManager, der auf dem Testsytem 30 mal so schnell dynamischen Speicher bereit stellt, wie malloc es tut, mit allen Vorteilen, die new über malloc hat, benutzen, ohne new global überschreiben zu müssen oder auf Klassenherarchien, welche new überschreiben, beschränkt zu sein.
Genialer Nebeneffekt:
Damit lassen sich jetzt sogar Arrays mit Non-Default Konstruktoren konstruieren!
PS:
Dank geht an die programmierende Katze für ihre sehr nützliche Hilfe bei der Lösung des Problems
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da :)
"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
DirectGL, endlich ist es da :)
"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Anti-Jammer-Thread
Exceptions sind bei dir gänzlich abgeschaltet, oder? Sonst müsstest du die nämlich behandeln. Davon abgesehen solltest du dir darüber im Klaren sein, dass all deine Konstruktorargumente rein semantisch kopiert werden. Tatsächlich kann der Compiler unter bestimmten Voraussetzungen Copy Elision durchführen, mit Sicherheit keine Kopien bekommst du jedoch nur mit const P1 &p1 ....
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Re: Anti-Jammer-Thread
Er könnte auch einen globalen new_handler haben, welcher beispielsweise einfach terminate aufruft.CodingCat hat geschrieben:Exceptions sind bei dir gänzlich abgeschaltet, oder? Sonst müsstest du die nämlich behandeln.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Anti-Jammer-Thread
Nein, hier müsste er die Exception in keinem Fall behandeln (er nutzt den Standard-new-Operator nicht mal, aber selbst wenn). Relevant ist hier, ob Konstruktoren Exceptions werfen können. In diesem Fall müsste der Speicher bei Exception nach Zerstörung aller bereits erfolgreich konstruierten Objekte wieder manuell freigegeben werden.eXile hat geschrieben:Er könnte auch einen globalen new_handler haben, welcher beispielsweise einfach terminate aufruft.CodingCat hat geschrieben:Exceptions sind bei dir gänzlich abgeschaltet, oder? Sonst müsstest du die nämlich behandeln.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Re: Anti-Jammer-Thread
Stimmt, das ist ja Placement-new, und das ist nothrow.CodingCat hat geschrieben:Nein, hier müsste er die Exception in keinem Fall behandeln (er nutzt den Standard-new-Operator nicht mal, aber selbst wenn).
Auch da hast du recht. Man man man; ich hätte einfach obigen Post nicht schreiben sollen. :oops:CodingCat hat geschrieben:Relevant ist hier, ob Konstruktoren Exceptions werfen können. In diesem Fall müsste der Speicher bei Exception nach Zerstörung aller bereits erfolgreich konstruierten Objekte wieder manuell freigegeben werden.
-
- Establishment
- Beiträge: 467
- Registriert: 18.04.2002, 15:31
Re: Anti-Jammer-Thread
Stimmt, da muss ich noch konstante Referenzen draus machen. Danke für den Hinweis. Komplett vergessen.CodingCat hat geschrieben:Exceptions sind bei dir gänzlich abgeschaltet, oder? Sonst müsstest du die nämlich behandeln. Davon abgesehen solltest du dir darüber im Klaren sein, dass all deine Konstruktorargumente rein semantisch kopiert werden. Tatsächlich kann der Compiler unter bestimmten Voraussetzungen Copy Elision durchführen, mit Sicherheit keine Kopien bekommst du jedoch nur mit const P1 &p1 ....
Exceptions sind bei mir in der Tat komplett abgeschaltet, weil die Codebase auch auf Plattformen laufen muss, die keine Exceptions implementiert haben, so dass ich keinerlei Code haben kann, der Exceptions schmeißt oder fängt (es sei denn, in entsprechenden Platform-ifdefs. Dazu kommt natürlich, dass man mit Exceptions an jeder Stelle aufpassen muss, dass auch alles aufgeräumt wird, falls eine Exception fliegt, für den Fall, dass sie wer fängt. Die gesamte Codebase exception-safe zu bekommen, wäre wohl Arbeit für Monate.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da :)
"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
DirectGL, endlich ist es da :)
"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Jammer-Thread
Ich habe gerade festgestellt, dass sich mit Templates und Friends wunderbar eine Handle-Klasse zum Verstecken interner Daten/Zeiger definieren lässt:
Damit lassen sich in handle<InternalType*, OwnerClass> gespeicherte Zeiger auf InternalType nur von OwnerClass aus lesen oder verändern, obendrein können außerhalb von OwnerClass keine neuen (und höchstwahrscheinlich unsinnigen) Handles erzeugt werden.
Code: Alles auswählen
template <class Type, class Owner>
class handle
{
friend Owner;
public:
/// Type of the value stored.
typedef Type value_type;
/// Type of the owner.
typedef Owner owner_type;
protected:
/// Value stored.
value_type value;
/// Constructs a handle from the given value.
explicit handle(const value_type &value)
: value(value) { }
/// Gets the value stored by this handle.
const value_type& get() const { return this->value; }
/// Gets the value stored by this handle.
operator value_type() const { return this->value; }
};
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- Schrompf
- Moderator
- Beiträge: 4858
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas Ziegenhagen
- Wohnort: Dresden
- Kontaktdaten:
Re: Jammer-Thread
Und was ist daran Jammer-Thread-Würdig? :)
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Anti-Jammer-Thread
Mist, verklickt und korrigiert. Selbst die 2 Threads sind schon zu viel in diesem Forum. ;)
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- Artificial Mind
- Establishment
- Beiträge: 802
- Registriert: 17.12.2007, 17:51
- Wohnort: Aachen
Re: Anti-Jammer-Thread
Endlich lückenlose LOD-Übergänge in meinem Dual Contouring :)
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Anti-Jammer-Thread
Der this-Zeiger lässt sich mit der gleichen Syntax __restricten, mit der er sich consten lässt:
Quelle mit weiteren Erläuterungen und Beispielen: http://www.codercorner.com/blog/?p=732
Code: Alles auswählen
class Foo
{
void method(...) __restrict { ... }
};
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Re: Anti-Jammer-Thread
Krishty hat geschrieben:Eine Ergänzung zu __restrict auf Seite 76: Bei Visual C++ hat es keine Auswirkung mehr, weil LTCG Aliasing mittlerweile sehr gut ausschließen kann; selber dekorieren lohnt nicht mehr.
Auf x64 im Release kompilieren oder nie geschehen.Krishty hat geschrieben:Der Grund, dass ich nie einen Unterschied sehe, ist also x64.
- Krishty
- Establishment
- Beiträge: 8245
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Anti-Jammer-Thread
Genau; wollte ich gerade sagen. Selbst ich setze deshalb __restrict nicht ein.
Anderes Anti-Jammer: Ein freundlicher Raubkopierer hat sich die Mühe gegeben, die aus dem Rohschnitt stammenden entfernten Szenen wieder mit der Endfassung von Starship Troopers zu vereinigen. Das Resultat hat mehr Sex, Gewalt, Neoliberalismus, Militarismus, und ein minimal anderes Ende. Das macht zwar keinen anderen Film draus, hätte aber ruhig von Anfang an so sein können.
Anderes Anti-Jammer: Ein freundlicher Raubkopierer hat sich die Mühe gegeben, die aus dem Rohschnitt stammenden entfernten Szenen wieder mit der Endfassung von Starship Troopers zu vereinigen. Das Resultat hat mehr Sex, Gewalt, Neoliberalismus, Militarismus, und ein minimal anderes Ende. Das macht zwar keinen anderen Film draus, hätte aber ruhig von Anfang an so sein können.
- Artificial Mind
- Establishment
- Beiträge: 802
- Registriert: 17.12.2007, 17:51
- Wohnort: Aachen
- Schrompf
- Moderator
- Beiträge: 4858
- Registriert: 25.02.2009, 23:44
- Benutzertext: Lernt nur selten dazu
- Echter Name: Thomas Ziegenhagen
- Wohnort: Dresden
- Kontaktdaten:
Re: Anti-Jammer-Thread
Schick! Schon in Voxeln mit Fluss-Simulation, oder erstmal nur ne Ebene mit Physikwirkung? In beiden Fällen aber gute Arbeit!
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
- Chromanoid
- Moderator
- Beiträge: 4259
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: Anti-Jammer-Thread
Wollt ihr endlich Edit and Continue unter x64 in Visual Studio? Dann stimmt ab!
Der entsprechende Eintrag ist:
![Bild](/app.php/senky/httpproxy/5a76c0f4b8590f5b585731b3db5ab1396e46feec/687474703a2f2f692e696d6775722e636f6d2f665868787a2e6a7067?sid=36aad2b3e678abc6ea60d8f1965cfe98)
Die gegenwärtige Situation von Edit and Continue bildlich zusammengefasst. Wenn ihr nichts daran ändert habt ihr hieran persönlich Schuld.
Der entsprechende Eintrag ist:
Abstimmen Kinners! Abstimmen!EnC Survey hat geschrieben:64-bit Native EnC: (Currently Native EnC is only supported on x86-32 bit platform, this choice is about extending support for Native EnC to x64)
Die gegenwärtige Situation von Edit and Continue bildlich zusammengefasst. Wenn ihr nichts daran ändert habt ihr hieran persönlich Schuld.
- Krishty
- Establishment
- Beiträge: 8245
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Anti-Jammer-Thread
Wie viele Stunden verbringen Sie durchschnittlich mit Visual C++ 2012 pro Woche?
– 80 oder so.
Wie viele Stunden haben Sie Visual C++ 2012 seit der Freigabe im August benutzt?
– 601 oder mehr.
Auf dem Papier hört sich mein Leben echt jämmerlich an … aber dann lese ich sowas:
14. Briefly describe your current experience using Native EnC.
– I attend a VS2010, x86-compatible code base for the sole purpose of downgrading my VS2012 x64 code to it whenever I need to use EnC.
Einige Features sind auch einfach lächerlich. Wie wichtig ist mir, dass ich meinen Quelltext in EnC kommentieren kann? Seid ihr völlig bescheuert?! Wenn sich die Semantik nicht ändert, hat das intrinsisch zu funktionieren. Wie kaputt muss eine Implementierung sein, dass das nicht geht?!
Aber trotzdem ganz nett die Abstimmung. Mal sehen, was draus wird. Von der letzten Abstimmung über den Optimizer habe ich nie mehr wieder was gehört.
– 80 oder so.
Wie viele Stunden haben Sie Visual C++ 2012 seit der Freigabe im August benutzt?
– 601 oder mehr.
Auf dem Papier hört sich mein Leben echt jämmerlich an … aber dann lese ich sowas:
Echt lustige Sachen in dem Survey. Die meisten Fragen suggerieren, dass sie längst wissen, was wir wollen (z.B. IntelliSense während des Debuggens); aber uns nochmal extra durch die Ringe hüpfen lassen, damit sie harte Zahlen dafür vorlegen können.Currently you cannot debug files with more than 64K lines. We cannot set breakpoints on line numbers greater than that.
14. Briefly describe your current experience using Native EnC.
– I attend a VS2010, x86-compatible code base for the sole purpose of downgrading my VS2012 x64 code to it whenever I need to use EnC.
Einige Features sind auch einfach lächerlich. Wie wichtig ist mir, dass ich meinen Quelltext in EnC kommentieren kann? Seid ihr völlig bescheuert?! Wenn sich die Semantik nicht ändert, hat das intrinsisch zu funktionieren. Wie kaputt muss eine Implementierung sein, dass das nicht geht?!
Aber trotzdem ganz nett die Abstimmung. Mal sehen, was draus wird. Von der letzten Abstimmung über den Optimizer habe ich nie mehr wieder was gehört.
- Krishty
- Establishment
- Beiträge: 8245
- Registriert: 26.02.2009, 11:18
- Benutzertext: state is the enemy
- Kontaktdaten:
Re: Anti-Jammer-Thread
Ich habe mein assert()-Makro gerade so modifiziert, dass ein Klick auf Wiederholen tatsächlich in die Zeile mit der Assertion springt statt in die Funktion. Wie viel Lebenszeit mir das spart
Re: Anti-Jammer-Thread
Krishty hat geschrieben:Auf dem Papier hört sich mein Leben echt jämmerlich an … aber dann lese ich sowas:Currently you cannot debug files with more than 64K lines. We cannot set breakpoints on line numbers greater than that.
Genau das habe ich mir auch gedacht, als ich das gelesen habe. Ich sehe es schon kommen: In Visual Studio 2014 gibt es Edit and Continue, dann steht da so ein fettes Sternchen daneben und da drunter steht etwas in der Art wie: Sie dürfen nur Kommentare und Leerzeichen einfügen. Viel Spaß!Krishty hat geschrieben:Einige Features sind auch einfach lächerlich. Wie wichtig ist mir, dass ich meinen Quelltext in EnC kommentieren kann? Seid ihr völlig bescheuert?! Wenn sich die Semantik nicht ändert, hat das intrinsisch zu funktionieren. Wie kaputt muss eine Implementierung sein, dass das nicht geht?!
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Anti-Jammer-Thread
Es ist faszinierend wie manche Konventionen zu einer großartigen Konsistenz führen. So zum Beispiel das Iterator-Range-Konzept der STL, durch dessen inklusiven Anfang und exklusives Ende in nahezu allen weiteren Rechnungen die Addition/Subtraktion zusätzlicher Einsen entfällt, womit sich Fencepost Errors enorm einfach vermeiden lassen. Das ist für die meisten vermutlich ganz natürlich.
Überrascht hat mich heute, dass etwas Ähnliches auch für das Entfernen einzelner Elemente aus Ranges gilt. Iteriert man gewohnheitsmäßig vorwärts über Ranges und sucht dabei nach bestimmten Elementen, welche bei Auffinden entfernt werden, so rutschen mit jeder Entfernung Elemente von hinten nach und der Iterator muss künstlich dazu bewegt werden, im nächsten Schleifendurchlauf noch einmal auf dieselbe Elementposition zu zeigen. Folgt man hingegen der C++-Konvention zu Konstruktions- und umgekehrter Destruktionsreihenfolge, die obendrein bei Nebenwirkungen zu wesentlich konsistenterem Verhalten führt, entfällt auch diese Sonderbehandlung. Iteriert man beim Entfernen rückwärts über die Elemente, so wurden bei Entfernen eines Elements alle nachrutschenden Elemente bereits gefiltert. Ganz egal, ob im aktuellen Schleifendurchlauf ein Element entfernt wurde oder nicht, das nächste zu verarbeitende Element ist immer eine Position weiter vorne.
Überrascht hat mich heute, dass etwas Ähnliches auch für das Entfernen einzelner Elemente aus Ranges gilt. Iteriert man gewohnheitsmäßig vorwärts über Ranges und sucht dabei nach bestimmten Elementen, welche bei Auffinden entfernt werden, so rutschen mit jeder Entfernung Elemente von hinten nach und der Iterator muss künstlich dazu bewegt werden, im nächsten Schleifendurchlauf noch einmal auf dieselbe Elementposition zu zeigen. Folgt man hingegen der C++-Konvention zu Konstruktions- und umgekehrter Destruktionsreihenfolge, die obendrein bei Nebenwirkungen zu wesentlich konsistenterem Verhalten führt, entfällt auch diese Sonderbehandlung. Iteriert man beim Entfernen rückwärts über die Elemente, so wurden bei Entfernen eines Elements alle nachrutschenden Elemente bereits gefiltert. Ganz egal, ob im aktuellen Schleifendurchlauf ein Element entfernt wurde oder nicht, das nächste zu verarbeitende Element ist immer eine Position weiter vorne.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Anti-Jammer-Thread
Der Nutzen von Funktionsselektion via Overload Resolution und Tag-Typen an Stelle von Template-Spezialisierungen ist nicht zu unterschätzen, insbesondere weil sich damit das Klammerchaos bisweilen drastisch reduzieren lässt. So konnte ich meinen multi_vector (Erinnerung: Variadisches Template für automatisiertes Structure-of-Arrays-Layout) gerade sowohl in Bezug auf Benutzbarkeit als auch in Bezug auf Compile-Zeit-Fehlerverhalten mit solchen Tag-Typen stark verbessern:
Lasst euch von multi_vector_t nicht irritieren, das ist nur ein hässlicher Hack, der das variadische Template multi_vector<...> notdürftig pre-C++11 umsetzt.
Code: Alles auswählen
// Vorher
entities.get<reflected>()[idx]...
entities.get<transformation>()[idx]...
// Nachher
entities(reflected)[idx]...
entities(transformation)[idx]...
// Wie?
enum registry_tag { registry };
enum reflected_tag { reflected };
enum transformation_tag { transformation };
...
typedef multi_vector_t<>::make<
Registry, registry_tag,
Entity*, reflected_tag,
Transformation, transformation_tag,
...
>::type entities_t;
// In multi_vector
using Base::operator (); // Rekursive Dekomposition mittels private-Vererbungshierarchie
vector_type& operator ()(Tag) { return v; } // Füge Overloads für Tag der aktuellen Hierarchieebene hinzu
const vector_type& operator ()(Tag) const { return v; }
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Re: Anti-Jammer-Thread
Bezieht sich das jetzt nur auf die Lesbarkeit der Fehlermeldung, oder werden dadurch tatsächlich weitere Fehlerfälle erkannt? Ich kann mir nämlich gerade kein Beispiel denken, in dem das mehr Fehlerfälle erkennt als in der Template-Variante.CodingCat hat geschrieben:als auch in Bezug auf Compile-Zeit-Fehlerverhalten
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Anti-Jammer-Thread
Ja, das bezieht sich natürlich auf die Fehlermeldung. In Bezug auf Korrektheit gibt es keine Unterschiede. Der große Unterschied ist, dass Spezialisierungen nicht einfach so über Klassengrenzen hinweg funktionieren, weshalb im Falle von Spezialisierungen unzählige "rekursive" Hilfsaufrufe notwendig werden, was sich im Fehlerfall am Ende in kilometerlangen Template-Instanziierungs-Traces äußert. Damit verbunden wäre im Übrigen auch großes Chaos beim Debuggen, sofern man den Debugger nicht dazu angewiesen bekommt, entsprechende Hilfsaufrufe zu überspringen. Mit Overload Resolution und Namensimport mittels using hat man hingegen überall nur einen einfachen Funktionsaufruf, was die Sache enorm verbessert, bezüglich Debug-Code-Generierung, Debugger-Tauglichkeit und Compiler-Fehlerverhalten. Sogar IntelliSense liefert dann brauchbare Information.eXile hat geschrieben:Bezieht sich das jetzt nur auf die Lesbarkeit der Fehlermeldung, oder werden dadurch tatsächlich weitere Fehlerfälle erkannt? Ich kann mir nämlich gerade kein Beispiel denken, in dem das mehr Fehlerfälle erkennt als in der Template-Variante.CodingCat hat geschrieben:als auch in Bezug auf Compile-Zeit-Fehlerverhalten
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
- Chromanoid
- Moderator
- Beiträge: 4259
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: Anti-Jammer-Thread
https://www.humblebundle.com/ Das Humble THQ Bundle (achtung Saint Row ist nicht in Deutschland verfügbar, also kann man ruhig "weniger" zahlen ;))
- TGGC
- Establishment
- Beiträge: 569
- Registriert: 15.05.2009, 18:14
- Benutzertext: Ich _bin_ es.
- Alter Benutzername: TGGC
- Echter Name: Ich _bin_ es.
- Wohnort: Mainz
- Kontaktdaten:
Re: Anti-Jammer-Thread
Man kann es aktivieren, wenn man sich ueber einen Proxy einloggt. Spielbar ist es danach wohl ganz normal in Dt.
- Chromanoid
- Moderator
- Beiträge: 4259
- Registriert: 16.10.2002, 19:39
- Echter Name: Christian Kulenkampff
- Wohnort: Lüneburg
Re: Anti-Jammer-Thread
ah, daran hatte ich auch schon gedacht. schön dass es funktioniert, werde ich gleich mal ausprobieren.
- CodingCat
- Establishment
- Beiträge: 1857
- Registriert: 02.03.2009, 21:25
- Wohnort: Student @ KIT
- Kontaktdaten:
Re: Anti-Jammer-Thread
Auf die Gefahr hin, dass ich alle schon längst mit überflüssigen C++ Hacks langweile, hier meine neuste Entdeckung: Halbe Move Semantics in C++03, in jenen STL-Containern welche ohne Reallokation auskommen:
vector ohne Vorallokation fällt selbstverständlich nicht in die Kategorie unterstützter Container, worauf die Assertion im Copy Constructor dann zur Laufzeit aufmerksam macht. Wenn ihr richtig reserve()t, ist auch das Speichern in Vektoren möglich.
Wenn möglich, nutzt ihr natürlich einfach std::move(), wie es inzwischen praktisch jeder Compiler unterstützt, der auch nur einen Hauch von C++11 kennt:
Code: Alles auswählen
struct RAIIFoo
{
Resource resource;
// Normaler RAII-Code
RAIIFoo(...)
: resource(...) {}
~RAIIFoo()
{
if (resource != invalid)
free(resource);
}
// Container erfordern Default Construction und Copy Construction
RAIIFoo()
: resource(invalid) {}
RAIIFoo(const RAIIFoo &right)
: resource(invalid)
{
// Stelle sicher, dass keine initialisierten Objekte kopiert und so
// Ressourcen durch mehrere Objekte gleichzeitig verwaltet werden
assert(right.resource == invalid);
}
void swap(RAIIFoo &right)
{
std::swap(resource, right.resource);
}
};
std::list<RAIIFoo> list;
// Konstruiere RAII-Objekt
RAIIFoo foo(...);
// Verschiebe per Swap in Liste
list.push_back(RAIIFoo());
list.back().swap(foo);
Wenn möglich, nutzt ihr natürlich einfach std::move(), wie es inzwischen praktisch jeder Compiler unterstützt, der auch nur einen Hauch von C++11 kennt:
Code: Alles auswählen
struct RAIIFoo
{
Resource resource;
RAIIFoo(...)
: resource(...) {}
RAIIFoo(RAIIFoo &&right)
: resource(right.resource)
{
right.resource = invalid;
}
~RAIIFoo()
{
if (resource != invalid)
free(resource);
}
};
std::list<RAIIFoo> list;
// Konstruiere RAII-Objekt "in" Liste
list.push_back(RAIIFoo(...));
// ... oder konstruiere erste und verschiebe dann
RAIIFoo foo(...);
list.push_back(std::move(foo));
// Achtung: foo genau wie nach swap ab hier ungültig
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite