目录
1.准备
2.查看汇编代码文件test.s
3.修改源文件,再次查看.s文件
4.结论
之前在C7.【C++ Cont】范围for的使用和auto关键字文章中提到了如下内容:
即auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期间(预编译-->编译-->汇编-->链接,在第二个阶段完成以后)会将auto替换为变量实际的类型(具体是怎么替换的参见C++ Dev专栏的文章,竞赛中不要求掌握)
本文将解释以上内容
1.准备
Linux服务器下创建test.cpp,写入以下内容:
int main()
{auto a=1;return 0;
}
使用以下命令编译生成test.s文件:
g++ -S test.cpp
2.查看汇编代码文件test.s
使用以下命令查看:
nano test.s
.file "test.cpp".text.globl main.type main, @function
main:
.LFB0:.cfi_startprocendbr64pushq %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq %rsp, %rbp.cfi_def_cfa_register 6movl $1, -4(%rbp)movl $0, %eaxpopq %rbp.cfi_def_cfa 7, 8ret.cfi_endproc
.LFE0:.size main, .-main.ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0".section .note.GNU-stack,"",@progbits.section .note.gnu.property,"a".align 8.long 1f - 0f.long 4f - 1f.long 5
0:.string "GNU"
1:.align 8.long 0xc0000002.long 3f - 2f
2:.long 0x3
对于test.s只看关键部分
画红框的指令解释:将4字节的1写入rbp-4的地址处的空间,注意是4字节,因为是movl,l代表long,只操作32位
3.修改源文件,再次查看.s文件
原文件改成:
int main()
{auto a='x';return 0;
}
查看test.s:
.file "test.cpp".text.globl main.type main, @function
main:
.LFB0:.cfi_startprocendbr64pushq %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq %rsp, %rbp.cfi_def_cfa_register 6movb $120, -1(%rbp)movl $0, %eaxpopq %rbp.cfi_def_cfa 7, 8ret.cfi_endproc
.LFE0:.size main, .-main.ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0".section .note.GNU-stack,"",@progbits.section .note.gnu.property,"a".align 8.long 1f - 0f.long 4f - 1f.long 5
0:.string "GNU"
1:.align 8.long 0xc0000002.long 3f - 2f
2:.long 0x3
只看关键部分:
画红框的指令解释:$120的前缀$代表立即数,120以十进制显示,转换为16进制为0x78,为'x'的ASCII码(ASCII码表 点我跳转查询)将1字节的0x78写入rbp-1的地址处的空间,注意是1字节,因为是movb,b代表byte,只操作8位
4.结论
从上述两次生成s文件的内容可以看出auto确实在在编译期间会将auto替换为变量实际的类型
例如上方两次生成的s文件的movl和movb,操作大小不同