这里有一些答案提到了调用约定。它们与您的问题无关:无论您使用什么调用约定,您声明参数的顺序都无关紧要。寄存器传递哪些参数,堆栈传递哪些参数并不重要,只要寄存器传递的参数数量相同,堆栈传递的参数数量相同即可。请注意,大小高于原生架构大小(32 位为 4 字节,64 位为 8 字节)的参数是通过地址传递的,因此它们以与较小尺寸数据相同的速度传递.
举个例子:
您有一个带有 6 个参数的函数。你有一个调用约定,我们称之为 CA,它通过寄存器传递一个参数,其余的(在这种情况下为 5 个)通过堆栈传递,第二个调用约定,让我们称之为 CB,它通过寄存器传递 4 个参数,其余的(在本例中为 2)按堆栈。
现在,当然 CA 会比 CB 快,但它与声明参数的顺序无关。对于 CA,无论您首先声明哪个参数(通过寄存器)以及声明第二个、第三个..6 个(堆栈),它都会一样快,而对于 CB,无论您为寄存器声明哪个 4 个参数,它都会一样快并且您将其声明为最后两个参数。
现在,关于你的问题:
唯一的强制性规则是可选参数必须最后声明。任何非可选参数都不能跟在可选参数之后。
除此之外,你可以使用任何你想要的顺序,我能给你的唯一强烈建议是保持一致。选择一个模型并坚持下去。
您可以考虑的一些准则:
- 目的地在源之前。这是要接近的
destination = source
。
- 缓冲区的大小在缓冲区之后:
f(char * s, unsigned size)
- 首先输入参数,最后输出参数(这和我给你的第一个冲突)
但是对于参数的顺序,没有“错误”或“正确”,甚至没有普遍接受的准则。选择一些东西并保持一致。
编辑
我想到了一种对参数进行排序的“错误”方式:按字母顺序:)。
编辑 2
例如,对于 CA,如果我传递一个 vector(100) 和一个 int,最好先使用 vector(100),即使用寄存器加载更大的数据类型。对?
不,正如我所提到的,数据大小并不重要。让我们谈谈 32 位架构(同样的讨论适用于任何架构 16 位、64 位等)。让我们分析一下参数大小与架构的原生大小相关的 3 种情况。
- 相同大小:4 字节参数。这里没什么好说的。
- 较小的尺寸:将使用 4 字节的寄存器或将在堆栈上分配 4 字节。所以这里也没什么有趣的。
- 更大的尺寸:(例如具有许多字段的结构或静态数组)。无论选择哪种方法来传递此参数,此数据都驻留在内存中,并且传递的是指向该数据的指针(大小为 4 字节)。同样,我们在堆栈上有一个 4 字节的寄存器或 4 字节。
参数的大小无关紧要。
编辑 3
@TonyD 如何解释,如果您不访问所有参数,顺序很重要。看他的回答。