Vorträge und Publikationen

Konferenzvorträge und Vortragsreihen

Nobody Can Program Correctly. A Practical and Interactive Guide to Debugging C++ Code
Sebastian Theophil

Wir schreiben gerne Code, aber trotz unserer besten Bemühungen machen wir Fehler. Unser Programm enthält Bugs. Manchmal schreiben wir nicht das, was wir eigentlich schreiben wollen, manchmal verstehen wir einen Aspekt unserer Programmiersprache nicht, und manchmal fehlen uns wichtige Informationen über die Systemumgebung unseres Programms – oder wir berücksichtigen sie nicht. Infolgedessen wird sich unser Programm nicht korrekt verhalten. Was machen wir jetzt? In diesem Vortrag möchte ich Euch durch den gesamten Debugging-Prozess führen, beginnend mit einem Programm, das abstürzt. Was machen wir jetzt? Welche Fragen musst Du stellen? Welche Informationen brauchst Du? Was können wir tun, um die Ursache des Absturzes zu finden? Welche Tools können uns bei dieser Aufgabe helfen und zu guter Letzt, was können wir tun, damit dieser Fehler nicht wieder auftritt? Anhand von Beispielen aus der Praxis, auf die wir im Laufe der Jahre bei think-cell gestoßen sind, lernt Ihr, wie Ihr selbst die schwierigsten Fehler reproduzieren, lokalisieren, verstehen und beheben könnt.


Typescripten — Generating Type-Safe Javascript Bindings for emscripten
Sebastian Theophil

WebAssembly hat sich zu einer sehr beliebten Zielplattform für C++-Entwickler entwickelt. Dank emscripten ist die Portierung nativer Anwendungen auf WebAssembly einfach – solange die Anwendung den Browser nur als Anzeige- und Eingabegerät verwendet. Allerdings bietet emscripten keine typsicheren Wrapper für die Standard-JavaScript-APIs wie die DOM-Manipulations-API, geschweige denn für andere JavaScript-APIs, die von bestehenden Webanwendungen bereitgestellt werden. Unser Open-Source-Tool „typescripten“ wurde auf der Grundlage von drei leistungsstarken Technologien entwickelt, um diese Lücke zu schließen. Es verwendet TypeScript-Schnittstellendefinitionsdateien und die TypeScript-Compiler-API, um typsichere C++-Wrapper auf der Grundlage von emscripten zu erstellen. TypeScript verfügt bereits über Schnittstellendefinitionsdateien für über 7.000 JavaScript-Bibliotheken, die man jetzt sicher von C++ aus verwenden kann. Wir bemühen uns, unsere C++-Wrapper so zu gestalten, dass der C++-Code, der sie verwendet, ähnlich aussieht wie der entsprechende TypeScript- oder JavaScript-Code. Die eigentümliche Semantik von prototypbasiertem Javascript und Typescript ist jedoch oft schwer in eine typbasierte Sprache wie C++ zu übersetzen. Ich werde auf die Herausforderungen eingehen, mit denen wir konfrontiert waren, und auf die Entscheidungen, die wir bei der Gestaltung dieses Frameworks getroffen haben.


„Windows, macOS and the Web: Lessons from Cross-Platform Development at think-cell“
Sebastian Theophil

Zwölf Jahre lang war think-cell ein reines Windows-Softwareunternehmen, und in unserer Codebasis von etwa 700.000 Codezeilen hatten sich viele unbeabsichtigte Plattformabhängigkeiten angesammelt. Vor sechs Jahren haben wir beschlossen, unsere Anwendung auf den Mac zu portieren. Diese Veränderung hat sich auf jeden Teil unseres Entwicklungsprozesses ausgewirkt: die Projektorganisation, das Build-System und die Art und Weise, wie wir heute in C++ programmieren. Die weit verbreiteten plattformübergreifenden Bibliotheken wie Qt und boost waren gute Werkzeuge, auf denen man aufbauen konnte, aber sie reichten allein nicht aus. Für viele Konzepte wie Mutexe, Semaphoren oder Shared Memory bieten sie lediglich eine gemeinsame Schnittstelle zu plattformspezifischen Objekten mit sehr unterschiedlicher Semantik und Lebensdauer. Wir wollten leichtgewichtige, plattformunabhängige C++-Abstraktionen mit identischer Semantik für Rendering, Internationalisierung, Datei-I/O, Mausereignisbehandlung, RPC-Aufrufe und Fehlerberichte. Diese zu entwickeln war eine Herausforderung, weil wir erstens definieren mussten, welche Semantik unsere Anwendung benötigt, und zweitens, weil wir sie auf jeder Plattform implementieren mussten. Das war kein einfaches Unterfangen, aber ich würde behaupten, dass es die Qualität unseres Codes sehr verbessert hat. Inzwischen sind wir zur nächsten Herausforderung übergegangen und haben begonnen, einige Funktionen in Webanwendungen zu übertragen. Wir wollten natürlich unsere vorhandene Codebasis wiederverwenden, und das bedeutete, dass wir Webanwendungen in ausdrucksstarkem, typsicherem C++ schreiben mussten. In unseren Augen definitiv ein Vorteil! Wir haben unsere Webanwendungen mit emscripten erstellt, aber wir generieren typsichere C++-Bindungen aus jeder TypeScript-Schnittstellendefinition. In meinem Vortrag werde ich einen Überblick über die C++-Abstraktionen geben, die wir implementiert haben, wobei ich mich auf die plattformübergreifenden Problembereiche konzentriere, in denen eine gemeinsame Semantik aufgrund der Beschränkungen eines der beiden Betriebssysteme schwer zu definieren war, und natürlich werde ich unsere Tools zeigen, mit denen wir Webanwendungen in C++ schreiben können.


The C++ Rvalue Lifetime Disaster
Arno Schödl

Rvalue-Referenzen gibt es schon seit C++11. Ursprünglich wurden sie eingeführt, um das Verschieben von Objekten effizienter zu machen: Bei dem Objekt, auf das ein rvalue-Referenzwert verweist, wird davon ausgegangen, dass es bald aus dem Anwendungsbereich verschwindet, sodass seine Ressourcen ohne Schaden bereinigt werden können. Die C++-Standardbibliothek, z. B. std::cref oder std::ranges, macht sich einen weiteren Aspekt von rvalue-Referenzen zunutze: Da sie bald den Anwendungsbereich verlassen, wird es als unsicher angesehen, sie über den Anwendungsbereich der aktuellen Funktion hinaus zu behalten, während lvalue-Referenzen als sicher gelten. Auch wir haben festgestellt, dass diese Annahme sehr nützlich für eine intelligente Speicherverwaltung ist, insbesondere bei generischem Code.
Leider verstößt die Sprache C++ selbst gegen diese Annahme. Rvalues binden an const. Das bedeutet, dass unschuldig aussehende Funktionen rvalues stillschweigend in lvalue-Referenzen umwandeln und dabei jegliche Begrenzung der Lebensdauer der rvalues verbergen. Die Verlängerung der Lebensdauer eines Temporärs dient dazu, die Bindung eines Temporärs an eine Referenz sicher zu machen, indem die Lebensdauer des Temporärs verlängert wird. Das funktioniert aber nur, solange das Temporär ein prvalue ist, und das klappt schon bei rvalue-Referenzen nicht, ganz zu schweigen von fälschlicherweise erzeugten lvalue-Referenzen. Diese Probleme sind nicht nur theoretischer Natur. Aufgrund dieser Probleme haben wir in unserem Code schwer zu findende Speicherfehler. In seinem Vortrag beschreibe ich das Problem detailliert und präsentiere unseren rein bibliotheksbasierten Ansatz zur Lösung des Problems und erläutere schließlich einen unorthodoxen Vorschlag dazu, wie die Dinge richtig angegangen werden können.


Better C++ Ranges
Arno Schödl

Bereiche sind nun schon seit einiger Zeit im C++-Standard enthalten und finden ihren Weg in moderne Codebasen. Bei think-cell entwickeln und verwenden wir seit 20 Jahren unsere eigene Bereichsbibliothek, die auf dem Standard aufbaut und mit ihm kompatibel ist, aber in vielen Aspekten über ihn hinausgeht. Bereichsadapter werden oft gestapelt, ein Filter über einem Transformator über einem anderen usw. Um einen solchen Stapel effizient zu machen, reichen Iteratoren nicht aus. Wir verwenden ein neues Konzept, das effizienter und gleichzeitig kompatibel mit Iteratoren ist, sodass Nutzer der Bibliothek die Iteratoren wie bisher verwenden können. Die Standardbibliothek unterscheidet sehr streng zwischen Containern und Views. Range Adaptors wiederum sind Views, die einen Verweis auf die angepassten Daten enthalten müssen. Stattdessen erlauben wir Bereichsadaptern, selbst Daten zu speichern, damit sie in sich geschlossen sind und gleichzeitig langsam ausgewertet werden können. Das Standard-Iteratormodell erlaubt nur externe Iteration. Die interne Iteration ist jedoch oft viel einfacher zu realisieren als die externe Iteration. Für viele Anwendungen ist die interne Iteration völlig ausreichend und effizienter als die externe Iteration. Daher wird die interne Iteration in die Bereichsfamilie aufgenommen, sodass der Nutzer der Bibliothek nicht wissen oder sich nicht darum kümmern muss, welche Art der Iteration verwendet wird. Standardalgorithmen geben Iterationen zurück und verwenden den End-Iterator, um einen Singleton-Status zu signalisieren. Durch die Anpassung von Rückgabewerten können wir unseren Code knapper und aussagekräftiger gestalten und zum Beispiel die gefürchteten Iterator-Endprüfungen eliminieren. Die Kombination dieser Funktionen macht die Sortimente zu einem hervorragenden Werkzeug für die Textformatierung. Wir können diese Bereiche verwenden, um die zu formatierenden Werte zu repräsentieren und diese damit konzeptionell in langsam bewertete Zeichenketten zu konvertieren. Diese können ebenso wie reguläre Zeichenketten verwendet werden: in Rückgabewerten von Funktionen, als Eingabe für den Standardalgorithmus, ebenso langsam bewertete Zeichenketten und so weiter, bevor sie schließlich für die Anzeige erweitert werden. Durch die Wahl der richtigen Schnittstellen können wir diese Erweiterung zur Kompilierzeit optimieren, was sowohl eine schöne Syntax als auch eine Leistung ermöglicht, die dem manuell optimierten Code sehr nahe kommt.


Range-Based Text Formatting – For a Future Range-Based Standard Library
Arno Schödl

Seit langem ist die Textformatierung ein bekanntes Problem für Autoren von C++-Bibliotheken. In diesem Vortrag möchte ich Euch davon überzeugen, dass die Kombination von Bereichen mit ein wenig Metaprogrammierung eine sehr elegante Lösung für das Problem der Textformatierung darstellt. Wir führen eine Form von Bereichen mit interner Iteration ein, die ihre Elemente nacheinander erzeugen, anstatt externe Iteratoren freizugeben. Wir können diese Generatorbereiche verwenden, um die zu formatierenden Werte zu repräsentieren und diese damit konzeptionell in langsam bewertete Zeichenketten zu konvertieren. Diese können ebenso wie reguläre Zeichenketten verwendet werden: in Rückgabewerten von Funktionen, als Eingabe für den Standardalgorithmus, ebenso langsam bewertete Zeichenketten und so weiter, bevor sie schließlich in einen Container erweitert werden. Durch die Wahl der richtigen Schnittstellen können wir diese Erweiterung so weit optimieren, dass sie nur 15 % langsamer ist als die Erstellung der entsprechenden Zeichenkette mit manuell optimiertem Spezialcode.


Why Iterators Got It All Wrong — And What We Should Use Instead
Arno Schödl

Ihr kennt euch dich doch mit Iteratoren aus, oder? Wie würdet Ihr sie beschreiben? "Iteratoren werden verwendet, um auf Abfolgen von Elementen zu zeigen." Klingt gut, oder? Unlängst wurde das Konzept der Bereiche eingeführt, das alles bezeichnet, was Iteratoren aufdeckt. Zu den Bereichen gehören insbesondere Bereichsadapter zur langsamen oder Transformation oder Filterung von Elementen, und auch sie haben Iteratoren.
Alles gut? Leider nicht. Das Iterationskonzept, das wir seit der Einführung von C++ verwenden, ist grundlegend fehlerhaft. Genauer gesagt, müssen sich einige Iteratoren unterschiedlich verhalten, je nachdem, ob sie auf ein Element oder auf eine Grenze zwischen den Elementen zeigen sollen. Elemente und Grenzen sind also zwei verschiedene Konzepte. In diesem Vortrag werde ich Euch davon überzeugen, dass das Problem real ist und praktische Auswirkungen hat. Außerdem werde ich einen Vorschlag machen, wie man es beheben kann, und zeigen, wie die Lösung nicht nur das Problem behebt, sondern auch für klareren Code sorgt und Fehler verhindert.


From Iterators To Ranges — The Upcoming Evolution of the Standard Library
Arno Schödl

Iteratorenpaare sind in der gesamten C++-Bibliothek allgegenwärtig. Es ist allgemein anerkannt, dass die Kombination eines solchen Paars zu einer einzelnen Entität, die üblicherweise als Ranges bezeichnet wird, im Normalfall zu einem präziseren und besser lesbaren Code führt. Die Definition der genauen Semantik eines solchen Bereichskonzepts erweist sich jedoch als überraschend schwierig. Theoretische Überlegungen stehen im Konflikt mit praktischen. Einige Designziele schließen sich sogar gegenseitig aus.


A Practical Approach to Error Handling
Arno Schödl

In jedem Programm können Fehler auftreten. Einige davon sind auf programminterne Bugs zurückzuführen, andere wiederum hängen mit der Umgebung zusammen, in der das Programm ausgeführt wird. Alle Fehler zu ignorieren führt dazu, dass das Programm völlig unzuverlässig ist. Andererseits kann man sich aber auch nicht um jede mögliche Situation kümmern, das wäre zu komplex und hätte nur wenig Vorteile. Bei think-cell haben wir unseren eigenen, einzigartigen prinzipiellen Ansatz zum Umgang mit Fehlern entwickelt. Dieser Vortrag beschreibt unsere Methode, so dass Du in Deinem nächsten Projekt mit weniger Aufwand zuverlässigere Software schreiben kannst.


C++ Wöchentliche Episode – Interview mit CppCast
Arno Schödl

Am 24. Januar 2018 sprach Arno im Rahmen des CppCast mit Rob Irving und Jason Turner über die Bereichsbibliothek von think-cell und über think-cell im Allgemeinen.


Wie schwer kann es sein, ein einfaches PowerPoint Add-in zu entwickeln?
Valentin Ziegler

Office-Entwicklung wird weithin mit langweiligen VBA-Makros oder kompliziertem JavaScript in Verbindung gebracht. Viele Entwickler, mit denen Valentin gesprochen hat, waren überrascht, als sie erfuhren, dass die Codebasis von think-cells aus einer Million Zeilen C++-Code besteht und dass wir auf dem Weg dorthin einige generische Bibliotheken erstellen mussten, um sie so kompakt zu halten. Wir bemühen uns, die einfachste Benutzeroberfläche auf PowerPoint zu implementieren, die es den Benutzern ermöglicht, in kurzer Zeit großartige Folien zu erstellen, und dafür müssen wir sehr leistungsfähige Werkzeuge verwenden. Wir zeigen Dir, wie wir modernste Algorithmen einsetzen, um Layout- und Platzierungsprobleme zu lösen, und welche Herausforderungen wir für eine nahtlose Integration in die Host-Anwendung bewältigen mussten.


Industrial Strength Software Hacking
Simon McPartlin

Software-Patching ist eine leistungsfähige, jedoch auch riskante Methode, Fehler zu beheben, Funktionalität hinzuzufügen und die Benutzerfreundlichkeit einer Software zu verbessern. In diesem Vortrag geht es um das Patching von Software, bei der kein Quellcode zur Verfügung steht, was landläufig als Hacking bezeichnet wird. Wir erläutern, warum und wann so etwas notwendig sein kann, bevor wir uns detailliert dem Design und der Implementierung solider Patches widmen. Am Ende des Workshops beschreiben wir verschiedene Tools und Methoden, die verwendet werden können, um geeignete Stellen für Software-Patching zu bestimmen.


std::cout is Out — Why iostreams Must Go
Sebastian Theophil

Wir haben kürzlich mit der Portierung unserer Software auf andere Plattformen begonnen. Dabei haben wir erkannt, wie umständlich iostreams und C-style I/O sind. Wir möchten gerne in diesem Vortrag einen kurzen Überblick darüber geben, warum wir iostreams aus unserer Code-Basis verbannt und womit wir sie ersetzt haben.


C++ Memory Model
Valentin Ziegler und Fabio Fracassi

Anhand des Speichermodells von C++ wird definiert, wie verschiedene Threads mit Speicher und freigegebenen Daten interagieren, und ermöglicht es so Entwicklern, plattformunabhängig Schlussfolgerungen zu parallelem Code zu ziehen. In diesem Vortrag geht es um Multithreading-Anwendungen und Data Races in C++ sowie um die Fragen, wie paralleler Code von Compiler- und Hardware-Optimierungen beeinflusst wird und wie man undefiniertes Verhalten durch die Verwendung von Schlössern und atomaren Operationen verhindern kann. Dann konzentriert sich der Vortrag auf verschiedene Speicherreihenfolgen für atomare Operationen, ihre Garantien und Leistungsimplikationen.


C++ vs. Java
Valentin Ziegler und Fabio Fracassi

Wir lieben C++ und nutzen es jeden Tag. In diesem Vortrag erklären wir, warum C++ – trotz seiner berüchtigten Komplexität – konzeptuell eine wesentlich bessere Programmiersprache als Java ist. Warum? Weil C++ Wertesemantik kennt. Weil C++ über undefiniertes Verhalten verfügt. Weil C++ keine Speicherbereinigung erzwingt. Weil wir mit C++ Code schreiben können, der sowohl abstrakt als auch effizient ist.


Wissenschaftliche Publikationen

An Efficient Algorithm for Scatter Chart Labeling
Sebastian Theophil und Arno Schödl
Proceedings of AAAI 2006

Diese Arbeit stellt einen effizienten Algorithmus für eine neue Variante des Problems der Beschriftung von Punktmerkmalen vor. Das Ziel besteht darin, die größte Anzahl an Punktbeschriftungen so zu positionieren, dass sie sich weder gegenseitig noch an ihren Punkten schneiden. Zunächst stellen wir einen Algorithmus unter Verwendung eines Greedy-Algorithmus mit beschränkter Vorausschau vor. Dann stellen wir einen Algorithmus vor, der Beschriftungen iterativ neu gruppiert, den ersten Algorithmus für jede Gruppe aufruft und so eine nahezu optimale Reihenfolge der Beschriftung identifiziert. Der vorgestellte Algorithmus wird in kommerziellen Produkten verwendet, um Diagramme zu beschriften, und unsere Bewertung zeigt, dass er Ergebnisse liefert, die anderen Beschriftungsalgorithmen weit überlegen sind.


A Smart Algorithm for Column Chart Labeling
Sebastian Müller und Arno Schödl
Proceedings of SMART GRAPHICS 2005

Diese Arbeit stellt einen intelligenten Algorithmus zur Beschriftung von Säulendiagrammen und deren Derivaten vor. Um dieses Problem effizient zu lösen, unterscheiden wir zwei Teilprobleme. Wir stellen zunächst einen geometrischen Algorithmus vor, um das Problem der Suche nach einer guten Beschriftung für die Beschriftungen einer einzelnen Spalte zu lösen, da einige andere Spalten bereits beschriftet sind. Dann präsentieren wir eine Strategie zur Suche nach einer guten Reihenfolge, in der Spalten beschriftet werden sollten, die wiederholt den ersten Algorithmus mit beschränkter Vorausschau verwendet. Der vorgestellte Algorithmus wird in kommerziellen Produkten zur Beschriftung von Diagrammen verwendet und zeigt in der Praxis zufriedenstellende Ergebnisse.


Graphcut Textures: Image and Video Synthesis Using Graph Cuts
Vivek Kwatra, Arno Schödl, Irfan Essa, Greg Turk und Aaron Bobick
Proceedings of SIGGRAPH 2003

In dieser Arbeit stellen wir einen neuen Algorithmus zur Synthese von Bild- und Videotexturen vor. In unserem Ansatz werden Patch-Bereiche aus einem Beispielbild oder einem Video transformiert und in die Ausgabe kopiert und dann entlang optimaler Nähte zusammengefügt, um eine neue (und typischerweise größere) Ausgabe zu erzeugen. Im Gegensatz zu anderen Techniken wird die Größe des Patches nicht a priori gewählt, sondern es wird eine Graph Cut-Technik verwendet, um den optimalen Patch-Bereich für jeden beliebigen Versatz zwischen Eingangs- und Ausgangstextur zu bestimmen. Im Gegensatz zur dynamischen Programmierung ist unsere Graph Cut-Technik zur Nahtoptimierung in jeder Dimension einsetzbar. Wir untersuchen dies speziell in 2D und 3D, um neben der normalen Bildsynthese auch die Videotextursynthese durchzuführen.


Controlled Animation of Video Sprites
Arno Schödl und Irfan Essa
Proceedings of SCA 2002

In dieser Arbeit präsentieren wir einen neuen Ansatz zur Erzeugung von kontrollierten Animationen von Video-Sprites. Video-Sprites sind Animationen, die durch die Neuanordnung von aufgezeichneten Videobildern eines sich bewegenden Objekts erstellt werden. Mit unserer Technik kann der Anwender Animationen mit einer flexiblen Kostenfunktion spezifizieren, die durch wiederholtes Ersetzen von Video-Sprite-Subsequenzen automatisch optimiert wird.


Video Textures
Arno Schödl, Richard Szeliski, David H. Salesin und Irfan Essa
Proceedings of SIGGRAPH 2000

Diese Arbeit stellt ein neues Medium vor, das als Videotextur bezeichnet wird und dessen Eigenschaften zwischen denen eines Fotos und eines Videos liegen. Eine Videotextur sorgt für einen kontinuierlichen, sich stufenlos verändernden Bildstrom. Während die einzelnen Einzelbilder einer Videotextur von Zeit zu Zeit wiederholt werden können, wird die Videosequenz als Ganzes nie exakt wiederholt. Videotexturen können anstelle von Digitalfotos verwendet werden, um einem statischen Bild dynamische Qualitäten und explizite Aktionen zu verleihen.

Du möchtest mehr erfahren?

Falls Du Fragen zur Arbeit bei think-cell, unseren offenen Stellen oder Events hast, wende Dich einfach an unsere Kollegin Julia Zhachuk.

hr@think-cell.com
+49 30 6664731-81

think-cell HR-Vertreterin.


Teilen