免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 20961 | 回复: 51
打印 上一主题 下一主题

关于代码的适度冗余 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-11-19 17:24 |只看该作者 |倒序浏览
最近有几个帖子在批判“垃圾代码”。
垃圾代码这个概念太模糊,不知所云,我暂且理解为冗余代码。

我的观点是,适度的冗余是必要的。

原因很简单,我们不妨考虑完全没有冗余代码的情况,用另一句话说,这样的代码应该是“多一个字罗嗦,少一个字出错”,且上下文之间关联性是最大化的。
这样好吗?不好!尤其是编码初期更是不好!因为这样的代码又脆又硬,说白了就是“禁不住折腾”——没人敢碰。因为代码不可能一次成型不再改动,出于各种原因,代码都可能后来发生变化,而且可能是由不同的人做出变化,如果你的代码牵一发而动全身,后来修改的人会很累不说,还可能引入BUG。

  1. ...
  2. ...
  3. ...
  4. static int arr[XXX]={0};
  5. ...
  6. ...
  7. ...
  8. static int somefunction(void)
  9. {
  10.     ...
  11.     ...
  12.     memset(arr, 0, sizeof(arr));
  13.     for (i=0;i<XXX;++i) {
  14.         ... /* 一段代码,要求arr数组的成员必须都是0 */
  15.     }
  16.     ...
  17.     ...
  18. }
  19. ...
  20. ...
复制代码
分析上例,
全局数组赋初值是不必要的,因为它是static的,没有强定义的需求,这就属于不必要的冗余。
而memset就属于适度冗余,利大于弊。如果不写memset的话,一旦后来有人在memset前面什么地方加入了别的代码,修改了arr的内容,他如果知道下面代码的需求,还是要加上memset的,如果他不知道,后果就未定义了。

另外:

  1. ...
  2. ...
  3. static int somefunction(void)
  4. {
  5.     ...
  6.     static char buf[XXX];
  7.     ...
  8.     ...
  9.     memset(arr, 0, sizeof(arr));
  10.     snprintf(arr, XXX, FMT, ...);
  11.     ...
  12.     ...
  13. }
  14. ...
  15. ...
复制代码
上面这段代码中的memset是不是冗余就很难说了。也许是无意义的冗余,也可能是绝对必要的代码,必须看清上下文才能判断。

冗余的的代码的确会降低代码执行速度,理应在编码最终完成后清理并重新测试。但是,事实上,编码真的能够最终完成,不再修改吗?这样的代码太少了!!!
即便最终完成了,应不应该清理也要参考oprofile等剖面分析工具的结果,是瓶颈的话,优化,不是瓶颈的话,不必优化。

论坛徽章:
1
CU十二周年纪念徽章
日期:2013-10-24 15:41:34
2 [报告]
发表于 2010-11-19 17:30 |只看该作者
这个应该是要的,曾经调试的教训。

论坛徽章:
0
3 [报告]
发表于 2010-11-19 17:34 |只看该作者
冗餘基本無濟於事 僥倖靠冗餘能使最終結果仍然對的幾率不多吧

论坛徽章:
0
4 [报告]
发表于 2010-11-19 17:40 |只看该作者
冗餘基本無濟於事 僥倖靠冗餘能使最終結果仍然對的幾率不多吧
huxk 发表于 2010-11-19 17:34


请说明顶帖第一种情形的“侥幸”在哪里。

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
5 [报告]
发表于 2010-11-19 18:51 |只看该作者
本帖最后由 gvim 于 2010-11-19 18:55 编辑

老牛,我觉得第一种不是冗余,因为有函数使用的契约或者说要求:
/* 一段代码,要求arr数组的成员必须都是0 */

全局arr一定只被自动初始化一次,而somefunction不一定只调用一次.
另外即便设计somefunction只调用一次如init类函数,也不能保证somefunction之前没有其他函数修改arr

所以在for 之前,必然要按照函数契约清理arr

论坛徽章:
0
6 [报告]
发表于 2010-11-19 18:56 |只看该作者
传说中的防御性编程?

论坛徽章:
0
7 [报告]
发表于 2010-11-19 19:21 |只看该作者
老牛,我觉得第一种不是冗余,因为有函数使用的契约或者说要求:
/* 一段代码,要求arr数组的成员必须都是0 * ...
gvim 发表于 2010-11-19 18:51


我觉得你说的没问题,这是个人尺度的差异——你认为不是冗余,我认为是良性冗余

论坛徽章:
0
8 [报告]
发表于 2010-11-19 20:17 |只看该作者
不喜欢冗余。一如不喜欢SGML/XML/HTML/XXML的标签语法。
如果非要靠冗余才能实现正确的编码,那么至少说明了两点——
1.使用者不够仔细;
2.语言缺乏易用的表达某种语义(例如契约)的机制。
同意5L的观点。

论坛徽章:
0
9 [报告]
发表于 2010-11-19 20:44 |只看该作者
不喜欢冗余。一如不喜欢SGML/XML/HTML/XXML的标签语法。
如果非要靠冗余才能实现正确的编码,那么至少说明 ...
幻の上帝 发表于 2010-11-19 20:17



    举个例子? 比如什么语言的什么机制支持你说的这种契约? 能给例子最好,谢谢

论坛徽章:
0
10 [报告]
发表于 2010-11-19 20:45 |只看该作者
很感兴趣这个话题,期望更多大牛讨论
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP