Este artículo del blog de Anton Zhiyanov detalla el proceso de portar el paquete strings de Go al lenguaje C. El objetivo no era crear un compilador Go a C, sino permitir el uso de código Go con la flexibilidad y control de C. La portación comenzó con el paquete io y continuó con bytes y strings, que son fundamentales en la mayoría de los programas Go.
El primer desafío fue lidiar con dependencias como math/bits (para manipulación de bits) y unicode/utf8 (para codificación UTF-8). La diferencia en la precedencia de operadores, especialmente en las operaciones de desplazamiento de bits (bit shifts) entre Go y C, requirió el uso de paréntesis para asegurar el comportamiento correcto. Por ejemplo, en Go 1<<2 + 3 se evalúa como (1 << 2) + 3, mientras que en C sin paréntesis sería 1 << (2 + 3).
La portación del paquete bytes implicó la implementación de funciones como Count, Equal, Index y Repeat. La función Equal se implementó utilizando una macro so_bytes_string que reinterpreta un slice de bytes como una cadena sin realizar una copia de memoria, optimizando el rendimiento. La función IndexByte se tradujo a un bucle for en C, simulando el for-range de Go. La función Repeat, que implica la asignación de memoria, introdujo la necesidad de un sistema de gestión de memoria. En lugar de usar un recolector de basura (garbage collector) como el de Go, se optó por implementar allocators, que ofrecen mayor control y flexibilidad en la gestión de memoria, permitiendo el uso de diferentes estrategias de asignación (malloc, arenas, stack allocators).
Los allocators se definen como una estructura con punteros a funciones Alloc, Realloc y Free, proporcionando una interfaz estandarizada para la asignación y liberación de memoria. La implementación del allocator del sistema utiliza calloc para la asignación inicial y free para la liberación, garantizando que la memoria asignada se inicialice a cero. Este enfoque permite una mayor claridad en la gestión de memoria y facilita las pruebas y la depuración. La portación del paquete strings es un paso importante para integrar la funcionalidad de la biblioteca estándar de Go en entornos C, abriendo nuevas posibilidades para el desarrollo de aplicaciones y la interoperabilidad entre lenguajes.
