V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
amiwrong123
V2EX  ›  程序员

怎么通过 VS2019 看 strlen()的源码?

  •  
  •   amiwrong123 · 221 天前 · 3050 次点击
    这是一个创建于 221 天前的主题,其中的信息可能已经有所发展或是发生改变。

    vs 工程里,写了这么一句strlen("123");,然后我按住 ctrl ,点 strlen 进去,是这个样子: 如上图,我依次点击 strlen ,_In_z_,_SAL2_Source_,_SA_annotes3 到最后这个_SA_annotes3 这个宏定义,我就懵了,它还有三种宏定义。

    而且这个过程,宏定义又包含宏定义的,太复杂了吧,我只是想看一下 strlen 的实现而已。( PS:突然怀念起以前看 java 源码的日子)

    所以我这么看源码是对的吗?还是说,我不应该在 VS 里面看 C 的源码阿?(可能以后还想看一下 c++库,比如 vector 的实现)

    第 1 条附言  ·  221 天前
    算了,我不去看这些基本函数的实现了,知道基本原理就好了。

    但标准 C++库 vector 这种,你们都是怎么看源码的啊?比如你想看一下 vector 的拷贝构造函数和赋值构造函数是怎么实现的?深拷贝还是浅拷贝?

    VS 里倒是也能看,或者我应该去看 glibc 的源码或者 llvm 的源码?毕竟基本都是在 linux 上开发 C++
    22 条回复    2022-01-13 00:05:54 +08:00
    x1596357
        1
    x1596357  
       221 天前   ❤️ 2
    msvc 的源码是没有公开的。MS 开源了 STL 的部分 https://github.com/microsoft/STL 。strlen 的实现比较简单,类似下面这样。你可以参考 wine 项目的一些 api 实现。
    size_t __cdecl strlen( const char *str )
    {
    const char *s = str;
    while (*s) s++;
    return s - str;
    }
    amiwrong123
        2
    amiwrong123  
    OP
       221 天前
    @x1596357 #1
    好吧,我也不是非得通过,msvc 的方式来看源码的。

    那问下层主,有没有别的方式,可以方便看 c 或 c++源码的?最好是 能通过 ctrl 点击跳转这种形式。(把 https://github.com/microsoft/STL 下载下来,然后用 sublime 打开,再用一个跳转插件,好像也能实现)

    或者说,你们平时看 c 或 c++源码,都是通过什么方式来看的呀?
    ipwx
        3
    ipwx  
       221 天前
    @amiwrong123 CLion (趴桌
    iQXQZX
        4
    iQXQZX  
       221 天前
    不是给人看的
    kokutou
        5
    kokutou  
       221 天前 via Android
    clion 。。。

    把 gcc llvm 搞到 Windows 上呗。。。
    skinny
        6
    skinny  
       221 天前
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\crt\src

    去那个目录里面去找,不过不全
    amiwrong123
        7
    amiwrong123  
    OP
       221 天前
    @ipwx #3
    @kokutou #5
    谢谢,原来是这样的阿😂
    ipwx
        8
    ipwx  
       221 天前   ❤️ 1
    @amiwrong123 其实 strlen 各家的实现可能都有差别,而且可能会有魔法优化。。。。这种基础库函数反而不容易读代码。比如 gcc 的 strlen:

    https://github.com/lattera/glibc/blob/master/string/strlen.c#L33

    你看这个实现, /* Instead of the traditional loop which tests each character,
    we will test a longword at a time. The tricky part is testing
    if *any of the four* bytes in the longword in question are zero. */
    ipwx
        9
    ipwx  
       221 天前
    @amiwrong123 稍微查了查,至少对 vs2008 而言,strlen 是直接用汇编写的,不是 C 代码

    First CRT's one is written directly in assembler. you can see it's source code here C:\Program Files\Microsoft Visual Studio 9.0\VC\crt\src\intel\strlen.asm (this is for VS 2008)
    msg7086
        10
    msg7086  
       221 天前
    这种核心函数一般都会优化到裤衩级。
    比如楼上贴的深度位运算优化,或者是根据 CPU 型号跑 SSE 或者 AVX 指令集等等。
    O3 编译完的汇编代码可能连亲妈都不认识了。
    amiwrong123
        11
    amiwrong123  
    OP
       221 天前
    @ipwx #8
    我蒙了,一个 strlen 居然能写的这么复杂,我反正咋一看没看懂咋回事。算了,吃饭去了回头再看。

    我只是想看一个 简明的版本罢了
    amiwrong123
        12
    amiwrong123  
    OP
       221 天前
    @ipwx #8
    @msg7086 #10
    算了,核心函数自己看下原理就行了。

    另外,如果想看一眼 C++标准库比如 vector 的实现(比如我可能就想看一下 vector 的拷贝构造函数,看它是怎么构造的),是建议从 vs 里看吗,还是从 clion 里(把 gcc llvm 搞到 Windows 上)?或者其他方式
    sujin190
        13
    sujin190  
       221 天前
    @msg7086 #10 10 楼说的对,这种十分基本的函数会有针对不同平台、不同 cpu 版本、不同指令集的对应汇编级实现,汇编的实现函数会在上层用宏来定义,你找不到具体实现可能是 ide 不能识别汇编函数定义,而且有可能不同版本的汇编函数定义过程是不一样的,很难找的,其实这个函数语义很简单,你不用管不用怀疑具体实现怎么做的吧,真想了解似乎你直接编译后 objdump 看汇编代码更有意义吧
    Jooooooooo
        14
    Jooooooooo  
       221 天前
    (java 如此方便怎么没人夸
    LUO12826
        15
    LUO12826  
       221 天前
    你这里看的应该只是头文件(声明),真正的实现源码应该是没有的,已经被编译成二进制库了。这点不像 java ,你点进去 idea 也会给你反编译出来。如果想看这些库函数的实现,可以看 glibc 的源码或者 llvm 的源码( llvm 自己弄了个 libc++,但我不确定它的 libc 搞好没)
    rainciousEatDung
        16
    rainciousEatDung  
       221 天前
    “你们平时看 c 或 c++源码,都是通过什么方式来看的呀?”
    中二时代:试图搞明白 C 语言的原理,从了解到懵逼。
    大学时代:《编译原理》《微机原理》,从上课到挂科。
    yolee599
        17
    yolee599  
       221 天前 via Android
    你需要看的是编译器源码,而且不同的编译器实现方法不同,有的编译器是不开源的
    ysc3839
        18
    ysc3839  
       221 天前 via Android
    @x1596357 msvcrt 和 ucrt 的部分源代码是公开的,注意是公开而不是开源,以前的许可协议不属于开源协议。 @skinny #6 说的是 msvcrt 部分的代码,ucrt 的在 Windows SDK 目录下。
    https://github.com/microsoft/STL 是把以前就已经公开 msvcrt 的代码中的 STL 部分换成了开源协议。
    至于你说的 点进去的那个只是声明,因为 VS 不知道去哪找源代码,你需要手动打开源代码。_In_z_ 是微软的 SAL 语法,用来描述参数传递的要求的,给代码检查工具用的。
    jinliming2
        19
    jinliming2  
       220 天前   ❤️ 2
    @amiwrong123 #11 一般来说这些你觉得挺简单的函数 /功能,因为要在系统中高频调用,早就被优化的妈都不认了。
    我之前看过一篇文章,讲的是 Linux 下的 yes 命令的实现: https://endler.dev/2017/yes/
    yes 命令很简单,就是无限循环输出字母 y 。类似于 while (true) { println("y"); }
    就这么一个命令,都做了一大堆优化手段,可想而知 strlen 这么“复杂”且在系统中高频使用的函数会需要优化到什么程度……
    billwsy
        20
    billwsy  
       220 天前 via iPhone
    作为用户一般不需要看具体实现,只要看接口是什么就可以了。比如 std::vector ,看这个页面一般就够了: https://en.cppreference.com/w/cpp/container/vector
    ipwx
        21
    ipwx  
       219 天前
    @amiwrong123 你放心,C++ 世界里,越是基础的东西,魔法优化越多。

    一个 std::vector 也可能有各种你看不明白的五花八门的魔法用法。建议你别看了,自己想想该怎么写就够了。
    agagega
        22
    agagega  
       210 天前 via iPhone
    常见的 C 库如 Glibc 、Musl 、FreeBSD 的 libc 还有未完工的 LLVM libc 都是开源的,可以去看它们的实现
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1708 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 17:02 · PVG 01:02 · LAX 10:02 · JFK 13:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.