empirical evidence points to 'yes', but i'd be surprised if there weren't exceptions (myriad calling conventions, etc.). anyone care to share some arcane knowledge?
empirical evidence points to 'yes', but i'd be surprised if there weren't exceptions (myriad calling conventions, etc.). anyone care to share some arcane knowledge?
I would guess that when the program initializes memory is reserved for all functions and there local variables. Which included parameters-variable, which will copy the value of the parameters passed. So, there is no point not having contiguous memory for each function. But in any case, I would assume that whatever goes for the main function goes for every function. If for example, the OS cannot reserve contiguous memory for a function, it won't. It will have to provide another mechanism for the separate memory chunks. But this would apply for the main funciton also. In general, the whole program is a bunch of instructions, nothing else. The functions are also included in the main program. Meaning that the executable file has all the information needed and takes a certain amount in RAM when executed, including all the variables and memory allocated statically. If it needs more memory it has to dynamically allocate it. Right?
i think i understood all that, but honestly i don't see how that directly answers the question...
Why do you ask? I have a feeling that the answer is yes in practice, but no in theory since I do not believe that the C++ standard mandates anything about this.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
i'm experimenting with techniques for function signature obfuscation and subsequent recovery
looking at the source for cstdarg, variadic functions must have their arguments passed as a contiguous block of memory
i recall, however, that certain calling conventions such as stdcall are incompatible with variadic function arguments.
It didn't sound like a direct answer because it isn't a direct answer and you won't get a direct answer, unless your asking about a very specific physical/operating system. Why? They're not all the same, who knows what some do. The bottom line comes down to guaranteeing functionality which does not require any specific memory allocation distribution other than what meets functional requirements. I can't say with certainty myself, but I have an idea of what it's likely to be.
I do think it is contiguous if *I had to guess, to an extent. Specifically function arguments? Yes and no actually. The space allocation for the function input would be I assume, the pointer you pass to the function could be copied from anywhere though...
This is more of a hardware and OS design question than it is programming language specific. imo~
Last edited by since; 12-04-2009 at 09:54 AM.
it seems to be compiler-dependent at worst.looking at the source for cstdarg, variadic functions must have their arguments passed as a contiguous block of memory
Most stack-based calling conventions will have all the parameters in a contiguous block. There's no reason to do otherwise, although technically, the compiler could place the params on Mars if it wanted to.
The most realistic violation of this would be register call, where params aren't even IN memory, and other hand-coded calls, like passing parameters in global variables.
Code://try //{ if (a) do { f( b); } while(1); else do { f(!b); } while(1); //}
I don't understand this question. Arguments are passed on the stack. In every 32-bit x86 PM application the first parameter to a function starts at EBP + 8. Here is the stack frame at the entrypoint of every 32-bit x86 protected mode function. Real mode differs somewhat from this layout.
EBP + 8 - first parameter starts here
EBP + 4 - Caller's address
EBP - Previous value of ebp
EBP - 4 - first local variable
The order in which params appear depends on the order in which they are pushed onto the stack.
Calling convention does determine the order in which the params are passed (left to right, right to left) but it really has more to do with who is responsible for cleaning up the stack before returning. If the calling conventions get mixed up or mistmatched then one function will expect the caller to clean up and the caller will expect the callee to clean up. This will definitely cause a stack overflow. However if the calling conventions are mismatched on the order of params it is quite likely the code will crash so it is important to understand which calling convention is being used. I had the wonderful privilege of debugging an error such as this which required looking at a lot of assembly code since the epilogue to a function is not in C/C++.
As to whether these occupy contiguous memory is really not important. It is important to know where to get them.
Last edited by VirtualAce; 12-04-2009 at 06:33 PM.
You're assuming the stack is even involved in parameter passing. For register calling conventions all parameters might fit in registers and no stack space at all is used for parameters.
If the compiler can prove that the program does not contain any recursion, it can completely eliminate the stack altogether. I don't know of any compiler that does that, but it's not outside the realm of possibility.
Code://try //{ if (a) do { f( b); } while(1); else do { f(!b); } while(1); //}
In most cases the stack is used but you are correct there is nothing to say it has to be. As far as my 12 mile horizon goes the stack is where they are passed. I rarely, if ever, see the register calling convention used. However I will freely admit it definitely is a valid use case and my statement does not take it into account.You're assuming the stack is even involved in parameter passing. For register calling conventions all parameters might fit in registers and no stack space at all is used for parameters.
If the compiler can prove that the program does not contain any recursion, it can completely eliminate the stack altogether. I don't know of any compiler that does that, but it's not outside the realm of possibility.
btw, while this was an interesting topic to look into, i found a much better way to deal with the problem; namely, not to obfuscate function signatures
i was trying to contain heterogenous function signatures as abstract functors in containers.
the problem? references! since i wanted to contain a reference to an argument type, i had a combinatorial-growth of the number of partial specializations i had to code with respect to the number of arguments, or else i woudl receive a "can't define a &&" error.
the (imo clever) solution was to create an intermediate template variable class with implicit conversion between it and it's template parameter type. then all i ahd to do was specialize that for T and T&
*nix systems mind you:
Every function except inline and or static functions implement a stack frame of which is a block of contiguous addresses. Though I think x64 bases systems may implement this differently with their use of GPRs ( not sure they are contiguous across all arguments being passed through, as they can be split across these two areas of memory mappings)
All of this and how the stack works I got from reading up on "Self Service Linux - Mastering the art of problem determination"