当前位置: 首页 > news >正文

【C++】extern

本文介绍一些externC++中的用法

声明与定义分离

C++程序员应该都知道单一定义规则ODR

在任何一个翻译单元中,只允许存在任何变量、函数、类类型、枚举类型 、概念 (自 C++20 起) 或模板的一个定义(其中一些可能具有多个声明,但只允许一个定义)。 在整个程序(包括任何标准库和用户定义的库)中,需要出现每个非 内联 函数或变量的一个且仅一个定义,这些函数或变量是 odr-使用 的(见下文)。 编译器不要求诊断此违规行为,但违反它的程序的行为是未定义的。

具体来说,如果在头文件中初始化一个变量,在多个源文件包含此头文件,在联合编译时,就会报重定义的错误。

global.h

int global_int = 1;

global1.cc

#include "global.h"

global2.cc

#include "global.h"int main()
{return 0;
}

使用以下命令,联合编译多个文件:

g++ global1.cc global2.cc -o main

结果编译报错:

/tmp/cc4Y38ub.o:(.data+0x0): global_int 的多重定义
/tmp/ccSwS0de.o:(.data+0x0):第一次在此定义
collect2: 错误:ld 返回 1

正确的做法是在头文件中使用extern声明,在源文件中定义。

global.h

extern int global_int;

globa1.cc

#include "global.h"int global_int = 1;

global2.cc

#include "global.h"
#include <iostream>extern int global_int;int main()
{std::cout << global_int << std::endl;return 0;
}

最后打印的结果为1.

更一般的做法是,在头文件声明外部变量,在对应的源文件初始化。此时在其他的源文件读取或者修改这个变量,达到跨文件全局变量的效果。在单线程场景下,这种做法十分有效。

以C语言的方式编译函数

在 C++ 里,为支持函数重载和类成员函数等特性,编译器会对函数名、类名等进行修饰,让它们在符号表中保持唯一。可以参考我写的这篇文章:【C++】filt工具的使用

比如刚才的代码:

#include <iostream>int get_int()
{return 1;
}int main()
{std::cout << get_int() << std::endl;return 0;
}

编译后对get_int提取名字:

0000000000400806 T _Z7get_intv

C语言是没有这个机制的,因为C语言不支持重载,当我们需要将代码打包为C接口供外部调用时,比如【Python】多线程/进程操作C++代码,就需要去掉这种修饰。

此时可以用extern "C"对函数调用进行包裹。编译器会按C语言的风格编译代码:

#include <iostream>extern "C"
{int get_int(){return 1;}
}int main()
{std::cout << get_int() << std::endl;return 0;
}

此时提取名字:

0000000000400806 T get_int

可以看到,名称修饰已经去掉了。

相关文章:

  • Android Kotlin 项目完整集成 Bugly 异常监控指南
  • RISC-V GPU架构研究进展:在深度学习推理场景的可行性验证
  • 数字智慧方案6172丨智慧医院扩建信息化整体规划方案(60页PPT)(文末有下载方式)
  • Mysql常用函数解析
  • 五下单元习作:《智慧的力量》——读《草船借箭》有感
  • Java 期中考试试题考点剖析
  • CSS响应式与自适应设计
  • PMP-第三章 项目经理的角色
  • zephyr架构下扫描和解析Beacon数据
  • 安川机器人常见故障报警及解决办法
  • react有哪些生命周期
  • 基于开源AI智能名片链动2+1模式S2B2C商城小程序的IP开发泡沫破局与价值重构研究
  • Spring 提供了多种依赖注入的方式
  • 短视频矩阵系统:源码搭建与定制化开发的深度剖析
  • 怪物猎人:世界-冰原10000+mod整合包5月最新更新!
  • 【c++】【STL】stack详解
  • 游戏引擎学习第253天:重新启用更多调试界面
  • 高并发场景下的MySQL生存指南
  • MERGE存储引擎(介绍,操作),FEDERATED存储引擎(介绍,操作),不同存储引擎的特性图
  • Qt进阶开发:QSS常用的语法介绍和使用
  • 三家“券商系”公募同日变更掌门人,新董事长均为公司股东方老将
  • 国铁集团去年收入12830亿元增3%,全年铁路运输利润总额创新高
  • 内蒙古公开宣判144件毁林毁草刑案,单起非法占用林地逾250亩
  • 迪卡侬回应出售中国业务30%股份传闻:始终扎根中国长期发展
  • 马上评|什么才是地方文旅宣传的正确姿势
  • 体坛联播|欧冠半决赛阿森纳主场不敌巴黎,北京男篮险胜山西