在关于开发规范的帖子里,我和王寅同学有一大段关于宏和inline函数的PK,感觉比较有代表性,这里摘录出来单独开贴,欢迎大家讨论。
|
-
习惯而已,如果没有实在的必要,在我的代码里面是禁止出现宏的。
理由只有一个,宏不是代码。编译器看不到宏,只有预处理能看到宏。
-
韩卫平(C/C++老师): 习惯而已,如果没有实在的必要,在我的代码里面是禁止出现宏的。嗯,补充一点,宏对调试不利。
理由只有一个,宏不是代码。编译器看不到宏,只有预处理能看到宏。
一般单步跟踪,跟踪到函数型宏,就跟不进去了。呵呵。
-
哦,帖在这里啊,没看到,不好意思。发到那边去了
-
肖兄:我学C++的,对宏不了解能不说详细点,我也从来没用过宏.不知它与const的区别?编译器以VC8或gcc 4.4.3.
-
没事,我拷贝过来。
回复#1 王寅(C/C++学生) 14分钟前
我也觉得会高一点,er。。。我不了解编译器在这里会怎样处理,我猜的话,编译器为了实现函数行为,确实需要生成代码来确保,比如参数会在进入函数体之前 先被计算,然后拷贝参数,最后有返回值的话也会也可能会拷贝返回值。整个相比一般函数节省下来的应该是,call 和 return 两个指令,以及保存现场所用的压栈啦,恢复现场用的弹栈啦。或许编译器有它自己的方法,不过我也觉得inline代价会高一点,查看一下生成的汇编会比较 清楚。不过我所举的那个误用宏的例子,让我偏向用inline,他带来得好处似乎更多一点。
那个空间增大的问题,er。。。能换来时间吗?难道读宏定义的数据会少几个指令,这个我不是很清楚。
-
湖北工业大学 吕固(C/C++学生): 肖兄:我学C++的,对宏不了解能不说详细点,我也从来没用过宏.不知它与const的区别?编译器以VC8或gcc 4.4.3.没用过,就不要用了。
inline+const能替代绝大多数用宏的场合。
我是C出身的,所以习惯用宏,仅此而已。
-
正好我的观点与楼主和肖兄的都不一样,肖兄讲一下啦,C89也是C++一部分.想了解C++更全面一点,不知道它怎么样至少应该知道它的缺点及带来的坏的 影响吧.我认为 define 与 const+inline 完全不是一个东西没有可比性,你们是怎么把这两个东西放在一起的比较的?
-
王寅(C/C++学生): 哦,帖在这里啊,没看到,不好意思。发到那边去了C和C++的编译器有个特点,见到大括号就建新栈。
函数内部也可以用这个技巧来划定一个变量的作用域的,我有时候故意这么用。
void Func(void)
{
//...
{
int i; //看这里,这个i的作用域仅限于内部的大括号,这是个技巧,强行建新栈。出了大括号范围,新栈自动拆除,i就没有了。
}
}
inline函数在编译时,由于有大括号,会有一次建栈和拆栈的过程,因此,其运行成本,其实还是相当于一正常次函数调用的百分之几十。仅仅是减少了一个call的CPU压栈行为,C部分的运行期浮动内存栈还是正常建立了的。
不过这不重要,正常情况下,现在CPU和内存的频率都这么快,这点开销不明显。
不过,空间换时间是很重要的技术手段,这个可是程序优化常用的,必须习惯使用。
比如我们画一个屏幕,可以一个点一个点的计算,也可以把屏幕左边的点建立一个表,绘制时根据y坐标直接查表获得。这个在游戏编程中是经常用到的技巧,高速图形处理,很多都是用查表法。
这个建立查询表,肯定就是用空间来换时间了。
-
湖北工业大学 吕固(C/C++学生): 肖兄讲一下啦,C89也是C++一部分.不知道它怎么样至少应该知道它的缺点及带来的坏的影响吧.我认为 define 与 const+inline 完全不是一个东西没有可比性,你是怎么把看帖子咯,再找本C的书看看,就有了。
其实很简单的。
宏两大作用
定义常量,C++建议用const
定义函数型宏,固化计算,C++建议用inline函数,就是内联。
原因是C是弱类型,C++是强类型,C++认为宏不检查变量类型,会留下bug隐患,因此建议不要使用。
不过近年来,宏的这个特点又被看成优点了,因为不检查类型,所以才能一个定义,适应多种变量类型,实现函数式编程。这个很热门,是多任务并行开发的利器。
只可怜C++把宏批评了半天,结果自己没办法,又搞了个泛型程序设计,又笨又重,累死不讨好。呵呵,这是开个玩笑了。
-
恩,空间换时间,时间换空间,似乎整个计算机科学都渗透这条法则。
怎么权衡那要看具体问题,具体分析了。
-
王寅(C/C++学生): 恩,空间换时间,时间换空间,似乎整个计算机科学都渗透这条法则。好,具体情况具体分析,
怎么权衡那要看具体问题,具体分析了。
说出这句话,就是吃透了程序设计的精髓了。
-
肖兄:之前有贴子不是说,inline就像是register 关键字一样,不是由你决定的是由编译器决定用不用的,只是优化时的修饰用,可选的.而define 是文本替换,两者作用不一样怎么搞到一起去的. const 除了固化变量外,再就是方便编译器优化的功能.运行时常变量也不是放在只读内在中,也和变量一起放在数据区(可能正因为这样你可能通过m什么的可以改 吧.).这也与define 联系不到一起去.
-
湖北工业大学 吕固(C/C++学生): 肖兄:之前有贴子不是说,inline就像是register 关键字一样,不是由你决定的是由编译器决定用不用的,只是优化时的修饰用,可选的.而define 是文本替换,两者作用不一没错,inline编译器有发言权。
我说的是编译器和你都同意的情况下,inline才有可能对#define有替代关系。
double check!明白吗?
实际用起来,inline是在编译器展开代码,而#define是在预编译展开代码,仅此而已。
-
像 #define BB "我是字面常量"
按C++的理解,常量有,文字常和常变量之分,
在程序中用BB替换后,编译器就会按字面常量处理,这样经编译器处理后,写在代码区,是不可寻址的.而用常变量,只是变量固化啦,还是个变量,它是可寻址的.不一样的东西呀.
肖兄:你会VC,在VC8下输出汇编代码,可看出字面常量是 mov DWORD PTR _n$[ebp],8888; 是在一帧数据中,n 距 帧指针 ebp的偏移量.是硬编码. 所以,论题没有可比性.
-
湖北工业大学 吕固(C/C++学生): 像 define BB = "我是字面常量";1、写错了,应该是
按C++的理解,常量有,文字常和常变量之分,
在程序中用BB替换后,编译器就会按字面常量处理,这样经编译器处理后,写在代
#define BB "我是字面常量" //没有=,没有分号
2、你说不一样就不一样咯,你就不用好了。
-
再是,看过一些开源C代码, 一般 define 会一戳一戳的定义一些相关量,为什么不用 enum,把它们都集中一起来,这样更对象些,也系统相互性也更内距些吧.
-
普罗通信西安有限公司 肖舸(C/C++老师): 1、写错了,应该是哦,马上该.
#define BB "我是字面常量" //没有=,没有分号
2、你说不一样就不一样咯,你就不用好了。
-
湖北工业大学 吕固(C/C++学生): 再是,看过一些开源C代码, 一般 define 会一戳一戳的定义一些相关量,为什么不用 enum,把它们都集中一起来,这样更对象些,也系统相互性也更内距些吧.枚举我没用过,20年了一直没用过,不知道为什么,就是不喜欢。
-
如果没有用到 #和##的话。宏完全可以被替换掉。
再说了宏要是中间结尾少写一个;啥的错误可不好查。
不光新手老手也会犯这个错误。
-
韩卫平(C/C++老师): 如果没有用到 #和##的话。宏完全可以被替换掉。看个人习惯吧。
再说了宏要是中间结尾少写一个;啥的错误可不好查。
不光新手老手也会犯这个错误。
我个人比较喜欢用宏。
太绝对的论证一个东西好还是不好,总不是太好的事情,因为未来的需求和方向我们预测不准,走起来看吧。
-
普罗通信西安有限公司 肖舸(C/C++老师): 看个人习惯吧。是啊,宏优缺点都有。
我个人比较喜欢用宏。
太绝对的论证一个东西好还是不好,总不是太好的事情,因为未来的需求和方向我们预测不准,走起来看吧。
MFC中大片的宏,完成了本该编译器做的事情,也完成了消息链这种复杂的过程。设计的巧妙让人惊叹啊。
同时也放倒了一批研究MFC原理的人。
-
韩卫平(C/C++老师): 是啊,宏优缺点都有。有本书你看过没?
MFC中大片的宏,完成了本该编译器做的事情,也完成了消息链这种复杂的过程。设计的巧妙让人惊叹啊。同时也放倒了一批研究MFC原理的人。
如果用汇编语言开发Windows程序。
里面更昏,全部是宏,写到后面,基本上见不到汇编了。
我用宏的习惯,其实是以前用汇编做游戏养成的。
一个游戏15万行代码,如果不用宏,快80万行了。敲都敲死人。
写到最后,你在我的汇编中,可以看到FOR,NEXT,PRINT这些语句的,全部是宏。呵呵。
-
那linux源代码中宏多不多呀,占 ?%呀?
唉,有一群顽固的老C程序员在做中流砥柱,想用现代的纯C++做系统都不行呀。
-
湖北工业大学 吕固(C/C++学生): 那linux源代码中宏多不多呀,占 ?%呀?呵呵,那是因为C++离了C做不了事情的。
唉,有一群顽固的老C程序员在做中流砥柱,想用现代的纯C++做系统都不行呀。
C++是C的面相对象解释。
在函数内部,还是C的写法多,呵呵。
我是愉快的C,我看着C++,就是不说话,哈哈。
-
不是有数据集的类模板,和建立算法库的函数模板。
数据(静的),操作(动的)都有了。
老顽固就是不用呀,浪费了编译器厂家精心写的标准库.
-
这倒没看过
不过我还是习惯用模板啥的C++提供的功能来写代码,好调试,容易维护。也不会有多少重复的代码。
-
LS的都是牛人.
我果断的采取观望态度.达到楼上诸位的实力
1.大量编程.
2.研究编译原理与编译器.
3.懂汇编.
4.优化代码
5.了解计算机思想.那一个资源换一种资源
抽象出物理学:
热力学第一定律:能量既不可能再生也不可能消灭只是一种形式转化为另一种形式.
热力学第二定律:墒是不断增加的.
-
对了,好像也没见用 MMX/SSE 写程序的,浪费了那些指令集啦。对了肖兄,近期一直不解,现在许多显卡的gpu的浮点计算速度已经远超intel cpu浮点计算速度的20-30倍了,能不能把计算量从CPU放到gpu上去,不然白白浪费了强大gpu啦。
湖北工业大学 吕固(C/C++学生): 对了,好像也没见用 MMX/SSE 写程序的,浪费了那些指令集啦。对了肖兄,近期一直不解,现在许多显卡的gpu的浮点计算速度已经远超intel cpu浮点计算速度的20-30倍了,能不能
你用DX呗
|