2009-11-14 10 views
16

Kann mir jemand auf die Definition von strlen() in GCC hinweisen? Ich habe jetzt Release 4.4.2 für etwa eine halbe Stunde grepping (während Googlen wie verrückt) und ich kann nicht finden, wo strlen() tatsächlich implementiert ist.Strlen() Implementierung in GCC

Antwort

26

Sie in glibc suchen sollte, nicht GCC - es scheint, in strlen.c definiert werden - hier ist ein Link zu strlen.c for glibc version 2.7 ... Und hier ist ein Link auf die glibc SVN repository online for strlen.c.

Der Grund, warum Sie bei glibc suchen sollten und nicht gcc ist:

Die GNU-C-Bibliothek als die C-Bibliothek in dem GNU-System und die meisten Systeme mit dem Linux-Kernel verwendet wird.

+0

Ich habe sogar glibc und dachte nicht zu suchen. Ziemlich schick. Danke für die Köpfe hoch. –

+2

Meh, das ist nicht sehr optimiert. Zumindest mit Visual C++ bekommen wir eine ordentliche Assemblersprache. – toto

+1

"Die GNU C-Bibliothek wurde in erster Linie als portable und leistungsstarke C-Bibliothek konzipiert." Ich schätze, sie legen vielleicht mehr Gewicht auf den Portabilitätsteil. –

7

Hier ist die bsd Implementierung

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

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

Ich warte immer noch auf den Tag, an dem ein Compiler daraus schnell brauchbaren Maschinencode erzeugen kann ... Momentan ist es weniger als die halbe Geschwindigkeit einer optimierten * C * -Version. –

3

Google Code Search ist ein guter Ausgangspunkt für Fragen wie diese. Sie verweisen in der Regel auf verschiedene Quellen und Implementierungen einer Funktion.

In Ihrem speziellen Fall: GoogleCodeSearch(strlen)

Google Code Search vollständig auf März 2013 stillgelegt wurde

3

Obwohl das ursprüngliche Plakat kann das nicht für diese Suche bekannt oder wurde, gcc intern inlines ein Anzahl der so genannten "eingebauten" c-Funktionen, die sie selbst definiert, einschließlich einiger der Funktionen mem *() und (abhängig von der gcc-Version) strlen. In solchen Fällen wird die Bibliotheksversion im Wesentlichen nie verwendet, und das Anweisen der Person auf die Version in glibc ist streng genommen nicht korrekt. (Es tut dies aus Performance-Gründen - zusätzlich zu der Verbesserung, die inlining selbst erzeugt, "gcc" bestimmte Dinge über die Funktionen, wenn es ihnen zur Verfügung stellt, wie zum Beispiel, dass Strlen ist eine reine Funktion und dass es so kann mehrere Anrufe, oder im Falle der mem * optimieren weg() Funktionen, die kein Aliasing stattfindet.)

weitere Informationen zu diesem Thema finden http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

8

ich weiß, diese Frage 4yrs alt, aber gcc wird oft seine eigene Kopie von Strlen, wenn Sie nicht #include <string.h> und keine der Antworten (einschließlich der akzeptierten Antwort) Konto dafür enthalten. Wenn Sie vergessen haben, erhalten Sie eine Warnung erhalten:

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

und gcc wird seine Kopie inline, die auf x86 ist die repnz scasb asm Variante, wenn Sie Werror oder -fno-builtin passieren. Die damit verbundenen Dateien befinden sich in gcc/config/<platform>/<platform>.{c,md}

Es wird auch von gcc/builtins.c gesteuert. Falls Sie sich gefragt haben, ob und wie ein strlen() auf eine Konstante optimiert wurde, sehen Sie sich die in dieser Datei als tree c_strlen(tree src, int only_value) definierte Funktion an.Es steuert auch, wie strlen (unter anderem) ist erweitert und gefaltet (basierend auf der zuvor genannten config/Plattform)

0

Ich weiß, dass dies alte Frage ist, können Sie die Linux-Kernel-Quellen bei Github here finden, und die 32-Bit Implementierung für Strlen() könnte in strlen_32.c auf Github gefunden werden. Die erwähnte Datei hat diese Implementierung.

#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

Sie können diesen Code verwenden, je einfacher desto besser!

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