0

I have written this little function:

int mayor(int n1, int n2, int n3, int n4, int n5) {

   int mayor = n1;

   for(int *p=&n2; p<=&n5; ++p)

           mayor = *p;

   return mayor;

}

Is it guaranteed that the memory block that contains n1 to n5 is contiguous? Since I get the expected return value I hope so, but I want to know whether this is safe.

cheroky
  • 755
  • 1
  • 8
  • 16
  • The compiler can do whatever it wants to: it can put some of them in the registers, some of them onto the stack (also in whatever order it prefers). – ForceBru Aug 04 '18 at 21:40
  • @ForceBru -- it is actually defined by the *calling-convention* of the API and differs greatly between architectures (e.g. x86 - pushed onto stack in reverse order, x86-64 - first six integer arguments (from the left) are passed in RDI, RSI, RDX, RCX, R8, and R9, in that order) – David C. Rankin Aug 04 '18 at 21:54
  • @DavidC.Rankin, right. The wording in my comment should be changed from "wants to" and "prefers" to "is required to", then. – ForceBru Aug 04 '18 at 22:02
  • @DavidC.Rankin - "standard" calling conventions (which the C standard doesn't define IIRC) mostly apply to functions that can be called from other compilation units. It appears this function could be (it's not declared `static`) but still, the most general rule for layout of parameters in memory is that there are no rules. There might not even be a "real" call at run-time since the function could be inlined. Because pointers are taken to some parameters the compiler will provide at least the illusion that they're in memory, though - but not necessarily the other parameters in-between. –  Aug 04 '18 at 22:25
  • @Steve314 - we have to be a little careful here. You are 100% correct that the C standard doesn't guarantee anything, and I agree. However, the compiler must produce valid assembly, and it is with the assembly ABI where the calling convention is guaranteed. (in fact the parameter order is what tells the assembler what to do with each parameter). So does the C standard guarantee anything? No. Is there a guarantee how parameters are passed and handled? Yes. – David C. Rankin Aug 04 '18 at 23:26
  • Then you can trust the way the parameters are passed and handled although the standard does not guarantee it. – cheroky Aug 04 '18 at 23:33
  • "Since I get the expected return value I hope so" - why do you hope so? And why do you think a compiler cares? There is not even guaranteed they all **have** addresses. What you do is just broken code. Please get a good textbook and don't even think about such nonsense. – too honest for this site Aug 05 '18 at 01:13
  • Btw: why don't you just `return n5;`; no need for all the other code in the function body (but then, why use a function at all?) – too honest for this site Aug 05 '18 at 01:14
  • Ps: It would have helped a little bit if the OP added a sentence explaining the need for using such a function. I.e. What he needs this function to return and why. I think it's a good question anyway, and I don't know why it was downvoted. – Andy J Aug 05 '18 at 02:27
  • @DavidC.Rankin - I was being relatively careful, which is why I mentioned the issue of whether functions can be called across compilation units. Standard calling conventions are generally only used when the compiled function might be called from outside the current compilation unit. Otherwise, the compiler is free to use "custom calling conventions" (basically make up whatever it thinks will be most efficient) because it doesn't need to worry how callers will know how to call it. Though again, there's no reason to believe the function couldn't be called from another compilation unit. –  Aug 05 '18 at 03:36
  • @DavidC.Rankin - the point being that even when you know the platform and the ABI, you can't simply assume that the standard calling convention for that ABI will be used. There's exceptions - cases where the compiler can and probably will ignore the ABI, which after all is intended to allow callers to call the function, not to allow the function itself to do non-portable fragile hackish tricks with its parameters. I don't think non-compiler-writers should care whether OPs function *is* an exception, though it probably isn't (because it's not `static`, so the symbol will be in the object file). –  Aug 05 '18 at 04:05
  • 2
    @Steve314 - sorry we were miscommunicating, or I was. I was not saying that because we know the calling convention we can fiddle with things we shouldn't in C. I was saying at the function level, when the assembly is ultimately generated, the parameters will be passed via the calling convention, not that you can otherwise use that information within C for some nefarious purpose. – David C. Rankin Aug 05 '18 at 07:01

2 Answers2

8

No. The variables do not have even to be in the memory - they can be (all or only some) kept in the registers.

So your assumptions are wrong. If you want to have them in the contiguous chunks of memory you need to place them there yourself.

int mayor(int n1, int n2, int n3, int n4, int n5) 
{
  int parameters[5] = {n1,n2,n3,n4,n5};
0___________
  • 60,014
  • 4
  • 34
  • 74
-1

The parameters passed to a function c unless they are pointers are stored in Stack or in registers. The decision is allocation is dynamic by the program loader.

If your intention is to manage them as contiguous location and use loop, initiate an array with those elements.

sette
  • 67
  • 4