V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
peiqing9003ah
V2EX  ›  C++

形参是什么时候初始化的?

  •  
  •   peiqing9003ah · 2019-11-28 12:29:03 +08:00 · 3165 次点击
    这是一个创建于 1601 天前的主题,其中的信息可能已经有所发展或是发生改变。
    学引用 ,看到定义时需初始化。

    故联想到一般情形, 哪位老铁讲清楚??
    12 条回复    2020-01-13 21:20:32 +08:00
    peiqing9003ah
        1
    peiqing9003ah  
    OP
       2019-11-28 12:30:14 +08:00
    函数形参的定义和初始化是在函数第一次调用时进行的? 能否用汇编说明
    mutalisk
        2
    mutalisk  
       2019-11-28 15:52:54 +08:00
    所谓的形参其实就是对应栈上的一个偏移量而已,所谓的初始化其实就是在调用函数前 push 到栈顶而已
    GeruzoniAnsasu
        3
    GeruzoniAnsasu  
       2019-11-28 19:51:24 +08:00   ❤️ 1
    不知道从哪开始吐槽

    建议《程序员的自我修养》





    体会一下“形式” 参数 的 形式 的概念
    形参定义了这个函数接受的参数的标准(类型),“形式” 参数并无所谓初不初始化,它的意义是在函数内用于指代传进来的实际参数,想想数学的变量代换


    当然实际编译器的实现很可能为形参这个名字的变量单独开了内存然后把实参的内存里的内容复制到那块内存去,但这种实现其实并不能体现“形参”为什么叫“形式”参数的原因

    说这么多是想说,你应该理解“形式”的东西讲道理无所谓“初始化”
    peiqing9003ah
        4
    peiqing9003ah  
    OP
       2019-11-28 20:53:26 +08:00
    @GeruzoniAnsasu 六,鼓掌
    FrankHB
        5
    FrankHB  
       2019-12-01 15:19:59 +08:00
    @mutalisk 放寄存器了就没人权了?
    @GeruzoniAnsasu 扯蛋。
    形式参数在 C/C++/Obj-C 的抽象机语义里就是特殊的局部对象 /变量,你调用了还能跳过初始化?行,试试证明不初始化不改变语义?
    所谓“形式”的含义,是指不同调用实例中的实际参数能具有一对多的对应关系。不管是使用作为所谓实际参数的表达式进行绑定变量的替换或者利用活动记录的存储的代换,对“形式”不形式而言,说穿了都是实现。没有因为变量替换(更确切地,capture-avoiding substitution )在历史上更早就更抽象的道理;况且这个节点里的语言全部不使用变量替换,而在语义上直接要求非一等的环境(局部变量的活动记录帧)外加允许一些 as-if rule (如 C++引用不要求占用存储)的变换。
    如果无视这些要求,按原始的 λ 演算的语义,你都可以说这里要求的替换是无副作用的,替换的操作不存在影响可观察行为的计算作用,直接把初始化的概念取消得了。
    FrankHB
        6
    FrankHB  
       2019-12-01 15:43:31 +08:00
    @GeruzoniAnsasu 还有一个无视历史行程的流毒甚广的基本理解偏差单独挑出来说。
    形式参数的“形式”跟“类型”无关。使用显式类型的语言才在函数的类型声明顺带形式参数的声明,因为决定函数类型的类型构造器(→)要求已知参数类型,不在函数声明中提供,还是要在其它位置明确,才可能允许函数类型检查。
    这个节点里照日常使用,姑且都能算是这样的语言,但严格讲,C 就不强制——函数原型声明是可选的,不要求总是具有函数参数类型:
    比如 int main() ,你拿 GCC 去调用 main(什么乱七八糟) 可能都过得去,Clang 倒是仍然会检查,但也不同于 int main(void) ;
    其它用法参见 K&R C 古董代码。
    不使用显式类型的语言里函数的绑定变量一般意义下也叫做形式参数,只不过“参数(parameter)”在某些情况有其它含义( Lisp 方言使用参数作为动态作用域的变量,纯函数式语言使用参数表示类似 C++的模板类型参数的参数多态的类型变量),所以不怎么单独提出来说而已。这样的函数形式参数的所谓类型,可能是不需要明确把类型写出来而确定的(如 Haskell 这样默认就鼓励使用类型推断(type inference) 确定的语言),也可能因为变量不存在确定的类型而根本不存在(如 Scheme 这样使用清单类型(manifest typing) 的语言)。

    最后回答 LZ 的问题。一般地,使用实际参数(actual argument) 初始化函数的形式参数(formal parameter) ,在函数被调用——带有作为操作符的函数以及函数的实际参数的后置表达式被求值时——发生。
    对这个节点讨论的语言,函数这个特性(排除宏这种更一般意义上的“函数”)对实际参数的求值总是使用原始的应用序(applicative order) ,即函数的实际参数先于函数体被求值(但注意,不同实际参数之间没有“最左”的保证),因此(借用 C++11 和 C11 照抄 C++11 的概念)初始化总是后序于(sequenced after) 函数调用的实际参数求值之后。

    一般地,函数的形式参数(formal parameter) 在
    FrankHB
        7
    FrankHB  
       2019-12-01 15:44:02 +08:00
    草、贴多了,以上最后一节请无视……
    mutalisk
        8
    mutalisk  
       2020-01-08 12:28:19 +08:00
    @FrankHB 老哥教育得很对,忘了寄存器这茬了。。。
    peiqing9003ah
        9
    peiqing9003ah  
    OP
       2020-01-09 15:34:54 +08:00
    @FrankHB 老哥, 我这是 X32, 不是 x86
    peiqing9003ah
        10
    peiqing9003ah  
    OP
       2020-01-09 15:35:47 +08:00
    @FrankHB 草,x86, 不是 X64
    peiqing9003ah
        11
    peiqing9003ah  
    OP
       2020-01-09 15:38:19 +08:00
    @mutalisk x86, 不是 X64
    mutalisk
        12
    mutalisk  
       2020-01-13 21:20:32 +08:00
    @peiqing9003ah 不管 x86 还是 x64,都有可能会用到寄存器,只是 x64 的寄存器数量更多而已
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1286 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 17:45 · PVG 01:45 · LAX 10:45 · JFK 13:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.