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. panda库2

    >>> a=pd.Series([1,2],index=['a','b']) >>> a a 1 b 2 dtype: int64 >>> b=p ...

  2. idea下使用autowire注解注入对象,结果初始化不到类

    如果idea下使用autowire注解注入对象,结果初始化不到类,明明使用快捷键alt+insert是可以找到该注入的对象的. 而我们在使用的时候,缺报错了??? 注意,当我们在注入对象的时候,我们留 ...

  3. 通用技术 : 异步调用 - Ajax技术

    Ajax技术概述

  4. C++格式化输出的好东西

    s = FormatFloat("0.######", d); 最多保留6位s = FormatFloat("0.000000", d); 始终保留6位s = ...

  5. Linux入门之常用命令(10)软连接 硬链接

    在Linux系统中,内核为每一个新创建的文件分配一个Inode(索引结点),每个文件都有一个惟一的inode号.文件属性保存在索引结点里,在访问文件时,索引结点被复制到内存在,从而实现文件的快速访问. ...

  6. 认识 Java Message Service

    1. Java Message Service : 是一个消息服务的标准或者说是规范,允许应用程序组件基于JavaEE平台创建.发送.接收和读取消息. 实现Java 程序与MQ Server 之间互相 ...

  7. 使用vs编译事件来动态发布配置文件

    我们知道开发有很多的环境,一般我们会分为开发环境,测试环境,生产环境.而我们使用的vs默认配置就两种:Debug和Release.当然vs支持通过配置管理器来添加,编辑及删除配置. 为此不同的环境和配 ...

  8. pongo英雄会-幸运数题解

    显然我们只要知道1~x范围有多少幸运数(用f(x)表示),lucky(x,y)=f(y)-f(x-1). 解法1. 计算排列数 由于y<=1000000000这个规模,我们不能暴力验证每个数是否 ...

  9. ARCGIS切图:TPK文件的空间参考为地理坐标系

    先来吐槽一下,之前习惯了百度地图API,所以一直习惯直接将经纬度点添加到地图上进行显示,目前使用ARCGIS RUNTIME FOR ANDROID进行开发,在地图上加点需要原始点的坐标为投影坐标系, ...

  10. Python打印乘法口诀表

    思路:第一行:1*1,第二行:1*2.,2*2,第三行:1*3,2*3,3*3-- 最后一行:1*9,2*9,3*9,-9*9,以此类推,可以设2个数:i,j:让 i 从1循环到9,让 j 从1到小于 ...