Considere la siguiente pieza de código:
#include <stdio.h> #include <stdlib.h> #include <stdarg.h> int printf(const char *format, ...) { va_list args; return 1; } int main() { printf("Hello there"); return 0; } Y, de hecho, printf no imprime nada. Es decir, el compilador 'prefiere' esta función sobre la declarada en <stdio.h> . Pero C no permite la anulación de funciones y, según tengo entendido, debería arrojar un error de errores en conflicto.
¿Alguien puede explicar este comportamiento?
El estándar C dice ( 7.1.3 Identificadores reservados ):
Entonces, cuando se incluye <stdio.h> , printf se reserva como un identificador con alcance de archivo en el espacio de nombres de los identificadores ordinarios. Además, printf siempre se reserva como un identificador con enlace externo, incluso si <stdio.h> no está incluido.
7.1.4 El uso de funciones de biblioteca no permite definir una función con un nombre reservado.
En la mayoría de las implementaciones, dicha definición reemplazará silenciosamente la función de biblioteca, pero el estándar no garantiza nada.
No se puede compilar por MSVC.
https://godbolt.org/z/Y1o14jj39
La respuesta es que en Linux el enlazador intentará usar su función local primero, y solo entonces buscará la función dentro de las bibliotecas del sistema, y eso no es un error por varias razones históricas.
Y sí, printf se puede definir dentro de varias bibliotecas, la última biblioteca cargada tendrá prioridad. ¡Esta es una característica! Puede anular cualquier llamada al sistema configurando la variable de entorno LD_PRELOAD en la ruta de su propia biblioteca compartida con esa llamada al sistema.