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

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

  •  
  •   amiwrong123 · 2022-01-01 17:09:22 +08:00 · 4089 次点击
    这是一个创建于 1042 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    第 1 条附言  ·  2022-01-01 23:12:20 +08:00
    算了,我不去看这些基本函数的实现了,知道基本原理就好了。

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

    VS 里倒是也能看,或者我应该去看 glibc 的源码或者 llvm 的源码?毕竟基本都是在 linux 上开发 C++
    22 条回复    2022-01-13 00:05:54 +08:00
    x1596357
        1
    x1596357  
       2022-01-01 17:39:48 +08:00   ❤️ 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
       2022-01-01 17:58:08 +08:00
    @x1596357 #1
    好吧,我也不是非得通过,msvc 的方式来看源码的。

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

    或者说,你们平时看 c 或 c++源码,都是通过什么方式来看的呀?
    ipwx
        3
    ipwx  
       2022-01-01 18:13:12 +08:00
    @amiwrong123 CLion (趴桌
    iQXQZX
        4
    iQXQZX  
       2022-01-01 18:36:33 +08:00
    不是给人看的
    kokutou
        5
    kokutou  
       2022-01-01 18:46:09 +08:00 via Android
    clion 。。。

    把 gcc llvm 搞到 Windows 上呗。。。
    skinny
        6
    skinny  
       2022-01-01 18:50:55 +08:00
    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\crt\src

    去那个目录里面去找,不过不全
    amiwrong123
        7
    amiwrong123  
    OP
       2022-01-01 18:57:49 +08:00
    @ipwx #3
    @kokutou #5
    谢谢,原来是这样的阿😂
    ipwx
        8
    ipwx  
       2022-01-01 19:13:17 +08:00   ❤️ 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  
       2022-01-01 19:15:19 +08:00
    @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  
       2022-01-01 19:18:16 +08:00
    这种核心函数一般都会优化到裤衩级。
    比如楼上贴的深度位运算优化,或者是根据 CPU 型号跑 SSE 或者 AVX 指令集等等。
    O3 编译完的汇编代码可能连亲妈都不认识了。
    amiwrong123
        11
    amiwrong123  
    OP
       2022-01-01 19:26:03 +08:00
    @ipwx #8
    我蒙了,一个 strlen 居然能写的这么复杂,我反正咋一看没看懂咋回事。算了,吃饭去了回头再看。

    我只是想看一个 简明的版本罢了
    amiwrong123
        12
    amiwrong123  
    OP
       2022-01-01 19:30:21 +08:00
    @ipwx #8
    @msg7086 #10
    算了,核心函数自己看下原理就行了。

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

    一个 std::vector 也可能有各种你看不明白的五花八门的魔法用法。建议你别看了,自己想想该怎么写就够了。
    agagega
        22
    agagega  
       2022-01-13 00:05:54 +08:00 via iPhone
    常见的 C 库如 Glibc 、Musl 、FreeBSD 的 libc 还有未完工的 LLVM libc 都是开源的,可以去看它们的实现
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4762 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 09:52 · PVG 17:52 · LAX 01:52 · JFK 04:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.