2011-05-08 22 views
14

Esto debería ser muy trivial. Yo estaba corriendo a través de un programa muy básico C para las cadenas que comparan:C funciones sin archivos de encabezado

#include <stdio.h> 
int strcmp(char *s, char *t); 
int main() 
{ 
    printf("Returned: %d\n", strcmp("abc", "adf")); 
    return 0; 
} 

int strcmp(char *s, char *t) 
{ 
    printf("Blah\n"); 
    while (*s++ == *t++) 
    { 
     if (*s == '\0') 
      return 0; 
    } 
    return *s - *t; 
} 

Así que he implementado básicamente mi propia versión de la función strcmp ya presente en string.h. Cuando ejecuto el código anterior, solo veo valores de retorno de 0, 1 o -1 (al menos para mi pequeño conjunto de casos de prueba) en lugar de los resultados reales esperados. Ahora me doy cuenta de que esto se debe a que el código no va a mi versión implementada de strcmp, sino que usa la versión string.h de la función, pero no estoy seguro de por qué este es el caso incluso cuando no lo tengo. t incluyó el archivo de encabezado apropiado.

Además, viendo cómo se usa la versión del archivo de encabezado, ¿no debería obtener un error de "múltiples implementaciones" (o algo similar) al compilar el código?

+0

su última prueba '* s ++ == * t ++' que podría fallar aún aumentará sus punteros ... ¿eso es lo que quiere? – Benoit

+0

Sí, tienes razón. Esa última línea debe ser devuelta * (- s) - * (- t) –

Respuesta

14

Estás usando gcc, ¿verdad? gcc implementa algunas funciones como compiladas en el compilador y parece que strcmp is one of those. Intente compilar su archivo con el interruptor -fno-builtin.

Los archivos de encabezado le dicen al compilador que existen ciertos símbolos, macros y tipos. Incluir o no un archivo de encabezado no tendrá ningún efecto sobre el origen de las funciones, ese es el trabajo del vinculador. Si gcc sacaba strcmp de libc, probablemente vería una advertencia.

+0

+1 esta es la parte de la respuesta que no sabía :) – MByD

+1

mi respuesta parece un gran error ... . deleted ... – MByD

+0

Estaba seguro de que no fue publicado, es una pena ... – MByD

1

Sin saber qué compilador y lib. versión que utiliza, todas las conclusiones son solo 'posibilidad'. Así que lo más razonable que stdio.h ya incluye stdlib.h o string.h

6

No es tan elegante como las respuestas anteriores, otra manera de hacer esto

#include <stdio.h> 
static int strcmp(char *s, char *t); /* static makes it bind to file local sym */ 
int main() 
{ 
    printf("Returned: %d\n", strcmp("abc", "adf")); 
    return 0; 
} 

int strcmp(char *s, char *t) 
{ 
    printf("Blah\n"); 
    while (*s++ == *t++) 
    { 
     if (*s == '\0') 
      return 0; 
    } 
    return *s - *t; 
} 
0

strcmp es el nombre de una función de biblioteca estándar. Como tal, solo se le permite declarar la función (aunque debe usar una declaración correcta); no está permitido proporcionar otra definición para ello. La implementación puede suponer que siempre que utilice strcmp se está refiriendo a la función de biblioteca estándar, incluso si no ha utilizado el #include correcto para ello.

Si desea proporcionar una alternativa strcmp, debe darle un nombre alternativo.

+0

Puedo proporcionar la redefinición de la mayoría de las funciones de la biblioteca. La mayoría de ellos son declarados débiles en glibc; Además, el estándar solo dice sobre la definición en el encabezado. Si no se incluye ningún encabezado, no hay ninguna "función de biblioteca" y puedo declarar cualquier cosa, incluso el 'y0()' o definir algo de una manera no estándar, p. Ej. 'double strcmp (int, float *)'. Muchas implementaciones permiten al usuario desactivar la suposición sobre la biblioteca estándar ('-fno-builtin' o' -ffreestanding'). El estándar dice acerca de la biblioteca en "Entorno alojado" ("implementación alojada conforme"), pero hay una "implementación independiente conforme". – osgx

Cuestiones relacionadas