关于header file、static、inline、variable hides的一点感想
前言
先看一段代码
#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的一点感想的更多相关文章
- 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 ...
- Header File Dependencies
[Header File Dependencies] 什么时候可以用前置声明替代include? 1.当 declare/define pointer&reference 时. 2.当 dec ...
- 原文: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 ...
- 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语言程序,编译出现错误: 预编译头文件 ...
- 【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 ...
- static inline
今天看到了这样一段代码, static inline BOOL IsEmpty(id thing) { return thing == nil || [thing isEqual:[NSNull nu ...
- static local variable
Putting the keyword static in front of a local variable declaration creates a special type of variab ...
- auto make System.map to C header file
#!/bin/bash # auto make System.map to C header file # 说明: # 该脚本主要是将Linux内核生成的System.map文件中的符号.地址存入结构 ...
- 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 ...
随机推荐
- SDN实验---OVS了解(转载)
转载自:https://opengers.github.io/openstack/openstack-base-use-openvswitch/ 一:Open vSwitch介绍 (一)介绍 在过去, ...
- Cassandra开发入门文档第五部分(使用场景)
正确建模 开发人员在构建Cassandra数据库时犯的另一个主要错误是分区键的选择不佳.cassandra是分布式的.这意味着您需要有一种方法来跨节点分布数据.Cassandra通过散列每个表的主键( ...
- 启动Oracle 12c数据库实例
启动Oracle 12c数据库实例 启动Oracle数据库实例,主要分为两步:第一步,启动监听:第二步,启动数据库实例. 1. 切换到oracle用户- su oracle- cd - source ...
- 解决org.springframework.dao.DeadlockLoserDataAccessException
添加链接池后批量添加更新出现了死锁 org.springframework.dao.DeadlockLoserDataAccessException: ### Error updating datab ...
- QT+OPENCV实现录屏功能
本文使用QT+opencv来实现对指定窗体画面录制,并保存为avi文件. (1)获取窗体界面 QScreen类有一个grabWindow函数,可以用来获取窗体的画面,这个函数使用很简单,就是传入窗体句 ...
- spark 性能优化简要总结
1.从同一个数据源尽量只创建一个rdd,后续业务逻辑复用该rdd2.如果要对某个rdd进行多次的transformation或action操作,应当持久化该rdd3.从数据源读取到rdd后,要尽早的进 ...
- SimpleDataFormat 线程不安全解决
SimpleDataFormat 是我们常用的时间转换工具,我再spark中使用sdf对时间戳进行转换,发现转化出的时间有异常,原来sdf是线程不安全的, 改用joda time,错误消失,样例如下 ...
- chrome的无头(headless)模式
chrome的无头(headless)模式 用selenium调用phantomjs浏览器的方式几乎可以爬取任何网站,但是与调用chrome相比,phantomjs的稳定性还是不够.如果能让chrom ...
- [转帖]很遗憾,没有一篇文章能讲清楚ZooKeeper
很遗憾,没有一篇文章能讲清楚ZooKeeper https://os.51cto.com/art/201911/606571.htm [51CTO.com原创稿件]互联网时代是信息爆发的时代,信息的高 ...
- Django-12-auth认证组件
1. 介绍 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能. Django作为一个完美主义者的终极框架,当然也会 ...