Hello all.
I just ran the following two functions 100 times each ...
When using MSVC your code is translated like this:
[source lang="plain"]?passing@@YAXH@Z (void __cdecl passing(int)):
00000000: C3 ret
?referrencing@@YAXPAH@Z (void __cdecl referrencing(int *)):
00000010: 56 push esi
00000011: BE 40 42 0F 00 mov esi,0F4240h
00000016: 6A 04 push 4
00000018: E8 00 00 00 00 call ??2@YAPAXI@Z
0000001D: 50 push eax
0000001E: E8 00 00 00 00 call ??3@YAXPAX@Z
00000023: 83 C4 08 add esp,8
00000026: 4E dec esi
00000027: 75 ED jne 00000016
00000029: 5E pop esi
0000002A: C3 ret[/source]
As you can see, the first function, [font=courier new,courier,monospace]passing[/font], is reduced to a single [font=courier new,courier,monospace]ret[/font] instruction making it equivalent to this one:
[source lang="cpp"]void passing(int j )
{
}[/source]
In other words, through optimization algorithms the comiler "concludes" (notice the qutation marks because we a talking about a piece of software) that the loop is redundant and removes it entirely from the function body. However, in [font=courier new,courier,monospace]referrencing[/font] the loop is translated because two external functions (the [font=courier new,courier,monospace]int[/font] constructor and -destructor) are called in each iteration. And even though it may seem like this could be optimized out of the loop as well, as soon as you invoke an external function things change quite significantly from a complier's "point of view" because the function's implementation isn't part of your code and is stored in binary form in some library (or object) file on your hard-drive.
I hope this answers your question.