Creé dos programas C
Programa 1
int main() { }
Programa 2
int main() { //Some Harmless comments }
AFAIK, al compilar, el compilador (gcc) debe ignorar los comentarios y los espacios en blanco redundantes y, por lo tanto, la salida debe ser similar.
Pero cuando verifiqué las sumas md5 de los binarios de salida, no coinciden. También intenté compilar con optimización -O3
y -Ofast
todavía no coincidían.
¿Que está sucediendo aquí?
EDITAR: los comandos exactos y md5sums son (t1.c es el programa 1 y t2.c es el programa 2)
gcc ./t1.c -o aaa
gcc ./t2.c -o bbb
98c1a86e593fd0181383662e68bac22f aaa
c10293cbe6031b13dc6244d01b4d2793 bbb
gcc ./t2.c -Ofast -o bbb
gcc ./t1.c -Ofast -o aaa
2f65a6d5bc9bf1351bdd6919a766fa10 aaa
c0bee139c47183ce62e10c3dbc13c614 bbb
gcc ./t1.c -O3 -o aaa
gcc ./t2.c -O3 -o bbb
564a39d982710b0070bb9349bfc0e2cd aaa
ad89b15e73b26e32026fd0f1dc152cd2 bbb
Y sí, md5sums coincide en múltiples compilaciones con las mismas banderas.
Por cierto, mi sistema es gcc (GCC) 5.2.0
yLinux 4.2.0-1-MANJARO #1 SMP PREEMPT x86_64 GNU/Linux
c
gcc
optimization
binary-reproducibility
usuario registrado
fuente
fuente
Respuestas:
Es porque los nombres de los archivos son diferentes (aunque la salida de las cadenas es la misma). Si intenta modificar el archivo en sí (en lugar de tener dos archivos), notará que los binarios de salida ya no son diferentes. Como tanto Jens como yo dijimos, es porque GCC descarga una gran cantidad de metadatos en los binarios que construye, incluido el nombre exacto del archivo fuente (y AFAICS también lo hace clang).
Prueba esto:
Esto explica por qué sus md5sums no cambian entre compilaciones, pero son diferentes entre diferentes archivos. Si lo desea, puede hacer lo que sugirió Jens y comparar la salida de
strings
cada binario; notará que los nombres de archivo están incrustados en el binario. Si desea "arreglar" esto, puedestrip
eliminar los binarios y los metadatos:fuente
La razón más común son los nombres de archivo y las marcas de tiempo agregadas por el compilador (generalmente en la parte de información de depuración de las secciones ELF).
Intenta correr
y es posible que veas la razón. Una vez usé esto para descubrir por qué la misma fuente causaría un código diferente cuando se compilaba en diferentes directorios. El hallazgo fue que la
__FILE__
macro se expandió a un nombre de archivo absoluto , diferente en ambos árboles.fuente
Nota : recuerde que el nombre del archivo de origen va en el binario sin eliminar, por lo que dos programas que provienen de archivos de origen con nombres diferentes tendrán hash diferentes.
En situaciones similares, si lo anterior no se aplica , puede intentar:
strip
contra el binario para eliminar algo de grasa. Si los binarios eliminados son los mismos, entonces algunos metadatos no son esenciales para el funcionamiento del programa.strings
, o voltee ambos programas en hexadecimal y ejecute un diff en los dos volcados hexadecimales. Una vez localizada la (s) diferencia (s), puede intentar ver si hay alguna rima o razón para ellas (PID, marcas de tiempo, marca de tiempo del archivo fuente ...). Por ejemplo, puede tener una rutina que almacene la marca de tiempo en el momento de la compilación para fines de diagnóstico.fuente
gcc (GCC) 5.2.0
yLinux 4.2.0-1-MANJARO #1 SMP PREEMPT x86_64 GNU/Linux