Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6934267
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T11:56:17+00:00 2026-05-27T11:56:17+00:00

I did an experiment: class A { public: A() {} A(const A& a) {

  • 0

I did an experiment:

class A {
public:
  A() {}
  A(const A& a) {
    printf("A - %p\n", this);
  }
};

class B {
public:
  B() {}
  B(const B& b) {
    printf("B - %p\n", this);
  }
};

void func(A a, B b) {}

int main() {
  A a;
  B b;
  func(a, b);
  return 0;
}

The output is:

B - 0x7fff636e2c48
A - 0x7fff636e2c50

Since the parameters are pushed from right to left, why B’s address is lower than A’s? Confused. (Stack starts from the higher address).

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T11:56:17+00:00Added an answer on May 27, 2026 at 11:56 am

    In short: parameters to func are “pushed” on stack correctly right-to-left; you are printing not the stack addresses of these parameters, but values of these parameters which also happen to be SOME addresses on stack.

    In slightly more detail…

    First of all, you are on x64 machine. You should forget about _cdecl, _stdcall etc calling conventions. There is only one calling convention (simplified version): first four function parameters (listed left-to-right in function call) will be passed on registers, the rest – on stack. Now, that said, caller is required to allocate enough “home space” on its own stack, so callee can “spill” there the parameters passed on registers. So, in principle, those first four parameters might be found on stack as well, if callee decides to use stack via “home space”.

    Second, if parameters passed on registers are “spilled” by callee, they are still “pushed” on stack right-to-left: callee will “spill” registers into “home space” using right-to-left order, meaning the first function parameter will end up having lower address on stack in the “home space” region than second parameter. So, in this respect parameters are always “pushed” on stack right-to-left.

    Third, your output has nothing to do with how parameters are passed to func, but with where temporaries are created. This is what happens: main has enough stack space reserved to create temporaries a and b; b is created first at lower address on stack of main, which is fine, since the order of calling functions (copy-constructors A(const A&) and B(const B&), in our case) within function call func is explicitly undefined; addresses of temporaries a and b are stored on registers (and there is enough “home space” for “spilling” by func reserved already); func is called; func can “spill” registers into “home space”; if it “spills” them, then address of b will be “spilled” into stack at higher stack address than stack address into which the address of a will be “spilled” – this is right-to-left order of passing parameters.

    Here is some code and corresponding assembler. Note, I used modified code (more parameters and two functions) to show how parameters are passed. The function funcI with int parameters is to illustrate important points without mess of calling copy-constructors. Version of function with two parameters is, essentially, “sliced” version of posted funcC – it’s “sliced” to code that deals with RCX and RDX registers (to last ones). Also, note that RSP contains stack pointer and inside funcI and funcC is less than RSP inside main by 8 (this explains offset when retrieving funcI and funcC last two parameters that were pushed on stack) :

    class A
    {
     public:
      int mData;
      A()
      { // mov     qword ptr [rsp+8],rcx    ; "spilling" rcx
      } // mov     rax,qword ptr [rsp+8]    ; RAX (return value) = pointer to the object;
      A( const A& )
      {// mov     qword ptr [rsp+10h],rdx   ;"spilling" RDX and RCX
       // mov     qword ptr [rsp+8],rcx
      }// mov     rax,qword ptr [rsp+8] ; notice, RAX has value of RCX
    };
    
    class B
    {
     public:
      int mData;
      B()
      { // mov     qword ptr [rsp+8],rcx    ; "spilling" rcx
      } // mov     rax,qword ptr [rsp+8]    ; RAX (return value) = pointer to the object
      B( const B& )
      {// mov     qword ptr [rsp+10h],rdx   ;"spilling" RDX and RCX
       // mov     qword ptr [rsp+8],rcx
      }// mov     rax,qword ptr [rsp+8] ; notice, RAX has value of RCX
    };
    
    void __cdecl funcI( int a, int b, int c, int d, int e, int g )
    { // mov     dword ptr [rsp+20h],r9d    ; "spilling" registers, notice right-to-left order
     // mov     dword ptr [rsp+18h],r8d
     // mov     dword ptr [rsp+10h],edx
     // mov     dword ptr [rsp+8],ecx
     a = 1; // mov dword ptr [rsp+8],1  ; accessing first 4 "spilled" function parameters
     b = 2; // mov dword ptr [rsp+10h],2    ; notice, first function parameter has lower stack address than second parameter etc
     c = 3; // mov dword ptr [rsp+18h],3    ; so parameters pushed right-to-left by callee's "spilling"
     d = 4; // mov dword ptr [rsp+20h],4    ;
     e = 5; // mov dword ptr [rsp+28h],5    ; here, accessing 2 parameters pushed on stack explicitly by caller
     g = 6; // mov dword ptr [rsp+30h],6    ; they were pushed right-to-left
           //  also notice the offset of 8 in RSP ("g" is accessed through [rsp+30h] while it was put into [rsp+28h] in main
    } // ret
    
    
    void __cdecl funcC( A a1, A a2, A a3, A a4, A a5, B b1 )
    {// mov qword ptr [rsp+20h],r9  ; "spilling"
     // mov qword ptr [rsp+18h],r8
     // mov qword ptr [rsp+10h],rdx
     // mov qword ptr [rsp+8],rcx
     a1.mData = 1;
     // mov rax,qword ptr [rsp+8]   ; same right-to-left order: a1 itself has lower stack address 'rsp+8' than a2 'rsp+18h'
     // mov dword ptr [rax],1   ; HOWEVER, stack address value 'rsp+88h' stored in a1 is HIGHER than stack address value 'rsp+78h' stored in a2!!!!
     a2.mData = 2;
     // mov dword ptr [rax],2
     // mov rax,qword ptr [rsp+18h]
     a3.mData = 3;
     // mov rax,qword ptr [rsp+18h]
     // mov dword ptr [rax],3
     a4.mData = 4;
     // mov rax,qword ptr [rsp+20h]
     // mov dword ptr [rax],4
     a5.mData = 5;
     // mov rax,qword ptr [rsp+28h]
     // mov dword ptr [rax],5
     b1.mData = 6;
     // mov rax,qword ptr [rsp+30h]
     // mov dword ptr [rax],6
    } // ret
    
    int main( void )
    {
     // sub     rsp,0C8h            ; reserving stack for `main`
     A a;
     // lea     rcx,[rsp+30h]   ; putting into RCX stack address of local 'a'
     // call    A::A()
     B b;
     // lea     rcx,[rsp+34h]   ; putting into RCX stack address of local 'b'
     // call    B::B()
    
     funcI( 1, 2, 3, 4, 5, 6 );
     // mov     dword ptr [rsp+28h],6   ; passing parameters to `funcI`
     // mov     dword ptr [rsp+20h],5   ; last 2 on stack, first 4 on registers
     // mov     r9d,4           ; notice the right-to-left order:
     // mov     r8d,3           ; "6" is put on stack at higher address than "5" etc.
     // mov     edx,2                   ; notice also that "6" is put into [rsp+28h]: during call to `funcI` RSP will be less by 8
     // mov     ecx,1                   ; and inside `funcI` parameter will be accessed accordingly through [rsp+30h]
     // call    funcI
     funcC( a, a, a, a, a, b );
     // lea rax,[rsp+38h]           ; some preparations: putting stack addresses of temporaries into stack variables
     // mov qword ptr [rsp+40h],rax     ; there are few indirections in debug mode, we can ignore them, noticing the addresses
     // lea rax,[rsp+48h]
     // mov qword ptr [rsp+50h],rax
     // lea rax,[rsp+58h]
     // mov qword ptr [rsp+60h],rax
     // lea rax,[rsp+68h]
     // mov qword ptr [rsp+70h],rax
     // lea rax,[rsp+78h]
     // mov qword ptr [rsp+80h],rax
     // lea rax,[rsp+88h]
     // mov qword ptr [rsp+90h],rax
    
     // lea rdx,[rsp+34h]           ; putting into RDX stack address of local 'b'
     // mov rcx,qword ptr [rsp+40h]     ; putting into RCX stack address of temporary - this is right-most temporary of type `B` in `funcC`:
     // call B::B(const B&)         ; [rsp+40h] = (rsp+38h) which is stack address of temporary `b`
     // mov qword ptr [rsp+98h],rax     ; putting on stack value of RAX: [rsp+98h] now contains (rsp+38h)
    
    
     // lea rdx,[rsp+30h]
     // mov rcx,qword ptr [rsp+50h]
     // call A::A(const B&)
     // mov qword ptr [rsp+0A0h],rax
    
     // lea rdx,[rsp+30h]
     // mov rcx,qword ptr [rsp+60h]
     // call A::A(const A&)
     // mov qword ptr [rsp+0A8h],rax
    
     // lea rdx,[rsp+30h]
     // mov rcx,qword ptr [rsp+70h]
     // call A::A(const A&)
     // mov qword ptr [rsp+0B0h],rax
    
     // lea rdx,[rsp+30h]
     // mov rcx,qword ptr [rsp+80h]
     // call A::A(const A&)
     // mov qword ptr [rsp+0B8h],rax
    
     // lea rdx,[rsp+30h]
     // mov rcx,qword ptr [rsp+90h]
     // call A::A(const A&)         ; notice, RAX is not copied onto stack, it's preserved (see below)
    
     // mov rcx,qword ptr [rsp+98h]     ; passing parameters (ignoring indirections): putting stack address of right-most temporary `b` onto stack
     // mov qword ptr [rsp+28h],rcx     ; notice stack address 'rsp+28h' where stack address of 'b' 'rsp+38h' is put
     // mov rcx,qword ptr [rsp+0A0h]    ; same for right-most temporary of type 'A' (indirection again)
     // mov qword ptr [rsp+20h],rcx     ; stack address 'rsp+20h' where stack address 'rsp+48h' of right-most `a` is put
     // mov rcx,qword ptr [rsp+0A8h]    ; NOW: this is RIGHT-TO-LEFT order - take a closer look:
     // mov r9,rcx              ; rsp+28h > rsp+20h but value [rsp+28h] = rsp+38h  < rsp+48h = [rsp+20h]
     // mov rcx,qword ptr [rsp+0B0h]    ; parameters are pushed right-to-left, parameters' values are not ordered this way (and, really, can be anything)
     // mov r8,rcx              ; other 4 parameters are put on registers
     // mov rcx,qword ptr [rsp+0B8h]
     // mov rdx,rcx
     // mov rcx,rax             ; notice, preserved RAX is put into RCX  - it has stack address of first temporary of type 'A'
    
     // call funcC
     return ( 0 ); // xor     eax,eax      ; return value is 0
    } 
    // add     rsp,0C8h       ; restoring stack
    // ret
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I just did a little experiment: public abstract class MyClass { private static int
Basically I did the Cavendish experiment, and I have a damped sinusoidal wave plotted
I did a little experiments with Ruby class dynamic loading/unloading/updating as implementing plugins infrastructure.
Ok, here is the code and then the discussion follows: public class FlatArrayList {
i have this matrix experiment=2*rand(npoints,3)-1 . I want to plot in in 3D,so i
I did find other posts similar to this, but wanted a little extra information
I did an experiment in viewDidLoad where I put: NSLog(@The View did load :-)
First i've asked this question: Can a system app be updated? I did a
I implemented Producer/Consumer pattern with BlockingCollection for my experiment. PerformanceCounter c = null; void
Did you ever have to choose between WISA or LAMP at the beginning of

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.