2009-11-14 11 views
16

Puede alguien me punto a la definición de strlen() en GCC? He estado grepping 4.4.2 estreno de una media hora ahora (mientras que buscar en Google como un loco) y me parece que no puede encontrar dónde strlen() se aplica realmente.strlen() implementación en gcc

Respuesta

26

Usted debe estar buscando en glibc, no GCC - parece estar definido en strlen.c - aquí hay un enlace a strlen.c for glibc version 2.7 ... Y aquí hay un enlace a la glibc SVN repository online for strlen.c.

La razón por la que debe buscar en glibc y no gcc es:

La biblioteca GNU C se utiliza como la biblioteca C en el sistema GNU y la mayoría de los sistemas con el núcleo Linux.

+0

Incluso tengo glibc y no pensé en mirar. Bastante ingenioso. Gracias por el aviso. –

+2

Meh, eso no está muy optimizado. Al menos con Visual C++ obtenemos un lenguaje ensamblador decente strlen. – toto

+1

"La biblioteca C de GNU está diseñada principalmente para ser una biblioteca C portátil y de alto rendimiento". Supongo que están poniendo más peso en la parte de portabilidad, tal vez. –

7

Aquí está la aplicación bsd

size_t 
strlen(const char *str) 
{ 
     const char *s; 

     for (s = str; *s; ++s) 
       ; 
     return (s - str); 
} 
+10

Todavía estamos a la espera del día en que un compilador pueda generar códigos de máquina usablemente rápidos a partir de este ... Actualmente, es menos de la mitad de la velocidad de una versión optimizada * C *. –

3

Google Code Search es un buen punto de partida para preguntas como esa. Por lo general, apuntan a diferentes fuentes e implementaciones de una función.

En su caso particular: GoogleCodeSearch(strlen)

Google Code Search fue completamente apagado de marzo 2013

3

Aunque el cartel original no puede haber sabido esto o estado buscando esto, gcc inlines internamente una número de las llamadas funciones c "incorporadas" que define por sí mismo, incluidas algunas de las funciones mem *() y (según la versión de gcc) strlen. En tales casos, la versión de la biblioteca nunca se usa, y apuntar a la persona en la versión en glibc no es estrictamente correcta. (Esto se hace por razones de rendimiento - además de la mejora que inlining sí mismo produce, gcc "sabe" ciertas cosas acerca de las funciones cuando se les proporciona, tales como, por ejemplo, que es una función strlen pura y que puede por lo tanto optimizar la distancia de varias llamadas, o en el caso de la mem *() funciones que ningún solapamiento está llevando a cabo.)

Para obtener más información sobre esto, ver http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

8

realizo esta pregunta es 4 años de edad, pero gcc a menudo incluyen su propia copia de strlen si no #include <string.h> y ninguna de las respuestas (incluyendo la respuesta aceptada) dan cuenta de eso. Si se le olvida, obtendrá una advertencia:

file_name:line_number: warning: incompatible implicit declaration of built-in function 'strlen'

y GCC inline su copia correspondiente en x86 es la variante SCASB asm repnz a menos que pase -Werror o -fno-incorporado. Los archivos relacionados con esto están en gcc/config/<platform>/<platform>.{c,md}

También es controlada por gcc/builtins.c. En caso de que se pregunte si y cómo un strlen() se optimizó a una constante, consulte la función definida como tree c_strlen(tree src, int only_value) en este archivo.También controla cómo se expande y se pliega strlen (entre otros) (basado en la configuración/plataforma mencionada anteriormente)

0

Me doy cuenta de que esta es una vieja pregunta, puedes encontrar las fuentes del núcleo de Linux en github here, y los 32 bits la implementación de strlen() se puede encontrar en strlen_32.c en github. El archivo mencionado tiene esta implementación.

#include <linux/types.h> 
#include <linux/string.h> 
#include <linux/module.h> 

size_t strlen(const char *s) 
{ 
    /* Get an aligned pointer. */ 
    const uintptr_t s_int = (uintptr_t) s; 
    const uint32_t *p = (const uint32_t *)(s_int & -4); 

    /* Read the first word, but force bytes before the string to be nonzero. 
    * This expression works because we know shift counts are taken mod 32. 
    */ 
    uint32_t v = *p | ((1 << (s_int << 3)) - 1); 

    uint32_t bits; 
    while ((bits = __insn_seqb(v, 0)) == 0) 
     v = *++p; 

    return ((const char *)p) + (__insn_ctz(bits) >> 3) - s; 
} 
EXPORT_SYMBOL(strlen); 
1

Puede usar este código, ¡cuanto más simple mejor!

size_t Strlen (const char * _str) 
{ 
    size_t i = 0; 
    while(_str[i++]); 
    return i; 
}