Anti-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
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Aramis »

Es nutzt Assimp :-)
joggel

Re: Anti-Jammer-Thread

Beitrag von joggel »

gut... das ist dann zumindest ein Sympathiepunkt^^
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: Anti-Jammer-Thread

Beitrag von kaiserludi »

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:

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

Re: Anti-Jammer-Thread

Beitrag von CodingCat »

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
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Anti-Jammer-Thread

Beitrag von eXile »

CodingCat hat geschrieben:Exceptions sind bei dir gänzlich abgeschaltet, oder? Sonst müsstest du die nämlich behandeln.
Er könnte auch einen globalen new_handler haben, welcher beispielsweise einfach terminate aufruft.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von CodingCat »

eXile hat geschrieben:
CodingCat hat geschrieben:Exceptions sind bei dir gänzlich abgeschaltet, oder? Sonst müsstest du die nämlich behandeln.
Er könnte auch einen globalen new_handler haben, welcher beispielsweise einfach terminate aufruft.
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.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Anti-Jammer-Thread

Beitrag von eXile »

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).
Stimmt, das ist ja Placement-new, und das ist nothrow.
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.
Auch da hast du recht. Man man man; ich hätte einfach obigen Post nicht schreiben sollen. :oops:
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: Anti-Jammer-Thread

Beitrag von kaiserludi »

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 ....
Stimmt, da muss ich noch konstante Referenzen draus machen. Danke für den Hinweis. Komplett vergessen.
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]
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Jammer-Thread

Beitrag von CodingCat »

Ich habe gerade festgestellt, dass sich mit Templates und Friends wunderbar eine Handle-Klasse zum Verstecken interner Daten/Zeiger definieren lässt:

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; }
};
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.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
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

Beitrag von Schrompf »

Und was ist daran Jammer-Thread-Würdig? :)
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von CodingCat »

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
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Anti-Jammer-Thread

Beitrag von Artificial Mind »

Endlich lückenlose LOD-Übergänge in meinem Dual Contouring :)
lodscreenie.jpg
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von CodingCat »

Der this-Zeiger lässt sich mit der gleichen Syntax __restricten, mit der er sich consten lässt:

Code: Alles auswählen

class Foo
{
   void method(...) __restrict { ... }
};
Quelle mit weiteren Erläuterungen und Beispielen: http://www.codercorner.com/blog/?p=732
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Anti-Jammer-Thread

Beitrag von eXile »

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.
Krishty hat geschrieben:Der Grund, dass ich nie einen Unterschied sehe, ist also x64.
Auf x64 im Release kompilieren oder nie geschehen.
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Krishty »

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.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Anti-Jammer-Thread

Beitrag von Artificial Mind »

Be water my friends
Be water my friends
Benutzeravatar
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

Beitrag von Schrompf »

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.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4259
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Anti-Jammer-Thread

Beitrag von Chromanoid »

Bild hehe
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Anti-Jammer-Thread

Beitrag von eXile »

Wollt ihr endlich Edit and Continue unter x64 in Visual Studio? Dann stimmt ab!

Der entsprechende Eintrag ist:
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)
Abstimmen Kinners! Abstimmen!

Bild
Die gegenwärtige Situation von Edit and Continue bildlich zusammengefasst. Wenn ihr nichts daran ändert habt ihr hieran persönlich Schuld.
Benutzeravatar
Krishty
Establishment
Beiträge: 8245
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von Krishty »

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:
Currently you cannot debug files with more than 64K lines. We cannot set breakpoints on line numbers greater than that.
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.

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

Re: Anti-Jammer-Thread

Beitrag von Krishty »

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
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Anti-Jammer-Thread

Beitrag von eXile »

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

Re: Anti-Jammer-Thread

Beitrag von CodingCat »

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.
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: Anti-Jammer-Thread

Beitrag von CodingCat »

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:

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; }
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.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: Anti-Jammer-Thread

Beitrag von eXile »

CodingCat hat geschrieben:als auch in Bezug auf Compile-Zeit-Fehlerverhalten
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.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von CodingCat »

eXile hat geschrieben:
CodingCat hat geschrieben:als auch in Bezug auf Compile-Zeit-Fehlerverhalten
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.
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.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4259
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Anti-Jammer-Thread

Beitrag von Chromanoid »

https://www.humblebundle.com/ Das Humble THQ Bundle (achtung Saint Row ist nicht in Deutschland verfügbar, also kann man ruhig "weniger" zahlen ;))
Benutzeravatar
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

Beitrag von TGGC »

Man kann es aktivieren, wenn man sich ueber einen Proxy einloggt. Spielbar ist es danach wohl ganz normal in Dt.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4259
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Anti-Jammer-Thread

Beitrag von Chromanoid »

ah, daran hatte ich auch schon gedacht. schön dass es funktioniert, werde ich gleich mal ausprobieren.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: Anti-Jammer-Thread

Beitrag von CodingCat »

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:

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);
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;

   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
Antworten