首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么clang要从声明为'extern "C"‘的函数中删除下划线?

clang是一个开源的C语言编译器,它被设计用于兼容标准的C和C++代码的编译。在C++中,为了兼容C语言的函数命名规则,可以使用extern "C"来声明一个C语言的函数接口。这样做可以使C++编译器按照C语言的规则进行函数名的解析和链接。

在一些编译环境中,C语言的函数名会在函数名前面添加一个下划线,而C++函数名不会添加下划线。然而,由于历史原因和不同编译器的实现差异,一些编译环境中会为extern "C"声明的函数在函数名前面添加两个下划线。

为了解决这个问题,clang编译器默认情况下会从声明为extern "C"的函数中删除下划线。这样做的目的是为了保持和其他编译器的兼容性,以及提供更一致的行为。

删除下划线的操作是由clang编译器内部的命名修饰器(name mangler)完成的。通过删除下划线,extern "C"声明的函数可以在C++代码中以一致的方式调用和链接,而不会受到特定编译环境的影响。

总结来说,clang删除从声明为extern "C"的函数中删除下划线是为了保持和其他编译器的兼容性,提供一致的行为,并使extern "C"声明的函数可以在C++代码中以一致的方式调用和链接。

关于腾讯云相关产品,由于答案要求不提及具体品牌商,无法给出腾讯云相关产品的介绍链接地址。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

深入iOS系统底层之程序汇编代码

一个汇编语言文件还可以使用和C语言类似的文件引入以及各种预编译指令,还可以引用高级语言中定义变量和符号以及函数。 1.注释 汇编指令中注释和C/C++/OC相同。...高级语言文件定义能被外部访问函数和全局变量其实都是一个符号,不管是函数地址还是全局变量内存地址,其实都是一个地址位置,而地址别名则是可以用标签表示,因此要想将一个标签定义为外部可访问,就需要将标签名声明为符号....private_extern 私有外部符号名 私有外部符号名: 符号名要和标签名匹配。因为C语言函数名称以及全局变量等符号在编译时生成符号前面添加一个下划线_。...这里面p2align貌似和align所表达意义相似,不知道为什么会有两个关键字。 .align 3 .p2align 3 5.宏定义 汇编语言也可以和C语言一样使用宏定义,来做一些代码复用处理。...所以当你在其他文件要想使用汇编语言中定义函数或者全局变量时,可以在你源代码文件顶部进行符号使用声明: //xxxxx.m //函数声明 extern void 不带下划线函数符号(参数列表

1.7K30
  • 弱符号__attribute__((weak))

    弱符号: 若两个或两个以上全局符号(函数或变量名)名字一样,而其中之一明为weak symbol(弱符号),则这些全局符号不会引发重定义错误。...链接器会忽略弱符号,去使用普通全局符号来解析所有对这些符号引用,但当普通全局符号不可用时,链接器会使用弱符号。当有函数或变量名可能被用户覆盖时,该函数或变量名可以声明为一个弱符号。...attribute((weak))作用 情况是这样,碰到一个棘手问题:我们不确定外部模块是否提供一个函数func,但是我们不得不用这个函数,即自己模块代码必须用到func函数extern int...在自己模块定义: int __attribute__((weak)) func(......) { return 0; } 将本模块func转成弱符号类型,如果遇到强符号类型(即外部模块定义了...main.c #include extern void real_func(); void main() { real_func(); } 如果 gcc main.c

    6.4K30

    C语言数据类型

    除库函数函数名由系统定义外,其余都由用户自定义。 C规定,标识符只能是字母(A~Z,a~z)、数字(0~9)、下划线(_)组成字符串,并且其第一个字符必须是字母或下划线。...例如在某版本C 规定标识符前八位有效,当两个标识符前八位相同时,则被认为是同一个标识符。   (2)在标识符,大小写是有区别的。例如CLANGClang 是两个不同标识符。   ...数据类型和关键字 在程序世界,承载一系列信息数字和字符都属于数据类型,但计算机需要一种方法来区别和使用这些不同类型。具体C通过识别一些基本数据类型做到这些。...关键字 在c语言中,为了定义变量、表达语句功能和对一些文件进行预处理,还必须用到一些具有特殊意义字符,这就是关键字,我们用户自己定义变量函数名等要注意不可以与关键字同名。...C语言中32个关键字 auto double int struct break else long switch case enum register typedef char extern return

    2.5K50

    module & Swift库

    export A表示将B.h导入A.h头文件重新导出 通过clang命令,开启module并将use.c编译成目标文件clang -fmodules -fmodule-map-file=module.modulemap...,外界如何使⽤Swiftpublic修饰类和函数?...OC编译器,当前就是clang 加载modulemap文件路径 对应Build Setting配置项 打开ViewController.m,写入以下代码: #import "ViewController.h...NS_REFINED_FOR_SWIFT:通过指定NS_REFINED_FOR_SWIFT宏,SwiftClang Importer将做一些额外工作,将该方法导入为私有方法,并以双下划线字符__开头...命令,合并静态库本身 用到头文件、Swift头文件以及modulemap文件,通过目录形式放到一起 OC要用合并静态库:clang: other c flags:-fmodule-map-file

    2.1K45

    C#调用GDI+1.1函数实现高斯模糊、USM锐化等经典效果。

    其实,这些函数我在VB6下两年前就已经调用过,调用方式也很简单明了,现在,在学习C#,就要考虑如何将他们封装入C#。...实现这个功能第一步就是要找到这些函数声明,这个在MSDN上有C风格声明,改成C#语言大部分都不成问题,参考 http://msdn.microsoft.com/en-us/library/ms533971...C#Bitmap类,或者你也可以声明为HandleRef类型,VS就是这么干, 对于最后几个参数,是用来给用户返回一些数据,基本上不会有人对那几个数据感兴趣,因此你不声明为out类型参数也无所谓...问题来了,第一个参数bitmap本意是GDI+image对象句柄,在C#,有Bitmap类,实际上我们知道他就是GDI+封装,那么他具体实例中肯定也对应了一个GDI+对象句柄,但是他封装太厉害了...要从其中获取字段值对象 /// 字段名称.

    1.8K40

    从Xcode10不再支持libstdc++说起

    目前比较流行C++编译器有微软VC++,GNU组织gcc(g++), 苹果LLVM(clang++)等。...你可以从这个类查看一个C++类名称,数据成员和函数布局信息,type_info信息就类似于OCisa所指向Class类型是一样。...Xcode对C++支持和设置 Xcode建立工程项目可以选择使用C++方言和C++标准库版本,在工程Build SettingsApple Clang - Language - C++...为什么可以在一个工程可以同时引入两个定义了相同内容类库呢?难道不会在编译时报符号冲突或者重名错误吗?...我们知道libc++内容是libstdc++超集,为什么在同时引入两个库时不会报函数或者类名冲突呢? 答案就是C++11提供了对inline namespace支持。

    2.1K30

    【计算机本科补全计划】C++ Primer 第二章 【变量和基本类型】

    for (unsigned i = 10; i >=0; --i) { cout<<i<<endl; } 在上面的函数,你永远也到不了-1,因为无符号数本身定义中就没有-1,0-1结果是当前位数最大值...如果是定义于函数体外变量会默认初始化为0,而函数体内内置函数变量不被初始化,即未定义初始化值。 当然,对于类,如果在类定义中有初始化值,就不需要函数体来操心了。...如果声明一个变量而不是定义,那么加一个关键字externextern int j; // 声明j而不是定义,还没有分配内存空间。...6、 标识符 C++标识符由字母,数字,下划线构成,并且标识符开头只能是字母或者下划线而不能是数字。并且标识符对大小写敏感。 书上有说两个要求,但是我实际跑时候没报错,也许是我自动更正了?...如下(毫无压力): 不能连续出现两个下划线 ; 不能以 下划线紧接着大写字母开头; 函数体外标识符不能以下划线开头。

    704110

    99%开发者从未听说过堆栈模型(加量增强版)

    在中文嵌入式环境,时不时总能看到不少朋友”堆”“栈“傻傻分不清楚,我很早之前在文章《漫谈C变量——夏虫不可语冰》介绍过二者区别,这里就不再深入展开,总之: 栈(Stack)“是我们用来分配局部变量...、实现函数调用和在异常响应时保存被打断代码上下文地方——具体细节不重要,在本文讨论,我们只需要记住以下信息: Cortex-M系统栈生长方向是自上而下,也就是随着更多内容被压入(PUSH)栈...“堆(Heap)”是我们使用 malloc 申请动态存储空间时所必须用到一种数据结构——通常由C语言系统库提供。...——Heap尺寸应该就是使用整个 RAM终止地址减去 RW_IRAM1 终止地址啊,为什么提示差4个字节呢?...__) # pragma clang diagnostic pop #endif 【后记】 ---- 在这篇文章,我们介绍了栈和堆在存储器常见排布模型,比较了它们优劣,并提出了一种被称为“两面包夹芝士

    1.9K30

    C++调用C函数

    前言:以前见到extern "C"这样语句,只是简单地知道跟外部链接有关,但是没有深刻理解它意思。 首先,为什么要使用extern "C"修饰符?...C++调用其它语言函数,由于编译器生成函数机制不一样,所以需要经过特殊处理,才可以调用。调用C语言函数,需要在函数声明地方语句extern "C"。...刚开始,我简单地在C++源文件前面使用该语句声明,但是还是出错,而且是在编译阶段就报错。 error C2732: 链接规范与“DeleteStack”早期规范冲突。 为什么会出现这个错误呢?...因为C++源文件已经引入了C头文件,在头文件里,声明该函数时没有extern修饰,而这里有extern修饰,所以冲突了。解决办法有两个。 一。在C头文件中加上extern修饰符。 直接加,也不行。...以上为单个形式,复合形式可以同时将几个函数明为extern "C" extern "C" { void DeleteStack(Stack stack); void PrintStack(Stack

    2.8K40

    实例说明

    那么,为什么C语言没有内置输入输出语句呢? 一个答案是并非所有的程序都要用到I/O(输入/输出)包,并且C语言一个基本设计原则就是避免不必要成分。...每个C程序必须有它! 那么圆括号功能呢?它表明main()是一个函数。以后,我们将遇到更多函数。现在,请记住这个函数就是C程序基本模块。 int指明main()函数返回类型。...把一个变量声明为整数类型或字符类型是计算机正确地存储,获取和解释该数据基本前提。在后面您将学到各种各样可用类型。...第一个字符必须是字母或者下划线C语言名字是区分大小写,即把一个大写字母和与之对应小写字母看作是不同。因此,clang不同于Clang或者CLANG。 六....; printf ("I am clang.cc\n"); printf ("My birthday is %d\n", num); 所有这些行都使用了 C语言一个标准函数:printf()。

    1.4K80

    利用Clang探究__block本质

    那么问题来了,为什么被__block说明符修饰变量就可以在block函数体内部访问呢?__block底层究竟对被修饰变量做了什么呢?__block是如何将“外部变量”从栈中转移到堆?...源码分析 和上一篇文章一样,我们还是在main.m文件定义一个main函数,并使用clang对这个main函数进行rewrite,使其转换为C++源码,通过C++源码窥探__block底层实现。...答案在构造函数第一个参数,构造函数第一个参数是__main_block_func_0,上面我们说过,__main_block_func_0是一个函数,而上篇文章也说过,CC++语言中函数名就是函数指针...分析下来,不难发现,以上main函数C++层面的执行过程和利用Clang探究block本质中所述简直一模一样。...在一个文件内定义全局变量,在另一个文件,通过extern声明全局变量,就可以使用全局变量;static修饰全局静态变量,作用域是声明此变量所在文件。

    7.3K20

    iOS 启动优化--二进制重排

    --> Order File设置自定义.order后缀文件路径,将需要重排符号按顺序写在里面,当Xcode编译时会按照.order文件符号顺序加载,我们可以通过下面几种方法获得APP启动时运行函数...HOOK objc_msgSend:由于objc_msgSend参数是可变,需要汇编获取,而且只能获取到OC方法和Swift@objc方法 静态扫描:扫描 Mach-O文件 特定段和节里面所存储符号以及函数数据...Clang插桩:批量100%符号获取,OC、Swift、C都可以获取 Clang插桩 通过LLVM内置工具SanitizerCoverage,可以在函数级、基本快级和边缘插入到用户定义函数调用,...官方文档clang 自带代码覆盖工具 中有使用简介和demo 【第一步】 开启SanitizerCoverage oc项目中,Build Settings --> Other C Flags 添加-...)); } 【第三步】 获取所有符号并写入文件保存 循环取出所有符号 数组取反,因为是入队存储是反序 数组去重 符号保存到yp.order文件 extern void getOrderFile(void

    1.3K60

    C++调用C链接库会出现问题

    add@@YAHHH@Z[/email]),原因是找不到add目标模块 这才令我想起C++重载函数命名方式和C函数命名方式,让我们回顾一下:C函数编译后命名会在函数名前加以"_",比如add函数编译成...obj文件时实际命名为_add,而c++命名则不同,为了实现函数重载同样函数名add因参数不同会被编译成不同名字 例如 int add(int , int)==>add@@YAHHH@Z, float...编译cpp.cpp编译器在cpp文件中发现add(1, 0);调用而函数明为extern int add(int x, int y);编译器就决定去找[email=add@@YAHHH@Z]add...add(int, int);}编译器就会知道 add(1, 0);调用C风格函数,就会知道去c.obj找_add(int, int)而不是[email=add@@YAHHH@Z]add@@YAHHH...@Z[/email]; 这也就为什么DLL中常看见extern "C" {},windows是采用C语言编制他首先要考虑到C可以正确调用这些DLL,而用户可能会使用C++而extern "C" {}就会发生作用

    1.1K30

    BPF可移植性和CO-RE (Compile Once – Run Everywhere)

    首先会调研BPF本身可移植性问题,描述为什么这是个问题,以及为什么解决它很重要。然后,我们将介绍解决方案高级组件:BPF CO-RE,并简要介绍实现这一目标所需要解决难题。...不同内核版本会在结构体内部混用结构体字段,甚至会转移到新内部结构体。结构体字段可能会被重命名或删除,类型可能会改变(变为微兼容或完全不同类型)。...使用BCC,可以将BPF程序C代码以字符串形式嵌入到用户空间程序,当程序最终部署并运行在目标主机上后,BCC会唤醒其嵌入Clang/LLVM,提取本地内核头文件(必须确保已从正确kernel-devel...BTF是一种节省空间,紧凑但仍具有足够表达能力格式,可以描述C程序所有类型信息。由于其简单性和使用重复数据删除算法,与DWARF相比,BTF大小可减少多达100倍。...类型名称三个下划线以及其后所有内容均被视为此结构“flavor”。

    1.3K20

    c++代码整洁之道

    整洁代码在团队无疑是很受欢迎,可以高效被其它成员理解和维护,本文参考《C++代码整洁之道》和《Google C++编码规范》,结合自己一些想法整理如下: C++本身作为面向对象语言,首先介绍下面向对象一般涉及到开发原则...良好命名 无论是什么语言,函数和变量良好命名都是很有必要,通过函数名字我们就可以知道这个函数里代码作用,而不是通过写注释,个人一直倾向于用代码自解释。...变量命名 不要将变量类型在名字中体现,这样以后变量类型改变的话还需要去改动变量名,充分利用IDE功能,变量 (包括函数参数) 和数据成员名一律小写, 单词之间用下划线连接....pool_; // 好. int i_table; // 不好,不要将变量类型在名字中体现 }; 常量命名 声明为 constexpr 或 const 变量, 或在程序运行期间其值始终保持不变,...C++主流技术 可以考虑更多使用异常处理方式,而不是C语言风格errno错误码等,这里可以参考你c++团队还在禁用异常处理吗?

    1.1K10
    领券