C++中弱符号(弱引用)的意义及实例
今天读别人代码时看到一个“#pragma weak”,一时没明白,上网研究了一个下午终于稍微了解了一点C、C++中的“弱符号”,下面是我的理解,不正确的地方望大家指正。
本文主要从下面三个方面讲“弱符号”:
1. 什么是“弱符号”? 它与“强符号”的区别是什么?
2. 弱符号的有什么作用?
3. 弱符号的实际应用实例
1.什么是弱符号?
在WikiPedia中弱符号的定义是:
a weak symbol is a symbol definition in an object file or dynamic library that may be overridden by other symbol definitions
A weak symbol denotes a specially annotated symbol during linking of Executable and Linkable Format (ELF) object files.
By default, without any annotation, a symbol in an object file is strong.
During linking, a strong symbol can override a weak symbol of the same name.
In contrast, two strong symbols that share a name yield a link error during link-time.
When linking a binary executable, a weakly declared symbol does not need a definition.
In comparison, (by default) a declared strong symbol without a definition triggers an undefined symbol link error.
Weak symbols are not mentioned by C or C++ language standards; as such, inserting them into code is not very portable.
Even if two platforms support the same or similar syntax for marking symbols as weak,
the semantics may differ in subtle points, e.g. whether weak symbols during dynamic linking at runtime lose their semantics or not
从第一个定义可以知道,“弱符号“是在一个文件或者动态库中定义的,可以被其他地方定义的符号overridden的符号。这里重点是“overridden”
从第二个定义,我们可以知道“弱符号”跟强符号主要有如下区别:
1. 弱符号可以只有申明,没有定义,强符号必须有定义
2. 弱符号可以定义多次,强符号只能定义。
另外第二个定义中还提到,弱符号并不是C、C++规范中的内容,这个跟编译器相关,不可移植。
在中文的很多文章中把weak symbol分为了两种“弱符号”(变量)“弱引用”(函数),但WikiPedia中弱符号的例子都是用的函数。
2.弱符号的作用
我的理解“弱符号变量“是C中遗留下来的,它除了引起麻烦,没有什么作用。C语言中凡是没有初始化的全局变量都是弱符号变量,如果存在多个同名的弱符号变量,编译器在链接时可以任意选一个(有的编译器选择占用空间最大的那个定义)。这样,你的代码中定义了一个x,忘了初始化,而你用到的某个库中又刚好定义了一个未初始化的x,后果大家可以自己想。C++中不会出现这个问题,因为C++中所有未初始化的全局变量都初始化为0。
弱符号函数的主要作用是为了多态,即使用定义中的”overridden“,一般在库中使用得比较多,比如你在你的库中为某个函数提供一个默认实现,用户如果想定制化的话可以自己实现一个。
例子:在library_foo.h中什么函数foo为弱符号函数,library_foo.cc中为foo提供一个默认实现,在my_foo.cc中为foo提供一个定制化的实现。
注:定义一个函数为弱函数有两种方式
1. 使用“#pragma week function”
2. 函数后面加“ __attribute__((weak))”,
我用的gcc好像不支持第一种方式。
//library_foo.h #ifndef __LIBRARY_FOO_H__
#define __LIBRARY_FOO_H__ void foo() __attribute__((weak));
void f(); #endif
//library_foo.cc #include <iostream>
#include "library_foo.h" void foo(){
std::cout<<"default foo"<<std::endl;
} void f(){
foo();
}
//main.cc #include <iostream>
#include "library_foo.h" using namespace std; int main(int argc, char* argv[]){
f();
}
//my_foo.cc
#include <iostream>
void foo(){
std::cout<<"My customized foo"<<std::endl;
}
编译及运行结果如下:
> g++ library_foo.cc main.cc my_foo.cc -o customized.x
> g++ library_foo.cc main.cc -o not_customized.x
> ./customized.x
my customized foo
> ./not_customized.x
default foo
可以看到,当链接my_foo.cc是,使用的是定制的foo.
3. 弱符号的实际应用实例
在C++库中,如下函数都是弱符号函数
void *operator new(std::size_t);
void *operator new(std::size_t, std::nothrow_t const &) noexcept;
void *operator new[](std::size_t);
void *operator new[](std::size_t, const std::nothrow_t&) noexcept;
void operator delete(void *) noexcept;
void operator delete(void *, std::nothrow_t const &) noexcept;
void operator delete[](void *) noexcept;
void operator delete[](void *, std::nothrow_t const &) noexcept;
C++中弱符号(弱引用)的意义及实例的更多相关文章
- C语言中的弱符号(weak)用法及实例
一 符号概念: 在C语言中,有强符号和弱符号,符号简单来说就是函数.变量的名字,对于全局(非局部.非static)的函数和变量,能不能重名是有一定规矩的,强.弱符号就是针对这些全局函数和变量来说的. ...
- 嵌入式C语言自我修养 09:链接过程中的强符号和弱符号
9.1 属性声明:weak GNU C 通过 __atttribute__ 声明weak属性,可以将一个强符号转换为弱符号. 使用方法如下. void __attribute__((weak)) fu ...
- 关于C语言中的强符号、弱符号、强引用和弱引用的一些陋见,欢迎指正
首先我表示很悲剧,在看<程序员的自我修养--链接.装载与库>之前我竟不知道C有强符号.弱符号.强引用和弱引用.在看到3.5.5节弱符号和强符号时,我感觉有些困惑,所以写下此篇,希望能和同样 ...
- 浅谈C语言中的强符号、弱符号、强引用和弱引用
摘自http://www.jb51.net/article/56924.htm 浅谈C语言中的强符号.弱符号.强引用和弱引用 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2014- ...
- 浅谈C语言中的强符号、弱符号、强引用和弱引用【转】
转自:http://www.jb51.net/article/56924.htm 首先我表示很悲剧,在看<程序员的自我修养--链接.装载与库>之前我竟不知道C有强符号.弱符号.强引用和弱引 ...
- GCC中的强符号和弱符号及强引用和弱引用
1. 强符号和弱符号 1.1 u-boot和kernel中的__weak指令 u-boot和kernel比较普遍地使用了__weak来定义函数. 在include\linux\compiler-gcc ...
- C语言中的强符号与弱符号
转自:http://blog.csdn.net/astrotycoon/article/details/8008629 一.概述 在C语言中,函数和初始化的全局变量(包括显示初始化为0)是强符号,未初 ...
- gcc/g++中weak弱符号及alias别名
最近查看linux内核代码时,表现了一些编译器选项如__attribute_((weak)).__attribute__( (alias("target"))),一开始不了解,后来 ...
- GNU C/C++ __attributes__ GCC中的弱符号与强符号
最近在看一些源代码,遇到了一些使用__attribute__修饰函数和变量的属性方面的代码,不是太了解,很是汗颜,再此做个总结: GCC使用__attribute__关键字来描述函数,变量和数据类 ...
随机推荐
- @RenderBody()和@RenderSection()
强大的Razor引擎 一.Razor基础简介 Razor采用了cshtml后缀的文件名,截图如下: A. 版面布局 从图上看到,新的视图引擎已经没有了Site.Master这种MasterPage了, ...
- CleanMyMac 1.10.8
CleanMyMac是一个系统清理工具,删除系统缓存文件 , 多余的应用程序语言包 , PowerPc软件运行库等. 是个给你的硬盘瘦身的好工具 下载地址:http://soft.macx.cn/so ...
- yum 命令提示语法错误
1. 问题信息 SyntaxError: invalid syntax 2. 问题原因 升级python版本导致 3. 解决方法 vi /usr/bin/yum 将#!/usr/bin/python ...
- php笔记08:数据库编程---使用php的MySQL扩展库操作MySQL数据库
1.使用php的MySQL扩展库操作MySQL数据库: php有3种方式操作MySQL数据库 (1)mysql扩展库 (2)mysqli扩展库 (3)pdo mysql扩展库与mysql数据库 ...
- Java ==,equals() 和hashCode
Kruger上课讲到==和equals()方法是不同的,经过查询将具体内容整理一下,在查询过程中发现hashCode()方法与equlas()联系紧密,故一起研究. 比较浅显,以后如果理解更多随时更新 ...
- 简单的实现QQ通信功能(三)
第三部分:登陆界面的设计及代码 一:效果图及界面设计 1. 效果图: 2. 界面设计: (1)仿照QQ的登陆界面,右上角放了三个Label,用来做关闭.最小化和设置,使用了它们的Click事件当做按钮 ...
- 编译inotify报错
错误如下: configure: error: no acceptable C compiler found in $PATH 这是因为没有找到编译器的原因造成的 解决方法: 安装gcc [root@ ...
- 4柱汉诺塔(zz)
多柱汉诺塔可以用Frame–Stewart算法来解决. The Frame–Stewart algorithm, giving a presumably optimal solution for fo ...
- 取caml查询结果的前多少行
取查询结果的前多少行的方法?spQuery.RowLimit = 1; SPList list = SPContext.Current.Web.Lists[ListNames. ...
- Ext.Net学习笔记09:Ext.Net Store的用法
使用Handler处理分页 首先来创建一般处理程序,我命名为StoreHandler.ashx,然后它的处理过程代码如下: public void ProcessRequest(HttpContext ...