2009-11-14 33 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; 
}