![]()
Cuando dependes de un programa antiguo (III): ¿y si el compilador no se entera, y te pone zancadillas?
Como podeis leer en un post anterior sobre cómo hacer funcionar Phrap, me encontré con el caso curioso de que, en una misma máquina de arquitectura IA64, los programas de Phrap compilados con GCC fallaban con Segmentation Fault, mientras que esos mismos programas compilados con el compilador de pago Intel funcionaban. Pues bien, tras estar investigando cómo hacer funcionar Phrap de forma nativa en las arquitecturas de 64 bits (x86-64 e IA64) compilándolo con GCC, me encontré con el meollo del problema: un fallo muy específico al hacer una conversión de tipos en el generador de código ensamblador del GCC.
Los programas más antiguos en C usados en bioinformática están escritos en el dialecto C de Kerningan & Ritchie, que es muy limitado en cuanto a lo que se podía hacer: las funciones devolvían a lo sumo un entero, no soportaba declaración de propotipos de función (con lo cuál no había validación de parámetros), los includes, ni macros (no había preprocesador) … El código fuente de Phrap está escrito así, pero se nota que ha sido retocado ligeramente a posteriori, porque tiene algunos includes.
Por ello, como no había NULLs (son meros defines), en códigos escritos en este dialecto su función es suplida por el 0, y el casting del 0 al tipo de puntero correspondiente. A diferencia de las arquitecturas de 32 bits, en las arquitecturas de 64 bits los punteros de C tienen un tamaño distintos que los enteros. Así que si el programa usa el 0 en lugar del NULL como algún parámetro directo para llamar a una función, y el compilador no sabe que tiene que hacer una conversión implítica de tipos (porque no conoce el prototipo de la función a llamar), entonces se produce el desastre.
Hay dos maneras de solucionar el problema, que implican en ambos casos tener experiencia de programación en C, e introducir cambios en el código problemático. La primera es reemplazar todos los usos implícitos del 0 como representación de NULL en las llamadas a función por (tipo *)0, donde tipo es el tipo que corresponda. La segunda, que es menos invasiva, consiste precisamente en buscar la declaración de la función, y tomándola como base crear el prototipo de la función. En el caso de Phrap, todo se soluciona añadiendo al final del fichero swat.h las líneas:
int get_LLR(
char * diffs,
char * orig_qual1,
char * orig_qual2,
char * adj_qual1,
char * adj_qual2,
int length1,
int start1,
int end1,
int length2,
int start2,
int end2,
int reverse,
Segment * segments1,
Segment * segments2,
int print_flag,
FILE * fp,
int q_start1,
int q_end1,
int q_start2,
int q_end2,
int ignore_ends
);
que corresponden a la declaración de la función problemática.

Hola,
Muchas gracias, voy a probar para ver si lo puedo compilar a 64 bits con esto.
Saludos!
funciono de lujo muchísimas gracias!