1、神奇的inline语法与语义

inline语义C99和C++98都有。之前在单源文件编写的时候一直没有发现问题,但是一考虑到多文件的链接,就发现矛盾了。

一些inline的原则:
1. inline 只是建议,不是写了 inline 编译器就一定会内联该函数。内联失败的原因有很多,识别方法也有不少,这里就不一一阐述。
2. 标准以及目标文件的本质就决定了真正的内联函数是不存在外部链接 external linkage 的,因此一般实现会要求要求 inline 的定义声明和使用一定要在同一个 Translation units 中,所以一般把内联函数定义写在头文件中。

我发现的矛盾出现在:如果内联失败,那就会为该函数生成一个代码段吗?这样多个文件编译生成的目标代码中,是否就会有多个相同且重复的代码段?这样链接的时候是否会出现命名冲突呢?

在我认知中的这些个矛盾是有递进的,或许应该这么写:

  1. 如果内联失败,那就会为该函数生成一个代码段吗?
  2. 这样多个文件编译生成的目标代码中,是否就会有多个相同且重复的代码段?
  3. 这样链接的时候是否会出现命名冲突呢?是否会出现代码冗余?

而我认为 1 2 的答案是肯定的,那编译器是如何避免 3 的后果呢?下面是个人的一些推测:

  1. C 角度 inline 的函数名没有外部链接, 具有像静态函数一样的性质。这就保证了内联失败时不会有命名冲突。
  2. ARM-ASM 角度 inline 的名字是 EXPORT [WEAK] ?也是解决命名冲突。
  3. 链接时的优化?去除冗余代码段?

1.5、教科书上的说法

[美] Stephen Prata “C++ Primer Plus(第6版)中文版” ISBN:9787115279460

8.1 C++ 内联函数

只是简单的在单源文件基础上的介绍,顺便对比了下内联函数和宏函数

10.2.3 实现类成员函数 2. 内联方法

定义位于类声明中的函数都将自动成为内联函数

如果愿意,也可以在类声明之外定义成员函数,并使其成为内联函数。为此,只需在类实现部分中定义函数时使用inline限定符即可

内联函数的特殊规则要求在每个使用它们的文件中都对其进行定义。确保内联定义对多文件程序中的所有文件都可用的、最简便的方法是:将内联定义放在定义类的头文件中(有些开发系统包含智能链接程序,允许将内联定义放在一个独立的实现文件)。

顺便说一句,根据改写规则(rewrite rule),在类声明中定义方法等同于用原型替换方法定义,然后在类声明的后面将定义改写为内联函数。

这里有提到其他的实现方法

15.1.2 友元成员函数

再次提及内联函数只有内部链接

I.1.2 使用inline而不是#define来定义小型函数

又一次对比了inline和宏函数

[美] Stephen Prata “C Primer Plus 第6版 中文版” ISBN:9787115390592

16.7 内联函数(C99)

其实C99和C11标准中叙述的是:“把函数变成内联函数建议尽可能快地调用该函数,其具体效果由实现定义”。

标准规定具有内部链接的函数可以成为内联函数,还规定了内联函数的定义与调用该函数的代码必须在同一个文件中。

与C++不同的是,C还允许混合使用内联函数定义和外部函数定义(具有外部链接的函数定义)

1.625、标准的说法

妈的C99/C11标准也定义的很乱!

未完待续

1.75、编译器的说法

2、和类相关

3、只有常成员函数足够吗?

¥¥¥、彩蛋

inline 的相关标准原文

写新的文章吧。

内联失败的原因

  1. 编译器没有实现
  2. 编译器判定不适合内联
  3. 不能内联(出现递归、取地、外部链接)

如何判读函数是否内联

  1. cc -g; db b inline_function, r & bt
  2. 利用包含符号表的运行时环境
  3. 查看汇编是否有调用

想写一篇关于asm+stdc+OS的编译链接文章

在草稿箱存着了个开头了

EXPORT [WEAK] 参考

某博文总结

CMSIS启动文件

C++ 对象成员函数(非静态方法)的更多相关文章

  1. java多态成员变量、成员函数(非静态)、静态函数特点

    1 package face_09; 2 3 /* 4 * 多态时, 5 * 成员的特点: 6 * 1,成员变量. 7 * 编译时:参考引用型变量所属类中的是否有调用的成员变量,有,编译通过:没有,编 ...

  2. JS组件系列——表格组件神器:bootstrap table 包含了js对象的定义和对象成员函数的定义

    前言:之前一直在忙着各种什么效果,殊不知最基础的Bootstrap Table用法都没有涉及,罪过,罪过.今天补起来吧.上午博主由零开始自己从头到尾使用了一遍Bootstrap Table ,遇到不少 ...

  3. c++ 学习之const专题之const成员函数

    一些成员函数改变对象,一些成员函数不改变对象. 例如: int Point::GetY() { return yVal; } 这个函数被调用时,不改变Point对象,而下面的函数改变Point对象: ...

  4. C++ Const成员函数

    一些成员函数改变对象,一些成员函数不改变对象. 例如:  int Point::GetY() { return yVal; }  这个函数被调用时,不改变Point对象,而下面的函数改变Point对象 ...

  5. 为什么NULL指针也能访问成员函数?(但不能访问成员变量)

    查看更加详细的解析请参考这篇文章:http://blog.51cto.com/9291927/2148695 看一个静态绑定的例子: 1 #include <iostream> 2 3 u ...

  6. MFC绘图相关GDI工具对象和函数介绍

    在利用MFC进行界面编程时,除了需要熟悉各种类型控件的操作外,还会经常遇到图形绘制和显示的问题,比如时频分析界面.图像处理界面等.处理这些软件界面开发问题时,不可避免地需要用到一系列GDI工具对象和相 ...

  7. C++,对象成员的访问

    成员变量和成员函数的访问可以采用以下几种访问方式:对象.成员变量名: 对象.成员函数名(实参列表)对象的指针->成员变量名; 对象的指针->成员函数名(实参列表)对象的引用.成员变量名对象 ...

  8. PHP 类中静态方法调用非静态方法

    静态方法调用非静态方法: 在类中静态方法中,需要实例化对象,然后再调用类中的方法 非静态方法调用静态方法: 可以self 或者 类名加::的形式调用 如下面的案例: <?php class A{ ...

  9. 为什么const对象只能调用const成员函数,而不能调用非const成员函数?

    在c++中,我们可以用const来定义一个const对象,const对象是不可以调用类中的非const成员函数,这是为什么呢?下面是我总结的一些原理. 假设有一个类,名字为test代码如下: clas ...

随机推荐

  1. temp--达州银行

    达州银行现场 服务器IP地址 192.168.1.234 ilink / ilink 自己电脑需要设置为固定IP 192.168.1.XXX 子网掩码 255.255.255.0 192.168.1. ...

  2. JVM锁机制之synchronized

    概述: synchronized是java用于处理多线程同步的一个关键字,用于标记一个方法/代码块,使之成为同步方法/同步块. 用synchronized可以避免多线程处理时的竞态条件问题. 相关概念 ...

  3. Oracle_Sequence如何初始化开始值

    Sequence的start with 值如何确定才能保证生成的主键不会冲突??? 我的项目中最开始数据库表主键的生成策略是 increment,但由于后来采用了集群部署的方式,出现了主键冲突的问题. ...

  4. LINUX通过PXE自动部署系统

    原理介绍 TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP 协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂.开销不大的 ...

  5. String.getBytes(),源码之下,了无秘密

    @Deprecated public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) { if (srcBegin ...

  6. mac 安装Beautiful Soup

    Beautiful Soup是一个Python的一个库,主要为一些短周期项目比如屏幕抓取而设计.有三个特性使得它非常强大: 1.Beautiful Soup提供了一些简单的方法和Python术语,用于 ...

  7. 移动端touch事件实现页面弹动--小插件

    动手之前的打盹 说实话真的是好久没有更新博客了,最近一直赶项目,身心疲惫:最关键的是晚上还要回去上一波王者,实在是忙啊! 这周下来,清闲了些许,或许是因为要到国庆的缘故吧,大家都显得无精打采.俗话说的 ...

  8. kbhit()

    kbhit() 非阻塞的响应键盘输入时间   C++函数 功能和返回值:检查是否有键盘输入 ,有返回非0 ,无返回0 int khbit(void) 头文件: #include<conio.h& ...

  9. Linux入门之常用命令(12) mount

    查看Linux所有设备 cd  /dev ls -l sd*  //分区 查看Linux磁盘 fdisk -lu 挂载 一般挂载至/mnt /media mount /dev/sda5   /mnt/ ...

  10. 学习如何看懂SQL Server执行计划(三)——连接查询篇

    三.连接查询部分 --------------------嵌套循环-------------------- /* UserInfo表数据少.Coupon表数据多嵌套循环可以理解为就是两层For循环,外 ...