PLT 板


LINE

看板 PLT  RSS
※ 引述《caml (suitengu)》之铭言: : : 推 jtmh:这里的 object 指的是 variable, 在 K&R C 那本常看到这麽用 04/01 00:48 : : 推 tinlans:一楼正解,PL 教科书和 C 标准规格书也会这样用。 04/01 08:35 : : 推 caml:c的传值会生成temp obj?? c++学太多了吧 04/01 09:40 : : 推 Lordaeron:这就是问题了, object 以现在的眼光来看, 另有意义了. 04/01 09:59 : : 推 tinlans:回三楼,&var 确实会生成一个 temp obj。 04/06 03:37 : : 你到wiki上查一下evaluation strategy : 在call by reference条目下﹐ C 只有 call by value, 没有 call by address/reference, foo(&var) 这种呼叫不管在 C or C++, 只要 foo() 的 parameter type 是 pointer type (programmer 在 argument 写 &var,而 pass 的是 argument 的 R-value), 这种就叫 call by value。 : If the argument expression is an L-value, its address is used. 所以上面这行只适用於 C++ 才有的 reference type parameter, 当 call site 写 foo(var) (programmer 在 argument 写 var,而 pass 的是 argument 的 L-value), 且 foo() 的宣告式是 void foo(T &) 时才适用。 : Otherwise, a temporary object is constructed by the caller and : a reference to this object is passed; the object is then discarded : when the function returns. : 推 godfat:这不也是表达 var 是 obj...? 04/11 12:04 : 推 caml:我说的意思是c传值不产生什麽temp obj, 传个地址还生成obj 04/11 12:17 : → caml:效率太低了。 04/11 12:21 这没办法, 虽说 compiler 的 optimization 可以省下一些事情, 然而还是有些事情不能避免, 一般来说如果系统不提供纯正的 absolute addressing mode (且不可重新定址), 取 variable 的 address 通常还是要靠「算」的 (local variable), 甚至是透过二次间接定址从 memory 内的表格「读」出来 (global variable), 不同硬体架构会有不同情形, 但几乎都逃不掉「算」和「读」, 而参数传递时也存在着「写」的动作 除非是硬体设计上有支援「把运算结果直接写入 memory 中某个 address」的功能, 但这种 machine-dependent optimization 已经失去一般性了。 ============================================================================ call by value: int foo(int *ptr) // 此处会将 &var 的值由 stack 上的参数区复制一份 // 到 local variable 区 (可最佳化)。 { int var2 = 0; ptr = &var2; // &var2 的新值是写到 local variable 区里放 ptr // 的地方。 ... } int main() { int var = 0; return foo(&var); // &var 算式的结果会是一份 temporary object, // 这个 temporary object 还要 push 到 stack // 进行参数传递动作 (可由最佳化合并)。 } ============================================================================ call by address/reference: int foo(int &obj) // 同上例 { int var2 = 0; obj = var2; // 此处语法和语意都与上例不同,虽同样是修改「参数」 // 本身,却是得将上例改写成 *ptr = var2; 才会相同, // 但是「语法依然相异」,而这个「语法」上的不同,也 // 是 value 和 address/reference 传递法上的差异。 ... } int main() { int var = 0; return foo(var); // 同上例,但注意「programmer 并没有对 var 做运算」 // ,这件事很重要,因为这就是 call by value 和 // call by address/reference 的差异之一。 } ============================================================================ 回到前面我说的四行话: 在 C 要送变数的 address/reference 只能用 address-of 运算子取出 lvalue, 但这样会 explicit 构成一个 temporary object (programmer 可见), 所以送过去的会是 temporary object 的 value, 也因此这个还是 call by value。 附上推文: 3F 推 caml:c的传值会生成temp obj?? c++学太多了吧 5F 推 tinlans:回三楼,&var 确实会生成一个 temp obj。 第二行末括的 (programmer 可见), 意思就是说「这样搞结果还是 call by value」的意思, 换言之就是「C 不管怎样还是只有 call by value」的意思, 所以我不清楚你去查「call by refernce」的条目来回的意义。 当然光是这四行是有漏洞的, 所以再往前推三行可以看到我说了: 在 C/C++ 分辨这种东西很单纯是看 call site 怎样写, 不经型别转换就自动取 lvalue 丢进去那就是 by address/reference, 其余的都是 by value, 那四行是这里第一行的详述 (意思相同,在说为什麽看 call site 就能判定), 而这里的第二行和第三行则是补述第一行的不足之处, 「型别转换」是指 implicit type conversion (又叫 coercion) 以及 explicit type conversion (又称 cast), 而我之所以补这两行的原因是在於, 有人会拿 array 跟 function 来做反驳: 在 call site 明明没有看到 & 这个 address-of operator, 那又为什麽还是被叫做 call by value 呢? 答案是这里有 implicit type conversion: function -> pointer 转换 array -> pointer 转换 这个转换後的 pointer 本身也是 temporary object, 而 callee 收到的是这个 temporary object 的副本, 所以这个也叫做 call by value。 讲到这边来回到你最後说的部分: 推 caml:我说的意思是c传值不产生什麽temp obj, 传个地址还生成obj → caml:效率太低了。 综合上面所述, 我所要回答的主旨是: 1. 事实上,C 传值是会产生 temporary object 的 (在 reg 或 stack 上)。 2. 传地址过去其实还是一种传值,所以还是有 temporary object, 实际上这个 temp obj 不管 by value 还是 by addr/ref 都跑不掉, 只是 compiler 可以透过最佳化来减少它, 但是藉由最佳化机制消去的 temporary object, 它本身还是被称之为 temporary object, 不会因为它被 compiler 砍了就失去这个名字。 因此,foo(var) 和 foo(&var) 相较之下, &var 是一个运算式 (而我们 pass 过去的是 &var 运算式结果的 R-value), 这个「&var 运算式结果」本身就是一个 temporary object, 这会比 foo(var) 还多了一个 temporary object, 因为 foo(var) 这样写并没有对 var 本身做运算。 3. C++ 写太多并不会影响我对 C 的观念, C++ 我是写了 10 年多, 但是 C 我已经写了快 20 年, 所以应该不是你所想的那样; 另外,我是在 PL 实验室里专门在做 compiler 的。 -- Name: Tseng, Ling-hua E-mail Address: [email protected] School: National Tsing Hua University Department: Computer Science Interesting: C++, Compiler, PL/PD, OS, VM, Large-scale software design Researching: Software pipelining for VLIW architectures Homepage: https://it.muds.net/~uranus --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.230.216.206 ※ 编辑: tinlans 来自: 61.230.216.206 (04/11 18:10)
1F:推 aoc90058:推一个 :) 04/11 22:24
2F:推 yago01:真不愧是LPC之神... 04/12 11:38
3F:推 revivalworld:推鹿神 04/22 17:28







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Soft_Job站内搜寻

TOP