作者ric2k1 (Ric)
看板EE_DSnP
标题Re: [转录] So, what's wrong with using macros?
时间Thu Oct 22 12:50:35 2009
※ 引述《dryman (dryman)》之铭言:
: 糟糕,我的推文好像得不到共鸣XD
: 留下一句觉得macro也不错就不说话了好像也不太好
: 以下是我半生不熟的想法,跟大家分享一下,欢迎大家指教:)
欢迎 & 感谢分享!!
: 最初想用macro时单纯因为有太多for回圈,而且里面有很多都长这样:
: for( i=_readBufPtr-_readBuf; i< _readBufEnd-_readBuf; i++)
: cout << "\b";
也许增加个 private member function?
虽然题目说最好不要再增加 functions, 那是为了避免同学就直接硬刻,
而没有照着 TODO 的建议. 不过像是这种情况当然是可以加 functions 的.
不过上面的 code 也许可以改成:
for (char *ptr = _readBufEnd; ptr != _readBufPtr; --ptr)
cout << "\b";
: 不管是array左移右移,输出空白、backspace,都需要用到类似的for回圈
: 这样也没什麽不好
: 只是当你有ptr到底的,又有整个buffer的,混在一起看真的会让人觉得有点不好读
: 最直觉的想法就是写个macro来让它好读一点
Or maybe some member functions like:
printChar(ptr1, ptr2, char); or
printChar(offset, char);
: 因为coding中必须要方便debug,所以我最初设的macro是
: IDX_PTR 还有 IDX_END
: 来替代指标相减(_readBufPtr-_readBuf 之类的)
: 这样是为了方便我debug,减少写错的机会
: 等到程式撰写完成功能全部都测试完後,我才开始想如何将程式码变得更精简
: 我现在知道的方法有两种啦
: 一种是用while来取代for loop
: 另一种就是自己设计的macro
: macro我使用的只有
: FOR_PTR_TO_END
: FOR_ENTIRE_BUFFER
: 用法是FOR_PTR_TO_END( cout << "\b"; )
: 基本上我觉得我的用法算是走good coding style的模糊地带XD
: 如果不是替代的程式码用法很单纯,macro真的不是一个好的solution
: 只是在这个题目中array左移右移,印出空白backspace的地方太多了
: 就算写function也没办法全部都罩住
: 反而是macro用起来很贴切XD
: 可是我想这只能算是特例吧?(也许还有更好的写法?)
STL 的爱用者可能会建议使用像是 for_each() 这样的 functional object.
不过不一定简洁就是了.
: ==============================================================
: google有个很棒的c++ coding style guide
: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
: 里面也是建议不要用macro:
: Be very cautious with macros. Prefer inline functions, enums, and
: const variables to macros.
: Macros mean that the code you see is not the same as the code the
: compiler sees. This can introduce unexpected behavior, especially
: since macros have global scope.
: Luckily, macros are not nearly as necessary in C++ as they are in
: C. Instead of using a macro to inline performance-critical code,
: use an inline function. Instead of using a macro to store a
: constant, use a const variable. Instead of using a macro to
: "abbreviate" a long variable name, use a reference. Instead of
: using a macro to conditionally compile code ... well, don't do
: that at all (except, of course, for the #define guards to prevent
: double inclusion of header files). It makes testing much more
: difficult.
: The following usage pattern will avoid many problems with macros;
: if you use macros, follow it whenever possible:
: Don't define macros in a .h file.
: #define macros right before you use them, and #undef them right
: after.
: Do not just #undef an existing macro before replacing it with your
: own; instead, pick a name that's likely to be unique.
: Try not to use macros that expand to unbalanced C++ constructs, or
: at least document that behavior well.
: 使用macro时最好跟随命名原则(naming)
: 使用全部大写及底线,而且最好在名称就把自己的目的说清楚
: You're not really going to define a macro, are you? If you do,
: they're like this: MY_MACRO_THAT_SCARES_SMALL_CHILDREN.
: Please see the description of macros; in general macros should not
: be used. However, if they are absolutely needed, then they should
: be named like enum value names with all capitals and underscores.
: #define ROUND(x) ...<--我觉得这个也不够好,如果别人用了同样的名字就糟了!
: #define PI_ROUNDED 3.0
: macro会存在是因为它有魔法般的威力来帮你程式码变更简洁
: 但是就如同operator overloading一样,太过魔幻(指简洁就能达到目的)的语法
: 常常会让debugging还有trace code变得异常困难
: 尽管如此我还是用玩火的心态想试试macro啦XD
: 我的对应之道是采三个步骤:
: 1.
: 还在建构功能时以方便trace code为目的
: 所以macro只有设IDX_PTR和IDX_END
: 因为使用後会比_readBufPtr-_readBuf更好读,也更好trace
: 2.
: 先把功能一个一个全部完成并通过测试
: 等到全部弄完後,才去想说要如何简化美化程式码
: (也就是先写eazy and dirty solution)
: 如果中间你就开始想实验奇怪的macro,最後程式码可能会需要砍掉重链吧..
: 3.
: 评估一下到底是哪几个地方程式码重复最严重
: 然後再想该用哪一种简化方式
: 这次作业的特色是需要计数的地方很多
: 刚好用macro比我所知的其他方法都合适(就计数而言)
: macro的命名真的很重要,千万不要怕长
: 尽量以能够完全表达这个macro的动作为命名原则
: 这样一方面不容易跟其他的程式人员的命名打架
: 另一方面我觉得撰写程式都是尽量以让人更好读为目标
: 而不是拼命让字数变少或是用一大堆的注解来取代
: 还有,如果有回传值这样的动作,尽量用function而不是macro
: 泡神就有举个例子:x*x的macro丢进++i会变成++i*++i..
: 我的废话好多喔XD
: 结论是:我觉得这次作业我会用macro只是特例而已
说实在的, 大部分的 C++ users 都会莫名奇妙的排斥 MACROs...
也许觉得那是 C 的遗毒吧~~~ :)
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.21.241
1F:推 dryman:推~又多学到了好几种作法!!! 10/22 13:00
2F:推 dryman:其实不只C++,有很多语言都不太推macro 10/22 13:04
3F:→ dryman:像是python, ruby, shell script, java(有外挂)... 10/22 13:05
4F:→ dryman:倒是perl有macro,不过他的程式特色本来就是走魔幻语法就是 10/22 13:06
5F:推 mymaydayya:perl魔幻语法 XD 10/22 20:38