-4
#include <stdio.h>
void f(int a, int b, int c)
{
    printf("%p, %p, %p", (void*)&a, (void*)&b, (void*)&c);
}
int main(int argc, char* argv[])
{
    int a = 0;
    int b = 0;
    int c = 0;
    f(a, b, c);
    return 0;
}

In windows, the result is in ascending order. However, in mac, the result is in descending order. I do not know why.

However, the result of code below is in decending order in mac os and windows os.

#include <stdio.h>
int main(int argc, char* argv[])
{
    int a = 0;
    int b = 0;
    int c = 0;
    printf("%p, %p, %p", (void *)&a, (void *)&b, (void *)&c);
    return 0;
}

And, the results of code below are same in mac os and windows os: "ba".

#include <stdio.h>
void f(int a, int b)
{}
int main(int argc, char* argv[])
{
    f(printf("a"), printf("b"));
    return 0;
}
monoid
  • 9
  • 2
  • 1
    https://en.wikipedia.org/wiki/Calling_convention – Sneftel Jun 14 '17 at 11:19
  • 4
    @datell There's no UB here, since the values of the uninitialized variables are never accessed. (There is *unspecified* behavior, though.) – Sneftel Jun 14 '17 at 11:20
  • Anything could be the reason - there is no standard that would specify a convention, and you shouldn't expect one to exist. In practice, on 64-bit unixen, the variables are passed in registers, and they need to be pushed on *stack* for the `&` operator to work, this could happen in *any* order. – Antti Haapala -- Слава Україні Jun 14 '17 at 11:20
  • 3
    `printf("%x, %x, %x", &a, &b, &c);` is UB => `printf("%p, %p, %p", (void *)&a, (void *)&b, (void *)&c);` – Stargateur Jun 14 '17 at 11:20
  • 1
    Please provide a reference to the C language requiring a specific stack allocation scheme - or even using a stack at all. – too honest for this site Jun 14 '17 at 11:21
  • @Stargateur Good point, I saw `%x` and thought pointer. – Sneftel Jun 14 '17 at 11:21
  • And`%x` expects an `unsigned int`; passing anything else invokes undefined behaviour. Any modern compiler will warn. When doing such research, first make sure your code is correct. This includes enabling recommended warnings and fixeing their causes before asking. – too honest for this site Jun 14 '17 at 11:22
  • Even if I initialize variables, the results in mac os and windows os are different as before. – monoid Jun 14 '17 at 11:22
  • @monoid Why do you expect them to be the same? – Jabberwocky Jun 14 '17 at 11:25
  • @monoid Even, on the same OS, your broken test can have different result. What did you expect and why your output differ ? Please read [ask]. – Stargateur Jun 14 '17 at 11:25
  • 1
    A stack is not defined in C scope. Why should all implementation do it the same way? Parameter passing can even be different with same CPU architecture but different compiler. – Gerhardh Jun 14 '17 at 11:27
  • 1
    I don't get what the big issue is with this question to be honest. Maybe it's rather beginner level but I'd rather have beginners take a stab at understanding what the spec really guarantees and learn something interesting than have them make an assumption that isn't true or just drop an opportunity to learn more about their OS / CPU / compiler. – jrh Jun 14 '17 at 11:29

1 Answers1

2

The C standard doesn't specify how arguments are passed to functions.

The platform's ABI (Applications Binary Interface) will specify how functions are called - and for the aspect you've identified, the different ABIs specify different order.

If your program is to interoperate with libraries or other code, it must behave as its platform ABI requires, and your compiler is obviously doing so.

For the local variables within a function, the compiler has complete choice as to how to arrange them - there's no requirement here for any interoperation with other code, and the compiler may choose to lay them out as you've declared them, to gather them by type or size, or in any other way. If you never take the address of a variable, it's allowed not to allocate any storage for that variable at all - it can use a register, for example.

In both cases, the specifics of what address a variable or parameter occupies is outside the scope of Standard C.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
  • Thx, I edited my question just now. In my question, the results in windows and mac are in same order of a situation. – monoid Jun 14 '17 at 11:50
  • @monoid that edit actually goes into a completely different, unrelated issue (and you're still in UB territory). I strongly recommend reverting it because that makes your question less specific. Please see [Parameter evaluation order before a function calling in C](https://stackoverflow.com/questions/376278/parameter-evaluation-order-before-a-function-calling-in-c) for more information. – jrh Jun 14 '17 at 12:18