Seite 92 von 255

Re: Jammer-Thread

Verfasst: 03.11.2012, 13:49
von CodingCat
Ich weiß, ich habe hier schon ein unfertiges Proposal liegen. Das Problem: Wenn es ernst wird, wird es richtig schwierig. In diesem Fall fängt das damit an, dass Klassen wie unique_ptr nicht mal Standard Layout garantieren. Außerdem ist die aktuelle Definition von layout-compatible weit weniger frei als mein Beispiel das erfordern würde (erfordert exakt gleiche Struktur, nicht nur transitiv auf den elementaren Typen).

Ich habe hier auch noch ein recht durchdachtes Proposal zum strikten Verbot implizit uninitialisierter Variablen. Leider wird damit sämtlicher C-Code (und der größte Teil des bestehenden C++-Codes) unkompilierbar. Diese ganze Sache mit der Weiterentwicklung bei voller Rückwärtskompatibilität ist wirklich ernüchternd.

Re: Jammer-Thread

Verfasst: 03.11.2012, 13:58
von CodingCat
Ein weiteres Proposal wären übrigens Modifier Templates:

Code: Alles auswählen

template <modifier M>
M Foo* getFoo() M { return this->foo; }
Aber wer würde so etwas überhaupt verstehen, geschweige denn nutzen?

Re: Jammer-Thread

Verfasst: 03.11.2012, 14:50
von CodingCat
Wo wir gerade bei Proposals sind, schiebe ich hier gleich noch ein nützliches Ding hinterher, welches wohl auch in den std-Namespace gehört:

Code: Alles auswählen

template <class T>
class forward_wrapper
{
   const T *p;
   bool is_rval;

public:
   forward_wrapper(T &&v)
      : p(addressof(v)), is_rval(true) { }
   forward_wrapper(const T &v)
      : p(addressof(v)), is_rval(false) { }

   bool rval() const { return is_rval; }
   T&& move() { return std::move( *const_cast<T*>(p) ); }
   const T& copy() const { return *p; }
};
Damit lassen sich Objekte dann endlich ohne Templates und ohne lästige R-Val-Überladung verschieben:

Code: Alles auswählen

// Header
void insertFooSomewhere(forward_wrapper<Foo> foo);

// Module
void insertFooSomewhere(forward_wrapper<Foo> foo)
{
   grow(1);
   if (foo.rval())
      new(myEnd) Foo(foo.move());
   else
      new(myEnd) Foo(foo.copy());
   myEnd++;
}

Re: Jammer-Thread

Verfasst: 03.11.2012, 14:58
von dot
Und das wird von gängigen Compilern auch wirklich entsprechend geinlined, sodass kein Laufzeit if() mehr drin is!?

Was genau wäre denn ein Anwendungsfall für so ein Modifier Teamplate!? (Sollte es nicht eher Qualifier heißen? ;))

Re: Jammer-Thread

Verfasst: 03.11.2012, 17:18
von klickverbot
CodingCat hat geschrieben:Ein weiteres Proposal wären übrigens Modifier Templates:

Code: Alles auswählen

template <modifier M>
M Foo* getFoo() M { return this->foo; }
Aber wer würde so etwas überhaupt verstehen, geschweige denn nutzen?
D hat übrigens ein Konstrukt, das – denke ich – das gleiche Problem ohne Templates löst: das inout-Schlüsselwort (völlig unpassender Name, aber man wollte kein zusätzliches Keyword einführen).

Re: Jammer-Thread

Verfasst: 03.11.2012, 20:08
von CodingCat
dot hat geschrieben:Und das wird von gängigen Compilern auch wirklich entsprechend geinlined, sodass kein Laufzeit if() mehr drin is!?
Interessante Frage. Ich hatte dieses Konstrukt bisher nur für Fälle vorgesehen, in denen man ohnehin nicht auf Inlining aus ist. Aber MSVC12 im Release Mode sagt: Ja für inline-Funktionen und ja für LTCG.
Was genau wäre denn ein Anwendungsfall für so ein Modifier Teamplate!? (Sollte es nicht eher Qualifier heißen? ;))
Richtig, der Standard nennt sie Qualifier. Der Anwendungsfall ist genau der oben gezeigte, Getter mit Besitzsemantik (also transitivem Qualifier). Die verlinkte Lösung in D mit inout wäre natürlich auch eine Option. Insbesondere müsste man das Template noch ergonomisch dazu bringen können, auf jeden Fall Code für bestimmte/alle Fälle zu generieren.

Re: Jammer-Thread

Verfasst: 03.11.2012, 23:06
von Krishty
eXile hat geschrieben:
Krishty hat geschrieben:Hmm; was meinst du mit korrekter Textselektion?
Angenommen wir haben den Quelltext

Code: Alles auswählen

template <typename Type1, typename Type2>
MyClass(
	MyClass<Type1, Type2> const & theOther
) {
	return;
}
Ich klicke doppelt auf Type1 in der dritten Zeile. Selektiert wird s<Typ, also genau eine Selektion, die im zwei Zeichen nach links verrückt ist. Diese Differenz von zwei Zeichen gilt dann auch für alle nachfolgenden Zeilen. Das Problem tritt nur auf:
  1. Wenn extrem Template-lastiger Code in der aktuellen Datei steht,
  2. zuvor Intellisense einige legale Konstrukte für fehlerhaft erkannt hat, und
  3. ich Visual Studio seit drei Tagen nicht geschlossen habe.
Wenn so ein Fall auftritt funktioniert auch ein go to definition nicht mehr in der aktuellen Quelltext-Datei. Bis zum Löschen der sdf-Datei bleibt das auch so bestehen.
Der Fehler ist mir aus 2010 wohlbekannt (er bewirkt ja u.A. auch, dass das Tippen eines Doppelpunkts das Caret wild durch die Zeilen fliegen lässt). Unter 2012 ist er bei mir aber trotz identischem Quelltext bisher nie aufgetreten. Gruselig, dass es ihn immernoch gibt; denn das für ewig um n Buchstaben verschoben hat mir schon damals die Haare zu Berge stehen lassen wie wohl ihre Implementierung aussehen möge.

Re: Jammer-Thread

Verfasst: 04.11.2012, 10:49
von CodingCat
CodingCat hat geschrieben:Ich wünsche mir ein layout_cast, das wie reinterpret_cast funktioniert, aber fehlschlägt, wenn das transitive Datenlayout von Quell- und Zieltyp nicht übereinstimmt [...]
Hier nun meine kontemporäre Billiglösung:

Code: Alles auswählen

/// Asserts layout-compatibility of the given (struct) members.
#define LEAN_LAYOUT_COMPATIBLE(s, m, t, n) static_assert( \
	offsetof(s, m) == offsetof(t, n) && sizeof(reinterpret_cast<s*>(0)->m) == sizeof(reinterpret_cast<t*>(0)->n), \
	#s "::" #m " is not layout-compatible with " #t "::" #n)

/// Asserts size-compatibility of the given (struct) types.
#define LEAN_SIZE_COMPATIBLE(s, t) static_assert( \
	sizeof(s) == sizeof(t), \
	#s " is not size-compatible with " #t)
Benutzung:

Code: Alles auswählen

//Header
struct RenderableMaterialTechnique
{
	beGraphics::Setup *Setup;
	const AbstractRenderableEffectDriver *EffectDriver;
};

// Module
struct RenderableMaterial::Technique
{
	lean::resource_ptr<beGraphics::Setup> Setup;
	lean::resource_ptr<AbstractRenderableEffectDriver> Driver;
};
LEAN_LAYOUT_COMPATIBLE(RenderableMaterialTechnique, Setup, RenderableMaterial::Technique, Setup);
LEAN_LAYOUT_COMPATIBLE(RenderableMaterialTechnique, EffectDriver, RenderableMaterial::Technique, Driver);
LEAN_SIZE_COMPATIBLE(RenderableMaterialTechnique, RenderableMaterial::Technique);
Langsam aber sicher entferne ich mich immer weiter vom guten Pfad des wohldefinierten Standard-C++. (Die exakte Typprüfung muss hier von Hand erfolgen. Bei den anschließenden reinterpret_casts nur zu const casten!)

Re: Jammer-Thread

Verfasst: 04.11.2012, 20:01
von Krishty
Sowohl YouTube als auch Vimeo lassen die Videos bei jedem Abspielen neu puffern. Ich höre mir also am Tag zehnmal denselben Song an und dann ist mein Volumenlimit erreicht.

Am schlimmsten ist, dass ich keinen rationalen Grund dafür finden kann. Mir nützt es nicht weil alles immer ruckelt und stockt und hakt (weil pausierter Kram nicht gepuffert wird) und mein Volumen dauernd ausläuft. Meinem Provider nützt es nicht weil er ständig grundlos Last auf der Leitung hat. Irgendein Pro für YouTube und Vimeo muss es geben, das diese ganzen Unannehmlichkeiten aus deren Sicht aufwiegt. Ich weiß nicht, ob ich das überhaupt wissen will.

Re: Jammer-Thread

Verfasst: 04.11.2012, 20:55
von CodingCat
Ich würde ja gerne ab sofort std::begin und std::end statt der entsprechenden Methoden nutzen, wenn ich dazu nicht <iterator> einbinden müsste, was selbst wieder halb <iostream> einbindet.

Re: Jammer-Thread

Verfasst: 04.11.2012, 20:57
von Biolunar
Wo du grad bei Youtube bist … Manche Videos laggen bei mir sogar bei 360p. Das ist einfach nur zum kotzen. Vormittags ist irgendwie die beste Zeit sich Videos in lagfreien 1080p anzusehen, was aber auch nicht immer funktioniert. Und das Puffern ist mir auch ein Rätsel. Wann läd der Player das Video komplett und wann nur die nächsten 10 Sekunden, wenn das Video pausiert ist? Ich sehe da keinen Zusammenhang. Manchmal so, manchmal so. Das ist besonders nervig, wenn ich grad wieder ein Video habe, was ich nicht lagfrei auf z.B. 480p gucken kann. Dann pausiere ich und erwarte, dass es weiterlädt um es später in einem Guss anzusehen. Leider die Rechnung ohne Youtube gemacht. Wenn sowas wieder eintritt, muss ich mir das Video erst mit einem externen Tool runterladen um es anzuschauen, denn diese 3 Sekunden Film und 5 Sekunden Nachladen sind einfach unzumutbar. *rageface.png*

Re: Jammer-Thread

Verfasst: 04.11.2012, 20:59
von Krishty
Ich verstehe es auch einfach nicht. Vielleicht haben sie versucht, den Datendurchsatz zu drücken indem nur das übermittelt wird, was die Besucher sich tatsächlich ansehen. Aber das dann zehnfach.

————

Ich habe eben alte Gesprächsprotokolle durchsucht und dabei begriffen, dass das einzige, was ich dieses Jahr nennenswertes programmiert habe, das Reduzieren der Kompilierzeit meines Hauptprojekts von 2,4 s (Januar 2012) auf 0,88 s ist.

Re: Jammer-Thread

Verfasst: 05.11.2012, 00:01
von glassbear
Nehmt beide einfach Flashgot.

Und das morgens die beste Zeit fuer 1080p-Videos ist, ist klar: Da sind alle anderen arbeiten. Abends surfen dann alle gleichzeitig auf Youtube.

Re: Jammer-Thread

Verfasst: 05.11.2012, 20:45
von eXile
Wenn ihr Firefox benutzt: Nehmt Scriptish und YousableTubeFix.

Re: Jammer-Thread

Verfasst: 05.11.2012, 22:03
von Krishty
> dxgi.dll!DXGI_SDK_MSG(enum DXGI_Message_Id,...)
  dxgi.dll!CDXGIFactory::CreateSwapChain(struct IUnknown *,struct DXGI_SWAP_CHAIN_DESC *,struct IDXGISwapChain * *)


Kann mir jemand sagen, wo ich diese Nachricht einsehen kann? Der einzige String, den ich aus den Registern pfriemeln konnte, war DXGI Error Message; und in der D3D11-Ausgabe taucht nichts auf.

Irgendwo wird std::_Allocate<unsigned short> aufgerufen; sie packen die Fehlernachricht also in einen STL-String.

Re: Jammer-Thread

Verfasst: 06.11.2012, 12:31
von CodingCat
Die Idee hinter Move Semantics und Perfect Forwarding durch R-Value-References mag genial sein, in C++ sind sie das Grab. Die Wahl zwischen alles doppelt, alles Template und alles by-Value führt immer zu grobem Unfug, egal wie man sich entscheidet. Ersteres und letzteres bietet korrektes Konversions- und Fehlerverhalten, zweiteres und letzteres kommt ohne Dopplung aus, letzteres erfordert auf jeden Fall optimal definierte Typen, insbesondere einen echten Move Constructor. Optimales Anwendungsverhalten erhält man folglich nur durch Dopplung, die optimale Implementierung durch by-Value.

Am nächsten kommt man dem Optimum im Moment mit enable_if:

Code: Alles auswählen

template <class Forward>
typename enable_if<is_equal<Forward, const value_type&>::value || is_equal<Forward, value_type&&>::value, void>::type push_back(Forward &&value)
{
    ...
    ... ( std::forward<Forward>(value) );
    ...
}
Aber wer kommt intuitiv auf sowas? Und wer will das benutzen?

Re: Jammer-Thread

Verfasst: 06.11.2012, 12:57
von CodingCat
Da ich natürlich trotzdem schon wieder darüber nachdenke, das tatsächlich umzusetzen, hier noch die Bibliotheksvariante:

Code: Alles auswählen

template <class Value, class Forward, class Type>
struct enable_move { };
template <class Value, class Type>
struct enable_move<Value, const Value&, Type> : identity<Type> { };
template <class Value, class Type>
struct enable_move<Value, Value&&, Type> : identity<Type> { };
Benutzung:

Code: Alles auswählen

// C++11 1/2
template <class Forward>
typename enable_move<value_type, Forward, void>::type push_back(Forward &&value) { ... }

// C++11
template <class Forward, typename enable_move<value_type, Forward, int>::type = 0>
void push_back(Forward &&value) { ... }


Nachtrag: Blödsinn, implizite Konstruktion passt damit immer noch nicht, weil der Compiler Forward nicht einfach deduzieren kann. Doppelt oder by-Value, es gibt kein Entrinnen.

Re: Jammer-Thread

Verfasst: 06.11.2012, 17:12
von Krishty
Mir fällt nach einem Monat auf, dass mein Visual Studio 2012 ohne <Windows.h> kam. WTF?!

Doch; es ist nur nicht im Standard-#include-Pfad. Danke, Cat.

Re: Jammer-Thread

Verfasst: 07.11.2012, 23:00
von Krishty
Es gibt Dinge, die man sein halbes Leben falsch macht, und es nicht bemerkt.

Bis heute hat mich der MSDN-Text An application should return zero if it handles this message immer dazu verleitet, tatsächlich return 0; zu schreiben. Nachdem ich eine Stunde lang die Ursache gesucht habe, warum ich WM_SIZE nur einmal beim Start und danach niemals wieder erhalte, weiß ich nun: DefWindowProc() muss immer und für jede Nachricht aufgerufen werden – und nicht bloß für die, mit denen man nichts anzufangen weiß, und die man ganz unten unter dem default-Schild vergräbt.

Re: Jammer-Thread

Verfasst: 07.11.2012, 23:11
von CodingCat
Ja, sie hätten schreiben sollen An application should return zero to suppress default message handling.

Im Rahmen meiner no-periodic-runtime-allocation Policy setze ich zwangsläufig massiv auf Pools und Object Reuse. Zustand in Massen, überall extra Reset-Methoden. Das Gegenteil von Sicherheit durch Verkleinerung des Zustandsraums und atomare Objektkonstruktion. Die Realität sieht eben doch anders aus.

Re: Jammer-Thread

Verfasst: 07.11.2012, 23:14
von Krishty
CodingCat hat geschrieben:Ja, sie hätten schreiben sollen An application should return zero to suppress default message handling.
Das Krasse ist, dass ja scheinbar Default Handling stattfindet, denn sonst hätte sich mein Fenster nie vergrößern, verkleinern oder sonstwas lassen – wahrscheinlich nicht einmal erzeugen lassen. Eine Pest, dass man erstmal das halbe Windows-Subsystem verstehen muss um zu begreifen, was ein return bedeutet.

Re: Jammer-Thread

Verfasst: 07.11.2012, 23:19
von CodingCat
Krishty hat geschrieben:Das Krasse ist, dass ja scheinbar Default Handling stattfindet, denn sonst hätte sich mein Fenster nie vergrößern, verkleinern oder sonstwas lassen – wahrscheinlich nicht einmal erzeugen lassen. Eine Pest, dass man erstmal das halbe Windows-Subsystem verstehen muss um zu begreifen, was ein return bedeutet.
WM_SIZE ist ja nur eine Nachricht von vielen. WM_WINDOWPOSCHANGED, WM_SIZING etc. regeln das vermutlich auch ohne WM_SIZE.

Re: Jammer-Thread

Verfasst: 07.11.2012, 23:21
von dot
Krishty hat geschrieben:Nachdem ich eine Stunde lang die Ursache gesucht habe, warum ich WM_SIZE nur einmal beim Start und danach niemals wieder erhalte, weiß ich nun: DefWindowProc() muss immer und für jede Nachricht aufgerufen werden – und nicht bloß für die, mit denen man nichts anzufangen weiß, und die man ganz unten unter dem default-Schild vergräbt.
Woher hast du diese Information, die MSDN sagt da doch eigentlich was Anderes!?

Re: Jammer-Thread

Verfasst: 07.11.2012, 23:36
von Helmut
Krishty hat geschrieben:Bis heute hat mich der MSDN-Text An application should return zero if it handles this message immer dazu verleitet, tatsächlich return 0; zu schreiben. Nachdem ich eine Stunde lang die Ursache gesucht habe, warum ich WM_SIZE nur einmal beim Start und danach niemals wieder erhalte, weiß ich nun: DefWindowProc() muss immer und für jede Nachricht aufgerufen werden – und nicht bloß für die, mit denen man nichts anzufangen weiß, und die man ganz unten unter dem default-Schild vergräbt.
Nein, nein. Das kann nicht sein. DefWindowProc macht für WM_SIZE garnichts. Bei WM_WINDOWPOSCHANGED musst du DefWindowProc aufrufen, um WM_SIZE zu erhalten, das steht aber auch in der Dokumentation.

Re: Jammer-Thread

Verfasst: 08.11.2012, 06:59
von Krishty
Helmut hat geschrieben:Nein, nein. Das kann nicht sein. DefWindowProc macht für WM_SIZE garnichts. Bei WM_WINDOWPOSCHANGED musst du DefWindowProc aufrufen, um WM_SIZE zu erhalten, das steht aber auch in der Dokumentation.
Stimmt. Wie konnte ich als ständig besorgte Seele, die jede MSDN-Seite auswendig lernt bevor sie die entsprechende Nachricht implementiert, das übersehen?!

Also weiterhin return 0;, falls ich mit der Nachricht was anzufangen weiß; außer bei WM_WINDOWPOSCHANGED … danke sehr.

Trotzdem noch eine Frage:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms632652 hat geschrieben:It is more efficient to perform any move or size change processing during the WM_WINDOWPOSCHANGED message without calling DefWindowProc.
Was meinen die? Werden die zwei Nachrichten, die zusätzlich geschickt werden müssen, meine Leistung töten?!

Re: Jammer-Thread

Verfasst: 09.11.2012, 14:08
von joggel
Hier war gerade Werbung von einer russischen Dame.
Ist jetzt leider weg :(

Re: Jammer-Thread

Verfasst: 09.11.2012, 14:30
von Schrompf
Weil ich sie gelöscht habe. Also sowohl die Dame als auch ihren automatisch übersetzten Werbebeitrag.

Re: Jammer-Thread

Verfasst: 09.11.2012, 14:46
von joggel
aber das klang so süß...

Re: Jammer-Thread

Verfasst: 09.11.2012, 17:25
von kaiserludi
Schrompf hat geschrieben:Weil ich sie gelöscht habe. Also sowohl die Dame als auch ihren automatisch übersetzten Werbebeitrag.
Das ist aber nicht sehr Gentlemanlike :D

@Topic:
Wann lernt Apple bitte schön endlich, dass es keine gute Idee ist, in ihrem Devportal Datumsangaben jahresübergreifend alphabetisch nach Monatsnamen zu ordnen?

Re: Jammer-Thread

Verfasst: 10.11.2012, 17:25
von Krishty
Visual Studio 2012 spuckt mir für einen zwei Befehle umfassenden Pixel Shader 500 Bytes Code aus?! Mit Optimierung und ohne Debug-Information (sonst 20 KiB)?! Haben wir schon 2029?

Oh; und: Der Header, den der Compiler ausspuckt, deklariert den Bytecode mit dem Datentyp BYTE. Den habe ich bei mir nicht und bin auch froh drüber. Wäre unsigned char wirklich unmöglich gewesen?! Oder ist das auf Windows-8-Telefonen eine 64-Bit-Zahl?

Außerdem weiß ich von Direct3D9-Shader-Bytecode, dass die Anweisungen als DWORD vorliegen. Der Compiler spuckt aber ein Byte-Array aus, und darum wird IntelliSense 4× langsamer. Hat das etwa mit der Endianness auf ARM nicht gepasst? Sind da nur Idioten und Halbaffen am Werk?

Oh ’tschuldigung. Wir sprechen ja über den HLSL-Compiler. Nevermind.