Chinaunix

标题: [C实现]条件表达式的执行顺序是固定的吗? [打印本页]

作者: safedead    时间: 2012-09-28 16:46
标题: [C实现]条件表达式的执行顺序是固定的吗?
函数声明:
uint32_t fun(uint32_t *argv);

下面的代码检查函数参数(位于函数定义中):

if ((NULL == argv) || (3 < argv[1])) return -EINVAL;

我记得好像什么地方说过,这样的条件判断里
如果(NULL == argv)成立则不进行(3 < argv[1])的判断
执行顺序是从左到右

如果不保证这个顺序的话,那我必须写成下面这样:

if (NULL == argv) return -EINVAL;
if (3 < argv[1]) return -EINVAL;

最近被单片机的BUG搞得疑神疑鬼,C程序开始用类似汇编的风格来写了
作者: OwnWaterloo    时间: 2012-09-28 16:52
条件表达式? if (...) ... ? 这货是语句。而且它不管(...)内的求值顺序的。

顺序是因为logic or(||)的关系。必须是先||的左操作数NULL == argv然后是右操作数3 < argv[1]。
这顺序C语言是保证了的。
如果产生的代码先计算3 < argv[1],那就可以给那个编译器报bug了。


而如果是其他的,例如 if ( X & Y ), X 与 Y 的顺序就没保证了。
作者: hellioncu    时间: 2012-09-28 17:12
OwnWaterloo 发表于 2012-09-28 16:52
条件表达式? if (...) ... ? 这货是语句。而且它不管(...)内的求值顺序的。

顺序是因为logic or(||)的 ...


你确信说的是 & 而不是 && 吧
作者: safedead    时间: 2012-09-28 17:19
hellioncu 发表于 2012-09-28 17:12
你确信说的是 & 而不是 && 吧


说真的我希望C语言用 & 而不是 && 表达逻辑乘
估计当初先有&取地址,后面只好用 && 来表达逻辑乘了
作者: hellioncu    时间: 2012-09-28 17:23
safedead 发表于 2012-09-28 17:19
说真的我希望C语言用 & 而不是 && 表达逻辑乘
估计当初先有&取地址,后面只好用 && 来表达逻辑乘了



应该是跟位操作 & 冲突吧
作者: OwnWaterloo    时间: 2012-09-28 17:32
回复 3# hellioncu

L && R 会保证先L后R
L & R 不知道谁现谁后。

没说错吧?
作者: hellioncu    时间: 2012-09-28 20:50
OwnWaterloo 发表于 2012-09-28 17:32
回复 3# hellioncu

L && R 会保证先L后R


嗯,我也这么认为。
看你那段话,容易误解只有||是那样,而&&不是
作者: wwwsq    时间: 2012-09-28 20:59

楼上几位的解释都是对的。

不过在实践中,比较推荐的做法是不要在 if (expr_a || expr_b) 的时候做什么实质性的‘写’操作。因为那样的代码读起来太累,容易隐藏bug。

比如楼主遇到的疑惑和担心,其实是完全可以避免的。之所以会有这麻烦,就是当初写代码的人水平太次,或者太爱卖弄。

建议楼主在有机会的时候,把那块代码改写一下,写成任何人都不会担心的代码,写成不会有任何迷惑的代码。


作者: OwnWaterloo    时间: 2012-09-28 21:39
回复 7# hellioncu

原来是这个意思。。。
放心,木有手误。。。

表达式的操作数们有求值顺序的就这几个:
first , then
first && when_non_zero
first || when_zero
first ? when_non_zero: when_zero

凭记忆写的。
为了避免误导,又去翻了翻附录,也确实只有这几个。。。
作者: starwing83    时间: 2012-09-28 21:39
回复 8# wwwsq


    ……………………我经常这么干……………………

通常是&&里面判断很多条件,然后顺手把实际操作当做最后一个条件,然后在if里面写错误处理:

  1. if (!cond1 || !cond2 || !cond3 || !do_something(v1, v2, v3))
  2.    printf("ERROR!");
复制代码
反正就是这么个意思吧。

还有就是while循环里面,给个实际的例子吧:
  1. static int read_one_char(ParseState *ps) {
  2.     if (isnewline(ps) || iseoz(ps))
  3.         return 0;
  4.     if (test_current(ps, ESCAPE_CHAR))
  5.         read_escape(ps);
  6.     else if (test_current(ps, COMMENT_CHAR))
  7.         skip_comment(ps);
  8.     else
  9.         save_and_next(ps);
  10.     return 1;
  11. }

  12. static size_t read_word(ParseState *ps) {
  13.     assert(!isspace(ps) || mb_bufflen(&ps->buff) > 0);
  14.     while (!isspace(ps) && read_one_char(ps))
  15.         ;
  16.     skip_whitespace(ps);
  17.     return mb_bufflen(&ps->buff);
  18. }
复制代码
这是从我写的ninja语言格式分析器里面随意抽出来的一段。read_one_char读取一个字节,然后进行实际操作,最后返回到底读到没(newline要特殊处理)。在这个情况下,while里面就直接&&搞事了,最后循环体是个空语句,因为事情都搞完了…………
作者: OwnWaterloo    时间: 2012-09-28 21:51
回复 10# starwing83

你这代码太容易隐藏bug了!水平太次了!!太爱卖弄了!!!这不是诚心让他人担心与迷惑么!!!!!
写过实践代码没啊你
作者: starwing83    时间: 2012-09-28 21:56
回复 11# OwnWaterloo


    咩…………
作者: wwwsq    时间: 2012-09-28 22:00
OwnWaterloo 发表于 2012-09-28 21:51
回复 10# starwing83

你这代码太容易隐藏bug了!水平太次了!!太爱卖弄了!!!这不是诚心让他人担心与 ...



唉,不听老人言,吃亏在眼前呀。实践这个事情,你走的路多了自然知道哪里容易摔倒。

你爱怎么写就怎么写吧,反正你写的代码又不是我维护。


作者: wwwsq    时间: 2012-09-28 22:01
starwing83 发表于 2012-09-28 21:56
回复 11# OwnWaterloo



盗用我的‘咩。。。’,你知道‘咩。。。。’是什么含义么。。。。


作者: OwnWaterloo    时间: 2012-09-28 22:22
回复 13# wwwsq

连C++都没让我摔过几跟头,别说C了,不劳你操心了。
我不知道哪来这么多跟头可让人摔的,眼神不好怪路陡,拉不出便便怪马桶?
我也不知道你在我面前充老人 —— 非年龄,指什么你懂的 —— 的自信是从哪来的。当然,你做事不需要合乎逻辑这我是见识过了。对此也不足为奇。

最后,不会让我迷惑的代码对你而言不一定就清晰;反之,不让你迷惑的代码对我毫无悬念。
不过那种为了让更多人参与 —— 尤其是那种只学if,for就可以开始工作 —— 而故意写得罗嗦的代码我还真没兴趣维护。
将他人当作傻瓜,无论他人到底是不是,最终结果很有可能只有自己变得越来越傻。
作者: wwwsq    时间: 2012-09-28 22:31
OwnWaterloo 发表于 2012-09-28 22:22
回复 13# wwwsq

连C++都没让我摔过几跟头,别说C了,不劳你操心了。




        i = 0;
        int j = (i == 1)?++i:i;

        i = 0;
        int k = (i == 1)?i:++i;

j和k分别是多少?

执行顺序这种事情,知道了固然好,不知道也无所谓。写出别人看不懂的代码,不是水平高,而是水平次。

最好的代码一定是平淡如水,看过去一马平川的。

作者: OwnWaterloo    时间: 2012-09-28 22:44
回复 16# wwwsq

喔唷喂,原来这就是你说的让人迷惑的代码?别丢人现眼好吗。


wwwsq 发表于 2012-09-28 22:31
写出别人看不懂的代码,不是水平高,而是水平次。


你这逻辑我不懂,我懂的逻辑是:看不懂别人的代码就是水平次。
作者: wwwsq    时间: 2012-09-28 22:50
本帖最后由 wwwsq 于 2012-09-28 22:51 编辑
OwnWaterloo 发表于 2012-09-28 22:44
回复 16# wwwsq

喔唷喂,原来这就是你说的让人迷惑的代码?别丢人现眼好吗。



你敢说你没去查手册,也没去写验证代码?

你百分之百确定你凭空想的结果是对的?

那再来一个:

        i = 5;
        int x = (++i = i++);

不要说什么UB不UB的,有人就是这么写。


作者: OwnWaterloo    时间: 2012-09-28 22:56
回复 18# wwwsq

我不知道你质疑他人一定要去查手册写验证代码的自信是从哪来的。
那两行代码对你来说就那么难? 洗洗睡吧。


明知道是未定义还让我分析? 又开始耍流氓了? 老人家你自己玩, 我陪不起。
作者: wwwsq    时间: 2012-09-28 22:58
本帖最后由 wwwsq 于 2012-09-28 22:59 编辑
OwnWaterloo 发表于 2012-09-28 22:56
回复 18# wwwsq

我不知道你质疑他人一定要去查手册写验证代码的自信是从哪来的。



        i = 5;
        int x = (++i = i++);

看得懂不?水平次不?

你说这是UB?我觉得未必是UB。你去查查手册看看,是不是UB。



作者: OwnWaterloo    时间: 2012-09-28 23:05
回复 20# wwwsq

我去帮你查手册?
1. 这用得着查手册?
2. 你付钱给我吗?

如果是其他人,以询问的态度我就回答了。
但你不行,哪怕你改个语气问也不行。你还信手册的? 你只用按你需要捏造概念就够了。C标准有什么概念关你什么事?
作者: wwwsq    时间: 2012-09-28 23:07
OwnWaterloo 发表于 2012-09-28 23:05
回复 20# wwwsq

我去帮你查手册?



你说那个句子是UB,哪个环节UB了?

没看懂吧?水平次吧?


作者: OwnWaterloo    时间: 2012-09-28 23:21
回复 22# wwwsq

我看没看懂与我告诉你与否有关系?  我不告诉你就一定是因为我没看懂? 瞧你这思考回路长得。。。

和我玩激将没用。当然,你老老实实求我告诉你也不一定有用。
你在我心中的节操信誉已经完全丢完了。
我高兴就陪你乐呵乐呵,不高兴就随你自己丢人现眼。

作者: starwing83    时间: 2012-09-28 23:23
回复 23# OwnWaterloo


    可惜你签名里面的(CU2B)已经没了,不然似乎可以加一个……
作者: wwwsq    时间: 2012-09-28 23:24
OwnWaterloo 发表于 2012-09-28 23:21
回复 22# wwwsq

我看没看懂与我告诉你与否有关系?  我不告诉你就一定是因为我没看懂? 瞧你这思考回路 ...



看不懂吧?水平低吧?

这是你的逻辑啊,看不懂的人才是水平低啊。你看,我随便写写,就写了一堆你看不懂的代码。

还可以随手写更多。



作者: captivated    时间: 2012-09-28 23:25
本帖最后由 captivated 于 2012-09-28 23:27 编辑

回复 22# wwwsq


        i = 5;
        int x = (++i = i++);

        真心求教下, 这个真的不UB? 这两个语句后面的分号不能当成序列点? 抑或声明初始化语句中还有别的序列点? 抑或声明初始化语句不遵守"两个序列点之间不允许对同一变量进行两次以上修改"的规定?

作者: wwwsq    时间: 2012-09-28 23:26
starwing83 发表于 2012-09-28 23:23
回复 23# OwnWaterloo




来来来,你水平可能会比较高一点:

        i = 5;
        int x = (++i = i++);

执行完之后,x和i各是多少,为什么?

看得懂不?


作者: starwing83    时间: 2012-09-28 23:29
回复 27# wwwsq


    手抚狗头,笑而不语
作者: OwnWaterloo    时间: 2012-09-28 23:30
回复 24# starwing83

你仔细看~ 不过,如果真要改,我觉得之前那些人都可以删了。。。 完全比不上这货。。。
作者: wwwsq    时间: 2012-09-28 23:30
starwing83 发表于 2012-09-28 23:29
回复 27# wwwsq



按照waterloo同学的看法,看不懂代码的才是水平低。

那段代码你看懂了没?



作者: starwing83    时间: 2012-09-28 23:31
回复 29# OwnWaterloo


    我擦……反白的……你个贱人………………
作者: OwnWaterloo    时间: 2012-09-28 23:31
回复 26# captivated

我只能PM你了。。。 嗯,论坛2b多了也不是完全没有危害的。。。
作者: wwwsq    时间: 2012-09-28 23:31
OwnWaterloo 发表于 2012-09-28 23:30
回复 24# starwing83

你仔细看~ 不过,如果真要改,我觉得之前那些人都可以删了。。。 完全比不上这货。 ...



看不懂代码的才是水平低啊。

int x = (++i = i++);

你看得懂不?


作者: captivated    时间: 2012-09-28 23:33
回复 32# OwnWaterloo


    擦, 果然反白的...
作者: starwing83    时间: 2012-09-28 23:34
回复 30# wwwsq


    貌似我看没看懂,也不需要告诉你吧?你黑的都能说是白的,告诉你有用么~

顺带说一句,这种无聊的东西,我08年就不看了的。
作者: wwwsq    时间: 2012-09-28 23:36
本帖最后由 wwwsq 于 2012-09-28 23:37 编辑
starwing83 发表于 2012-09-28 23:34
回复 30# wwwsq



这个代码说实话我自己也看不懂。但我还真见过有人写这样的代码。

你觉得是写的那个家伙水平次,还是看的人水平次?

真实项目里面的代码,可不是一句UB就可以推脱掉的。




作者: starwing83    时间: 2012-09-28 23:37
本帖最后由 starwing83 于 2012-09-28 23:39 编辑

回复 36# wwwsq


    这我就真的很好奇了?谁写过呢?在哪个成熟的产品中间有这样的代码?或者哪个开源的项目里面有这样的代码?贴出来我开开眼好不?

对了,写这种代码的人,不是水平次,是根本没入门。


我也来耍个赖:这种代码,应该算是ill-formed的,也就是说根本就不是正确的,比如说,下面的代码
  1. &*^%&^%$^%#^#*&^%*^&^%#^$#
复制代码
我一口咬定这是C代码,看不懂的人算啥捏……
作者: wwwsq    时间: 2012-09-28 23:38
本帖最后由 wwwsq 于 2012-09-28 23:38 编辑
starwing83 发表于 2012-09-28 23:37
回复 36# wwwsq



何止是这样的代码。有没有见过项目就没代码的?

大公司哦,很大的国内一流的it公司哦。


作者: starwing83    时间: 2012-09-28 23:40
回复 38# wwwsq


    别转移话题,我就想知道,谁/哪家公司的项目里面有这种代码?哪个开源的项目里面光明正大有这种代码在仓库里面?你指给我。
作者: wwwsq    时间: 2012-09-28 23:40
本帖最后由 wwwsq 于 2012-09-28 23:42 编辑
starwing83 发表于 2012-09-28 23:40
回复 38# wwwsq



写UB的代码,到处都是。

“貌似UB”、“可能UB”的代码,更多。




作者: OwnWaterloo    时间: 2012-09-28 23:46
回复 34# captivated

叔叔你说要不要更新下这个CU13列表呢?
呃,其实都不该叫列表了,而叫CU13大魔头   而且也不反白了,让人都看见。
作者: wwwsq    时间: 2012-09-28 23:46
starwing83 发表于 2012-09-28 23:37
回复 36# wwwsq


“看不懂的人算啥捏……”


以waterloo同学的标准,看不懂的当然算水平次。



作者: wwwsq    时间: 2012-09-28 23:47
OwnWaterloo 发表于 2012-09-28 23:46
回复 34# captivated

叔叔你说要不要更新下这个CU13列表呢?



int x = (++i = i++);

看得懂不?水平次不?


作者: captivated    时间: 2012-09-28 23:49
回复 41# OwnWaterloo


    必须的 而且应该一部分反白 一部分不反白...
作者: OwnWaterloo    时间: 2012-09-28 23:51
starwing83 发表于 2012-09-28 23:34
回复 30# wwwsq

貌似我看没看懂,也不需要告诉你吧?你黑的都能说是白的,告诉你有用么~

顺带说一句,这种无聊的东西,我08年就不看了的。


如果这话能对他起作用,早就应该起效果了:

OwnWaterloo 发表于 2012-09-28 23:21
回复 22# wwwsq

我看没看懂与我告诉你与否有关系?  我不告诉你就一定是因为我没看懂? 瞧你这思考回路长得。。。

和我玩激将没用。当然,你老老实实求我告诉你也不一定有用。
你在我心中的节操信誉已经完全丢完了。
我高兴就陪你乐呵乐呵,不高兴就随你自己丢人现眼。



耍流氓的人,你只能和他对耍流氓。问题是,你会耍流氓么?

作者: wwwsq    时间: 2012-09-28 23:52
captivated 发表于 2012-09-28 23:49
回复 41# OwnWaterloo



        int x = (++i = i++);

有位同学写了上述代码,而且还编译成功发布出去了。
现在轮到你来维护这个模块。模块有bug,你需要理解上面这段代码在做什么。

你能看懂这段代码吗?

以waterloo同学的标准,看不懂就是水平低的。



作者: wwwsq    时间: 2012-09-28 23:56
OwnWaterloo 发表于 2012-09-28 23:51
如果这话能对他起作用,早就应该起效果了:



项目中并不是所有代码都符合UB的。有些垃圾代码纯粹就是垃圾,但是那个模块在线上跑。有bug你怎么修复?可不是一句UB就能推脱。

看不懂就是水平低?你的想法要再考虑一下。


作者: captivated    时间: 2012-09-28 23:56
回复 46# wwwsq


    倒, 这种代码我也是不看的好伐.
作者: wwwsq    时间: 2012-09-29 00:00
captivated 发表于 2012-09-28 23:56
回复 46# wwwsq



老板让你维护那个模块,找出bug来修复掉。你看还是不看?并不是每个模块你想重构就能重构的。

看不看不是你能选择的。工作需要。

按waterloo同学的标准,看不懂就是水平次。int x = (++i = i++)你能看懂吗?



作者: starwing83    时间: 2012-09-29 00:17
本帖最后由 starwing83 于 2012-09-29 00:18 编辑

回复 40# wwwsq


    请你直接告诉我哪*里*有这样的代码,不然我就认为你是在造谣。

为什么“哪 里 有”变成了***???
作者: wwwsq    时间: 2012-09-29 00:37
starwing83 发表于 2012-09-29 00:17
回复 40# wwwsq



你还没看过项目里面UB的代码?简直像处女一样纯洁啊。



作者: starwing83    时间: 2012-09-29 00:44
回复 51# wwwsq


    无赖就是无赖,你告诉我哪个项目代码里面有(i++ = ++i)这种代码的,我就只问这个,不问其他的UB,你自己说是某个项目某个公司里面的代码,我就知道是哪个公司。不说的话就不要再耍无赖了。
作者: wwwsq    时间: 2012-09-29 00:50
starwing83 发表于 2012-09-29 00:44
回复 51# wwwsq



当然不是完全一样,而是类似这样的代码。这个case你看不懂,难道换个case你就看得懂了?

以waterloo同学的标准,看不懂代码就是水平次。你想想你的水平得有多次?



作者: OwnWaterloo    时间: 2012-09-29 00:59
wwwsq 发表于 2012-09-29 00:00
老板让你维护那个模块,找出bug来修复掉。你看还是不看?并不是每个模块你想重构就能重构的。

看不看不是你能选择的。工作需要。

按waterloo同学的标准,看不懂就是水平次。int x = (++i = i++)你能看懂吗?


你这个回帖除了复读机似的重复那句话之外还有一点新东西。

"老板让你什么什么,不是你想重构就重构",这些苦水你去找你老板吐。
懒惰、没意愿或没能力改变自己的工作环境那是你自己的事,跟我装苦逼没用。
拿你那苦逼的处境来衡量其他人更没用。



PS:关于复读机。这是你的老招数了(包括对pm)。
为什么你要不停的重复? 我猜测你是觉得抓到我们的辫子了。
我给你个提示,你换位思考下,为什么我们不阻止你复读? 是因为这果真是辫子,只能认栽? 还是其他原因?
有你这么傻不停重复对自己不利的言论的人么。。。


关于我懂不懂x = (++i = i++),前面就已经说了,我懂不懂与我是否告诉你是两码事 <- 我估计这话说了你也会当作没听见。
所以我换个方式,说明我懂但就是不想不告诉你

captivated 在26楼 2012-09-28 23:25:41 这个时刻问我的。我在 2012-09-28 23:42 这个时刻通过短消息回复他的。
我都懒的截图了,因为你可以说我PS。 但反正CU有记录,我不怕没证据。

这两个时刻间差了接近20分钟。
对这问题, 我还犯不着去查手册。 花时间回复下其他帖子, 整理整理思路, 打打字, 时间就过去了。
对此我就没办法找到证据, 你可以诬陷说我花了20分钟去查手册。 但你如果在20分钟内能查手册说出原因我都算你有本事。
作者: starwing83    时间: 2012-09-29 01:01
回复 54# OwnWaterloo


    何必呢,跟他说这个完全没用的。
作者: starwing83    时间: 2012-09-29 01:03
回复 53# wwwsq


OK,那你就在开源代码里面找个UB的case告诉我呗。说好啦,是这种顺序点相关的哦,免得你拿我之前说的Lua的case说事儿。

不过就算你能找到Lua的那个Caes也算你厉害~~你敢直接说个case么?说是什么项目,哪家公司?是不敢说还是之前就是信口开河?
作者: starwing83    时间: 2012-09-29 01:10
回复 54# OwnWaterloo


    赶快编辑签名吧,我们都等着呢
作者: OwnWaterloo    时间: 2012-09-29 01:11
回复 56# starwing83

他还停留在 "改代码 -> 某个环境下观察行为 -> 再改代码" 的循环, "环境i -> 环境j -> ..." 的循环当中。 哪懂什么undefined behavior。
要他找出来, 你这不是为难他吗
作者: starwing83    时间: 2012-09-29 01:15
回复 58# OwnWaterloo


    没啊,好不容易他自己亲口承认的东西,不让他自己吃下去,我怎么甘心

技术挫其实不是他的错,技术挫还拿出来现其实也无所谓,但是技术挫就说别人都挫这个是不是就犯了众怒了?估计今天拿出来case明天就有人请他去喝茶了
作者: wwwsq    时间: 2012-09-29 03:07
OwnWaterloo 发表于 2012-09-29 00:59
你这个回帖除了复读机似的重复那句话之外还有一点新东西。

"老板让你什么什么,不是你想重构就重构" ...



我很老实的承认,x = (++i = i++)这个代码我是看不懂的,而且我也不确定它是否UB。
在项目代码里面看到这种代码,我的采取解决办法一定是写个例子验证一下。以确保我理解的结果,就是线上运行的结果。

按你的逻辑,写出垃圾代码不是水平次,看不懂垃圾代码的才是水平次。什么逻辑。即使我相信你看得懂这个例子,难道 i = i++ + 1 你也看得懂,凭空能知道运行结果?

有些垃圾代码就是很难看懂的,你不实际验证一下,你所谓的分析阅读就只是猜测。

至于改变环境什么的,我只能哈哈了。线上模块在那里运行,你不维护搞毛啊?还是你没能力维护?

找点看不懂的垃圾代码,这还不容易?你都能看懂?扯淡!


作者: starwing83    时间: 2012-09-29 03:18
回复 60# wwwsq


    你知道什么叫懂么?
作者: OwnWaterloo    时间: 2012-09-29 04:23
wwwsq 发表于 2012-09-29 03:07
我很老实的承认,x = (++i = i++)这个代码我是看不懂的,而且我也不确定它是否UB。

你那点斤两,以为你不承认大家就看不出来?


wwwsq 发表于 2012-09-29 03:07
在项目代码里面看到这种代码,我的采取解决办法一定是写个例子验证一下。以确保我理解的结果,就是线上运行的结果。

按你的逻辑,写出垃圾代码不是水平次,看不懂垃圾代码的才是水平次。什么逻辑。即使我相信你看得懂这个例子,难道 i = i++ + 1 你也看得懂,凭空能知道运行结果?

有些垃圾代码就是很难看懂的,你不实际验证一下,你所谓的分析阅读就只是猜测。

至于改变环境什么的,我只能哈哈了。线上模块在那里运行,你不维护搞毛啊?还是你没能力维护?


我前面才说了你在"改代码 -> 观察 -> 改代码" 的内循环里跑不出去,我知道你只会这一招,别这么急着赞同我好吗?

问我有没有能力维护出问题的代码之前,不如先问问你自己问什么要发布有错的代码。
只能做一颗螺丝的人的眼界不同确实不同,我不指望也不愿意去理解你的苦逼。


wwwsq 发表于 2012-09-29 03:07
找点看不懂的垃圾代码,这还不容易?你都能看懂?扯淡!


我说的只是能看懂的比你多, 有说过我全能看懂?

看懂的意思是说: 首先能分辨代码本身是否是错的,其次才是它表达的含义。所以我知道哪些代码值得去理解它的含义,那些代码不值得。
我能区分哪些是文章 —— 不管它用了多么生僻的词汇 —— 而那些只是猴子随便敲出的乱码。
这种区分就是懂的一部分,理解不属于乱码部分的能力又是懂的另一部分。

你,哪怕是屎,也非得去尝一口、验证一下才能知道。
作者: OwnWaterloo    时间: 2012-09-29 04:46
回复 60# wwwsq

我自己明白且读起来最顺畅的代码,对你来说可能疑惑重重。
这事很无奈,但错不在我,因为我不是为了让人看不懂而这样写。至少我自己(再搭个sw,他的水平我还是很了解的)看得懂。
我不可能为了让你看懂而选择让我写起来不舒服的方式。只能怪你自己水平不够。


而你自己读起来顺畅的代码,对我来说毫无悬念。按我的逻辑,你就是水平次。


但在这个回复里:
wwwsq 发表于 2012-09-29 03:07
找点看不懂的垃圾代码,这还不容易?你都能看懂?扯淡!


你将命题了,变成故意找你自己都不明白的代码来考我
1. 居心不良
2. 你还没考倒
3. 你自己都不懂了,那按我的逻辑你即使把我考倒了,也没法证明你水平就不比我次


总之就是一个字:次。
作者: starwing83    时间: 2012-09-29 06:47
回复 62# OwnWaterloo


   
按你的逻辑,写出垃圾代码不是水平次,看不懂垃圾代码的才是水平次。什么逻辑。即使我相信你看得懂这个例子,难道 i = i++ + 1 你也看得懂,凭空能知道运行结果?


恩,我主要就是看到这句无语的…………不过,我们要不要考较一下他理解中文的能力再跟他说?我强烈怀疑前面的帖子他看不懂呢……


另外就是,线上更新也不是什么很难的东西,但是要线上更新,本身架构就很重要,因此肯定不会有什么非常垃圾的代码——肯定有人把关的。

如果不是这样,要线下更新也不难,以前我们做网游,一天24小时都有玩家,我们就要关服务器维护把所有玩家踢下去,又不是很难的事情。而且后来改了Linux服务器,直接脚本搞事,先拷贝文件(Windows是做不到的,因为会锁住运行的可执行文件),然后服务器重启,我们客户端又做了断线重连,玩家根本就察觉不到的。

最后,就算是全都是这么烂的代码,我也能改回来,以前客户端这边的C++base一堆的烂代码,我都一点点改过来了。没有改变现状的能力,这是水平问题。简而言之,次~
作者: hellioncu    时间: 2012-09-29 08:41
都不需要睡觉的么
作者: wwwsq    时间: 2012-09-29 10:42
OwnWaterloo 发表于 2012-09-29 04:46
回复 60# wwwsq

写我自己明白且读起来最顺畅的代码,对你来说可能疑惑重重。



“我自己明白且读起来最顺畅”

这可能就是你我水平的差异。你只能写你自己明白且读起来最顺畅的代码,而我能写大部分人明白且读起来最顺畅的代码。

之前我维护过一个晦涩的C模块,我重构之后,一个实习生也看得懂,能维护了。

要是你,估计还觉得那晦涩的代码很高明吧?



作者: wwwsq    时间: 2012-09-29 10:50
本帖最后由 wwwsq 于 2012-09-29 11:09 编辑
starwing83 发表于 2012-09-29 06:47
回复 62# OwnWaterloo



有能力写出晦涩代码,其实是一种缺陷。因为这会无形之中让你不小心写出晦涩的代码,因为你了解那种晦涩的写法,所以你认为写出来也无所谓。但晦涩代码其实是劣质的代码。

以运算顺序来说,a?b:c的运算顺序,程序员最好是不知道。因为程序员如果不知道,就不会去利用运算顺序来写代码,而会老老实实的先运算好。
运算好再逻辑判断的代码,反而是好代码。


作者: OwnWaterloo    时间: 2012-09-29 11:29
wwwsq 发表于 2012-09-29 10:42
“我自己明白且读起来最顺畅”

这可能就是你我水平的差异。你只能写你自己明白且读起来最顺畅的代码,而我能写大部分人明白且读起来最顺畅的代码。

之前我维护过一个晦涩的C模块,我重构之后,一个实习生也看得懂,能维护了。

要是你,估计还觉得那晦涩的代码很高明吧?


晦涩的代码根本就不差在哪几个运算符上。就因为几个运算符就被难倒了,水平是得有多次?
实习生连看不懂难道不是因为他是实习生自己水平次的错?  这年头都喜欢反客为主毁三观?

你我差异就是,我对:
1. 用与不用哪些人的代码
2. 按何种方式写代码
3. 允许、禁止哪些人参与我的项目
都有选择权而你没有。

实习生?连几个运算符都看不懂的实习生就该一边玩蛋去。你敢交给他们维护?也难怪那代码成天出纰漏了。
作者: OwnWaterloo    时间: 2012-09-29 11:36
回复 67# wwwsq

这一个a?b:c得有多晦涩?连这都不知道,也配称C程序员?也敢把代码交给他维护?


关于你所谓的好代码、坏代码:
sacry 发表于 2012-09-28 16:16
回复 12# 清华弟弟

你有个很脑残的地方,
当别人在讨论对错的时候,你只是在试图用你自己的审美来影响别人。

所谓学语言就是为了做实际项目,请问你是指去努力当个码农?我就喜欢研究标准玩,怎么了?
所谓看到更高的,请问你多高了?整个天朝IT领域都没见什么惊喜,要你跳出来告诉别人怎么做才能当大师拿图灵奖?

PM说错了你尽管去打脸,
但你这种"xxx不该怎么样,xxx就该怎么样"的,只是你个人审美问题,少当真理来强迫别人。

作者: starwing83    时间: 2012-09-29 11:42
回复 67# wwwsq


    你怎么知道我写出来的代码就是真的晦涩了?

就比如说,玩DoTA的APM要过200才是职业的(我不玩DoTA,乱说的,但是肯定对APM有要求),那么对职业DoTA选手来说,过200是非常合理的要求,是职业素养。难道你非得把自己APM降到200以下去迁就不合格的DoTA选手?这可能吗?

如果你说这是比赛,你不服,好,我换个例子。一群数学家用海德堡编码的形式学证明某样东西,一个初学者看不懂,你说这是初学者的错还是数学家的错?

我认为我自己是个合格的计算机编程从业者。我十分了解这个行业对于代码的质量需求,我也了解我使用的工具(C语言),我为什么要迁就那些考试只得60分的人的水平??

我们以前招实习生通常是我去面试,语法知识烂点不要紧,但是编译器都不会用的肯定是从没写过代码的人。这种人做开发你放心?短路运算的明显是没用过这个功能的人,这种人你放心?我小学五年级用BASIC写小游戏玩,写完以后惊奇的发现课本上几乎所有的知识点全用上了。C明显比BASIC复杂多了,我不求你都精通,也不求你都知道,但是那些平时几乎每次写代码都得用的东西你得知道吧?如果一个C初学者连&和|的含义都分不清楚(我高二的时候也分不清楚,背了一个月才熟悉,因为BASIC里面都是英文and和or,当时还抱怨过C语言晦涩),你又有什么理由招他进来???

我的第一家单位有个同事,人很可爱,我们都很喜欢他,姓曾,我们都叫他曾哥。他特别怕我们主管,后来还是离职了。原因是主管让他写代码,他不会,在那里看了一下午的教程,然后主管问他进度他说他还在学,主管说“我们招你来,是让你来工作的,不是让你来学习的!”结果后来曾哥一见到主管来就怕。

如果一个人不能胜任这个岗位,你要做的不是降低这个岗位的工作难度,是找一个能胜任的人做这个事情!!!
作者: cjaizss    时间: 2012-09-29 11:44
本帖最后由 cjaizss 于 2012-09-29 11:44 编辑
wwwsq 发表于 2012-09-28 22:58
i = 5;
        int x = (++i = i++);

......这不是UB,++i做不了左值,是个error才对
作者: OwnWaterloo    时间: 2012-09-29 11:47
回复 70# starwing83

>> 如果一个人不能胜任这个岗位,你要做的不是降低这个岗位的工作难度,是找一个能胜任的人做这个事情!!!

他做得到就不会这么苦逼了。

他错就错在,因为他自己处境苦逼:
1. 就认为大家都应该陪他一起苦逼
2. 对自己的次找到一个合理的借口去逃避
作者: starwing83    时间: 2012-09-29 11:51
回复 71# cjaizss


    在C++里是UB,C++里++i返回的是引用。
作者: OwnWaterloo    时间: 2012-09-29 11:53
回复 71# cjaizss

在C中不是,在C++中是。
至于那货为什么要用这个当例子嘛。。。我不知道那货是不是就属于pm说的C、C++不分的那种。。。
PS:貌似这货不知道左值这说法。好像是他,也有可能是我记错了。
作者: wwwsq    时间: 2012-09-29 12:54
starwing83 发表于 2012-09-29 11:42
回复 67# wwwsq



你这种级别,只能写写toy级别的代码。自己玩玩还行,大规模部署,算了吧。

一个长期维护的项目,一定会经过很多人的手,经过的这些人一定是水平参差不齐。
大公司大项目里面,模块数目一定都很多,而且不会让一个人长期做同一个模块,会有项目轮换制度。
谁的代码写的晦涩,必然就是给其他人带去麻烦。增加公司整体的维护成本。

C/C++假如有100个晦涩的特性,我用其中30个,他用另外30个,互相写的代码怎么看的清爽?

x = (++i = i++)这种代码纯粹就是找抽。写出这种代码才是水平次。


作者: wwwsq    时间: 2012-09-29 12:56
cjaizss 发表于 2012-09-29 11:44
......这不是UB,++i做不了左值,是个error才对



你也不懂这个表达式,没关系。最好的办法就是回避这种找抽的代码。

因为不懂这种找抽的逻辑,所以也不会写这种找抽的代码。这对项目是最好的。



作者: OwnWaterloo    时间: 2012-09-29 12:59
wwwsq 发表于 2012-09-29 12:54
x = (++i = i++)这种代码纯粹就是找抽。写出这种代码才是水平次。


我知道你分不清它与 "" "&&" "||" "," 的区别,我也懒得给你解释。
只提醒你一下,这种找抽的代码到底是谁举出来的?别说得像我们支持这种写法一样。
作者: cjaizss    时间: 2012-09-29 13:04
wwwsq 发表于 2012-09-29 12:56
你也不懂这个表达式,没关系。最好的办法就是回避这种找抽的代码。

因为不懂这种找抽的逻辑,所以 ...

那就麻烦大神帮偶解释解释,偶搬个椅子过来听听
作者: wwwsq    时间: 2012-09-29 13:05
OwnWaterloo 发表于 2012-09-29 11:47
回复 70# starwing83

>> 如果一个人不能胜任这个岗位,你要做的不是降低这个岗位的工作难度,是找一个能 ...



如果你不能把你维护的模块变得容易维护,那我认为你就是失败的。

如果你的代码晦涩到普通人读不懂,那我认为你的代码就写的不够好。

你去看看mysql的代码,看看glibc的代码,看看nginx的代码,何曾有什么晦涩的地方?

你敢以那样的标准来要求自己吗?


作者: wwwsq    时间: 2012-09-29 13:06
cjaizss 发表于 2012-09-29 13:04
那就麻烦大神帮偶解释解释,偶搬个椅子过来听听



那种找抽的代码说实话我也不懂。在vc下也许有一个特定的结果,按C标准也许有一个预期的结果,但我不确定在gcc下面,结果是否还和前面两个结果一致。

这种找抽的逻辑,你要找waterloo来给你解释。



作者: starwing83    时间: 2012-09-29 13:07
本帖最后由 starwing83 于 2012-09-29 13:08 编辑

回复 75# wwwsq


    你怎么知道我是哪个级别?我看过我的项目?你知不知道我负责过哪些项目?

项目管理你真以为你懂啊?哪个公司敢随便轮换??就算是一个人多个模块,也肯定有一个最终负责人,你懂吗?

如果真是你说的项目太大模块太多一个人搞不定,你以为Product Manager是吃屎的?你做过Product Manager吗?

我告诉你,项目管理里面除了Product Owner以外的其他职务我都做过了的,我比你更清楚项目怎么管。

自以为是不是你的错,但是如此黑白不分信口开河真不知道你的脸皮怎么就这么厚。
作者: wwwsq    时间: 2012-09-29 13:10
starwing83 发表于 2012-09-29 13:07
回复 75# wwwsq



哈,项目轮换制度都没有,我知道你的公司是什么级别的了。



作者: cjaizss    时间: 2012-09-29 13:12
wwwsq 发表于 2012-09-29 13:06
那种找抽的代码说实话我也不懂。在vc下也许有一个特定的结果,按C标准也许有一个预期的结果,但我不确 ...

。。。。。。
作者: wwwsq    时间: 2012-09-29 13:14
cjaizss 发表于 2012-09-29 13:12
。。。。。。



谁要是没去把所有编译器都试一遍就敢说他懂“x = (++i = i++)”,我就说他是sb。

这个问题的标准回答是:对于这种边缘问题,各个编译器有可能不同,我也不知道每个编译器会怎么处理这个表达式。


作者: pandaiam    时间: 2012-09-29 13:15
starwing83 发表于 2012-09-29 11:42
回复 67# wwwsq

玩dota apm不需要这么高的....
作者: cjaizss    时间: 2012-09-29 13:17
wwwsq 发表于 2012-09-29 13:14
谁要是没去把所有编译器都试一遍就敢说他懂“x = (++i = i++)”,我就说他是sb。

这个问题的标准回 ...

这叫未定义行为啊,未定义行为当然不能写啊,这难道还需要论证吗?
当然,对于C语言来说,++i不能作为左值,那这句连未定义行为的级别都还没到了,压根就无法编译。
就事论事啊,呵呵
作者: starwing83    时间: 2012-09-29 13:19
回复 82# wwwsq


    你哪只眼睛看到我说没有轮换制度的????

麻烦你看清楚点,我特地加粗了你都没看么?是不能随意轮换!!!

实习生再轮换也是实习生的活儿,架构师再轮换也是设计架构,你敢让实习生去设计架构?

轮换制度,是要站在公司各项基本技术规范之上的。代码质量谁说了算,不是按照暂时的轮换负责人来的,这样代码只会一塌糊涂。代码质量是靠总体的规范,和轮换之后实际程序员的上级的项目组长负责的。你懂吗?

也就是说,一个实习生如果发现看不懂的代码,一定会去问自己的负责人,否则你以为他们过来学什么的?当免费劳工吗?人家是实习,是来学习的!不是来看自己已经学会的东西的!

这样才能让项目整体都稳定在一个较高的水准上。这样的手法仅仅是项目人事管理的一小部分,还有项目版本控制、发布周期、开发流程、测试/开发协调、需求控制反馈/反转、紧急敏捷开发、反馈流程、应急轮班负责。你懂吗?

你真以为想当然就能做项目管理了?
作者: starwing83    时间: 2012-09-29 13:23
回复 84# wwwsq


    你这么说,恰巧就证明你不懂UB,也不懂这段代码实际上是什么。

当然,你已经说了你不懂了。不懂你拿这段代码出来干嘛?
作者: OwnWaterloo    时间: 2012-09-29 13:23
wwwsq 发表于 2012-09-29 13:05
如果你不能把你维护的模块变得容易维护,那我认为你就是失败的。

如果你的代码晦涩到普通人读不懂,那我认为你的代码就写的不够好。

你去看看mysql的代码,看看glibc的代码,看看nginx的代码,何曾有什么晦涩的地方?

你敢以那样的标准来要求自己吗?


你再次歪曲事实。

前一次是:": ?" "&&", "||", "," 有规定顺序 , 你替换成另外两个无规定顺序的例子。
再前一次是: 自然的写出 ": ?" "&&", "||", "," 看不明白只能怪自己 , 你改为故意写成你那两个例子去为难他人。
再往前, 算了,我都懒得翻了。

而这次是: 写": ?", "&&", "||", "," , 而你替换成让模块变得不容易维护。
": ?", "&&", "||"在glibc随处都是。 只有","我不记得有没有了。 但我记得sgi stl里有","。 嗯,按你的标准,他们都是晦涩的,不可维护的。


我还是要再次问你, ": ?" "&&", "||", "," 到底晦涩在哪里?
了解语言80%部分的人, 看只用语言60%的代码处处都是清晰的。
只了解语言40%的人, 看只用语言60%的代码处处都是混乱的、晦涩的。
作者: pmerofc    时间: 2012-09-29 13:23
提示: 作者被禁止或删除 内容自动屏蔽
作者: wwwsq    时间: 2012-09-29 13:25
starwing83 发表于 2012-09-29 13:19
回复 82# wwwsq



哈,没见过架构组招实习生吧?

实习生写一个上亿pv的对外服务,没见过吧?

见识少不是你的错,还要出来卖弄就是你的不对了。

你喜欢把编码搞的很神秘,我就喜欢破除这种神秘。代码是什么?代码应该是按预期执行的逻辑。


作者: OwnWaterloo    时间: 2012-09-29 13:27
wwwsq 发表于 2012-09-29 13:14
谁要是没去把所有编译器都试一遍就敢说他懂“x = (++i = i++)”,我就说他是sb。

这个问题的标准回答是:对于这种边缘问题,各个编译器有可能不同,我也不知道每个编译器会怎么处理这个表达式。


对"x = (++i = i++)",依然以去把所有编译器试个遍的方式去理解的人,我也说他是sb。
知道这问题不应该以这种思路去理解,是为懂。
作者: starwing83    时间: 2012-09-29 13:27
回复 79# wwwsq


    顺便说一下,mysql和glibc的代码很烂。确切的说GNU的代码烂是非常出名的,你真的看过吗?

的nginx代码倒是挺漂亮的,但是里面用到的高级技巧你看得懂吗?

对于C runtime support,我推荐你去看APR,难度很低,代码质量也很好。

对于小型项目,我强烈推荐你看Lua,代码质量非常好,不过也几乎处处都有"? :",“&&”,“||”,“,”,我昨天还举了个例子说Lua的check_exp是用逗号表达式实现的,你没看还是没看懂?
作者: pandaiam    时间: 2012-09-29 13:29
x = (++i = i++)

哎,看不懂,也不知道到底是不是未定义行为..
反正从我做起,不写就是了.
作者: starwing83    时间: 2012-09-29 13:29
回复 91# wwwsq


    没见过ACM/ICPC区冠军的实习生吧?也没见过十分钟能实现一颗红黑树的实习生吧?问题是实习生就是实习生,实习生就是要来学习的。刚进项目的实习生我们是不允许直接碰repo的,必须先做一些独立的课题才允许上repo,你知道具体的流程吗?

你以为道听途说就能搞好项目管理了?
作者: wwwsq    时间: 2012-09-29 13:29
OwnWaterloo 发表于 2012-09-29 13:27
对"x = (++i = i++)",依然以去把所有编译器试个遍的方式去理解的人,我也说他是sb。
知道这问题不应该 ...




对于UB的代码,你能凭空猜出每个编译器是怎么工作的?

给出一个UB的结论,等于没有结论。


作者: wwwsq    时间: 2012-09-29 13:31
starwing83 发表于 2012-09-29 13:29
回复 91# wwwsq



ACM高手我是见过一些,还带他们做过项目,没像你这么狂妄的。



作者: OwnWaterloo    时间: 2012-09-29 13:31
wwwsq 发表于 2012-09-29 13:25
代码是什么?代码应该是按预期执行的逻辑。


搞笑, ": ?", "&&", "||", "," 难道没有按预期执行逻辑?
作者: wwwsq    时间: 2012-09-29 13:34
OwnWaterloo 发表于 2012-09-29 13:31
搞笑, ": ?", "&&", "||", "," 难道没有按预期执行逻辑?



对于晦涩的代码,不同的人会有不同的预期。比如“x = (++i = i++)”这种。

bool a();
void b();
void c();

a()?b():c()

即使是上面这样简单的代码,也会有人误解。

这样的误解会对项目造成伤害。

你可以说误解的人水平次,但你的能力仅此而已吗?如何规避对项目的伤害?


作者: starwing83    时间: 2012-09-29 13:36
回复 91# wwwsq


    说忘了,编码一点都不神秘。确切的说编码是项目里面比重很小的一个部分。在设计、会议、计划、美工资源匹配过后,我们才会真正开始编码。大多数时候是写一个standalone做设计验证,验证成功了才会编码。这的确是整个开发流程中最普通的一个部分了。真正有神秘感、很好玩的部分是功能设计。我们会尽力让新需求和旧架构匹配,让新的需求能很轻易的实现。

举个例子吧。做网游的资源动态加载。我们直接用proxy对象来做,上层所有架构不变,下头偷天换日了,本来是要动根的一个需求,我们硬是添加了一个中间层实现了,而且实现了项目资源的完全监控式管理,后来半天时间就加了资源cache。

再举个例子,过了很长时间上面要求资源动态加载的时候要带默认资源,又是一个动根的需求,但是我们根本一行代码都没改,做了一个脚本自动跑了一遍客户端,下载了所有需要下载的资源,然后打了个包随着客户端一起发布,完事,一行代码都没动。

你真的以为项目就完全都是编码了?

我在第一家公司负责的小组的效率,是我后来去华为那边看到他们的效率的近十倍,没听说吧?




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2