Skip to content

Instantly share code, notes, and snippets.

@FrankHB
Last active May 19, 2024 10:43
Show Gist options
  • Save FrankHB/00731fedf07b4ea271afa70a5cdc8d9d to your computer and use it in GitHub Desktop.
Save FrankHB/00731fedf07b4ea271afa70a5cdc8d9d to your computer and use it in GitHub Desktop.
贴吧相关 FAQ 、资源链接和其它附带清单。

贴吧历史资源整理

吧务操作

http://tieba.baidu.com/p/4171474077

日常(经)整理

http://tieba.baidu.com/p/2286985797

头衔

http://tieba.baidu.com/p/1293939748 C++吧的头衔勋章应该能改了吧

http://tieba.baidu.com/p/1294795004 【征集】C++吧头衔名征集帖。

http://tieba.baidu.com/p/1297445553 C++吧头衔碉堡了

http://tieba.baidu.com/p/2124684426 咱就不能有个正常点的会员名称吗?

http://tieba.baidu.com/p/2484488705 请问咱们吧的头衔亮出**cm是什么意思呢

http://tieba.baidu.com/p/2497542074 新人刚来 头衔好奇怪…………

http://tieba.baidu.com/p/2190079071 新人报道,话说这神奇的头衔是怎么回事→_→

http://tieba.baidu.com/p/2601257047 我非常迫切的想知道,咱吧里的会员头衔是什么个意思,亮出...C

0cm

<15cm

=15cm

似乎是 http://tieba.baidu.com/p/1820200287 ,已炸。

>15cm

关于头衔的外吧评论

会员名

个人 FAQ

头像

http://tieba.baidu.com/p/1291218344

学习历程

http://tieba.baidu.com/p/3388459316

基本法

操作示例

部分引用置顶索引贴 http://tieba.baidu.com/p/2678895259

例 1

[吧务操作]
解释备案。
依据现行吧规(git版本81e9aa0a0eccc127fa87ecb99b506b65c3c332ea,最后修订20140322),对本帖操作解释如下。
A.鉴于由LZ本人提交给吧务的证据,兹裁定LZ在本贴以前违反以下条款:
3.10。
B.兹裁定本贴LZ违反以下条款:
1.1、1.3、1.4、4.3、B.7、B.8。
C.违规认定和正文条款处理意见:
由条款2.5,判断LZ已经构成违规。依据2.1、2.3、2.5条款,对LZ违反3.10的处罚已经先期执行,对其它违规行为暂予保留2.4条款执行权力。
D.B条款处理意见:
操作者认为此贴意义不足以挂城门。
操作者认为此贴可以于不特定时间不解释删除,但暂缓执行。
[吧务操作]
补充30L说明。
E.25L建议按2.1条款仍然有效。不确定时间生效。
F.鉴于保留处理不属于不解释事项(2.9条款定义),兹解释保留暂缓处理的理由如下:
F.1 涉嫌多项违规,在30L明确行为前可认为不宜直接合并处理。
F.2 涉嫌傀儡账号(2.4条款定义)。对傀儡账号是否需要和LZ此帐号合并处理有待审议。
F.3 涉嫌的事由涉及操作者以外的吧务。尽管事实清楚,操作者仍然认为有必要转达处理现场。通知已经发放,待结案。
F.4 操作者认为此案例具有现实教育和阻止继续违规的意义,可以重申私信骚扰对于合理诉求无效这一常识性问题。
F.5 操作者认为此案处理过于仓促,不足以发挥惩戒的威慑作用;操作依赖F.1和F.2,仍不足以构成判例。

例 2

[吧务操作]再次提醒,暴力膜吱也须遵守基本法。
作为管理者,吧务希望吧友能够亲切友好的交谈,或者至少能坦率交谈。因为一般来说,会谈是有益的。
本吧对主题内容的要求和限制整体上并不严格。回复中个别人交换了意见,即便和主题内容无关,吧务原则上也没有必要干涉。当然,明显超出必要的限度,过于充分地交换了意见而造成不愉快,不管是否增进了双方的了解,都可能适用吧规处理而限制权利。
在合理合法的前提下,我们尊重吧友的言论自由权利,赞赏强调遵守规则的讨论者。对于非明令禁止以避免损害吧友利益的个人观点,我们持保留态度。在规则限定外,若产生误会,只能表示遗憾。
我们历来会对在规则之外没事找事、套用双重标准、道德绑架的讨论者表示极大的愤慨,并对可能发生的违规行为表示严重关切。特别地,单方面主张自身权利而无视他人权利者,不能置之不理。对所有这些不利于正常讨论氛围的情况,吧务保留做出进一步反应的权利。
考虑到出错可能在所难免,我们有限地允许关于言论中的不当内容,并留出适当时间做出修正。必要时,吧务可能限定时间限制。在进一步回复后,我们将重新考虑这一问题的立场。
无视客观事实、颠倒黑白和煽动群众分裂吧友阵营是我们万万不能容忍的;这是不友好的行动,是可忍孰不可忍。
我们敦促某些挑衅者悬崖勒马。执迷不悟者,不妨拭目以待,希望本吧的立场给你们能留下深刻印象。这对社会资源来说是也有益的,所以道德制高点基本上也自然失效了——换言之,请不要继续无谓地挣扎;否则,请自行负责由此引起的后果。勿谓言之不预也。

题外话,这样一说为什么到此为止这里瞎bb跳脚的不是“路人”就是有据可查作奸犯科嫌疑者?或者说“路人”就能和当权者划清界限于是乎了不起?也罢,看了这几个所谓的“路人”,要是真能代婊路人的平均水平,我以后都不好意思拿自己当路人逛别的吧示众了……
用祈使句前请搞清楚自己的能耐,不要别人科普权利和义务的有关常识。

借LZ贴,以下对所有自我意识过剩目无法纪好为人师没事瞎bb的逗比宣战。

(因为这个话题太low所以不好意思开新主题。看LZ先前积极参与的态度,放在这里大概也不算污染主题。)哪个想对号入座不满的,除了自挂到http://tieba.baidu.com/p/2390940218,到这里回复能澄清自己立场的不违反吧规的仍然保留。不过既然有够多敬酒不吃吃罚酒/给脸不要脸的例子,之后我也懒得警告,直接专政到能认识到错误、自觉闭嘴为止。到底战斗力过剩,拭目以待。

 [吧务操作]鉴于此类主题的内容和影响,拿基础学科话题解释而不是纯水的,注意尽量做到以下几点,否则同吧规4.6并从严处理:
1 明确讨论的具体对象的外延,以及和主题之间的关联。
1.1 一般应指出具体的学科分支以及直接影响,能让读者推断重要性之理由。
1.2 区分该学科的理论和课程。能让读者明确了解知识点依赖和学习的困难程度。
1.3 明确讨论的理论分支和整个学科的联系,严禁以偏概全。如有必要,明确该分支适用的范围。
2 确保可能发生争议的观点可以查证。
2.1 区分原创研究和公认事实。
2.2 没有把握或存疑的观点应明确指出。
2.3 必要时引用文献。

惩治戡乱纪要

例 1

http://tieba.baidu.com/p/3716248078

(因为内文含文本转义记号,分别加注。)

这个主题保留。

正好挂人,我懒得开新主题污染版面。

首先,关于LZ的一些“为什么学”的问题:有些人蠢惯了,也喜欢你们跟着一起蠢,这样谁都“方便”。然而只要制造了些玩具扩散了,擦屁股的人还是要有的,只不过怎么也轮不到没能耐的蠢人。

yucwei:        回复 幻の上帝  看来你是很懂了,那我问你一个问题,解决一个问题是用简单易懂的方法好,还是用只有你自己明白的不知道从哪里抠出来的歪门邪道的方法好?你所谓的懂就是一些不入流的,拿不到堂面,不值一提偏道技巧而已。

做个典例挂着。楼中楼回复不够显要,重复一遍:

幻の上帝:   回复 @yucwei   :你爱怎么解决就怎么解决。但是当你提出一个足够蠢的问题却还掩饰欺骗别人说这不蠢时,你浪费的别人的时间和精力就比你无论怎么解决的价值更大,那么就老 实挨打吧。好好反省一下懂一般需求的正常用户和只懂其中一小撮子集的逗比用户评论解决一般问题入不入流这种破事上,谁更有说服力呢。

然后要补充的是分析一下行为动机和额外结论。
先说结论:蠢货多数是牺牲品,然而另一方面又是祸害——只是因为收拾起来太麻烦了所以才能苟延残喘——这里应该也不例外。
分析理由:
首先这些人入门的时候就被某些现成的蠢货推销了挂羊头卖狗肉的黑材料,以为他们“学会”了某些真的“有用”的东西。
恰好C这样的语言因为设计和历史原因,特别适合造成这种错觉。实际上他们不是学会了真正被普遍承认的、在现实中发挥作用的C(羊头),而是一种按照个人智商局限下曲解以后的方言(狗肉)。
不巧,这些黑材料的作者自己并没有能耐实现语言(写个编译器啥的),自然更不可能改变工业界会用的解决方案了。
而某些黑材料又特别乐于或者只擅长于把C++阉成那种不伦不类的玩意儿。
于是这些黑材料的读者就被迫在微妙对不上号的现实实现和黑材料本身做出取舍。可能智商局限性会传染,缺乏其它补充材料对比时,就更容易盲信了。
比如说,当发现编译运行结果不符合预期,就自行脑补“原理”,以为靠自己眼前的个别现象就能归纳出普遍规律;甚至选择性无视,忽略和期望不符的事实自欺欺人。
可惜不管语言还是语言的实现,都是人为设计的结果。这种一厢情愿的学习方法一开始就是图样逗比的笑话。于是当没有正常靠谱点的材料撑腰又不知道对比和直面无知时,姿势当然正确不到哪里去。
对着C/C++这类敢于规定UB的语言这样YY,不仅是给自己挖坑,还给别人制造擦屁股的成本。(重复,智商局限性有传染的风险。)

无知是没问题,卖蠢还真是敬谢不敏。

然后,关于陈良乔。
我为啥要说这个人呢——大概是因为某些方面也比较极端吧。
@人类的潜力 :        回复 用微笑释怀岁月  :如果觉得自己技术可以,推荐c++primer,或者2本都买,再给你推荐本国内牛人写的《我的第一本c++书》
正好有人提到了,看来也不算有意误导那就回一下。
首先,他那本《我的第一本C++书》的逗程度应该还是有点知名度的。
(其实以前也说过了:http://tieba.baidu.com/p/1519041467。)
要真以这本书的水平把所谓的“牛人”划分成一个等价类,我觉得这快到人身攻击了。所以就吐槽了。
客观地说,这人应该也不是完全有胆子像谭×自信爆棚乱跑火车,所以有时候翻译Bjarne Stroustrup的话啥的也没敢夹带私货。不过原创材料基本就只是笑话了。
这个人和我没啥私怨,不过给我和许多其他人的印象很糟糕。我能记得他的唯一一个突出优点就是说话能不带脏字,而骨子里十动然拒就是死皮赖脸,被指出硬伤以后就是当作没有造成伤害判定。换句话说,厚脸皮。
具体一点,要八卦的:
http://bbs.chinaunix.net/thread-3692320-1-1.html
http://bbs.chinaunix.net/thread-3772840-1-1.html
当然,图书市场编辑水准啥的这个也习惯了,另当别论,这里不多展开。
另外一个八卦是陈良乔和某个不入流的民科以下水准自称“人宇科学”的奇葩团体有一些看来说不大清楚的关联。
看来对一般的中老年人都没啥传教效果……这使我对其信众的素(智)养(商)判定降低了30点偏差值。

贴吧官方作死

就这点斤两也想 70W 大戏,呵呵呵…… (结果是 4W 都没人要……)

“很遗憾地告诉您,您因不符合我们的要求申请未被通过。可能在以下方面需要加强哦~”
呵呵……
“1、提高您的活跃度,多登录,多发言”
请指教每月90%登录的Lv14的2.8w贴还差多少?
“2、提高您的发言质量,积极参与有意义的言论建设,不要为刷等级而灌水”
咦这里有谁敢刷等级灌水?
“3、使用文明的用户名”
不文明的用户名不直接干掉居然还能留着允许点申请吧主?

待定整理内容

待补充

const/常量表达式。

参考:

https://github.com/FrankHB/pl-docs/blob/master/zh-CN/variables.md

指引和科普

文献相关

范型

计算理论

所谓语言入门基础说

所谓“语言就是工具”

什么东西适合用 C++ 写?

http://tieba.baidu.com/p/4054226083

@回复 MaDDove :

仍然需要 FAQ ,列个提纲。
什么东西适合用 C++ 写?
现有的参照:http://www.lextrait.com/vincent/implementations.html
为什么?
总体来说理由有两类:
1 不得不用。用其它语言,现实中不够具有可操作性,不是不可能,就是不方便到基本不可能。
有些东西,不管是在什么系统上几乎都只可能用确定的一种或几种主要实现语言。
通常贸然换用其它语言会遇到这种情况:有更大的风险遇到别人都没遇到过,又没法保证自己解决的问题。
如果加了虚拟机之类的间接运行时可能稍微好一点,基本上用其它语言直接扩展也比较麻烦。
这大类理由也适合其它语言,不限 C++ 。
一些大型的应用软件(典型地如浏览器)、应用虚拟机、可复用组件(如游戏引擎)和以及许多特定领域的应用,传统上主要的核心都是建筑在 C++ 上的且现在仍然占据绝对优势(历史上使用其它 C 、 Java 等其它语言实现的很多也迁移回 C++ ),极少有例外。
对于 C ,则集中在操作系统组件(及设备驱动程序)和版本管理控制等相对少数领域内。
还有一些领域,如数据库引擎、桌面环境等,主要实现语言不是 C++ 就是 C ,有更多机会混用。这也是很多情况下统称 C/C++ 的理由。
也有一些领域,曾经 C/C++ 也被相当广泛地使用,但之后使用更简便的其它替代,典型的就是 Web 后端(不含应用服务器自身的实现)。
1.1 历史包袱。很多项目历史代码就是主要用确定的语言写的。
1.2 习惯因素。这影响现有资源的可用性。
2.虽然也可以用其它的写,但因为需求不够固定之类的原因,考虑由此带来的(以及本来就有的)互操作性等方面的风险,综合起来找不到其它更合适的。
这点是 C++ 的专长:高效而同时具有抽象能力,支持多种范式,灵活迁移(当然前提还是用得对)。在面向应用领域的“通用”上可以说是现时(自从 Lisp 被放置 play 以后)最好的——只要你明确了设计,基本上什么都能实现得出来。同时,仍然能够保持一定可移植性。
而且 C++ 的一些设计能帮助避免做出来后发现不满足关键需求还要考虑换语言的情况(和具有 C++ 类似设计目标的,也就只有 Rust 等极少数语言,然而除了 C++ 都不成气候):例如,运行时性能坑爹——基本上用对 C++ 还不能满足性能需求的情况下靠换其它语言也不可能解决问题了。这也从一方面说明为什么很多严肃的应用会迁移回来重新使用 C++ 。
代价是语言和实现都比较复杂,没有足够的训练容易用错;用户素质普遍不够,沟通成本可能很大,导致损失开发效率。但是反过来也说明如果工程手段得当,就比较容易控制在预期范围之内。另外,复杂性同时限制了不遵从可移植要求的滥用(对比 C 很容易发现这点)。
对初学者来说,学习阶段不需要考虑上面的第 1 点原因。因为相当多基础是各个语言通用的,尽管大部分材料都不会清楚地告诉你多少内容,得自己课外补程序语言理论。而只是“会用”,或者会抄代码,难度不会差太多。自己玩玩就更不用考虑第 2 点原因了。所以 C++ 顶用和去学 C++ 没有直接的因果关系。
现实的 C++ 用户,几乎不可能只会用 C++ —— C++ 没有强到让一般用户容易代替其它所有语言的程度。尽管理论上来说可以做得到,但历史包袱和用户水平决定了不现实。于是许多时候都是 C++ + 其它某种“胶水”“脚本”语言。这算是一种妥协。
另一方面, C 的情况类似但更糟,只会用 C 基本上并没有什么卵用——就算是经典的场景你也得会 makefile 之类的至少一种 DSL ,退一步讲也至少别指望用 C 处理文本什么的了。除了这些历史包袱擅长的领域, C 的用途主要就是拿来写抽象解释器(解释器、编译器、汇编器等等)……不过现状是这些领域也正在逐步被 C++ 替代中(虽然比较慢)。
顺便, Scheme 主要就是拿来被实现的……
最后,非得学 C++ 入门的话,找尽量新的语言和实现版本(语用上表面看起来比较像其它“脚本语言”,虽然实现坑得可能会完全莫名其妙),自己反思能解决什么问题。
严格来说,类 C 语言的历史上一些基本的设计(像类型系统)都相当差,有太多随意的 artifacts ,导致很多东西要么没有,要么就是以后不很自然地打补丁糊上去的,背后的理由并不容易看出来也并不容易立刻就说清楚。(所以这里提到 constexpr 、 auto 和 decltype 什么的不理解,我也不方便一一解释。)对天赋没点到设计语言上的用户来说想像为什么要有这样设计的特性和如何去使用都是脱离真正要解决问题太远的负担。所以我强烈不推荐这些语言当第一入门语言——特别提醒, C 没像其它语言那样有那么多补丁(虽然方言特性倒是一堆),但一直只是表面上看起来简单,论坑的密度比 C++ 还大,学了半吊子基本白学还特别容易产生学会了的错觉,影响以后的正常路线。

IDE

http://tieba.baidu.com/p/4170297948

看来这里也要加个TODO。
先列提纲。
XP作死装不了高版本VS以及targetting XP的质量都烂什么就不管了,就说为什么VS不适合新手。
1.编译器是个残废:支持特性缺斤少两,bug一堆。
2.IntelliSense bug更感人,没经验的信了就等着被误导吧。
3.build system也废,没什么现成简单设置改用其它编译器。
4.编辑器还可以,但作为IDE除了上面的残废以外,大部分其它功能学C++压根用不到。
5.最小安装仍然太大,是不是装得成功可能比较看脸。

存储和存储资源管理

TODO conceptual:

  • memory 翻译成“内存”的问题
  • storage v. memory
  • RAM/ROM/...

默认 GC 的危害

GC = garbage collection/garbage collector ,垃圾回收/垃圾回收器。

一些技术性观点: http://tieba.baidu.com/p/3171730339

GC 特指非决定性(nondeterminstic) 的自动资源回收机制,主要管理在线存储资源(内存)。静态 GC 等本质上属于决定性资源回收的机制不属于此讨论范围。

GC 本质上是一种以闲置存储换取吞吐量或变通其它问题(如 ABA problem)的优化实现,不适合解决一般问题的默认手段,特别地,不适合被通用的语言作为公开接口被依赖。

GC 可省略显式释放,给一些人造成了“通用”的错觉。当在这些人设计语言时,会诱导用户使用“简单”的机制,反而把问题复杂化,同时让最终用户体验受损。

不够通用:因为延迟释放的特性, GC 也只能用于和内存足够近似的特性,不能像其它决定性自动资源管理机制(如 RAII )推广到其它资源(锁、数据库连接等),造成无谓的实现冗余,增加维护代码的工作量。

GC 造成的问题很多(也正因为如此在一般意义上只能作为谨慎的优化):

  • STW(stop-the-world) :
    • 降低响应,不适合实时任务。
    • 时延容易引起明显的卡顿,损害可用性和用户体验。因此也不适合对绝大多数和最终用户交互的程序,或至少容易增大实现和质量保证的难度。
    • 存在不受到 STW 的“无暂停” GC 实现,但其它问题(实现难度、并发调度、内存占用)更严重。如 Azul Zing 使用 C4 GC ,设计为一个实例占用 “a few Gigabytes to 2 TB of memory”
  • 显著增加内存占用:
    • 在内存紧缺的环境下难以使用。
    • 可能导致更高的能耗。
    • 资源利用率低下:典型地,要实现相同的流畅响应,使用 GC 可能相对不使用 GC 需要占用 5 倍的内存,考虑能耗问题,使硬件的选择更加困难。在移动 Web 应用上这些问题尤其突出。
    • 在允许分页的系统配置中引起换页:可能增加 I/O 负担,进一步损害响应,极大降低运行时效率。
    • 更容易引起 OOM(out-of-memory) 问题,降低应用乃至整个多任务系统的可用性。
    • 某些系统如 Linux 默认使用 OOM killer 允许 over commitment 导致内存最终耗尽时行为难以控制引起比内存短缺时直接禁止分配更严重的系统可用性问题。这本质上是半吊子的系统内核级 GC 。

可以看出 GC 不适合多数消费和桌面级产品;在某些特定类型(特别是怕内存多得没地方用)的服务器上, GC 才可能发挥积极作用。然而即便如此,这也只是通用资源管理中的区区一种实现而已——一个 GC 实例说到底就是一个把所有权松散提升到程序实例生存期允许延迟释放的资源池;不带默认 GC 的场合,用户仍然可以自行实现 GC 并且因为可定制性,容易做到性能更高,更适合具体应用场景。

造成这种选型错误的主要原因:对资源管理需求的错误理解且缺乏足够系统学习相关设计的经验,他们通常不明白:

  • 特定场景下最终用户需要的是什么。
  • 什么是成本和效率之间的妥协,什么是一开始就应该考虑满足的需求。
  • 什么是开发者本应做到的,什么是适合让机器自动完成的。

反面教材例: http://yinwang.org/blog-cn/2016/09/18/rust

语言设计问题相关实例

基础知识

文本编码

一般语言话题

标准库的称呼

求值策略相关

数组和指针

数组和指针(误导实例)

指针和引用

C 范围检查

http://tieba.baidu.com/p/4389930794

delete 后清空指针值

http://tieba.baidu.com/p/4325323468

看来还是有必要上FAQ。提纲。
0.确定在这之后必须使用这个空值是另一回事。然而具体到指针上如果不是内部实现,一般也是蠢用法。(智能指针/optional死哪去了?)
1.不管是不是空,反正访问了都UB,语言层面上一样没保证(扯什么异常的妥妥重修)。
2.考虑具体实现,基本上也就是调试,所谓的防御性编程除了糊弄(隐藏错误行为,而不是错误的来源)外没卵用。往往因为你不知道的——并且这种做法下通常你更难以搞清楚的——原因,运气不好一点QA都糊弄不过去(特别是你只能测试你自己撸的有限的部分,而UB炸了原则上是没有范围限制的)。
3.给自己没事找事:破坏第一现场给调试造成麻烦。
4.仍然是没事找事:废话+语义噪音。
上面是鸡汤式偷懒思路。如要考虑原则正确性问题,以上几点从下往上看。

分配函数

http://tieba.baidu.com/p/4303278739

算了,这个也是经了,加个work item列入FAQ。这里列提纲。
首先,如果是你自己想出来的问题也是罢了,如果是别人教的……拖过来我保证不打死他。
什么new/delete和malloc/free?抱歉,没个卵关系。
非得沾亲带故,也就是new和delete不和operator连用能有new-expreesion和delete-expression的语法,然后new-expression和operator new有一腿,delete-expression和operator delete有一腿,然后调用默认nothrow版本的::operator new的行为可以类似调用malloc,调用默认::operator delete的行为可以类似调用free而已。原来的问题仍然是蠢问题。
不算placement new以外的new-expression和operator new调用的求值主要差别是前者可以多出来构造函数调用;delete-expression和operator delete调用的求值主要差别是前者可以多出来析构函数调用。而placement new某种意义上就是手动调用构造函数……

operator new/operator delete和malloc/free差别一箩筐,即便行为能够接近:
前者是钦定的allocation/deallocation function,后者充其量只能是可能的实现;
前者能在类作用域重载后被自动用上,后者没这待遇;
前者是区分数组和非数组版本的;

除非nothrow版本,operator new失败抛异常,而malloc失败返回空指针值;
前者的全局版本可以由用户替换标准库实现提供的定义,没有任何其它函数有这种待遇;

异常了滚回去的时候operator delete会被自动调用。

说白了差得太多太明显了,malloc/free充其量只是和nothrow版本的::operator new/::operator delete在行为上能有那么点可比性而已。混一起炒冷饭的是什么居心,嫌不够乱?

在理解上面的常识之前,记住不管是哪坨玩意都不是给你用的,随便乱用八成效果是通不过code review找抽或者蠢代码之一。

再补三点不限LZ估计也不太容易注意而不是那么像常识的,想无聊撵人的可以塞面试题或者业务考试里:
1.数组版本的operator new在ISO C中并没有对应。注意calloc是带初始化填0的,目的不一样;
2.malloc对0参数的行为impl-def:
WG14/N1570
7.22.3/1 ... If the size of the space requested is zero, the behavior is implementation-defined: either a null pointer is returned, or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object.
而allocation function在此情况下可能失败但不是impl-def,没有要求实现文档明确,而返回的结果上附加约束:
WG21/N4567
3.7.4.1/2 ... The effect of indirecting through a pointer returned as a request for zero size is undefined.36
36) The intent is to have operator new() implementable by calling std::malloc() or std::calloc(), so the rules are substantially the same. C++ differs from C in requiring a zero request to return a non-null pointer.
3.C++14开始实现有权合并满足特定条件的::operator new调用而不需根据as-if rule证明不存在可观察行为改变后才能优化。C没有类似的东西。
WG21/N4567

5.3.4
10 An implementation is allowed to omit a call to a replaceable global allocation function (18.6.1.1, 18.6.1.2).
When it does so, the storage is instead provided by the implementation or provided by extending the
allocation of another new-expression. The implementation may extend the allocation of a new-expression e1
to provide storage for a new-expression e2 if the following would be true were the allocation not extended:
(10.1) — the evaluation of e1 is sequenced before the evaluation of e2, and
(10.2) — e2 is evaluated whenever e1 obtains storage, and
(10.3) — both e1 and e2 invoke the same replaceable global allocation function, and
(10.4) — if the allocation function invoked by e1 and e2 is throwing, any exceptions thrown in the evaluation
of either e1 or e2 would be first caught in the same handler, and
(10.5) — the pointer values produced by e1 and e2 are operands to evaluated delete-expressions, and
(10.6) — the evaluation of e2 is sequenced before the evaluation of the delete-expression whose operand is the
pointer value produced by e1.
[ Example:
void mergeable(int x) {
// These allocations are safe for merging:
std::unique_ptr<char[]> a{new (std::nothrow) char[8]};
std::unique_ptr<char[]> b{new (std::nothrow) char[8]};
std::unique_ptr<char[]> c{new (std::nothrow) char[x]};
g(a.get(), b.get(), c.get());
}
void unmergeable(int x) {
std::unique_ptr<char[]> a{new char[8]};
try {
// Merging this allocation would change its catch handler.
std::unique_ptr<char[]> b{new char[x]};
} catch (const std::bad_alloc& e) {
std::cerr << "Allocation failed: " << e.what() << std::endl;
throw;
}
}
—end example ]
(嘛,这里的例子被我在working draft里改过。。。)

<iostream><cstdio> 有什么区别?

http://tieba.baidu.com/p/3971013816

1.cstdio是面向“文件”的,或者不强调文件和非文件流的区别,默认流就是可以关联外部文件,至于文件的外延是啥就不管,扔给宿主环境了。从std::FILE这个名字以及printf/scanf接口描述基于fprintf/fscanf上就可以看出来。
iostream头只是包含了一坨东西,封装标准输入输出流,和文件流(在<fstream>)不通用。
2.cstdio不知道iostream,而iostream知道cstdio并且默认同步,此外提供有限的接口摆脱关系(sync_with_stdio)。因为这个接口约束,iostream要脱离cstdio(的实现)是不太可能的。
3.cstdio有orientation的概念;iostream是否wide是直接写死在静态类型的模板参数里的,并且底层的流不只支持char和wchar_t字符类型。
4.iostream底层公开了相对完整的缓冲接口(如std::basic_filebuf),可以自行扩展;cstdio只能笼统地设置缓冲模式和提供提供区的接口,但多了行缓冲的概念(_IOLBF)。
5.iostream和std::locale交互。C标准库的<locale.h>(对应C++的<clocale>)提供locale-specific behavior,和cstdio不直接关联。两者不是一回事。
因为这个原因,iostream能直接编解码字符串,而cstdio不能处理和wide-oriented无关的编码,需要<wchar.h>(对应C++的<cwchar>)或C11的<uchar.h>的例程显式调用。
6.iostream体系提供了基于字符串提供了“内存流”(主要是std::stringstream),而cstdio这部分一般只是内部实现,如果需要得自己造。
7.iostream底层通过继承和重写protected虚函数提供实现。cstdio这部分是内部实现,不提供与之对应的扩展功能。
8.两者都实现了流的状态,但不尽相同。iostream显式区分bad和fail,但cstdio没有。
9.iostream提供特定的打开模式的组合,而cstdio使用字符串参数。前者无法直接扩展;后者解析较低效,虽然不需要修改类型就可扩展但也存在实现的运行时兼容性问题。
10.除了检查流的状态,iostream处理错误可选使用异常。cstdio处理错误依赖返回值和流状态。
11.iostream的格式输入输出基于重载,静态分派且类型安全,可以实现得更高效;cstdio的格式输入输出使用的是领域特定语言,需要运行时解析,通常比较低效,且实现的运行时兼容问题修复较困难。
但后者同时提供运行时配置可修改的格式的功能,而前者没有。

另外, iostream 在主流实现默认比 cstdio 慢的主要原因,基本上就是因为兼容后者的锅。具体来说,后者为了兼容某些扩展行为,通常会实现为具有互斥锁定语义的底层调用。默认前者允许和后者混用,结果保持同步,实际实现一般也直接复用后者的部分接口和实现。这要求每次 I/O (极端情况下,每个字符的 I/O )进行一次锁定,在典型操作系统下很可能涉及陷入内核的系统调用,上下文切换的单次开销即可能无法忽视,频繁调用导致性能极端低下。

解决方案:一个 sync_with_stdio(false) 天下太平。注意要在开始使用前确定调用,确保之后不使用 cstdio ,否则无法确保 I/O 行为可预测。关闭同步后,实现可使用对应非同步的接口(如 getc_unlocked 代替 getc ),不存在此类性能瓶颈。

关于 scanf_s 等接口

由微软在 Visual C++ 中提供,后来提交标准化为 ISO/IEC TR 24731-1

这些接口的实用性存在争议反对者包括 Austin Group ( POSIX.1 起草者)以及 Ulrich Drepper ( GLibC 维护者)等

虽然后来这些内容作为 Annex K(normative) 进入了 ISO C11 , 但并不要求所有实现支持(明确只有定义了宏 __STDC_LIB_EXT1__ 的实现需要支持)。计划引用 ISO C11 的新版 ISO C++ 要求实现定义。而当前仍引用 ISO C99 的 POSIX.1 并中不包含对此的实现要求。

正因为当前由于绝大多数主流实现者拒绝实现而导致有 WG14 提案提议把它从未来的语言标准中移除或先 deprecated 后移除,使用它一直会导致可移植性问题。

<cstring><string>

http://tieba.baidu.com/p/4641914364

完全不同的标准库头。

按 ISO C++ 的惯例,前者对应 ISO C 的 <string.h> ,区别 <cstring> 要求库函数在 namespace std 声明并且还多出来一些 C++ 支持的重载(对 <cstring> 而言主要和函数参数和返回类型中的 const 有关),以及 ISO C++ 要求的库函数保证不以宏实现。注意 <cstring> 不要求包含 <string.h> ,所以全局命名空间可能有或者没有对应的 ISO C 函数的声明,而 <string.h> 可能支持的非 ISO C 扩展(如 POSIX 的 strdup )也不能保证在全局命名空间中声明。

<string> 主要提供 std::char_traitsstd::basic_string ,和 <string.h><cstring> 提供的接口无关。

另见下一节注意事项。

关于 C 和 C++ 标准库头

注意 ISO C++ 包含了 ISO C 的标准库头,但在 ISO C++ 中被 deprecated ,如无必要,使用 C++ 标准库时, <xxx.h> 应尽量用被 <cxxx> 代替。必要情况如前言使用 POSIX 扩展。尽管甚至 Stephan T. Lavavej 都曾表示不知道这为何被 deprecated ,这里的主要原因应是鼓励这种做法。

顺带,注意到某些人鼓吹只使用 <xxx.h>,如:

另外 ctime 头文件没定义 std::gmtime_r,而 time.h 定义了 ::gmtime_r。我可不想去背哪些函数是 C 语言的哪些是 Posix 的,哪些头文件是 C 语言的哪些是 Posix 的(在Linux下,二者基本不分家)。为了用几个系统函数(例如 fcntl() ),我该 include cfcntl 还是 fcntl.h?用线程是 cpthread 还是 pthread.h?我总是记不住 memset() 的参数顺序,因此一般用 bzero() 代替,但是 manpage 说 bzero() 声明于 strings.h,那我要不要考虑试试 cstrings 呢?何必给自己找麻烦,C++ 标准库之外的内容干脆统一用 .h 头文件好了。

硬伤一堆,列举如下:

  • “ctime 头文件”——暴露出不知道ISO C++ 标准库头不要求实现为“文件”
  • “C++ 标准库之外的内容干脆统一用 .h 头文件好了”——没有搞清 C++ 标准库的外延。不管 <xxx.h> 还是对应的 <cxxx> ,当前都是 C++ 标准库要求实现的一部分。并且如上面 STL 所说,看样子前者并不打算短期内移除。
  • “哪些头文件是 C 语言的哪些是 Posix 的”—— POSIX 头文件要求支持 C (因为 POSIX.1 直接就是 ISO C 的扩展),可不保证支持其它语言;然而实现中,很多都有 #ifdef __cplusplus 这样的考虑,所以区分什么头文件是什么“语言的”本来就是莫名其妙的做法。应要知道的,是指定的接口来自于哪个规范,以便减少必要时查证的开销
  • “系统函数(例如 fcntl() )”——概念混乱。系统函数是指什么?系统调用?用户空间提供的 POSIX 的接口的实现?
  • “我总是记不住 memset() 的参数顺序,因此一般用 bzero() 代替,但是 manpage 说 bzero() 声明于 strings.h”——愚蠢。 BSD 发明 bzero 并不是为了纵容记性差,记不住为什么不查?(哦,好吧,会 man bzero 是吧……怎么不会 man memset 了?)连这点都做不到,写的代码谁敢用?更别提 bzero 本身可移植性明确更差的事实了。
  • “那我要不要考虑试试 cstrings 呢?”——文档明确告诉干嘛了还多此一举,吃饱了撑的?只有找文档的漏洞时这样做可以理解,不过看上面连搞清楚引用的哪个文档都懒得做,实在不像是有做这个的资质。

这样做纯粹损害可移植性而没有获得任何好处(允许以混淆读者视线而适合让自己变蠢这点在此论外),应予视为误导。

标准库头包含

经常有见到什么某个标准库头(如 <iostream> )包含另一个(如 <cstdlib> )所以不用包含后一个就能用,不信看源码云云——明摆着犯了特定实现代替接口的以偏概全的逻辑谬误。

实际上, ISO C++ 还真规定了一些必须(等价于)包含的情况,但也就只有那么些情况

其它待挂列表

Style, also known as readability

乱弹琴。

The term Style is a bit of a misnomer

不过之后似乎有自知之明……

Forward Declarations

A "forward declaration" is a declaration of a class, function, or template without an associated definition.

冗余定义。

C system files.

C++ system files.

__USE_MINGW_ANSI_STDIO 呵呵呵……

Do not use a using-directive. Do not use inline namespaces.

无脑逗比,显然不知道这些特性干什么用的。放着 inline namespace 不用难道上 ABI tag ?

FRP

发明者对外延失去控制?

http://weibo.com/1684815495/CsFjTbcOj?refer_flag=1001030103_

被人嫌弃命名烂

http://stackoverflow.com/questions/5385377/the-difference-between-reactive-and-functional-reactive-programming

http://tieba.baidu.com/p/2286985797

找FRP的denotational semantics,结果随便搜就是挂婊的2333……

http://conal.net/blog/posts/garbage-collecting-the-semantics-of-frp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment