Conferencias y publicaciones

Conferencias, charlas y ponencias

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

Nos gusta escribir código, pero, pese a nuestros esfuerzos, cometemos errores. Nuestro programa contendrá errores. A veces, no escribimos lo que queremos escribir, otras veces no entendemos algún aspecto de nuestro lenguaje de programación y en otras ocasiones nos falta o no tenemos en cuenta alguna información crítica sobre el entorno del sistema de nuestro programa. Como resultado, nuestro programa no se comportará correctamente. ¿Qué hacemos ahora? En esta charla, me gustaría llevarle a través de todo el proceso de depuración, comenzando con un programa que se bloquea. ¿Qué hacemos a continuación? ¿Qué preguntas tenemos que plantear? ¿Qué información necesito? ¿Qué puedo hacer para encontrar la causa del bloqueo? ¿Qué herramientas pueden ayudarnos en esta búsqueda y, por último, qué podemos hacer para que este fallo no vuelva a producirse? Gracias a ejemplos reales que hemos encontrado, y depurado en think-cell a lo largo de los años, aprenderá a reproducir, localizar, comprender y solucionar incluso los fallos más difíciles.


Typescripten — Generating type-safe JavaScript bindings for emscripten
Sebastian Theophil

WebAssembly se ha convertido en una plataforma objetivo muy popular entre los desarrolladores de C++. Gracias a emscripten, portar aplicaciones nativas a WebAssembly es fácil, siempre y cuando la aplicación sólo utilice el navegador como dispositivo de visualización y entrada. Sin embargo, emscripten no proporciona envolturas de tipo seguro a las API de JavaScript estándar, como la API de manipulación del DOM, y mucho menos a cualquier otra API de JavaScript proporcionada por las aplicaciones web existentes. Nuestra herramienta de código abierto "typescripten" se ha construido sobre tres potentes tecnologías para cerrar esta brecha. Utiliza los archivos de definición de interfaz de TypeScript y la API del compilador de TypeScript para crear envoltorios C++ de tipo seguro basados en emscripten. TypeScript ya tiene archivos de definición de interfaz para más de 7000 bibliotecas JavaScript que ahora puede utilizar de manera segura desde C++. Nos esforzamos por diseñar nuestros envoltorios C++, como el código C++ utilizándolos de manera similar al código TypeScript o JavaScript equivalente. Sin embargo, la semántica peculiar de Javascript y Typescript, basados en prototipos, suele ser difícil de traducir a un lenguaje basado en tipos como C++. Discutiré los desafíos a los que nos enfrentamos y las decisiones que tomamos al diseñar este marco.


Windows, macOS and the Web: Lessons from cross-platform development at think-cell
Sebastian Theophil

Durante doce años, think-cell había sido una empresa de software exclusiva de Windows y nuestra base de código de aproximadamente 700 000 líneas de código había acumulado muchas dependencias involuntarias de la plataforma. Hace seis años, decidimos portar nuestra aplicación al Mac. Este cambio ha afectado a todas las partes de nuestro proceso de desarrollo: la organización del proyecto, el sistema de compilación y la forma en que programamos en C++ en la actualidad. Las bibliotecas multiplataforma utilizadas habitualmente, como Qt y boost, eran buenas herramientas sobre las que construir, pero por sí solas no bastaban. Para muchos conceptos, como los bloqueos de exclusión mutua (o mutex), los semáforos o la memoria compartida, sólo ofrecen una interfaz común a objetos específicos de la plataforma con una semántica y un tiempo de vida muy diferentes. Queríamos abstracciones C++ ligeras e independientes de la plataforma con una semántica idéntica para el renderizado, la internacionalización, la E/S de archivos, la gestión de eventos del ratón, las llamadas de procedimiento remoto (RPC) y la notificación de errores. Desarrollarlas fue todo un desafío, en primer lugar, porque tuvimos que definir qué semántica necesitaba nuestra aplicación y, en segundo lugar, tuvimos que implementarlas en cada plataforma. No fue un proyecto sencillo, pero diría que ha mejorado mucho la calidad de nuestro código. A estas alturas, ya hemos pasado al siguiente desafío y hemos empezado a trasladar algunas funcionalidades a aplicaciones web. Por supuesto que queríamos reutilizar nuestra base de código existente, pero eso significaba escribir aplicaciones web en C++ “type-safe” o seguro. Sin duda, es una ventaja. Hemos construido nuestras aplicaciones web utilizando emscripten, pero generamos bindings de C++ seguros a partir de cualquier definición de interfaz TypeScript. En mi charla, abordaré de forma resumida las abstracciones de C++ que hemos implementado y se centrará en las áreas problemáticas multiplataforma donde ha resultado complicado definir una semántica compartida debido a las limitaciones de cualquiera de los sistemas operativos. Además, como es natural, les mostrará herramientas que nos permiten escribir una aplicación online en C++.


The C++ rvalue lifetime disaster
Arno Schödl

Las referencias rvalue llevan con nosotros desde C++11. Originalmente se introdujeron para hacer más eficiente el movimiento de objetos: se supone que el objeto al que hace referencia un rvalue estará pronto fuera del alcance y, por tanto, se podrán rebuscar sus recursos sin sufrir daños. La biblioteca estándar de C++, por ejemplo std::cref o std::ranges, hace uso de otro aspecto de las referencias rvalue: dado que salen pronto del alcance, se asume que no es seguro mantenerlas más allá del ámbito de la función actual, mientras que las referencias lvalue se consideran seguras. También nosotros hemos comprobado que esta suposición es muy útil para la gestión inteligente de la memoria, en particular en el código genérico.
Por desgracia, el propio lenguaje C++ viola esta suposición. Los rvalues se unen a const&. Esto significa que las funciones de apariencia inocente convierten silenciosamente los rvalues en referencias lvalue, ocultando cualquier limitación de vida útil de los rvalues. La extensión de la vida útil de un temporal tiene como objetivo hacer que la vinculación de un temporal a una referencia sea segura mediante la extensión del tiempo de vida útil del temporal. Pero esto sólo funciona mientras el temporal sea un prvalue, y ya se rompe con las referencias rvalue, por no hablar de las lvalue generadas espuriamente. Estos problemas no son meramente teóricos. Debido a estos problemas, nos ha costado encontrar corrupción de memoria en nuestro código. En esta charla, describiré los problemas en profundidad, presentará un enfoque centrado únicamente en nuestra biblioteca para mitigar problemas y, por último, hará una propuesta imposible de llegar a la norma sobre cómo hacer las cosas correctamente.


Better C++ Ranges
Arno Schödl

Los rangos llevan tiempo en el estándar C++ y se abren camino en las bases de código modernas. En think-cell llevamos 20 años desarrollando y utilizando nuestra propia biblioteca de rangos, que se basa en la norma y es compatible con ella, pero la supera en muchos aspectos. Los adaptadores de rangos suelen apilarse, un filtro encima de un transformador encima de etc. Para que una pila de este tipo sea eficiente, los iteradores no son suficientes. Utilizamos un nuevo concepto que es más eficiente y al mismo tiempo compatible con los iteradores para que los usuarios de la biblioteca puedan seguir utilizando los iteradores como hasta ahora. La biblioteca estándar es muy estricta en cuanto a la distinción entre contenedores y vistas, y los adaptadores de rangos son vistas que deben mantener una referencia a los datos que se están adaptando. En su lugar, permitimos que los adaptadores de rangos contengan datos por sí mismos para que sean autónomos y se evalúen perezosamente al mismo tiempo. El modelo de iterador estándar sólo permite la iteración externa. Sin embargo, la iteración interna suele ser mucho más fácil de aplicar que la externa. Para muchas aplicaciones, la iteración interna es completamente adecuada y más eficiente que la iteración externa. Por lo tanto, introducimos la iteración interna en la familia de rangos, hasta el punto de que el usuario de la biblioteca puede no saber o no importarle qué tipo de iteración se está utilizando. Los algoritmos estándar devuelven iteraciones y utilizan el iterador final para señalar algún estado de instancia única o singleton. Al personalizar los valores de retorno, podemos hacer que nuestro código sea más escueto y expresivo, por ejemplo eliminando esas temidas comprobaciones de fin de iterador. Estas características combinadas hacen de los rangos una herramienta excelente para dar formato al texto. Podemos usar estos rangos para representar los valores que se van a formatear, convirtiéndolos conceptualmente en cadenas vagamente evaluadas. Estas se pueden usar como se usan actualmente las cadenas normales: en devoluciones de funciones; como entrada de algoritmo estándar; incrustadas en otras cadenas también vagamente evaluadas; etc., antes de que terminen por expandirse para su visualización. Si elegimos las interfaces adecuadas, podemos optimizar esta expansión en tiempo de compilación, lo que permite tanto una sintaxis agradable como un rendimiento muy cercano al código optimizado manualmente.


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

Los formatos de texto hace mucho tiempo que son uno de los problemas favoritos de los autores de bibliotecas de C++. En esta charla, quiero convencerles de que la combinación de rangos con un toque de metaprogramación es una solución muy elegante al problema de los formatos de texto. Presentamos una forma de rangos con iteración interna, que están generando sus elementos uno a uno en lugar de exponer iteradores externos. Podemos usar estos generadores de rangos para representar los valores que se van a formatear, convirtiéndolos conceptualmente en cadenas vagamente evaluadas. Estas se pueden usar como se usan actualmente las cadenas normales: en devoluciones de funciones; como entrada de algoritmo estándar; incrustadas en otras cadenas también vagamente evaluadas; etc., antes de que terminen por expandirse en un contenedor. Al elegir las interfaces correctas, podemos optimizar esta expansión hasta el punto en que sea únicamente un 15 % más lenta que crear la cadena equivalente usando código para un caso especial optimizado a mano.


Why Iterators Got It All Wrong — and what we should use instead
Arno Schödl

Entienden el funcionamiento de los iteradores, ¿verdad? ¿Cómo los describirían? "Los iteradores se usan para apuntar hacia secuencias de elementos." ¿Les parece acertada la definición? Recientemente, el concepto de rangos se ha ampliado para representar todo lo que exponga iteradores. En particular, los rangos incluyen adaptadores de rangos para transformar o filtrar vagamente secuencias de elementos y también tienen iteradores.
¿Correcto? Lamentablemente, no. El concepto de iteradores, que se lleva usando desde los inicios de C++, es básicamente imperfecto. En particular, algunos iteradores se deben comportar de diferente manera según deban apuntar a un elemento o a un límite entre elementos. De modo que elementos y límites son realmente dos conceptos distintos. En esta charla, les convenceré de que es un problema real y que tiene implicaciones prácticas, haré una propuesta sobre cómo arreglarlo y mostraré que esta solución no solo arregla el problema, sino que conduce a un código más claro y evita errores.


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

Los pares de iteradores son ubicuos en la biblioteca de C++. Es un hecho generalmente aceptado que la combinación de dicho par en una entidad única, normalmente denominada rango, genera un código más conciso y legible. Sin embargo, la definición de la semántica precisa de dicho concepto de rango ha demostrado ser inesperadamente compleja. Las consideraciones teóricas entran en conflicto con las prácticas. Algunos objetivos de diseño son mutuamente incompatibles.


A Practical Approach to Error Handling
Arno Schödl

En todos los programas se pueden producir errores, algunos de los cuales tienen su origen en errores internos del programa y otros del entorno en el que se ejecuta el programa. El hecho de ignorar todos los errores hace que el programa no sea fiable, pero el tratamiento de cada uno de ellos introduce una gran complejidad con escasas ventajas. En think-cell, hemos estado utilizando y perfeccionando nuestro propio enfoque, totalmente innovador, hacia la gestión de errores. Esta charla describe nuestro método de forma que, en su próximo proyecto, usted también pueda escribir software más fiable con menos esfuerzo.


Episodio semanal de C++: Entrevista en CppCast
Arno Schödl

En el episodio de CppCast de Rob Irving y Jason Turner del 24 de enero de 2018 se entrevistó a Arno sobre la biblioteca de rangos de think-cell y el desarrollo de C++ en think-cell en general.


Developing a simple PowerPoint Add-in, how hard can it be?
Valentin Ziegler

El desarrollo ofimático está muy asociado a las aburridas macros VBA o al poco elegante y socorrido JavaScript. Muchos desarrolladores con los que Valentin ha hablado se sorprendieron al saber que la base de código de think-cell tiene un millón de líneas de código C++, y que tuvimos que crear algunas bibliotecas genéricas por el camino para que fuera tan corta. Nos esforzamos por implementar la interfaz de usuario más sencilla sobre PowerPoint que permita a los usuarios crear diapositivas con un aspecto magnífico en poco tiempo, y para ello necesitamos utilizar herramientas muy potentes. Permítanos mostrarle cómo aplicamos los algoritmos más avanzados para resolver los problemas de disposición y colocación, y qué retos tuvimos que superar para lograr una integración perfecta con la aplicación huésped.


Industrial Strength Software Hacking
Simon McPartlin

El parcheado de software es un potente pero peligroso método para solucionar errores, agregar funciones y mejorar la usabilidad y el rendimiento del software. Esta conferencia se centra en el parcheado de software cuando el código fuente no está disponible, lo que comúnmente se conoce como hacking. Hablamos sobre por qué dicha actividad puede ser necesaria antes de abordar en profundidad el diseño y la implementación de parches robustos. Finalizamos describiendo diferentes herramientas y técnicas que se pueden utilizar para localizar ubicaciones de parcheado adecuadas.


std::cout is out — Why iostreams must go
Sebastian Theophil

Recientemente hemos comenzado a migrar nuestro software a otras plataformas. En este proceso, hemos descubierto el inconveniente que suponen los iostreams y las operaciones de entrada/salida tipo C. En esta charla, ofreceremos un breve resumen de por qué hemos desterrado los iostreams de nuestro código base y con qué los hemos sustituido.


C++ Memory Model
Valentin Ziegler y Fabio Fracassi

El modelo de memoria C++ define cómo interactúan diversos hilos con la memoria y los datos compartidos, lo cual permite a los desarrolladores razonar sobre código concurrente con independencia de la plataforma. La charla explica las ejecuciones multiproceso y las carreras de datos en C++, cómo afecta al código concurrente el compilador y las optimizaciones de hardware, y cómo evitar comportamientos indefinidos usando candados y operaciones atómicas. Seguidamente, se centra en distintas órdenes de memoria para operaciones atómicas, sus garantías y sus implicaciones de rendimiento.


C++ vs. Java
Valentin Ziegler y Fabio Fracassi

Nos encanta C++, lo usamos a diario. En esta charla explicamos por qué C++ es un lenguaje de programación mucho mejor que Java, a pesar de su reputación de lenguaje complicado. ¿Por qué? Porque C++ conoce la semántica de los valores. Porque C++ tiene comportamiento indefinido. Porque C++ no obliga a guardar la basura. Porque con C++ podemos escribir código que es abstracto además de eficiente.


Publicaciones científicas

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

En este documento se presenta un algoritmo eficiente para una nueva variación del problema de etiquetado de la característica de punto. El objetivo es colocar el mayor número de etiquetas de punto de manera que no se crucen entre sí ni con sus puntos. Primero presentamos un algoritmo que utiliza un algoritmo ambicioso con look-ahead limitado. A continuación, presentamos un algoritmo que reagrupa iterativamente etiquetas, llamando al primer algoritmo de cada grupo e identificando, por lo tanto, un orden de etiquetas casi óptimo. El algoritmo presentado se utiliza en un producto comercial para etiquetar gráficos y nuestra evaluación muestra que genera resultados muy superiores a los de otros algoritmos de etiquetado.


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

En este documento se presenta un algoritmo inteligente para etiquetar gráficos de columnas y sus derivados. Para resolver eficientemente el problema, lo dividimos en dos subproblemas. Primero presentamos un algoritmo geométrico para resolver el problema de encontrar un buen etiquetado para las etiquetas de una única columna, dado que algunas otras columnas ya se han etiquetado. Presentamos una estrategia para encontrar un buen orden en el que se deben etiquetar las columnas, que utiliza repetidamente el primer algoritmo para look-ahead algo limitado. El algoritmo presentado se utiliza en un producto comercial para etiquetar gráficos y, en la práctica, ha demostrado generar resultados satisfactorios.


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

En este documento presentamos un nuevo algoritmo para síntesis de texturas de imagen y vídeo. En nuestro enfoque, las regiones de parche de una imagen o un vídeo de muestra se transforman y copian al resultado y, a continuación, se “cosen” con uniones óptimas para generar un nuevo resultado (normalmente mayor). A diferencia de otras técnicas, el tamaño del parche no se elige a-priori, sino que se utiliza una técnica de corte de gráficos para determinar la región de parche óptima para cualquier desplazamiento determinado entre la textura inicial y final. A diferencia de la programación dinámica, nuestra técnica de corte de gráficos para la optimización de costura se aplica a cualquier dimensión. Los exploramos en concreto en 2D y 3D para realizar síntesis de textura de vídeo además de la adición a síntesis habitual de la imagen.


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

En este documento presentamos un nuevo enfoque para la generación de animaciones controladas de sprites de vídeo. Los sprites de vídeo son animaciones creadas reorganizando los fotogramas de vídeo grabados de un objeto en movimiento. Con nuestra técnica, el usuario puede especificar animaciones utilizando una función de costes flexible, que se optimiza automáticamente mediante la sustitución repetida de las subsecuencias de sprite de vídeo.


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

Este documento presenta un nuevo tipo de medio, denominado textura de vídeo, que tiene cualidades en intermedias entre las de una fotografía y las de un vídeo. Una textura de vídeo proporciona una secuencia de imágenes que varían infinitamente de forma continua. Aunque los fotogramas individuales de una textura de vídeo se pueden repetir de vez en cuando, nunca se repite exactamente la secuencia de vídeo completa. Las texturas de vídeo se pueden utilizar en lugar de fotografías digitales para introducir una imagen estática cualidades dinámicas y acción explícita.

¿Desea más información?

Si tiene alguna pregunta relativa al trabajo en think-cell, las vacantes que haya en la empresa o los eventos que tengamos previsto organizar, póngase en contacto con nuestra colega Julia Zhachuk.

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

representante de RR. HH. de think-cell.


Compartir