当前位置: 首页 > 互联网 > 正文

一个C语言问题引起的讨论

一个C言问题引起的争论

几天前我在开源社区(oschina.net)发了一帖:C语言不同头文件的函数名冲突问题。具体的内容是我在一个项目中在两个头文件中定义两函数,这两个函数除函数名称(都是MakeEmpty)一致外,函数的参数类型及返回类型都不相同。编译时仍报出这样的错误:错误 1 error LNK2005: _MakeEmpty 已经在 Stack.obj 中定义。错误 2 error LNK1169: 找到一个或多个多重定义的符号。问题发出去,当然有人回:C语言不支持函数重载,编译后的名称都是一样的;可以用静态函数或者用宏替代一下;也有人回复:这个在C语言中基本没有好的的解决办法,特别是代码量一大。我也从网上或其它地方找到原因并在原帖中标注:

假设某个函数的原型为:
void foo( int x, int y );
该函数被C编译器编译后在符号库中的名字为_foo。
所以同名函数编译之后在符号库中的名字都一样,有冲突。

一个很看似很简单的问题却引起了一个巨大的讨论,并从C语言衍生到了C++语言的探讨。激烈的讨论是由小耶果的回复触发的,我将聊天过程中我认为有参照意义的部分摘抄下来吧:

小耶果:

我想正因为有这个那个原因在随着代码量的增多C的易用性和简洁性越来越丧失导致C++的诞生.那些批C++的人基本都没有参与过100w行以上的纯C代码维护的痛苦.如果你看过foo1-foo499并且能够很好的在代码call中分辨出他们,我只能说你确实能够有资格批C++.

上面的话马上引起了宏哥的回复:宏哥引用了“小耶果”的上面答案:

C++几乎没有100万行代码的东西
人们学习C++不是从MFC, 就是从STL, 这两样都是非常糟糕的设计.
应该好好想想为什么, 100万行以上代码的都是C而不是C++
另外回答楼主:
static可以解决问题. 名字空间, 是任何程序设计必须解决的问题, 不管你使用何种语言.
动态链接库可以有更高级的名字空间管理方法. 根据不同编译器/系统不同.
楼主的问题在于它把函数作为全局名字输出.

小耶果立马回复:

C++我自己搞的一个项目虽然离100w还差一个数量级,但最终目标应该定在70w-90w行之间.哈哈,的确还差一些.呵呵.windows是C/C++/masm+其他的混合产物,代码已达到9000w,现在还不止.可能累计的C++代码肯定超过100w吧,另外Unreal Engine,CryEngine还有不少3A级大作游戏估计都有100w吧.不过没具体统计与考证.

宏哥回复:

回复 @小耶果 : 我没有用C编写过很大的项目. 目前只是看到的, Oracle, 以及linux下所有大规模软件, 以及工业领域, 甚至windows所有的原语级别东西, 全部都是C, 没有C++的影子.

甚至, 要为C++学习者, 找一个好的样本来学习,都非常困难. 因为C++几乎没有什么好的东西.

我没有考证过我不熟悉的领域.

只是根据个人经验, C++不适合做大规模项目. 至于你说的引擎, 一个是没有见过,另外一个,也不知道它们在市场上的地位. 我通常以市场地位来衡量项目价值. 如果你有足够的人力, 有足够的资源, 那么你用C++没用问题, 有钱烧就无所谓. 可以通过增加资源投入来达到目标.

不能说, 绝对不能使用C++,我只能说, 大项目, 你使用C++, 只会增加失败的可能. C++主要用途还是在桌面.

小耶果回复:

这二个引擎(Unreal Engine,CryEngine)都是世界级的,可以说是世界top3之内的.很多3A大作以及国内大型3D MMORPG很多都是使用它们的成果.另外使用C++会有很多陷阱我想主要有二个方面:1 团队合作的方面 2 过度使用的方面.

1.我个人单兵作战没有问题
2.我只用C++的一个子集,就是class.从不去碰什么菱形继承,模板偏特化和一些hack种种的做法.用class的目的就是更好的组织和封装代码,使得整体结构更清晰.在我的项目中只要把class关键字去掉,所有成员方法前加上class name前缀,处理好批次数据封装和继承等问题就能在C编译器中通过.如果这样使用还有什么陷阱那么就是C的陷阱和C++无关了 ,另外我自己的项目中实现了一套STL基本容器,虽然使用C++,但几乎没有使用到STL的类似东西,字符串都是自己实现.这样做的目的倒不是否定STL,只是定位不同,在我的项目中STL并不合适.呵呵.

至于你自己的项目, 用C++, 如果不是以C的方式来使用的话, 我个人认为,失败的几率极高, 除非规模很小. 这里面的陷阱太多了, 没有几十年的经验, 你没有机会逃离所有陷阱. 当然, 最终决定成败的是市场定位, 不是c或者C++的选择. C++只大幅增加你失败的可能.

宏哥回复:

不得不说, 你能控制C++. 大多数人做不到这点.
这是大师级的用法.

这时billzheng也加入了讨论。

billzheng说:@宏哥 @小耶果

我们在电信的时候,里面的工程师都是10多年C开发经验,结果程序开发周期特别长。用timesten数据库再结合C简直要命。有些人几年写不好一个程序,C 水平不高么? 也不是是高级技术专家。后来我建议用C++,代码缩水80%, 速度反而提高。全部使用smart pointer, 没有原始指针,再也没有麻烦了. 节省的资金是千万美元级别的…

小耶果回复:

表示怀疑,C用不好的人很难能用好C++,因为C++是引入更多的特性同时带入更多的隐患.平均多一个特性就多3个隐患.如果使用C++那么立竿见影的话那么肯定是使用了一整套非常优秀稳定的库来帮助开发.就如很多不会写C/C++的人用C#很爽,写出来的东西也没有明显的缺陷一样(当然损失些性能是肯定的)

宏哥在billzheng的评论上进行了回复:

@billzheng : 在你所指的这个项目/产品上说, C的确被淘汰.但是,从更广泛的商业领域, 就不是这个结果. 任何事情,总有一个决定, 有赢有输,很正常.

@billzheng : 你特定的项目,当然是这样. 如果说工控, C++就被淘汰了,国内银行,电信也是这种情况. 这种比较是以偏盖全.只能说明,你的项目上,C被淘汰.

宏哥自己另起了评论:

我没有绝对化关于C++的选择问题. 我通常所指C++是那一大堆的玩意,继承, 友元等等,将他们作为整体看的时候. 我一直建议, C++的用法, 就是要简单得用. C和C++指针都是大麻烦. C语言也很难掌握.

也是我一直鼓励野鬼写一个C的书, 很少书籍从生产角度分析.

我自己也曾经用C++封装过OCI的库, 最终提供一个非常简单的接口访问Oracle, 利用STL, 当时引以为豪.

后来我把这个东西,完全删除. 理由就是, 和数据库相关的东西, 性能瓶颈在磁盘, 完全可以用PHP 的OCI库来达到更简单的目标. 所以删除了.就这么简单. 弱类型对数据类型处理更方便. 如果你不要很高的性能.

我基本上谈论一个最佳approach的问题.实际上, 在成本/计划范围内, 大多时候, 你不需要最佳approach, 你需要的是可控. 如果你有这种控制力,当然OK.

小耶果评论:

我始终认为优秀的C#程序员都是其他语言转过来的,尤其是C/C++,糟糕的C#程序员通常他们学的第一门语言就是C#.同理,优秀的C++程序员都是C过来的,直接C++你会失去很多本来因有的东西.但是现实是绝大部分人一开始就从C++开始学,这样导致他们丧失了闻到代码中潜在坏味道的功能,所以不可维护,处处漏洞的代码处处可见.问题是C精通的人有几个再愿意转C++,人都是惰性的…

宏哥引用“小耶果”的评论:

从语言角度,我同意你的看法.

但是另外一个方面.Domain 和Function更重要.

我见过用vbscript写的Excel应用, 是CFO自己写的,没有学过计算机, 极好用. 以至于买软件的时候 , 就拿excel对销售人员说,我们要的就是这个效果.

卖软件的一个供应商对我说,我们的系统是java写的,跨平台, 能支持多种数据库………..

最后我们选择一个只支持mssql的供应商, 因为他们能在我要求的30分钟之内, 做现场演示.

很多成功的软件开发者,其实都是从Domain, Function转过来的, 因为他们解决了一个软件当中最重要的问题:

就是这个软件到底要干什么?

有时候, 代码好坏很难说, 你只需给它一个好名字, 如果它经过很好的测试, 就是好代码. 测试过的代码, 任何修改都导致回归测试.

在商业社会中, 有综合考量, 是不是最佳approach,常常根本不重要. 这本身也是一种智慧. 可以说, 你选择C++也是一种智慧, 但是不代表C没有更好的办法.

小耶果回复:

前提之一是 业务大于技术这个前提成立

比如从未了解系统原理,指针等,但是用C#把业务实现得很漂亮的人大有人在.以我的划分这些人就是业务型人才同时掌握实现的能力.因为在这些领域,懂业务更重要.技术上的东西选用成型的东西就可以了,可以是任何库也可以是任何语言.

在这些人眼里,技术只是实现业务的手段之一. 所以关注点不同导致对技术的选择也不同.
是的,计算机行业涉及太广.而我们程序员,纯研究技术的程序员研究的是计算机技术本身的技术领域.所以从语言讨论的角度来谈都会倾向于计算机本身的模型,但是往往忽略了计算机本身是解决问题的环之一.所以很多程序员再一起出发点不同,关注点不同,大都谈不拢的根源也再此.

billzhen的讨论:

1. static 变量是全局变量. 大量使用全局变量严重违法简单化和数据隐藏。

2. static变量非线程安全, 如singleton非现场安全

3. static变量导致的bug非常难找.

4. Class 成员在栈上而非全局和static完全不同。

如果你的程序经常有莫名其妙的错误,而你找不到…想想是不是有static变量,如果只说static function那是对的

简单的问题经过大家的讨论一切变得丰富起来,从语言特性到编程细节再到习惯等等。让人从更多的方面去比较c与c++的不同,从而要求我们在学其中一门语言的时候要去注意什么,并结合具体的项目选择更好的环境和工具,并组织最好的人员。原帖网址

本文固定链接: http://www.byhard.com/?p=749 | 海纳百川

该日志由 byhard 于2012年10月29日发表在 互联网 分类下,
原创文章转载请注明: 一个C语言问题引起的讨论 | 海纳百川
关键字: ,
【上一篇】
【下一篇】

一个C语言问题引起的讨论:目前有26 条留言

  1. 12楼
    百家乐:

    简单的问题经过大家的讨论一切变得丰富起来,从语言特性到编程细节再到习惯等等。有时一个话题出来,就有很多问题

    2012-10-30 00:04
    • byhard:

      嗯,越讨论越清晰,越对自己有帮助。所以,有些时候开会变得很重要。

      2012-10-30 08:55
  2. 我是进来学习的,嘎嘎

    2012-10-30 00:08
    • byhard:

      大家互相学习吧。谢谢你的支持。

      2012-10-30 08:55
  3. 受益很多啊,谢谢啦

    2012-10-30 11:56
    • byhard:

      不用客气,分享是我很大的快乐,谢谢支持。

      2012-11-01 08:47
  4. 来学习了

    2012-10-30 13:39
    • byhard:

      你很好学哦,谢谢支持啦。

      2012-11-01 08:47
      • 哈哈,多学习学习总是没错的嘛

        2012-11-01 15:26
        • byhard:

          希望能学以致用,这样学习才有价值。

          2012-11-06 14:16
  5. N年前学习的,现在都忘差不多了

    2012-10-30 15:55
    • byhard:

      同样啊,现在再重新开始学习呢。

      2012-11-01 08:46
  6. 学好久了,都忘的差不多了

    2012-10-31 09:54
    • byhard:

      也是的,我也忘了很多了。

      2012-11-01 08:46
  7. 过来学习学习下

    2012-10-31 15:00
    • byhard:

      欢迎光临,谢谢支持哦。

      2012-11-01 08:39
  8. 反正我对C++是深恶痛绝,封装之丑陋,简直让人发指!

    2012-11-01 04:43
    • byhard:

      嗯,也听到很多人讨厌C++,我还是先不接触吧,先学下c语言吧。

      2012-11-01 08:39
  9. 曾经的哪些编程都变得很陌生了,似乎不应该那样学习

    2012-11-01 09:49
    • byhard:

      嗯,也可以说当时的学习方法不好,让人印象不够深刻。

      2012-11-06 14:14
  10. 应该这样说,似乎老师将方法弄的复杂了,所以不容易理解

    2012-11-01 09:50
    • byhard:

      也可以说我们老师的教育水平可以,但是实践功底差了些,纯粹的教语言。

      2012-11-06 14:15
  11. 板凳
    四季网:

    佩服会编程序的人才

    2012-11-01 12:50
    • byhard:

      你的网站刚在设计,加油啦。

      2012-11-06 14:15
  12. 沙发
    菲奥娜:

    很精彩的争论啊

    2012-11-01 22:19
    • byhard:

      呵呵,我也是这么想的。

      2012-11-06 14:17