一个 paradox

某公司的 style guide 人员在会议上说了几条基本原则,其中一条是说要在 call site 留下 trace,依据这条原则某公司规定传递函数参数如果用做输出,必须传递指针,因为 C++ STL swap 不在其管辖范围以内而得以幸免。

最近在该 style guide 上发现一个关于 rvalue reference 的说法,仅仅在 move constructor 上允许使用 rvalue reference,而一般的函数并不允许这么做,这就回到了 Herb 同学讲的那个被怂恿的函数传递方式,C++11 下是不是我们应该 prefer 传递值而不是引用(这里主要是指 rvalue reference 这种用来匹配 rvalue reference 的情况了)。

比如我们有一个函数 foo 它需要一个 LargeObject 传递给其中使用的某个对象完成一些事情,按照某 style guide 的说法:

void foo(LargeObject obj) {
  // something else
  MyObject mine(std::move(obj));
  // mine will handle something
}

auto obj = LoadLargeObject("somewhere");
foo(obj);            // obj will be copied
foo(std::move(obj)); // obj will be moved

我得到的说法是 caller 有权决定 obj 是被 copy 还是被 move,所以写成如上形式简化了函数传递的的复杂性。然后说你要觉得需要 move 那你就搞个 performance test 啊。我晕难道不是我知道这地方是个几百 Mb 的字典传进来那就应该被 move 吗?还需要写个 test 来 justify?我们可以与 rvalue reference 的情况比较一下:

void foo(LargeObject&& obj) {
  // something else
  MyObject mine(std::move(obj));
  // mine will handle something
}

auto obj = LoadLargeObject("somewhere");
foo(obj);              // won't compile
foo(LargeObject(obj)); // obj will be copied
foo(std::move(obj));   // obj will be moved

很明显 rvalue reference 会拒绝 lvalue,通过强制调用 copy constructor 就能实现 copy 传递,同时 move 行为也有明确的标识。两者下面的代码似乎都能 work

foo(LoadLargeObject("somewhere"));

不会导致额外的 copy 发生。很显然后者为 call site 留下了很明确的痕迹,而且我一直不理解,如果我需要调用 foo 难道我不会去看 foo 的文档嘛,难道写传值会比传 rvalue reference 更加明确其含义?即使换成某人所说哦代码读的次数远大于写的次数,难道不是后者更加明确的告诉大家其行为吗?传值和传递常值引用在前面一种情况下完全无法区分嘛…

很多时候某些人说太复杂所以学习起来有 cost,我们要减轻大家的 cost,然而同一条讲 rvalue reference 的 style guide 里面却把 universal referecen/forwarding reference 与其混为一谈,说 rvalue reference 是用来“实现” forwarding reference 的,我表示非常不解… 概念上 forwarding reference 完全是为了一个不同的目的,而且很明显 forwarding reference 不仅仅能匹配 rvalue reference 也能匹配 lvalue 等等,为什么要把一个风马牛不相及的东西放在一起,我问了,答曰“technically the same”,为了有 forwarding reference 人家需要做 reference collapse 机制的好吧… 然后我说为啥不能分开两条,读者不是更容易接受一些吗,他们却说不乐意降低读者的 cost,说我们没有义务教人家学习 C++ 语言。

我一直不喜欢有个 style guide,特别像某些号称如何如何导致了代码多么好管理这个说法,因为窃以为即便没有某公司一样能做出来很多东西,一样容易管理,现在把 style guide 捧上神坛,就跟 Redemption of Shawshank 里面所说的一样 institutionalization,不过限制的是程序员的自由,一旦 get used to it 后果可能是一辈子都不能接受其他的方式写 code… 并不是说完全不应该有 guide,有的事情很明显不应该那样做(会有 bug 或者明显啰嗦了),大家都同意,那么就规定;有的事情是没有争执的意义,定下来我也觉得的确没必要改(什么间距、行宽之类的事情),这些都很好,作为 guide 的一部分。至于传指针传引用总归是个 case by case 的事情,有什么必要写到 style guide 里面来限制程序员自己的发挥呢?

有人的地方就有江湖,为什么这句话那么有道理被人传诵,因为讲道理这个事情也只在“观点”相投的人之间,即使是这些能说出道理的问题上大家都会有严重的分歧,更何况一些公说公有理婆说婆有理的问题呢?要让他人接受自己的的意见,reasoning 很重要 politics 也同样很重要…

——————
And God said unto him, I am God Almighty:be fruitful and multiply; a nation and a company of nations shall be of thee, and kings shall come out of thy loins

Advertisements
一个 paradox

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s