今天读别人代码时看到一个“#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++中弱符号(弱引用)的意义及实例的更多相关文章

  1. C语言中的弱符号(weak)用法及实例

    一 符号概念: 在C语言中,有强符号和弱符号,符号简单来说就是函数.变量的名字,对于全局(非局部.非static)的函数和变量,能不能重名是有一定规矩的,强.弱符号就是针对这些全局函数和变量来说的. ...

  2. 嵌入式C语言自我修养 09:链接过程中的强符号和弱符号

    9.1 属性声明:weak GNU C 通过 __atttribute__ 声明weak属性,可以将一个强符号转换为弱符号. 使用方法如下. void __attribute__((weak)) fu ...

  3. 关于C语言中的强符号、弱符号、强引用和弱引用的一些陋见,欢迎指正

    首先我表示很悲剧,在看<程序员的自我修养--链接.装载与库>之前我竟不知道C有强符号.弱符号.强引用和弱引用.在看到3.5.5节弱符号和强符号时,我感觉有些困惑,所以写下此篇,希望能和同样 ...

  4. 浅谈C语言中的强符号、弱符号、强引用和弱引用

    摘自http://www.jb51.net/article/56924.htm 浅谈C语言中的强符号.弱符号.强引用和弱引用 投稿:hebedich 字体:[增加 减小] 类型:转载 时间:2014- ...

  5. 浅谈C语言中的强符号、弱符号、强引用和弱引用【转】

    转自:http://www.jb51.net/article/56924.htm 首先我表示很悲剧,在看<程序员的自我修养--链接.装载与库>之前我竟不知道C有强符号.弱符号.强引用和弱引 ...

  6. GCC中的强符号和弱符号及强引用和弱引用

    1. 强符号和弱符号 1.1 u-boot和kernel中的__weak指令 u-boot和kernel比较普遍地使用了__weak来定义函数. 在include\linux\compiler-gcc ...

  7. C语言中的强符号与弱符号

    转自:http://blog.csdn.net/astrotycoon/article/details/8008629 一.概述 在C语言中,函数和初始化的全局变量(包括显示初始化为0)是强符号,未初 ...

  8. gcc/g++中weak弱符号及alias别名

    最近查看linux内核代码时,表现了一些编译器选项如__attribute_((weak)).__attribute__( (alias("target"))),一开始不了解,后来 ...

  9. GNU C/C++ __attributes__ GCC中的弱符号与强符号

    最近在看一些源代码,遇到了一些使用__attribute__修饰函数和变量的属性方面的代码,不是太了解,很是汗颜,再此做个总结:   GCC使用__attribute__关键字来描述函数,变量和数据类 ...

随机推荐

  1. Android中滑屏初探 ---- scrollTo 以及 scrollBy方法使用说明

    今天给大家介绍下Android中滑屏功能的一个基本实现过程以及原理初探,最后给大家重点讲解View视图中scrollTo 与 scrollBy这两个函数的区别 . 首先 ,我们必须明白在Android ...

  2. cocos2dx jsb 在IOS与安卓下的一些不同之处

    cocos2dx版本 2.1.4 1:字体大小 cocosbuilder publish后应该注意IOS和安卓目录下的字体文件的规格是否齐全: 2:cc.LabelTTF 在ios下,cc.Label ...

  3. HDU2076

    夹角有多大(题目已修改,注意读题) Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  4. 这种写法用过没:string.Format("{0,-10}", 8)

    1 2 3 4 var s1 = string.Format("{0,-10}", 8); var s2 = string.Format("{0,10}", 8 ...

  5. Android开发百度地图(一)--显示基本地图

    最近由于比赛的需要,自己学习了一下百度地图的开发.希望以下的内容能够对大家有用. 一.开发前的准备工作: 1.注册百度账号,并登录.(有百度账号的话直接登录) 2.申请Key,地址:http://de ...

  6. Java strictfp关键字

    保证浮点运算的结果不受平台的影响,在任何平台上,使用统一的标准进行浮点运算,提高程序的可移植性(毕竟结果更可控,更精确),相应的,以降低性能为代价 Strictfp ensures that you ...

  7. C#扫盲之:前台线程后台线程

    1.线程分类 线程由程序员创建,可是创建的方式不同,总体来说有两种,一种是个人构造,也就是使用thread类new线程对象创建,这一类线程是大部分程序员知道的,也叫专用线程;还有一种是由CLR创建,这 ...

  8. 纯js写“运动”框架

    所谓“运动”不一定真的是运动,在连续的一段时间内改变某一样式都可以成为“运动”. 先写几个会用到的函数 //获取某一元素的指定样式 function getstyle (element, target ...

  9. Browser 对象

    Browser 对象 window对象表示浏览器中打开的窗口如果文档包含框架(iframe 或 iframe标签),浏览器会为HTML文档创建一个window对象,并为每个框架创建一个额外的windo ...

  10. CSS 隐藏多余的字符

    日常开发中常常会碰到,字符长度太大,撑破了样式的问题.如果采用截取的话,显然是不灵活的.但是通过css样式来控制显示就比较简单和高效了.下面是关键代码 样式名称{wedth:??px;height=? ...