[分享] Include What You Use

楼主: lc85301 (pomelocandy)   2020-10-31 11:16:24
最近用了 include-what-you-use 这个工具,分享一下
https://yodalee.me/2020/10/2020_iwyu/
大家都知道,程式不是写完就算了,是会长大跟更新
这时候 include 就会慢慢过时,可能本来需要的 include 现在不需要了
但通常在改程式码时不会意识到这点
如果参考 Google 的 cpp coding guide,会看到 Include What You Use 这条准则:
If a source or header file refers to a symbol defined elsewhere, the file
should directly include a header file which properly intends to provide a
declaration or definition of that symbol. It should not include header files
for any other reason.
原始码档案和标头档所需的符号,都应该引入适当的标头档来提供宣告或定义;
不能因为其他理由而引入标头档。
Do not rely on transitive inclusions. This allows people to remove
no-longer-needed #include statements from their headers without breaking
clients. This also applies to related headers - foo.cc should include bar.h
if it uses a symbol from it even if foo.h includes bar.h.
不可依赖过渡引入。开发者可以随时移除不需要的引入,又不会破坏客户端的相依性;
这也适用于相关的标头档:即使 foo.h 已经引入 bar.h,foo.cc 还是要引入 bar.h 。
作者: dces4212 (flawless)   2020-10-31 15:33:00
作者: sarafciel (Cattuz)   2020-10-31 16:06:00
作者: james732 (好人超)   2020-11-01 15:09:00
作者: loveme00835 (发箍)   2020-11-01 15:46:00
从软件架构的品质属性 (Quality Attributes) 来看,如果你改了扣, 却不知道应该要引入哪些标头档, 不会很雷吗? coding standard 只能告诉你结果, 为了确保这个结果, 其实人员的教育/训练才是最重要的; 而不是透过工具来把训练不足的问题掩盖下来, 这也会衍生其他问题
作者: firejox (Tangent)   2020-11-01 19:19:00
发现人会疏漏的问题就是CI的工作了
作者: loveme00835 (发箍)   2020-11-01 19:23:00
找错误是 testing 在做的事情
作者: firejox (Tangent)   2020-11-01 19:29:00
@@ 找违反coding standard也算testing喔
楼主: lc85301 (pomelocandy)   2020-11-01 19:53:00
所以说这个工具就是要丢给 CI 去跑的呀
作者: loveme00835 (发箍)   2020-11-01 20:06:00
我的意思是 iwyu 应该单纯作为 testing/diagnostic tool, 就像 clang-tidy等, 但是找出错误时应该是由人类来修正, 并且要有明确的回报机制. fix_include 不应该放进开发流程, 因为我们无法从最后的程式码看出它和人员素质之间的关系
楼主: lc85301 (pomelocandy)   2020-11-01 20:34:00
可以接受我的使用结果,iwyu 在解完 include 之后还是会有错
作者: CoNsTaR ((const *))   2020-11-01 23:14:00
程式语言都不要 typecheck 好了,写 type safe 的程式是人类的工作,不该由机器来做,typechecking 是测试在做的事人员的教育训练才是最重要的
作者: descent (“雄辩是银,沉默是金”)   2020-11-02 10:03:00
感谢分享
作者: chuegou (chuegou)   2020-11-02 11:13:00
同意推文 类似变量宣告了没用会跳warning这样我比较喜欢
作者: hsnuconan (☁☁☁)   2020-11-04 10:09:00
所以过度引入会有什么副作用吗? compile过慢吗?
作者: Killercat (杀人猫™)   2020-11-04 11:26:00
compile三级跳的慢 因为这是连锁反应另外虽然多半肇因于设计错误,但是名称空间冲突机会也会变大,当你用两个3rd party的.h里面的include还互相冲突的时候你真的会欲哭无泪 要改都没办法改
作者: LPH66 (-6.2598534e+18f)   2020-11-04 11:33:00
简单观念: #include 是编译器帮你剪贴标头档在引入处所以 #include 越多最后编译时要看的东西就越多那编译过程中编译器需要记录搜寻判断的东西就越多
作者: ucrxzero (RX-0)   2020-11-04 12:48:00
所有的MACRO 包括include 不是都是展开的概念吗跟inline 的差别在于inline是编译器做的是真的函式而preprocessing是text的代换而已Preprocessing->编译->处理inline补充一下 inline 有自己的scope 较稳定
作者: MOONRAKER (㊣牛鹤鳗毛人)   2020-11-05 16:04:00
阿展开以后compiler不用看过喔 那这个compiler太妙了不用看就可以变出来bin 妙不可言
作者: ucrxzero (RX-0)   2020-11-05 16:46:00
当然要看我又没有说不用看但不稳定是因为还要加类似do{}while(0)这种东西*MACRO
作者: Lipraxde (Lipraxde)   2020-11-05 18:55:00
我在思考这里是怎么谈到 inline 的...
作者: eye5002003 (下一夜)   2020-11-06 09:07:00
GCC能帮我列出没被使用的函式,也许以后还能帮忙抓没被使用的标头档,不过如果你很在乎编译时间长短的话那还是要亲手整理,把标头档藏好别到处引用
作者: ucrxzero (RX-0)   2020-11-06 10:13:00
像static 就不会被剪贴进去啊
作者: loveme00835 (发箍)   2020-11-06 10:19:00
笑死..
作者: ucrxzero (RX-0)   2020-11-06 10:37:00
...
作者: firejox (Tangent)   2020-11-06 12:41:00
inline 只是 inline it if you can ,又没强制如果 static不会剪贴,那 static inline 又是什么
作者: CoNsTaR ((const *))   2020-11-06 12:51:00
include 不就单纯的剪贴吗?还会管你是不是 static 喔?语法分析可能都还没开始,不可能管到语意去吧...
作者: ucrxzero (RX-0)   2020-11-06 13:01:00
好喔最初应该会啦 但你也用不了喔喔我懂你意思了我是说在其他source档定义static同名一起include header的其他source抓不到那个被定义static的symbol但如果你一开始就把static function 写在header那当然都可以用 但是你每个source 档自己定义都是分开的这样没错吧?text剪贴当然是预处理而已
作者: CoNsTaR ((const *))   2020-11-06 13:15:00
呃... 不论某个 symbol 是不是 static、或它被从哪里 include 到哪里、或 scope 是什么 etc...,它被 include 进来就是会增加编译器的工作,就可能会导致编译速度变慢,就这样而已...
作者: ucrxzero (RX-0)   2020-11-06 13:20:00
我用词错误啦 我讲到编译的地方去了不要再鞭了更正 讲到连结的地方去了
作者: loveme00835 (发箍)   2020-11-06 13:22:00
就跟你说从结果论来学习是错的方法, 买一本书好好把它看完, 没看完别来误导其他人
作者: CoNsTaR ((const *))   2020-11-06 13:24:00
没有要鞭,看了就忍不住想讲orz
作者: ucrxzero (RX-0)   2020-11-06 13:28:00
没错,这里传道授业的地方讲话不能太笼统可能会让人搞混 我刚刚剪贴是讲最后的连结的地方不会被连结而不是引用的时候不会被剪贴我略过太多而且用词不精大家我先去看书明年见看讲话的艺术
作者: descent (“雄辩是银,沉默是金”)   2020-11-06 18:06:00
ucrxzero: 讨论就是这样, 不用太在意
作者: Killercat (杀人猫™)   2020-11-10 07:42:00
我能给的建议是,不要急着发表意见先把想说的在脑袋里面顺一次 想想要不要发表 再写不过这篇居然没有人把pImpl拖出来 真令人意外XD
作者: LPH66 (-6.2598534e+18f)   2020-11-10 08:30:00
(离题) 这其实是推文成章的坏处之一: 发完出去了就没得改(再拉回来) 这么一提我才发现 pImpl 好像和这段 guide 之间有些微妙的互动...
作者: Lipraxde (Lipraxde)   2020-11-10 08:53:00
Pimpl 在 header 应该没有用到 impl class 底下的 symbol,应该还好?
作者: Killercat (杀人猫™)   2020-11-10 14:51:00
基本上这条guide就是给没用pimpl的code补救的方案之一你真的写成pimpl 这东西应该没办法再优化了....就全部被凝缩成一个opaque pointer是还能怎么最佳化XD应该说 还是能拿掉用不到的header啦 但效果不明显了
作者: Lipraxde (Lipraxde)   2020-11-10 20:16:00
我是觉得 pimpl 和这条 guide 两者是独立的
作者: Killercat (杀人猫™)   2020-11-10 22:39:00
是没错,不过要是使用pimpl的话,绝大多数的redundentheader都会在.cpp而不在.h 这条guide最佳化就很有限了
作者: Lipraxde (Lipraxde)   2020-11-10 23:42:00
这条 guide 应该是要人们避免 transitive include,让人可以安心的拿掉不用的 header。编译速度有机会变快应该算是属于附加的,并不是本来的目的。而使用 pimpl 的其中一个目的是可以让人修改 impl 时不用改到 header,可以避免重新编译其他 .cpp。就这样我觉得 pimpl 跟这条 guide 不冲突也不相关。
作者: mickey94378 (Holy)   2020-12-07 20:54:00
推分享

Links booklink

Contact Us: admin [ a t ] ucptt.com