There are some answers here mentioning calling conventions. They have nothing to do with your question: No matter what calling convention you use, the order in which you declare the parameters doesn't matter. It doesn't matter which parameters are passed by registers and which are passed by stack, as long as the same number of parameters are passed by registers and the same amount of parameters are passed by stack. Please note that parameters that are higher in size than the native architecture size (4-bytes for 32-bit and 8-byte for 64-bit) are passed by an address, so they are passed with the same speed as a smaller size data.
Let's take an example:
You have a function with 6 parameters. And you have a calling convention, lets call it CA, that passes one parameter by register and the rest (5 in this case) by stack, and a second calling convention, lets call it CB, that passes 4 parameters by registers and the rest (in this case 2) by stack.
Now, of course that CA will be faster than CB, but it has nothing to do with the order the parameters are declared. For CA, it will be as fast no matter which parameter you declare first (by register) and which you declare 2nd, 3rd..6th (stack), and for CB it will be as fast no matter which 4 arguments you declare for registers and which you declare as last 2 parameters.
Now, regarding your question:
The only rule that is mandatory is that optional parameters must be declared last. No non-optional parameter can follow an optional parameter.
Other than that, you can use whatever order you want, and the only strong advice I can give you is be consistent. Choose a model and stick to it.
Some guidelines you could consider:
- destination comes before source. This is to be close to
destination = source
.
- the size of the buffer comes after the buffer:
f(char * s, unsigned size)
- input parameters first, output parameters last (this conflicts with the first one I gave you)
But there is no "wrong" or "right" or even a universal accepted guideline for the order of the parameters. Choose something and be consistent.
Edit
I thought of a "wrong" way to order you parameters: by alphabetic order :).
Edit 2
For example, both for CA, if I pass a vector(100) and a int, it will be better if vector(100) comes first, i.e. use registers to load larger data type. Right?
No. As I have mentioned it doesn't matter the data size. Let's talk on a 32-bit architecture (the same discussion is valid for any architecture 16-bit, 64-bit etc). Let's analyze the 3 case we can have regarding the size of the parameters in relation with the native size of the architecture.
- Same size: 4-bytes parameters. Nothing to talk here.
- Smaller size: a 4-bytes register will be used or 4-bytes will be allocated on stack. So nothing interesting here either.
- Larger size: (e.g. a struct with many fields, or a static array). No matter which method is chosen for passing this argument, this data resides in memory, and what is passed is a pointer (size 4-bytes) to that data. Again we have a 4-bytes register or 4-bytes on the stack.
It doesn't matter the size of the parameters.
Edit 3
How @TonyD explained, the order matters if you don't access all the parameters. See his answer.
memcpy
while C++ STL put destination after source, such asstd::copy
. I guess the difference is only a matter of style, the same as Intel syntax vs AT&T. – Tensive