C++:翻译单元和链接

本文介绍了C++程序中的翻译单元和链接过程。翻译单元由实现文件及包含的头文件组成,每个单元单独编译后由链接器合并为程序。ODR规则规定同一名称只能定义一次。全局变量和自由函数默认具有外部链接,可在所有翻译单元中可见。通过`static`关键字可声明内部链接,限制对象的可见性。常量、constexpr对象、typedefs和命名空间内的静态对象默认具有内部链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++:翻译单元和链接

简介

在 c + + 程序中, 符号(例如变量或函数名)可以在其作用域内任意多次声明,但只能定义一次。 此规则是 (ODR) 的 “一个定义规则”。 声明 会引入 (或重新引入程序) 名称。 定义 会引入一个名称。 如果名称表示一个变量,则定义会对其进行显式初始化。 函数定义 包括签名和函数体。 类定义包含类名,后跟一个列出所有类成员的块。 (可以选择在另一个文件中单独定义成员函数的主体。 )
下面的示例演示了一些声明:

int i;
int f(int x);
class C;

下面的示例演示了一些定义:

int i{42};
int f(int x){ return x * i; }
class C {
public:
   void DoSomething();
};

程序由一个或多个 翻译单元 组成。 翻译单元由实现文件以及它直接或间接包含的所有标头组成。 实现文件通常具有 cpp 或 .cxx 的文件扩展名。 标头文件通常具有 h 或 hpp 扩展名。 每个翻译单元都是由编译器单独编译的。 编译完成后,链接器会将编译的翻译单元合并到一个 程序 中。 ODR 规则的冲突通常显示为链接器错误。 当同一名称在不同的翻译单元中具有两个不同的定义时,将发生链接器错误。

通常,使变量在多个文件中可见的最佳方式是将其放在标头文件中。 然后在每个需要声明的 cpp 文件中添加 #include 指令。 通过在标头内容周围添加 include 防护 ,可以确保它声明的名称只定义一次。

在 c + + 20 中, 模块 被引入为标头文件的改进替代方法。

在某些情况下,可能需要在 cpp 文件中声明全局变量或类。 在这些情况下,您需要一种方法来告诉编译器和链接器名称的 链接 类型。 链接类型指定对象的名称是仅适用于一个文件,还是应用于所有文件。 链接的概念仅适用于全局名称。 链接的概念不适用于在范围内声明的名称。 范围由一组封闭大括号(如在函数或类定义中)指定。

外部和内部链接

Free 函数 是在全局或命名空间范围中定义的函数。 非常量的全局变量和 free 函数默认情况下具有 外部链接;它们在程序的任何翻译单元中可见。 因此,其他全局对象不能具有该名称。 带有 内部链接 的符号或 没有链接 的符号仅在声明它的翻译单元中可见。 如果名称具有内部链接,则同一名称可能存在于另一个翻译单元中。 在类定义或函数体中声明的变量没有链接。

您可以通过将全局名称显式声明为来强制使用内部链接 static 。 这会将其可见性限制在声明它的同一转换单元中。 在这 static 种情况下,表示应用于局部变量的方式不同。

默认情况下,下列对象具有内部链接:

const 对象
constexpr 对象
typedefs
命名空间范围内的静态对象
若要为常量对象外部链接,请将其声明为, extern 并为其赋值:

extern const int value = 42;

该博文为原创文章,未经博主同意不得转载,如同意转载请注明博文出处
本文章博客地址:https://blog.youkuaiyun.com/it_cplusplus/article/details/118107489

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值