学C++越学越有味是怎么回事

上面有的朋友说,这种辩论可以引发论点对撞,激发头脑风暴,获取新的知识。但我觉得在 『language holy war』里面,『越辩越明』只是一厢情愿,很多的时候只是越辩越乱。

『没有银弹』这个道理太简短,大家都会背,都会说。但是实际要理解这个道理,需要很多 的实战经验支持。我觉得像 finalpatch 这些参与讨论的大佬,应该是明白这些道理的。但 是旁边围观的人不一定明白。而大佬们的时间往往比较宝贵,不想把时间浪费在这种琐碎的 事情上(我发这几个回复,整理资料组织语言都用了 1 个多小时)。如果没有通俗地讲解 问题,旁观的人不明所以,可能会被讨论的情绪所煽动,火上浇油把『激烈的技术讨论』变成『互相 攻击的骂战』。就像这个帖子里面的一样:

1 个赞

举例问题#

Common Lisp 没有逼你一定要 CLOS,因为考虑兼容 Lisp Machine 之类的历史原因结合得并不是很紧密,很多实现就是做成“没有 OOP 的 Lisp”以后再用 Lisp 实现 CLOS。实际上哪怕是直接从 OOP 自举的 SICL,也不影响用户自己另外实现 OOP 系统。

比如 200 行左右就能实现的 Corbits (CMU AI REPO)

显然更显著的问题是靠动态分发实现 OOP 的性能损失。但这个和问题没关系,因为 GObject 也有这问题。而且和其他所有性能问题一样都可以“靠编译器技术的进步”解决。

这里 C++ 的问题实际是,大约 2015 以后委员会就有了“C++不再是C的超集”的共识。只要标准继续更新,就会离兼容 C 越来越远,每次新标准出来都有更加魔幻的 C++ Hello World。反而一些老资历的程序员都没有意识到这点。

而不是像 ObjC,那才是“真的一直都兼容 C”。

3 个赞

不能编辑原想法,只好删了重发。。。


c和c++都喜欢。仅仅谈c语言的优点。

c从一开始就是作为高级的汇编存在,c的定位很明确,用c写的项目,多是底层稳定的模块,如nginx, redis, libev, kcp等等。

c的项目,虽然指针,宏等看起来并不清晰,但是这是c作为 ‘高级的汇编’ 不太优雅但是适用的解决方法。

如果为其做加法,例如: 增加泛型简化宏, 增加闭包简化void* args + void(func)(void)等高级语言的特性. 功能当然会更加强大,例如,上面道友提到的例子,c++的std::sort()可以内联函数对象,而c的qsort()要通过函数指针而多了一次函数调用。

不过如果这样做了,c的设计定位不再是‘高级的汇编’,语言逻辑出现漏洞,往后就只能不断打补丁了。

c一开始就坦然面对自己的缺点,虽然远远没有c++强大,但是拥有明确的语义和使用场景(也许在底层领域并不需要多么高级的语言特性)。 malloc, free等等都很明确,没有歧义,我认为这很重要!!!

我不太认同 “c++包含c,所以写c代码就是c++代码”,因为我认为语言的设计哲学会影响使用者的思维。例如使用c++时,一方面c++能够让你控制内存,但又允许你利用容器去接管内存,这样容易留下暗坑,如下代码(你不能像写java一样写的飞起)。而写c代码,你一开始就不会有这种想法。

std::vector<std::string> vec;
vec.push_back("hello");
std::string &str = vec[0];
v.push_back("world");

我发现你这个辩论方法很有意思:“我虽然打不过你,但是泰森打得过你,所以你也没什么了不起”。我从第一个帖子里就在说,我们用C++不是因为它是一种优美的语言,而是因为往往没有其他选择。做业余项目的朋友也许难以理解,在公司里做东西,不是我想今天加个kotlin或者rust就可以的。

这个帖子争论的开始就是我建议某个网友不要自找麻烦去用C做泛型容器,因为这个早就证明是做不好的。我看大家也都认可Go接受泛型以后变成了一种更好的语言。不知道为什么接受C语言不支持Generics是个缺点就这么困难,一定要争辩没有Generics用宏也都能做到一摸一样的效果。

2 个赞

你的观点没错,但是编程语言这个话题,大家自己工作经验,适用范围和个人喜好都不一样,更不用说编程语言的优缺点了。

这也是每次争论编程语言都不会有好结论的原因。

你的头像看起来很权威,我也学一下

7 个赞

我c,c++都喜欢,各自有适合的场景,不是竞争关系

哈哈哈哈,头像不错哈。

头像草

2 个赞

我感觉 cireu 并不是在和你辩论。分享那篇文章只是恰好联想到了而已,并非用来说 C/C++/Rust 哪个更好。 :grin:

是否被证明过我不清楚,但是我觉得你说的是有道理的。

对我来说,如果你说 “C语言不支持Generics” 那么我表示同意。我回想了一下,我之所以会回复,是因为看到下面这句。

特别是这里限定了“在性能上”,我想着只考虑性能的话,这句话有些绝对了。而且我当时说的是“类似的效果”,而不是“一模一样”。哈哈,你看这不小心错了一个词,意思就完全不一样了。当然我知道你肯定不是故意的 :grin: 。另外,咱们后面讨论的范围已经超出性能了,我感觉你的一些观点我是很赞成的。

下面有些题外话,昨天通过 @cireu 的帖子看到了很多之前未曾仔细读过的论战,以及翻到了论坛上的一些陈年旧事。有些感慨,在网络上做到有意义的讨论是一件比较困难的事情。 原因很多,其中一个是文字的表达力不足,举例来说:

  • 我发了一句:“今天上海天气真好”

你并不知道我这句是开开心心地说,还是咬牙切齿地说,又或者是充满讥讽地说。 :rofl:

而且大家的关注点又不一样,于是会有不同的回复:

  • A:难道昨天天气不好吗?
  • B:今天是个 XXX 纪念日,你就只顾着天气?
  • C:怎么着,上海还有优越感了?

而且每个人的主观感受也不同,心情可能完全不一样:

  • D:上海这么热的天气也叫好?
  • E:上海这么冷的天气也叫好?
  • F:(刚和别人吵过架,应该也会有不同的回复吧,我想不出例子了 :joy:

上面这些情况夹杂在一起,非常容易争论起来。尤其争论过程中,当有人不小心说了些让其他人觉得被伤害的话,而感觉到被伤害的人又要奋起反击的时候,场面可能会变得不可收拾。

这方面我自己的经验是,以最大的善意去揣测别人的回复,避免一些不必要的冲突。不一定适用于所有人,但执行下来确实能让我自己想得开了 :slight_smile:

上面这小段有些偏题了,不过初衷还是希望论坛能越来越好 :stuck_out_tongue_winking_eye:

我觉得有必要再加一句:我这些表情真的真的都是字面意思。自从微笑表情有了多种含义,感觉发表情也不安全了 :rofl:

5 个赞

老实讲我压根没想到有人会来杠用预处理宏实现泛型容器,因为这个选择太过不实际。结果这个讨论就变成了证明宏是不是一个可靠的语言机制,我当然觉得它很明显不是。

也不算是杠吧 :joy: ,因为看到在 Linux 内核里用宏很多,所以你一说泛型我就想到了 Linux 他们的写法,导致认为用宏是一个很正常的想法。至于选择是否实际,每个人看法可能会不同,我尊重你的想法。

想体验用宏过度可以看看 emacs 的 C 源代码(

5 个赞

笑死 :joy_cat:

DEFUN绝对是良心,那些CAR之类的一路跳进去简直想死。。 :rofl:

今天在Emacs中,用C语言实现了栈
感觉很好 :grinning:

1 个赞

今天在Emacs中,用C语言实现了队列
感觉很好 :grinning:

1 个赞

我觉得语言争论还是少一点比较好,非科班的初学者很容易就陷入到语言争论里面去的。之前我看了太多反对Java的帖子,然后就真的学了一年半编程都没有去碰过Java。。。

当然,讨论语言的缺陷其实也是一个深化熟悉的过程,就像C语言使用者就有一本《C缺陷》,知道自己不能做什么才能更好地去做一些什么。

不过我觉得其实即使批评某个东西,那也是熟悉的人才能批评到点子上面,就像小马过河,真的要学了才知道优点和缺点,才有资格去评价这门语言。如果根本就不熟悉这门语言就听信了负面评论而跟着别人走了,那简直是愚蠢无知。

2 个赞

这有什么需要熟悉才能批评到点子上的,java写个helloworld罗嗦的一批内存起飞,直接劝退有什么需要熟悉的。评价一道菜好不好吃需要知道怎么做吗,尝一下就够了吧。

3 个赞

请大家以后少发编程语言的话题吧,从本论坛历来的经验看,很少是以好好交流态度结束的。

每个人都说自己是客观交流,但是一旦自己形成固定认知,别人说自己熟悉领域不对的时候,每个人都只会为了证明自己对而辩论,或者抓住一些细节不断歪楼,甚至达到相互攻击的程度。

请问大家,到底是客观交流相互学习重要?还是为了证明自己就是一个自大的人,自己就是对的这件事更重要?

13 个赞