分享

女朋友问我:什么时候用 C 而不用 C ?

 新用户0118F7lQ 2022-08-25 发布于山东
来自公众号:高性能服务器开发

从事 C/C++ 编程快九个年头了,今天女朋友突然问我:什么时候用 C 而不用 C++?一下子把我的思绪拉入往昔那些使用 C 和 C++ 的“峥嵘岁月”里。女朋友还是原来的女朋友,而我却不是当初的那个我了。

老实说,这些年用 C 和 C++ 分别写过很多项目,也研究像 Linux 内核、Nginx、Redis、freeswitch 等各种经典 C 项目,当然研究的 C++ 项目也不少(例如 MySQL 的源码),玩的不亦乐乎,常看常新,看到这些经典项目的精彩代码处时有时候喜不自禁,那真是笑看妻子愁何在,漫卷诗书喜欲狂。

贴几张图:

图片

调试分析 C 项目 Redis 源码

图片

调试分析 C 项目 Nginx 源码

图片

调试分析 C++ 项目 MySQL Server 8.0

如果一个项目如果对内存和编译后的机器指令做精准控制,那么应该优先选择 C 而不是 C++,C++ 编译器在背后插入了太多的指令。举两个例子:

class A {
public:
    A() {}
    ~A() {}
};


int main()
{
    A a;
    return 0;
}

这个例子说明了在 C++ 中一个对象出了其作用域(这里是 a),会自动调用其析构函数,这是编译器自动加入的:

    A a;
00007FF71E2918DD  lea         rcx,[a]  
00007FF71E2918E1  call        A::A (07FF71E291302h)  

    return 0;
00007FF71E2918E6  mov         dword ptr [rbp+0E4h],0  
00007FF71E2918F0  lea         rcx,[a]  
00007FF71E2918F4  call        A::~A (07FF71E291258h)  ;编译在这里自动插入调用类A的析构函数
00007FF71E2918F9  mov         eax,dword ptr [rbp+0E4h]  
}

再比如假设 A 类有一个实例方法 f,编译器的调用 A 方法的实现是编译器自动插入了一个 this 指针作为方法的第一个参数:

class A {
public:
    A() {}
    ~A() {}

    void f(int a, int b) {}
};


int main()
{
    A a;
    a.f(1, 2);

    return 0;
}

汇编代码如下:

 A a;
00007FF7157D193D  lea         rcx,[a]  
00007FF7157D1941  call        A::A (07FF7157D1311h)  
00007FF7157D1946  nop  
    a.f(1, 2);                       ;由于函数调用方式是__thiscall,
00007FF7157D1947  mov         r8d,2  ;所以参数从右往左入栈,这是第一个参数2
00007FF7157D194D  mov         edx,1  ;这是第一个参数的1
00007FF7157D1952  lea         rcx,[a];这是对象a的地址,即this指针
00007FF7157D1956  call        A::f (07FF7157D110Eh)  ;调用a的方法f

    return 0;
00007FF7157D195B  mov         dword ptr [rbp+0E4h],0  
00007FF7157D1965  lea         rcx,[a]  
00007FF7157D1969  call        A::~A (07FF7157D1267h)  
00007FF7157D196E  mov         eax,dword ptr [rbp+0E4h]  

同样的道理,如果如果一个复杂的 C++ 工程中,一个类有多个复杂类型成员,而这些复杂类型成员又有多个复杂类型成员,这种层级关系比较深的情况下,上层对象的构造函数会自动触发其成员变量的构造函数的调用,而进而又触发下一级成员变量的构造函数的调用,而析构函数正好反过来,这些构造动作都是编译器自己往开发者的程序中插入的指令。如果要涉及到模板或者像智能指针包裹的对象的构造、析构和移动,那编译器自动嵌入的指令就更多。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多