c - 静态链接中的静态函数与非静态?
问题描述
我使用 C 编写了以下 2 个程序:
第一的:
int foo(int x)
{
return 1;
}
int main()
{
return foo(4);
}
第二:
static int foo(int x)
{
return 1;
}
int main()
{
return foo(4);
}
然后我跑了:
gcc -c my_file.c
对于我看到的第一个文件(不是完整的输出):
000000000000000e <main>:
e: 55 push %rbp
f: 48 89 e5 mov %rsp,%rbp
12: bf 04 00 00 00 mov $0x4,%edi
17: e8 00 00 00 00 callq 1c <main+0xe>
1c: 5d pop %rbp
1d: c3 retq
对于第二个:
000000000000000e <main>:
e: 55 push %rbp
f: 48 89 e5 mov %rsp,%rbp
12: bf 04 00 00 00 mov $0x4,%edi
17: e8 e4 ff ff ff callq 0 <foo>
1c: 5d pop %rbp
1d: c3 retq
我的问题是,为什么在第一个文件中当函数在当前文件中定义(而不仅仅是声明)时我们需要重定位?这对我来说听起来太奇怪了。
解决方案
您查看未解析的代码。
第一个版本是foo()
全局的,因此在适当的表、符号和重定位中有条目,列表中没有显示。<编辑>很可能是因为编译器是这样工作的,当它发出对全局函数的调用时,它会在地址字段中放置零(或其他任何东西)。这个全局函数在同一个翻译单元中并不重要。使用其他选项或其他版本的编译器或其他编译器调用可能会产生不同的结果。< /Edit >
在第二个版本中,编译器知道这foo()
是本地的并立即解析调用,而无需生成重定位条目。
如果链接程序,调用将被解析为相等的值。
<编辑>有趣:我尝试在 Windows 上使用 GCC 8.1.0 (MinGW-W64) 重现此问题,并且两个调用都由编译器解析。但是,对于当前 Manjaro Linux 的 GCC 11.1.0,它会显示所描述的行为。< /Edit >
推荐阅读
- python - 导入“matplotlib”时出错 - Windows Python3.7.4 32 位
- javascript - 无法通过 onClick 事件处理程序访问按钮 id
- scala - 显示单词长度大于8的单词
- html - 如何在输入表单中隐藏提示?
- python - Python google云功能部署失败-Madmom pip包
- vb.net - 如何在 VB 中执行以下操作:月份的最后日期
- c# - ASP.NETCore 模型中的十进制字段格式
- python - Python检查内联字符串中的值并更改它
- swift - iOS 13 - 右栏按钮项目在模态表演示中偏移
- maven - 错误“无法传输文件 *.jar,状态码为 409”,尽管已传输