GCC中strlen()的实现在哪里?
谁能给我指出 GCC 中 strlen()
的定义吗?我已经 grep 4.4.2 版本大约半个小时了(同时疯狂地谷歌搜索),我似乎找不到 strlen()
实际实现的位置。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
谁能给我指出 GCC 中 strlen()
的定义吗?我已经 grep 4.4.2 版本大约半个小时了(同时疯狂地谷歌搜索),我似乎找不到 strlen()
实际实现的位置。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(10)
您应该查看 glibc,而不是 GCC - 它似乎是在
strlen.c
中定义的 - 这是 strlen.c for glibc version 2.7... 这里是 strlen.c 的 glibc SVN 在线存储库。您应该查看 glibc 而不是 gcc 的原因是:
You should be looking in glibc, not GCC -- it seems to be defined in
strlen.c
-- here's a link to strlen.c for glibc version 2.7... And here is a link to the glibc SVN repository online for strlen.c.The reason you should be looking at glibc and not gcc is:
这是 bsd 实现
Here's the bsd implementation
我意识到这个问题已经有 4 年历史了,但是如果您不
#include
并且没有答案(包括接受的答案)对此进行解释。如果你忘记了,你会得到一个警告:file_name:line_number: warning: incompromedimplicit statements ofbuilt-in function 'strlen'
并且gcc将内联它的副本,该副本在x86上是repnz scasb asm变体,除非您传递 -Werror 或 -fno-builtin。与此相关的文件在
gcc/config//.{c,md}
中,也是由 gcc/builtins.c 控制的。如果您想知道 strlen() 是否以及如何优化为常量,请参阅此文件中定义为
tree c_strlen(tree src, int only_value)
的函数。它还控制 strlen (以及其他)如何展开和折叠(基于前面提到的配置/平台)I realize this question is 4yrs old, but gcc will often include its own copy of strlen if you do not
#include <string.h>
and none of the answers (including the accepted answer) account for that. If you forget, you will get a warning:file_name:line_number: warning: incompatible implicit declaration of built-in function 'strlen'
and gcc will inline its copy which on x86 is the repnz scasb asm variant unless you pass -Werror or -fno-builtin. The files related to this are in
gcc/config/<platform>/<platform>.{c,md}
It is also controlled by gcc/builtins.c. In case you wondered if and how a strlen() was optimized to a constant, see the function defined as
tree c_strlen(tree src, int only_value)
in this file. It also controls how strlen (amongst others) is expanded and folded (based on the previously mentioned config/platform)定义于glibc/string/strlen.c
defined in glibc/string/strlen.c
glibc 2.26 有几个手工优化的
strlen
汇编实现 从glibc-2.26
开始,快速:在 glibc 树中显示了十几个汇编手工-所有主要拱门和变体的优化实现。
特别是,x86_64 本身就有 3 种变体:
确定使用哪一种的一种快速而肮脏的方法是逐步调试测试程序:
编译时使用:
Off the bat:
contains:
所以调用 libc 版本。
经过几个 si 指令级步骤后,GDB 达到:
它告诉我
strlen-使用avx2.S
。然后,我进一步确认:
并将反汇编与glibc源进行比较。
使用 AVX2 版本并不奇怪,因为我有一个 i7-7820HQ CPU,发布日期为 2017 年第一季度,支持 AVX2,以及 AVX2 是最先进的汇编实现,发布日期为 2013 年第二季度,而 SSE2 从 2004 年开始就更加古老。
这就是 glibc 的核心性很大一部分来自于:它有很多经过架构优化的手写汇编代码。
在 Ubuntu 17.10、gcc 7.2.0、glibc 2.26 中测试。
-O3
TODO:使用
-O3
,gcc不使用glibc的strlen
,它只是生成内联汇编,这提到的是: https://stackoverflow.com/a/19885891/895245是因为它可以优化得更好吗?但它的输出不包含AVX2指令,所以我觉得事实并非如此。
https://www.gnu.org/software/gcc/projects/optimize。 html 提到:
我的简单测试表明
-O3
版本实际上更快,因此 GCC 做出了正确的选择。提问于:https://www.quora.com/unanswered/How-does-GCC-know-that-its-builtin-implementation-of-strlen-is-faster -than-glibcs-when-using-optimization-level-O3
glibc 2.26 has several hand optimized assembly implementations of
strlen
As of
glibc-2.26
, a quick:in the glibc tree shows a dozen of assembly hand-optimized implementations for all major archs and variations.
In particular, x86_64 alone has 3 variations:
A quick and dirty way to determine which one is used, is to step debug a test program:
compiled with:
Off the bat:
contains:
so the libc version is being called.
After a few
si
instruction level steps into that, GDB reaches:which tells me that
strlen-avx2.S
was used.Then, I further confirm with:
and compare the disassembly with the glibc source.
It is not surprising that the AVX2 version was used, since I have an i7-7820HQ CPU with launch date Q1 2017 and AVX2 support, and AVX2 is the most advanced of the assembly implementations, with launch date Q2 2013, while SSE2 is much more ancient from 2004.
This is where a great part of the hardcoreness of glibc comes from: it has a lot of arch optimized hand written assembly code.
Tested in Ubuntu 17.10, gcc 7.2.0, glibc 2.26.
-O3
TODO: with
-O3
, gcc does not use glibc'sstrlen
, it just generates inline assembly, which is mentioned at: https://stackoverflow.com/a/19885891/895245Is it because it can optimize even better? But its output does not contain AVX2 instructions, so I feel that this is not the case.
https://www.gnu.org/software/gcc/projects/optimize.html mentions:
My simple tests show that the
-O3
version is actually faster, so GCC made the right choice.Asked at: https://www.quora.com/unanswered/How-does-GCC-know-that-its-builtin-implementation-of-strlen-is-faster-than-glibcs-when-using-optimization-level-O3
尽管原始发布者可能不知道这一点或一直在寻找这一点,但 gcc 内部内联了许多它自己定义的所谓“内置”c 函数,包括一些 mem*() 函数和(取决于gcc 版本)strlen.在这种情况下,库版本基本上不会被使用,并且将人指向 glibc 中的版本严格来说并不正确。 (这样做是出于性能原因——除了内联本身产生的改进之外,gcc 在提供函数时“知道”有关函数的某些事情,例如 strlen 是一个纯函数,因此它可以优化掉多个调用,或者在 mem*() 函数的情况下不会发生别名。)
有关这方面的更多信息,请参阅 http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
Although the original poster may not have known this or been looking for this, gcc internally inlines a number of so-called "builtin" c functions that it defines on its own, including some of the mem*() functions and (depending on the gcc version) strlen. In such cases, the library version is essentially never used, and pointing the person at the version in glibc is not strictly speaking correct. (It does this for performance reasons -- in addition to the improvement that inlining itself produces, gcc "knows" certain things about the functions when it provides them, such as, for example, that strlen is a pure function and that it can thus optimize away multiple calls, or in the case of the mem*() functions that no aliasing is taking place.)
For more information on this, see http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
这是您要找的吗? 斯特伦() 来源。有关详细信息,请参阅 git 存储库。 glibc 资源页面 有 git 存储库的链接(如果您想获取它们)而不是看网页视图。
Is this what you are looking for? strlen() source. See the git repository for more information. The glibc resources page has links to the git repositories if you want to grab them rather than looking at the web view.
Google 代码搜索 是解决此类问题的一个很好的起点。它们通常指向函数的各种不同来源和实现。在您的特定情况下:GoogleCodeSearch(strlen)Google 代码搜索于 2013 年 3 月完全关闭
Google Code Search is a good starting point for questions like that. They usually point to various different sources and implementations of a function.In your particular case: GoogleCodeSearch(strlen)Google Code Search was completely shut down on March 2013
我意识到这是老问题了,你可以在 github 这里 找到 linux 内核源代码,以及 32 位内核源代码strlen() 的实现可以在 strlen_32.c< 中找到/a> 在 github 上。提到的文件有这个实现。
I realize that this is old question, you can find the linux kernel sources at github here, and the 32 bit implementation for strlen() could be found in strlen_32.c on github. The mentioned file has this implementation.
您可以使用此代码,越简单越好!
You can use this code, the simpler the better !