rolin 发表于 2013-7-8 13:01

本屌丝来装个码农比 求各位fackbook ibm microsoft apple 华为 中兴大牛指教

本帖最后由 rolin 于 2013-7-8 13:08 编辑

一提到ub问题 大多数貌似都具体到c/c++语言
为什么呢 按理说一个序列点上多次修改变量 每种语言都会有这种情况啊
具体到编译器优化,我发现只有m记的vc独树一帜
对于这段代码
int a = 1;
int b = a++ + a++

vc结果是2
gcc结果是3

我另外用了chrome v8测试js代码 结果是3
adobe的actionscript3.0 结果是3
python lua没有自增运算符
c# 结果是3

反汇编发现  
vc是在statement结束后才对变量自增/自减操作
g++是在一个factor结束后马上操作

为什么vc编译器要搞的跟大家不一样?
是因为这些稍微现代的如c#,java都用了同一个前端吗

个人认为vc是牺牲了编译时间来优化程序速度
g++则更便于理解

而对于js这样的无类型脚本语言,没办法把程序解析成仅仅操作char/number类型的字节码,所以vc这样的优化就没办法实现了,如果在eos之后再push ref , push key, ++/-- 这样不是优化,是反过来了

当然这一切都是我的臆想  这方面的资料根本查不到
求指教

风剑 发表于 2013-7-8 13:16

吊丝从不写这样的句子    ++ -- 这样的   一句话里面只用一次

  用着放心   写着舒心

热啊 发表于 2013-7-8 13:32

这种问题完全就是蛋疼

切克闹 发表于 2013-7-8 13:40

傻逼才写这种代码

潜规则 发表于 2013-7-8 18:17

原创内容 水晶 +2

bingle 发表于 2013-7-8 18:52

上学时用VC比较多,LZ说的问题也碰到过,区别就是表达式的左解释和右解释,还有VC函数参数的解释顺序和gcc也不同。
当时的感觉微软的很多东西设计的很别扭,故弄玄虚,简单问题复杂化,比如命令名,函数名,接口。
个人感觉是,那些OS,编译方面的基础技术,Unix,Borland已经给出了最合理设计,而微软跳不出这些技术思路,却又想显得不同,只好。。。

buddha 发表于 2013-7-8 19:52

这种代码都写得出来

stupid_ks 发表于 2013-7-8 20:53

切克闹 发表于 2013-7-8 13:40 static/image/common/back.gif
傻逼才写这种代码

+1, 的确很2B的代码

刁总书记 发表于 2013-7-8 23:17

写这种代码会被人爆菊的

GGiloveU 发表于 2013-7-8 23:51

1 确定gcc是3?咋试出来vc不一样的?
2 别反汇编也别优化了,先搜索下左值右值和自增究竟咋回事吧。
3  fackbook ibm microsoft apple 华为 中兴 任何一家的编程规范都不会允许这么写,谁敢这么写抽谁。别研究了。

记梦亦梦己是梦 发表于 2013-7-9 09:57

rolin 发表于 2013-7-9 12:57

GGiloveU 发表于 2013-7-8 23:51 static/image/common/back.gif
1 确定gcc是3?咋试出来vc不一样的?
2 别反汇编也别优化了,先搜索下左值右值和自增究竟咋回事吧。
3  f ...

还左值右值
谁给你勇气大放厥词的?
本文讨论的编译器实现,不是软件工程 你看懂了吗?
既然a++ + a++这样的代码只是ub警告能通过编译
那就有价值  你自己实现编译器就必须解析这种语法
懂?

牛clear 发表于 2013-7-9 14:37

c++只定义了规范标准,但是很多细节根据不同厂家不同编译器实现是不一样的。
这种问题真不值得花时间研究,除非是线上产品问题。

Neutrino 发表于 2013-7-9 14:42

本帖最后由 Neutrino 于 2013-7-9 14:57 编辑

我写个编译器,这种情况一律解释成a="coder is da sha bi"

OruA 发表于 2013-7-9 14:54

这种问题有研究的必要性吗 ?

rolin 发表于 2013-7-9 15:02

给各位大神跪了。。。
我要讨论的是编译实现啊
不是这种代码傻逼不傻逼啊
既然市面上的编译器能通过
那我也需要解析这样的语法
怎么都给看成了洪水猛兽

难道python lua就是因为这个原因取消了inc, dec运算符.....

rolin 发表于 2013-7-9 15:12

如下我现在的实现跟大多数语言一样var x
var y
;var x = {};
0  New_Obj
1  Pop eax
2  Mov x , eax
;x.name = 3;
3  Push x
4  Push "name"
5  Push 3
6  Set_Field
;var y = x.name++ + x.name++;
7  Push x
8  Push "name"
9  Get_Field
10 Push 1
11 Add_Field 1
12 Push x
13 Push "name"
14 Get_Field
15 Push 1
16 Add_Field 1
17 Pop ebx
18 Pop eax
19 Add eax, ebx
20 Push eax
21 Pop eax
22 Mov y , eax
23 Ret 0
但是我觉得c编译器的遇到EOS之后再 add/sub 1的处理方式更好
才有了这么个帖子

Neutrino 发表于 2013-7-9 15:27

如果是写编译器,就应该给个warning,告诉他是UB,然后随便给个随机值就行了。
让他程序崩溃几次,就老实了,以后也不会这么写
页: [1]
查看完整版本: 本屌丝来装个码农比 求各位fackbook ibm microsoft apple 华为 中兴大牛指教