I have a number of quibbles with your terminology:
There's no such thing as a "procedure" in C or C++. At best, there are functions that return no value: "void"
Your example has no "side effect".
I'm not sure what you mean by "clean function" ... but I HOPE you don't mean "less source == cleaner code". Nothing could be further from the truth :(
TO ANSWER YOUR ORIGINAL QUESTION:
In your example, double mySum1(myArea a)
incurs the space and CPU overhead of a COMPLETELY UNNECESSARY COPY. Don't do it :)
To my mind, double mySum1(myArea & a)
or double mySum1(myArea * a)
are equivalent. Personally, I'd prefer double mySum1(myArea * a)
... but most C++ developers would (rightly!) prefer double mySum1(myArea & a)
.
double mySum1 (const myArea & a)
is best of all: it has the runtime efficiency of 2), and it signals your intent that it WON'T modify the array.
PS:
I generated assembly output from the following test:
struct myArea {
int t[10][10];
};
double mySum1(myArea a) {
double sum = 0.0;
for (int i=0; i < 10; i++)
for (int j=0; j<10; j++)
sum += a.t[i][j];
return sum;
}
double mySum2(myArea & a) {
double sum = 0.0;
for (int i=0; i < 10; i++)
for (int j=0; j<10; j++)
sum += a.t[i][j];
return sum;
}
double mySum3(myArea * a) {
double sum = 0.0;
for (int i=0; i < 10; i++)
for (int j=0; j<10; j++)
sum += a->t[i][j];
return sum;
}
double mySum4(const myArea & a) {
double sum = 0.0;
for (int i=0; i < 10; i++)
for (int j=0; j<10; j++)
sum += a.t[i][j];
return sum;
}
mySum1, as you'd expect, had extra code to do the extra copy.
The output for mySum2, mySum3 and mySun4, however, were IDENTICAL:
_Z6mySum2R6myArea:
.LFB1:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
pushq %rbx
movq %rdi, -32(%rbp)
movl $0, %eax
movq %rax, -24(%rbp)
movl $0, -16(%rbp)
jmp .L8
.cfi_offset 3, -24
.L11:
movl $0, -12(%rbp)
jmp .L9
.L10:
movl -16(%rbp), %eax
movl -12(%rbp), %edx
movq -32(%rbp), %rcx
movslq %edx, %rbx
movslq %eax, %rdx
movq %rdx, %rax
salq $2, %rax
addq %rdx, %rax
addq %rax, %rax
addq %rbx, %rax
movl (%rcx,%rax,4), %eax
cvtsi2sd %eax, %xmm0
movsd -24(%rbp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -24(%rbp)
addl $1, -12(%rbp)
.L9:
cmpl $9, -12(%rbp)
setle %al
testb %al, %al
jne .L10
addl $1, -16(%rbp)
.L8:
cmpl $9, -16(%rbp)
setle %al
testb %al, %al
jne .L11
movq -24(%rbp), %rax
movq %rax, -40(%rbp)
movsd -40(%rbp), %xmm0
popq %rbx
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
<= mySum3 and mySum4 had different labels ... but identical instructions!
It's also worth noting that one of the benefits of "const" is that it can help the compiler perform several different kinds of optimizations, whenever possible. For example: