前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >校长讲堂第八讲

校长讲堂第八讲

作者头像
一头小山猪
发布2020-04-10 10:13:01
2310
发布2020-04-10 10:13:01
举报
文章被收录于专栏:微光点亮星辰微光点亮星辰

C语言的连接

一个 C 程序可能有很多部分组成,它们被分别编译,并由一个通常称为链接器、链接编辑器或加载器的程序绑定到一起。由于编译器一次通常只能看到一个文件,因此它无法检测到需要程序的多个源文件的内容才能发现的错误。 在这一节中,我们将看到一些这种类型的错误。有一些 C 实现,但不是所有的,带有一个称为 lint的程序来捕获这些错误。如果具有一个这样的程序,那么无论怎样地强调它的重要性都不过分。

4.1 检查外部类型

假设你有一个 C 程序,被划分为两个文件。其中一个包含如下声明:

int n;

而令一个包含如下声明:

long n;

这不是一个有效的 C 程序,因为一些外部名称在两个文件中被声明为不同的类型。然而,很多实现检测不到这个错误,因为编译器在编译其中一个文件时并不知道另一个文件的内容。因此,检查类型的工作只能由链接器(或一些工具程序例如lint)来完成;如果操作系统的链接器不能识别数据类型,C 编译器也没法过多地强制它。

那么,这个程序运行时实际会发生什么?这有很多可能性:

1. 实现足够聪明,能够检测到类型冲突。则我们会得到一个诊断消息,说明 n 在两个文件中具有不同的类型。

2. 你所使用的实现将 int 和 long 视为相同的类型。 典型的情况是机器可以自然地进行 32 位运算。

在这种情况下你的程序或许能够工作,好像你两次都将变量声明为 long(或 int)。但这种程序的工作纯属偶然。

3. n 的两个实例需要不同的存储,它们以某种方式共享存储区,即对其中一个的赋值对另一个也有效。这可能发生,例如,编译器可以将 int 安排在 long 的低位。不论这是基于系统的还是基于机器的,这种程序的运行同样是偶然。

4. n 的两个实例以另一种方式共享存储区,即对其中一个赋值的效果是对另一个赋以不同的值。在这种情况下,程序可能失败。

这种情况发生的里一个例子出奇地频繁。程序的某一个文件包含下面的声明:

char filename[] = "etc/passwd";

而另一个文件包含这样的声明:

char *filename;

尽管在某些环境中数组和指针的行为非常相似,但它们是不同的。在第一个声明中,filename 是一个字符数组的名字。尽管使用数组的名字可以产生数组第一个元素的指针,但这个指针只有在需要的时候才产生并且不会持续。

在第二个声明中,filename 是一个指针的名字。这个指针可以指向程序员让它指向的任何地方。如果程序员没有给它赋一个值,它将具有一个默认的 0 值(null)[译注:实际上,在 C中一个为初始化的指针通常具有一个随机的值,这是很危险的!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-10-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微光点亮星辰 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C语言的连接
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档