On 2004-03-29 at 02:02:32 [+0200], anqe wrote: > > > I'm not sure, what you mean by `code time constant', but passing something > > per reference means nothing else than that it is not passed by value. The > > `const' concept has nothing to do with this; a reference can refer to both > > constants and mutables. > > > > > Either way the 4B is still gonna be transferred somewhere along the > line, > > > via stack though the compiler nowadays might be passing it through in > > > fastcall. > > > > > > That &string is gonna make the compiler generate an "lea esi, string" > which > > > could possibly be avoided by using a constant pointer to the string. My > > > reasoning for this is that the compiler knows where it should be > > > initializing the variable and in some cases can make the assumption as > to > > > where it is, allowing the lea to be avoided. > > > > > > I could be off the mark, if so just ignore me (I try my best to ignore > me) > > > but it seems that if worrying about 4B of memory is an issue then there > are > > > probably other places to look for speed first. Condition hoisting and > > > appropriate usage of case and nested if structures would probably yield > more > > > performance than chassing all calls. > > > > Passing a reference to a function is not any different from passing a > pointer > > to it. In both cases the address of the referenced object must be passed. > > > > The following two functions, for instance, are compiled to exactly the > same > > executable code: > > > > extern "C" > > void > > add_one(int& var) > > { > > var++; > > } > > > > extern "C" > > void > > add_one(int* var) > > { > > (*var)++; > > } > > Neither of those examples correspond to a code time constant. There is an > inherent difference when your dealing with constant pointers and references. > > When the compiler passes a reference its sending a variable through without > being specific about what its going to be used for. > > void echomsg (int& rString) { > if (rString != 0) { > printf(*rString); > } > else { > printf("Echod null string"); > } > } Sorry, but this example is badly broken. Neither can you dereference an `int&' not would printf() eat it. > and say you called it as > > // Some stuff now echo it to console > echomsg(*ErrorMessage); > // Where error message is a string defined when the code is written (hence > code constant) > > that will make the compiler generate something along the lines of > > // <- Somestuff > lea eax, ErrorMessage > push eax > call echomsg > --> > enter 0,4 //I don't normally use enter so that might be a missuse > pop eax > test eax,eax > jz $steptoerror > ... > ... > > and so on I wouldn't claim to speak x86 assembly, so I don't try to comment that. > Because your message has been defined at code time its not going to change > when the program runs, so this allows the compiler to make assumptions about > the data that it can't if you give it a reference. > > void echomsg (const char* rString) { > printf(rString); > } > > will allow the lea to be eliminated and the compiled code can become > > // <- Somestuff > push [ErrorMessage] // !!! Different > call echomsg // !!! Different > --> > enter 0,4 //I don't normally use enter so that might be a missuse > pop eax > > > thats one instruction removed from the call and the push is now an rmw > instruction so it should pipeline better in the cpu. Again, I don't know enough about x86 assembler to argue about into what the compiler produces exactly, but I'm sure enough to know that there is simply no difference between passing a pointer and passing a reference. I think, I know now, what you mean by `code time constant'. I suppose that refers to constants that can be evaluated at compile time. Again, there is no difference in passing pointers and references to those. Example: const int c = 7; extern "C" int add(int x, const int& y) { return x + y; } void test() { int x = 1; x = add(x, c); } vs. const int c = 7; extern "C" int add(int x, const int* y) { return x + *y; } void test() { int x = 1; x = add(x, &c); } Again the compiler produces exactly the same code. > The other difference is > that the cleanup for a null pointer can be removed because the compiler > takes responisbility. Which isn't something it could do using reference, it > had to trust the programmer to never type echomsg(NULL) without pointer > cleanup. Whereas passing a NULL into the const char* version will most > likely cause the compiler to at least give a warning. No, it will not. Passing NULL for a const char* is completely legal. Nor does the compiler do any checking for NULL pointer or references in any other case. > If the compiler were to inline the code then it could be simplified further. > Then again my example is hardly realistic since calling a function to simply > call printf is pretty much pointless. In the above example, replace `extern "C"' by `static inline' and compile with -O1 and you'll see that the compiler produces exactly the same code again. CU, Ingo