深入 C 语言和程序运行原理
于航
PayPal 技术专家
21121 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 49 讲
深入 C 语言和程序运行原理
15
15
1.0x
00:00/00:00
登录|注册

课堂答疑(一)|前置篇、C 核心语法实现篇问题集锦

提供 extern 定义
使用 static inline
去掉 inline
类似功能的实现
C11 泛型宏 _Generic
C 语言不支持多态
x86 体系结构优化
减少执行指令数量
简化计算表达式
栈中数据的处理
寄存器 rsprbp 的修改
性能优化和细节理解
应用场景需求
C 语言的目的
-pedantic-errors 选项
gnu-folding-constant 扩展
非常量表达式的处理
工业界使用情况
Intel 风格 vs AT&T 风格
向前兼容性
C17 标准规定
inline static vs static inline
解决方案
static 提供内部链接(internal linkage)
inline 函数的链接问题
更多问题的探讨
评论区交流
深入讨论和解答
问题八:C 语言的函数重载
问题七:lea 指令的性能优势
问题六:leave 指令与栈清理
问题五:学习汇编的必要性
问题四:Clang 编译器的特殊行为
问题三:内联汇编与编译汇编风格差异
问题二:关键字顺序
问题一:static 关键字的作用
后续文章
前置篇、C 核心语法实现篇问题集锦
课堂答疑总结

该思维导图由 AI 生成,仅供参考

你好,我是于航。
看到这里的你,应该已经完成了本课程前两个模块的学习。随着课程的不断推进,我陆续收到了很多反馈。很高兴看到你在评论区积极留言,和大家一起讨论思考题。并且,还有很多同学提出了一些非常有意义的问题。那么,在继续学习后面更深入的内容之前,让我们先暂缓脚步,从问题出发,进行一次整体性的回顾。
在这一讲中,我会以加餐的形式,为你剖析一些值得讨论的思考题,以及你们提出的有代表性的问题。
问题一:01 讲 的最后,我留给你的问题是:在这一讲第一部分的 C 代码实例中,我们为何要给函数 findAddr 添加 static 关键字?不添加这个关键字的话,程序是否可以编译运行?
这里,我将那段代码简化了一下,只提取出与问题相关的部分,放到了下面。因此,问题也变成了:对于下面这段代码来说,将函数 foo 定义中使用的 static 关键字去掉,是否会影响程序的正常编译和运行呢?
#include <stdio.h>
inline static int foo(void) {
return 0;
}
int main(void) {
printf("%d", foo());
return 0;
}
实际上,如果你能够在 godbolt 上快速实践一下,就会发现:在默认情况下(没有使用任何优化参数),编译器会报出类似 “error: ld returned 1 exit status” 的链接器错误;而在使用 “-O1” 及以上优化参数的情况下,编译器则可以正常编译。那么,为什么会这样呢?
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了C语言核心语法实现中的一些技术细节和讨论。首先讨论了在C代码中使用`static`关键字的作用,以及在不同优化参数下的编译结果。接着解释了`inline`关键字的使用方法,以及`inline static`和`static inline`的区别。文章还介绍了不同编译器下的汇编风格差异,以及编译器对非标准用法的处理方式。此外,还讨论了学习C语言是否需要了解汇编语言,以及`leave`指令在清理栈时是否会将相关内存清空的问题。最后,文章提到了编译器为什么会使用`lea`指令而非`mov`指令来实现某些简单的算数运算逻辑。总体而言,本文对于想要深入了解C语言实现细节的读者来说,是一篇值得阅读的文章。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入 C 语言和程序运行原理》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(6)

  • 最新
  • 精选
  • sugar
    请教于航老师一个问题,我的日常开发程序语言主要是JavaScript和C/C++,这个技术栈与老师应该比较类似。在js中,我们在运行时console.log可以打出任何一个代码中可见的变量的具体值,无论它是一个number、string这样的简单类型,还是各种类嵌套定义出的超级复杂的数据结构,这个能力在阅读其他人写的代码时很有帮助:我不确定一段程序中的某个符号代表的对象究竟是什么结构的时候,我可以直接去运行时把它log出来,尤其是项目代码量庞大的时候这能省去大量人肉读代码的时间;但是在c/c++当中,据我目前所知似乎只能cout 或者 printf出一个基本类型,比如int double char等,不能像js那样轻松的console.log出任何type的变量完整结构。请问于航老师在面对这种情况时是怎么处理?是否只能人肉一个一个class definition去翻代码?c的一些三方库只能翻到.h文件,翻不到具体实现.c或者.cpp文件。

    作者回复: 可以试试 Visual Studio Code?我之前的 C++ 项目在 VSC 里单步调试的时候就可以直接 inspect 对应变量的内容(包括各类 STL 容器)。

    2022-01-03
    3
    2
  • 火云邪神霸绝天下
    #include <stdio.h> void foo(void) { int x; printf("%d\n", x); x = 10; } int main(void) { foo(); foo(); return 0; } 这个代码两次输出都是0。不太明白它说清楚了什么。 本来不就该是 0 吗? 函数执行一次就栈内空间回收了吧。下次执行下次说。

    作者回复: 试着在 “-O0” 下编译,再看看执行结果呢?

    2022-01-19
    1
  • TableBear
    专属的微信群是哪个?还能进去吗

    作者回复: @极客时间 小编,帮忙拉一下?

    2022-08-09归属地:广东
  • 青鸟飞鱼
    我觉得老师可以请大佬来讲讲c语言在redis应用哈哈,有了nginx,怎么能少了redis

    作者回复: 好的,我帮你问问看哈哈哈。

    2022-01-12
  • ZR2021
    老师强大!!!
    2022-01-01
    1
  • Fan
    Good
    2021-12-31
    1
收起评论
显示
设置
留言
6
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部