C/C++编程:翻译单元和链接

1059 篇文章 286 订阅

翻译单元

在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()
  • 内部链接/无链接:只能在声明它的翻译单元可见
    • 如果名称具有内部链接,则同一名称可能存在另一个翻译单元中
    • 在类定义或者函数体中声明的变量没有链接

可以通过将全局名称显示声明为static来强制要求使用内部链接。

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

  • const对象
  • constexpr对象
  • typedefs
  • 命名空间范围内的静态对象

如果要为常量对象外部链接,请将其声明为extern并为其赋值:

extern const int value = 42;
  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值