前言

先看一段代码

#ifndef  _INLINE_H
#define _INLINE_H template<typename T>
static inline
T my_max(T a, T b)
{
a *= 2;
b /= 3;
return (a>b) ? a : b; //找出最大值
} #endif

代码本身逻辑很简单,无外乎简单的找出两个T类型变量中大者。

这里有几个关键字的用法很值得深究,特此记录下感想。

inline

简单的理解inline就是,他只有带参宏的优点,没有带参宏的缺点。但实际情况,这可能仅仅是Programmer的一厢情愿。因为啥? inline和register的行为很像,正确的理解方式是,这两个关键字是programmer对compiler的一种建议。至于你的建议会不会被compiler所接纳,那是compiler的事,我们不应该对compiler有任何假设。因此上面代码中是对然你加了inline,最终效果可能和不加inline的normal function一样。

static

要想理解此处static的作用,首先想像我们经常遇到的重复定义error。软件开发中遇到的重复定义error,99%都是来自于global空间被“污染”。为啥这么说?对于文件作用域内的variable or function,重复定义情况你是很容易发现的,都写在一个文件中,打眼一看就知道有没有冲突。然而实际开发中,多人协作开发,global空间有啥东西谁也不清楚。对于那些拍脑子乱加global variable or function 的人更是如此,可能他自己“污染”了global空间,自己都不知道。

想想哪些地方可能会导致global空间被“污染”,嗯....头文件(.h)和.c文件

.h文件

对于在.h里面的强符号,应该始终秉持这样一种观点:尽可能将header files封锁在include他的单个.c文件。除非对那些必须要共享的variable or function,其余强符号最好加上static。虽然header guard帮我们避免了一份头文件多次包含的情况,确保整个头文件在最终可执行文件中只有一份。但是header guard无法保证header files中的强符号与其他人.h  or  .c文件中的强符号发生重复定义风险。

.c文件 

对于.c中的强符号,如果不想被他人使用 或者 可能给他人带来风险,最好加上static,将其锁死在文件作用域。

软件开发是个多人合作活动,对于编码问题上的风险,我们应该将其扼杀在萌芽中。一个良好的编码规范无疑是重要的。核心代码必须有企业自己把握,业务代码(简单扩充函数)完全可以外包出去,外包出去的代码质量由公司内部人员把控。这样可以进一步缩减人力成本。

variable hides

#include <stdio.h>

int var = 20;
int main()
{
int var = var;
printf("%d\n", var);
return 0;
}

variable hides很好理解,The local variable always hides a global one of the same name as soon as it's declared.

那么换成function hides呢?

我们知道C不支持overloading,C++支持overloading。C++下最终识别到的函数名字类似于这样:

那有没有这种可能?

某个.c内的static function 和 某个 global function在compiler那一侧解析的名字完全一致,那不就会存在类似于variable hides的情况了吗?虽然这种情况概率比较低,但是面对百万行代码的时候还是难免不会遇到。

事实上,这个问题完全是多虑了。

之所以会想到这个奇怪的问题,其根源是对作用域问题的思考。上层上讲就是谁的作用域有效,低层上函数名就是个地址,地址值都不一样。因此最终翻译成二进制代码的时候是不会出现function hides的情况的。

关于header file、static、inline、variable hides的一点感想的更多相关文章

  1. About Why Inline Member Function Should Defined in The Header File

    About why inline member function should defined in the header file. It is legal to specify inline on ...

  2. Header File Dependencies

    [Header File Dependencies] 什么时候可以用前置声明替代include? 1.当 declare/define pointer&reference 时. 2.当 dec ...

  3. 原文:I don’t want to see another “using namespace xxx;” in a header file ever again

    http://stackoverflow.com/questions/5849457/using-namespace-in-c-headers http://stackoverflow.com/que ...

  4. C1853 编译器错误:fatal error C1853: 'pjtname.pch' precompiled header file is from a previous

    转载:https://www.cnblogs.com/emanlee/archive/2010/10/16/1852998.html 用VC++ 2008 编写C语言程序,编译出现错误: 预编译头文件 ...

  5. 【iOS】The differences between Class Extension and Header File 类扩展与头文件的区别

    . As the name suggests, they extend the class. A class continuation is another name. The class exten ...

  6. static inline

    今天看到了这样一段代码, static inline BOOL IsEmpty(id thing) { return thing == nil || [thing isEqual:[NSNull nu ...

  7. static local variable

    Putting the keyword static in front of a local variable declaration creates a special type of variab ...

  8. auto make System.map to C header file

    #!/bin/bash # auto make System.map to C header file # 说明: # 该脚本主要是将Linux内核生成的System.map文件中的符号.地址存入结构 ...

  9. c++预编译问题:fatal error C1083: Cannot open precompiled header file: 'Debug/DllTest.pch': No such file or d

    1)单独编译StdAfx.cpp 2)编译所有(即按Ctrl+F7) 这时因为该模块没有包括预编译头文件“stdafx.h”的缘故.VC用一个stdafx.cpp包含头文件stdafx.h,然后在st ...

随机推荐

  1. shell基础知识6-在不按回车键的情况下读入N个字符

    Bash命令 read 能够从键盘或标准输入中读取文本.我们可以使用 read 以交互的形式读取用 户输入,不过 read 能做的可远不止这些.编程语言的大多数输入库都是从键盘读取输入,当回 车键按下 ...

  2. darkflow测试和训练yolo

    转自 https://blog.csdn.net/u011961856/article/details/76582669参考自github:https://github.com/thtrieu/dar ...

  3. Appium基础之屏幕截图

    应用背景 在实际自动化项目运行过程中,很多时候App可以会出现各种异常,为了更好的定位问题,除了捕捉日志我们还需要对运行时的设备状态来进行截屏.从而达到一种“有图有真相”的效果. 截图方法 方法1 s ...

  4. SpringBoot 为什么能够自动的注入一些常用的Bean ?

    原文转载至:https://blog.csdn.net/qq_29941401/article/details/79605388 但是我一直没有搞懂druid是怎么自动配置的? 这个是properti ...

  5. vue遇到组件数据变更了,但是不渲染的问题

    要绑定key,key改变,会触发组件重新渲染

  6. DOM事件: DOM事件级别、DOM事件流、DOM事件模型、DOM事件捕获过程、自定义事件

    前端面试中只要问到事件,就肯定会有DOM事件:如果回答出来了,就会一直向下延申,其实这些东西都很简单,但我第一次被问到的时候,也是懵的: DOM事件级别: DOM0 element.onclick = ...

  7. Java序列化的方式。

    0.前言 本文主要对几种常见Java序列化方式进行实现.包括Java原生以流的方法进行的序列化.Json序列化.FastJson序列化.Protobuff序列化. 1.Java原生序列化 Java原生 ...

  8. 构建C1000K的服务器(1) – 基础

    转自: http://www.ideawu.net/blog/archives/740.html 著名的 C10K 问题提出的时候, 正是 2001 年, 到如今 12 年后的 2013 年, C10 ...

  9. Hyperledger Fabric 入门 first-network 搭建

    1.准备环境: 安装git.docker.curl.go [root@test_vonedao_83 fabric]# git --version git version 1.8.3.1 [root@ ...

  10. Delphi RSA签名与验签【支持SHA1WithRSA(RSA1)、SHA256WithRSA(RSA2)和MD5WithRSA签名与验签】

    作者QQ:(648437169) 点击下载➨ RSA签名与验签 [delphi RSA签名与验签]支持3种方式签名与验签(SHA1WithRSA(RSA1).SHA256WithRSA(RSA2)和M ...