2009-11-14 34 views
16

任何人都可以指向我在GCC中定義的strlen()嗎?我一直在抱怨釋放4.4.2現在大約半小時(雖然Google瘋狂),我似乎無法找到strlen()實際上在哪裏實施。strlen()在gcc中的實現

回答

26

你應該看glibc,而不是GCC - 它似乎被定義在strlen.c - 這是一個鏈接到strlen.c for glibc version 2.7 ...這裏是一個鏈接到glibc SVN repository online for strlen.c

你應該看glibc,而不是海灣合作委員會的原因是:

GNU C庫作爲在GNU系統 C庫和最系統的Linux內核。

+0

我甚至有glibc,並沒有想到看起來。很漂亮。感謝您的高舉。 – 2009-11-14 04:51:25

+2

梅,這不是很優化。至少在Visual C++中,我們得到了一個體面的彙編語言strlen。 – toto 2009-11-14 04:55:20

+1

「GNU C庫主要是爲便攜式和高性能C庫設計的。」我猜他們可能會把更多的重量放在可移植性部分。 – 2009-11-14 05:00:30

7

這裏的bsd實施

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

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

仍然在等待編譯器從此產生可用快速機器代碼的日子......目前它還不到優化的* C *版本速度的一半。 – 2011-02-24 04:38:36

3

雖然原來的海報可能不知道這還是一直在找這個,海合會內部內聯一它自己定義的所謂「內建」c函數的數量,包括一些mem *()函數和(取決於gcc版本)strlen。在這種情況下,庫的版本基本上不會被使用,並且將人指向glibc中的版本並不嚴格地講是正確的。 (這是出於性能方面的考慮 - 除了內聯本身產生的改進之外,gcc在提供函數時會「知道」某些函數,例如,strlen是一個純函數,因此它可以優化掉多個電話,或在MEM *()不走樣正在發生作用。)

有關的更多信息的情況下,看到http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

8

我意識到這個問題是4歲,但GCC通常會包括自己的 strlen的副本,如果您沒有#include <string.h>並且沒有答案(包括接受的答案)對此作出說明。如果你忘了,你會得到一個警告:

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

和gcc將它內聯副本在x86上運行的REPNZ SCASB ASM變種,除非你通過-Werror或-fno-內置。與此相關的文件在gcc/config/<platform>/<platform>.{c,md}

它也由gcc/builtins.c控制。如果您想知道是否以及如何將strlen()優化爲常量,請參閱此文件中定義爲tree c_strlen(tree src, int only_value)的函數。它也控制如何擴展和摺疊(基於前面提到的配置/平臺)(基於前面提到的配置/平臺)

0

我意識到這是一個老問題,你可以在github上找到linux內核源碼here,以及32位strlen()的實現可以在github上的strlen_32.c中找到。提到的文件有這個實現。

#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

您可以使用此代碼,越簡單越好!

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