为什么 main() 在 C 中不能声明为静态?

2023-11-25

为什么必须将 main 声明为具有外部链接?

为什么它不应该是静态的?

外部链接是什么意思?


因为您将启动文件链接到您的程序,其中(通常)包含调用 main.c 文件的汇编代码。如果 main 是静态的,则该代码将无法调用 main。

external linkage意味着其他所谓的translation-units可以看到您的符号在其自己的翻译单元中声明为 extern 。因此,您的 main 是 extern,并且它的翻译单元符号表中将有一个条目来说明其地址。当其他翻译单元想要调用 main 时,它们将能够跳转到该地址。

static linkage意味着您的符号严格是本地翻译单元。这意味着其他translation units将无法看到该符号。因此,具有静态链接的符号可以在不同的翻译单元中多次出现,并且它们不会相互冲突,因为它们是本地的。

Edit:通常,编译器从翻译单元生成的文件特定于该特定编译器。对于Linux 上的gcc,通常使用ELF 对象格式。您可以使用查看其符号表readelf -sW <file>.o(下面是简单的测试文件):

test.c

void bar(void);

static int foo(void) {
    return 1;
}

int main(void) {
    bar();
    return foo();
}

这是 readelf 的输出:

Symbol table '.symtab' contains 10 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS test.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1
     3: 00000000     0 SECTION LOCAL  DEFAULT    3
     4: 00000000     0 SECTION LOCAL  DEFAULT    4
     5: 00000000    10 FUNC    LOCAL  DEFAULT    1 foo
     6: 00000000     0 SECTION LOCAL  DEFAULT    6
     7: 00000000     0 SECTION LOCAL  DEFAULT    5
     8: 0000000a    36 FUNC    GLOBAL DEFAULT    1 main
     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND bar

您会看到 main 函数和一个由 main 调用的静态 foo 函数。还有一个名为的函数未在文件中定义,但在另一个目标文件中定义。由于目标文件尚未最终链接,因此函数尚未分配最终地址。在最终链接之后,这些将被安排到可执行文件中并分配地址。目标文件具有调用尚未定义的函数的条目,因此当链接文件时,这些调用指令可以存储最终地址(readelf -r <file>.o):

Relocation section '.rel.text' at offset 0x308 contains 1 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0000001c  00000902 R_386_PC32        00000000   bar
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 main() 在 C 中不能声明为静态? 的相关文章

  • 没有强命名的代码签名是否会让您的应用程序容易被滥用?

    尝试了解authenticode代码签名和强命名 我是否正确地认为 如果我对引用一些 dll 非强命名 的 exe 进行代码签名 恶意用户就可以替换我的 DLL 并以看似由我签名但正在运行的方式分发应用程序他们的代码 假设这是真的 那么您似
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现

随机推荐

  • 从 Django DetailView 分页

    给定一个 models py class Partner models Model fields irrelevant to this example class Lecture models Model other fields not
  • vagrant:无法在 Linux 来宾中挂载文件夹,“vboxsf”文件系统不可用?

    I have 虚拟盒4 3 10 and 流浪者1 4 3安装在我的乌班图14 0464 位桌面 此前 曾与vagrant技术 但这一次 多重问题 让我描述一下我所做的事情 将私有git克隆到本地系统 opt lampp htdocs 项目
  • 如何在android中使用UDP套接字?

    我正在尝试在 android 中使用 UDP 套接字 在这里我从 android 模拟器发送字符串并通过 PC 上的 Java 程序接收该字符串 但我的 Java 程序没有收到任何内容 尽管当我使用 Java 程序作为客户端和服务器时 我制
  • 使用 Doctrine2 和 Symfony2 删除表

    如何使用 Doctrine2 和 Symfony2 删除表 我已经生成了实体并更新了架构 现在我想删除此结构 不确定我是否正确理解你的问题 您删除了一个实体并想从数据库中删除其生成的表 如果是这样 你不能这样做 因为 Doctrine2 只
  • bind_param() 的作用是什么?

    resultSpendStmt connection gt prepare array gt bind param sdidi A B C D E array gt execute array gt store result array g
  • 如何检查和设置 max_allowed_pa​​cket mysql 变量[重复]

    这个问题在这里已经有答案了 可能的重复 MySQL 错误 1153 收到的数据包大于 max allowed pa cket 字节 您好 我收到错误 1153 Got a packet bigger than max allowed pac
  • Java JDK 11 打破旧的罐子/程序

    据我了解 Java JRE是向后兼容的 如果你用Java JDK 7编写程序 它将与Java JRE 8一起运行 我有几个用 Java 8 开发的程序 并且有我完成它们后构建的 jar 和 EXE 文件 它们总是运行良好 但是 安装 Jav
  • 严重高估 Reserve() 是否有负面影响?

    假设我们有一个创建和使用可能非常大的方法vector
  • Scala 列表串联,::: 与 ++

    有什么区别吗 and 在 Scala 中连接列表 scala gt List 1 2 3 List 4 5 res0 List Int List 1 2 3 4 5 scala gt List 1 2 3 List 4 5 res1 Lis
  • Swift iOS 模块未部署到预期的调试目录

    我有一个用 Swift 编写的模块 框架 打算在 iOS 上使用 当我尝试将框架包含在我的应用程序中时 我首先注意到构建阶段有一些红色的 未找到 提示 但是 该项目builds很好 找到了目标依赖项 因此不存在编译问题 这只是生成的框架 果
  • 有没有办法在 API 25 中引入的 Google 官方 BottomNavigationView 菜单项上显示通知徽章?

    我已经试了BottomNavigationView在 API 25 中发布 我想在底部导航栏中的菜单项之一上显示一个通知徽章 例如一个带有或不带有计数的蓝色小圆圈 我有一个选择器可绘制对象 其中添加了选中的 true 和选中的 false
  • 如何使用 pyspark 更新结构体嵌套列中的值

    我尝试做非常简单的事情 更新嵌套列的值 但是 我不知道如何 环境 阿帕奇火花2 4 5 数据块 6 4 Python 3 7 dataDF Jon Smith 1580 01 06 M 3000 schema StructType Stru
  • 如何在 DataFrame 上将“style”与“to_html”类结合使用?

    我有一个像这样的数据框 df pd DataFrame np random randn 10 reshape 2 5 df 0 1 2 3 4 0 0 067162 0 505401 0 019208 1 123936 0 087682 1
  • android中SDK和NDK的区别

    两年来我一直担任 Android 应用程序开发人员 我通常使用 android SDK 进行所有 Android 应用程序开发 现在我有一个 Android 应用程序项目 其中我必须使用 SDK 和 NDK 进行应用程序开发 根据客户要求
  • 使用 jquery-ui 自动完成功能与多个输入字段

    大家下午好 我花了很多时间 阅读了 stackoverflow 上的所有帖子 但我无法使用 multilpe 输入字段进行自动完成 我尝试为每个输入添加一个 autoc 类 我为每个字段使用不同的 id 实际上是 php 循环生成字段的 i
  • 创建接受文件(流)的 Web 服务不需要其他参数

    我有一个文件想要上传到 Web 服务 但它需要额外的参数 因此我创建了一些带有关联名称 值对的隐藏字段以推送到服务器请求 但问题在于服务的定义 Error 合约 IFormServices 中的操作 NewImage 具有多个请求正文参数
  • Puppeteer Chrome 由自动化测试软件控制

    我尝试了很多关于这个问题的答案 其中一些已被弃用 我想删除 Puppeteer Chrome 正在由自动化测试软件控制 建议 我的配置是 const args no sandbox enable logging disable infoba
  • 如何消除 angular-cli 站点中的渲染阻塞?

    跑步后ng build prod我可以进入我的index html在新创建的 dist 文件夹中添加文件async属性到捆绑的脚本标签以防止它们被阻塞 这有助于提高网站速度 但偶尔会导致网站崩溃 中有一个选项吗angular cli jso
  • 小部件中的 jQuery

    我想在 JS 库上使用 jQuery 该库可以添加到随机网站 这些网站可能已经使用也可能尚未使用 jQuery 我实际上有3个问题 我可能会从我自己的 js 脚本 而不是从文档头中的脚本标记 动态加载 jQuery jquery会这样工作吗
  • 为什么 main() 在 C 中不能声明为静态?

    为什么必须将 main 声明为具有外部链接 为什么它不应该是静态的 外部链接是什么意思 因为您将启动文件链接到您的程序 其中 通常 包含调用 main c 文件的汇编代码 如果 main 是静态的 则该代码将无法调用 main extern