user-0 提问: 参数执行顺序问题

回复:
user: user-1
content: 引用 18 楼 xsklld 的回复:[quote=引用 17 楼 cfjtaishan 的回复:] [quote=引用 16 楼 xsklld 的回复:] [quote=引用 13 楼 cfjtaishan 的回复:] [quote=引用 11 楼 xsklld 的回复:] [quote=引用 10 楼 paschen 的回复:] 默认的调用约定中函数参数是从右向左进行压栈的 压栈顺序和求值顺序并没有什么关系，我完全可以先从左往右求值，（然后存下求得的值），再从右往左压栈。[/quote] 对于楼主的这个函数参数是有关系的，从右向左压栈就是func(8,8)，从左向右就是func(6,8)[/quote] 你指的是求值顺序，和压栈顺序没有关系。 见：calling convention and evaluation order[/quote] 入栈顺序决定了楼主这个函数调用的求值顺序[/quote] 依据呢？[/quote] func(8,8)

user: user-2
content: 不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  不要写连自己也预测不了结果的代码！

user: user-2
content: 理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

user: user-1
content: 引用 11 楼 xsklld 的回复:[quote=引用 10 楼 paschen 的回复:] 默认的调用约定中函数参数是从右向左进行压栈的 压栈顺序和求值顺序并没有什么关系，我完全可以先从左往右求值，（然后存下求得的值），再从右往左压栈。[/quote] 对于楼主的这个函数参数是有关系的，从右向左压栈就是func(8,8)，从左向右就是func(6,8)

user: user-3
content: 引用 17 楼 cfjtaishan 的回复:[quote=引用 16 楼 xsklld 的回复:] [quote=引用 13 楼 cfjtaishan 的回复:] [quote=引用 11 楼 xsklld 的回复:] [quote=引用 10 楼 paschen 的回复:] 默认的调用约定中函数参数是从右向左进行压栈的 压栈顺序和求值顺序并没有什么关系，我完全可以先从左往右求值，（然后存下求得的值），再从右往左压栈。[/quote] 对于楼主的这个函数参数是有关系的，从右向左压栈就是func(8,8)，从左向右就是func(6,8)[/quote] 你指的是求值顺序，和压栈顺序没有关系。 见：calling convention and evaluation order[/quote] 入栈顺序决定了楼主这个函数调用的求值顺序[/quote] 依据呢？

user: user-4
content: 不确定，不要这样写。

user: user-1
content: 引用 16 楼 xsklld 的回复:[quote=引用 13 楼 cfjtaishan 的回复:] [quote=引用 11 楼 xsklld 的回复:] [quote=引用 10 楼 paschen 的回复:] 默认的调用约定中函数参数是从右向左进行压栈的 压栈顺序和求值顺序并没有什么关系，我完全可以先从左往右求值，（然后存下求得的值），再从右往左压栈。[/quote] 对于楼主的这个函数参数是有关系的，从右向左压栈就是func(8,8)，从左向右就是func(6,8)[/quote] 你指的是求值顺序，和压栈顺序没有关系。 见：calling convention and evaluation order[/quote] 入栈顺序决定了楼主这个函数调用的求值顺序

user: user-3
content: 引用 13 楼 cfjtaishan 的回复:[quote=引用 11 楼 xsklld 的回复:] [quote=引用 10 楼 paschen 的回复:] 默认的调用约定中函数参数是从右向左进行压栈的 压栈顺序和求值顺序并没有什么关系，我完全可以先从左往右求值，（然后存下求得的值），再从右往左压栈。[/quote] 对于楼主的这个函数参数是有关系的，从右向左压栈就是func(8,8)，从左向右就是func(6,8)[/quote] 你指的是求值顺序，和压栈顺序没有关系。 见：calling convention and evaluation order

user: user-3
content: 引用 10 楼 paschen 的回复:默认的调用约定中函数参数是从右向左进行压栈的 压栈顺序和求值顺序并没有什么关系，我完全可以先从左往右求值，（然后存下求得的值），再从右往左压栈。

user: user-5
content: 引用 楼主 qq_18888869 的回复:#include<stdio.h>  fun(int a ,int b) { int c; c=a+b; return c; } main() { int x=6,r; r=func(x,x+=2); printf("%d\n",r); } 结果是16先求了右边的参数，为什么不是x=6带进去，第二个x+2=8带进去呢？求大神指点  那你应该func(x, x+2);

user: user-2
content: 调用约定 https://msdn.microsoft.com/zh-cn/magazine/9b372w95.aspx

user: user-1
content: 引用 3 楼 vnvlyp 的回复:[quote=引用 2 楼 cfjtaishan 的回复:] 这是函数栈参数压栈的顺序决定的，从右开始依次压入栈，栈是先进后出，最后压栈的第一个参数会第一个出栈。 如果楼主不想将计算后的值作为第一个参数，那么建议在调用函数前先保存，然后在传入；  这就是个表达式顺序点的问题，和栈有什么关系？ gcc现在都会检查这种问题并且警告 warning: unsequenced modification fastcall调用方式甚至都不一定用到栈，编译器完全可以从左到右计算参数，然而这样写依然是未定义行为。[/quote] 虽然是表达式，但是参数传递，传递的是值，那么它需要将计算结果传过去。我看fastcall的参数从左到右传递也不是所有参数，是有条件的 http://blog.csdn.net/shenwansangz/article/details/50965415

user: user-6
content: 默认的调用约定中函数参数是从右向左进行压栈的

user: user-7
content: 引用 2 楼 cfjtaishan 的回复:这是函数栈参数压栈的顺序决定的，从右开始依次压入栈，栈是先进后出，最后压栈的第一个参数会第一个出栈。 如果楼主不想将计算后的值作为第一个参数，那么建议在调用函数前先保存，然后在传入；  这就是个表达式顺序点的问题，和栈有什么关系？ gcc现在都会检查这种问题并且警告 warning: unsequenced modification fastcall调用方式甚至都不一定用到栈，编译器完全可以从左到右计算参数，然而这样写依然是未定义行为。

user: user-8

user: user-1
content: 引用 7 楼 vnvlyp 的回复:[quote=引用 4 楼 cfjtaishan 的回复:] [quote=引用 3 楼 vnvlyp 的回复:] [quote=引用 2 楼 cfjtaishan 的回复:] 这是函数栈参数压栈的顺序决定的，从右开始依次压入栈，栈是先进后出，最后压栈的第一个参数会第一个出栈。 如果楼主不想将计算后的值作为第一个参数，那么建议在调用函数前先保存，然后在传入；  这就是个表达式顺序点的问题，和栈有什么关系？ gcc现在都会检查这种问题并且警告 warning: unsequenced modification fastcall调用方式甚至都不一定用到栈，编译器完全可以从左到右计算参数，然而这样写依然是未定义行为。[/quote] 虽然是表达式，但是参数传递，传递的是值，那么它需要将计算结果传过去。我看fastcall的参数从左到右传递也不是所有参数，是有条件的 http://blog.csdn.net/shenwansangz/article/details/50965415[/quote]  我不是要说fastcall是从左到右，我是说标准并没有规定函数参数的计算顺序，任何人完全可以写一个编译器是按照随机顺序入栈而依然符合语言标准。宣传从右到左或者从左到右都有点误导别人的成分。 https://timsong-cpp.github.io/cppwp/n3337/expr.call#8 N3337说： The evaluations of the postfix expression and of the argument expressions are all unsequenced relative to one another.[/quote] 我感觉这样做没有实在意义，不按照编译器的执行。

user: user-7
content: 引用 4 楼 cfjtaishan 的回复:[quote=引用 3 楼 vnvlyp 的回复:] [quote=引用 2 楼 cfjtaishan 的回复:] 这是函数栈参数压栈的顺序决定的，从右开始依次压入栈，栈是先进后出，最后压栈的第一个参数会第一个出栈。 如果楼主不想将计算后的值作为第一个参数，那么建议在调用函数前先保存，然后在传入；  这就是个表达式顺序点的问题，和栈有什么关系？ gcc现在都会检查这种问题并且警告 warning: unsequenced modification fastcall调用方式甚至都不一定用到栈，编译器完全可以从左到右计算参数，然而这样写依然是未定义行为。[/quote] 虽然是表达式，但是参数传递，传递的是值，那么它需要将计算结果传过去。我看fastcall的参数从左到右传递也不是所有参数，是有条件的 http://blog.csdn.net/shenwansangz/article/details/50965415[/quote]  我不是要说fastcall是从左到右，我是说标准并没有规定函数参数的计算顺序，任何人完全可以写一个编译器是按照随机顺序入栈而依然符合语言标准。宣传从右到左或者从左到右都有点误导别人的成分。 https://timsong-cpp.github.io/cppwp/n3337/expr.call#8 N3337说： The evaluations of the postfix expression and of the argument expressions are all unsequenced relative to one another.

user: user-1
content: 这是函数栈参数压栈的顺序决定的，从右开始依次压入栈，栈是先进后出，最后压栈的第一个参数会第一个出栈。 如果楼主不想将计算后的值作为第一个参数，那么建议在调用函数前先保存，然后在传入；

user: user-9
content: 首先求值顺序是不确定的 参数有两个表达式 x x += 2 它们的先后求值顺序并不确定，所以是一个未定义行为 有可能是6 8， 8 8甚至是其他（x+=2求值过程取x）  跟压栈顺序并没有很大关系