首页IT科技c++exec(【C++】extern "C"详解)

c++exec(【C++】extern "C"详解)

时间2025-07-29 22:22:13分类IT科技浏览4779
导读:先说结论 :...

先说结论 :extern "C"只影响到链接期的name mangling

什么是name mangling?

    请看 :C++函数重载的实现机制之name mangling - 知乎 (zhihu.com)

举个例子 :

// external.cc #include "external.h" template <typename T> // 这明显是C++特性, gcc是无法编译的 void external() { T a; }
// main.c #include "external.h" int main() { external(); }

在这里 : main函数里面调用了c++函数external(), 如果这个函数没被 extern "C"包裹, 会出现"undefined reference to"的错误.

这是因为g++               、clang++都优先判断后缀名 ( 除非自己改option ), 就会对external.cc文件进行C++方式编译 :

  由于c++重载机制的存在, 编译器只能在你命名之后 再悄悄重新给函数做个标记, 这个标记名也是有规则的, 比如g++, [ _Z + 函数名长度 + v / i ...标记符 ] .

  external()函数被compiler赋予一个"符号", 如果是gcc, 这个符号就是external;

                     如果是g++, 这个符号是_Z8externalv或者_Z8externali;

                   而clang++更夸张, 变成了"?external@@YAHXZ"或者"?external@@YAHH@Z"这种怪物.

然后把obj文件中定义和引用的global variable和function存到一张"符号表"中方便链接器的工作.

------------------------------------------------------------------------------------------------------------------

名字 | 类型 | 是否可被外部引用 | 区域

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

_Z8externalv | 定义, 引用 | 可 | 代码段

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

_Z8externali | 定义, 引用 | 可 | 代码段

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    main | 定义 | |

-------------------------------------------------------------------------------------------------------------------

  链接器说"我开始找了 ! ", 然后给main函数找external(), 发现没有c版本的, 只有c++版本的呀, 它干不了了,"undefined reference to external".

  如果你把声明extern "C", 链接器才能找到c版本的external(), 加上依赖库/模块 全打包起来. 还是拿gnu来说吧, c程序会打包libgcc.a静态库,c++程序则会打包很多libstdc++.a的东西和一些各式各样的依赖, 这也是一般c++程序大小都要pure c大的原因, 在嵌入式平台这种差距尤为明显.

  人家卡马乔也有话说的 : " 我找的是什么表啊, 你这个表什么都有 我都能找到为什么不能链接? "

  c文件和c++文件直接链接在一起, 链接器应该用libgcc这个链子还是libstdc++呢?它没法去判断啊,只能你骗他一下这是c文件, 用libgcc去链.

所以, 你extern "C"包裹函数的声明, 并不会改变函数体内语句的实际编译方式, 因为它的定义仍在.cc文件里, g++仍会优先将它以c++的方式编译. 但是函数名的确是以c的方式编去了.

声明:本站所有文章              ,如无特殊说明或标注                       ,均为本站原创发布               。任何个人或组织      ,在未征得本站同意时          ,禁止复制                    、盗用        、采集            、发布本站内容到任何网站                    、书籍等各类媒体平台                    。如若本站内容侵犯了原著者的合法权益                        ,可联系我们进行处理        。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
路由器mw300r设置(路由器怎么选择连接模式?选择MW300RM路由器模式的方法) 百度seo排名技术必不可少(百度seo排名规则)