1

This question is regarding Function Stack Creation.

Suppose we create a function fn(int a,char b) and call from main fn(A,B) , in this case when the function is called a fn. stack is created with return address, Stack pointer (etc) where local variables and parameters are created and on return is destroyed.

I have a few questions: 1) For our parameterized constructor suppose

myClass{
    int a;
    char c;
public:
    myClass(int a,char c)
    {
        this->a=a;
        this->c=c;
    }
};

does the constructor myClass(int a,char c) also create its function stack and create local variables a and c.

2) Now suppose we are calling by reference : my function is fn(int* a,char* b) or fn(int& a, char& b) and calling from our main by fn(&A,&B) and fn(A,B) respectively , in this case also, a function stack will be created with return address,SP etc. My question is that, will a local pointer or reference be created on stack in this case (i.e. creating a local copy of pointer or reference that will point to the passed object). Or is it that no local copy of object is created and the original object pointed by the pointer or the refence is directly passed?

3) Can we overload a function like fn(int& a,char& b) and fn(int a,int b)?

Thanks

EDIT

#include <iostream>

using namespace std;

void fn(int , char);
//void fn (int* a, char* c);
void fn (int& a, char& c);

int main()
{
   int a=10;
   char c= 'c';


  cout << "Inside main()" << endl;
  cout << hex << "&a : " << &a << endl;
  cout << hex << "&c : " << (int *)&c << endl;

   fn(a,c);
   //fn(&a,&c);
   fn(a,c);

    return 0;
    }


void fn (int a, char c)
{
    int tempInt;
    char tempChar;
    cout << "\n\nInside Call By Value Function " << endl;
    cout << hex << "&a : " << &a << endl;
    cout << hex << "&c : " << (int *)&c << endl;
    cout << hex << "&tempInt : " << &tempInt << endl;
    cout << hex << "&tempChar : " << (int *)&tempChar << endl;
    }

/*void fn (int* a, char* c)
{

    cout << "\n\nInside Call By Pointer Function " << endl;
    cout << hex << "*a : " << a << endl;
    cout << hex << "*c : " << (int*) c << endl;

    }
*/

void fn (int& a, char& c)
{

    cout << "\n\nInside Call By Reference Function " << endl;
    cout << hex << "*a : " << &a << endl;
    cout << hex << "*c : " << (int*) &c << endl;

    }

Output:

$ make
g++ -Wall Trial.cpp -o Trial
Trial.cpp: In function `int main()':
Trial.cpp:19: error: call of overloaded `fn(int&, char&)' is ambiguous
Trial.cpp:5: note: candidates are: void fn(int, char)
Trial.cpp:7: note:                 void fn(int&, char&)
Trial.cpp:21: error: call of overloaded `fn(int&, char&)' is ambiguous
Trial.cpp:5: note: candidates are: void fn(int, char)
Trial.cpp:7: note:                 void fn(int&, char&)
make: *** [Trial] Error 1
Gaurav K
  • 2,864
  • 9
  • 39
  • 68

2 Answers2

4

does the constructor myClass(int a,char c) also create its function stack and create local variables a and c

Yes, a function stack is created but a and c are not local variables to the function stack, they are member variables and there lifetime does not end with the end of the constructor. They remain alive throughout the lifetime of the class instance whose member they are.

Or is it that no local copy of object is created and the original object pointed by the pointer or the reference is directly passed?

This is known as pass by reference. The two ways are:

  • Passing the address of the object or
  • Pass the object by a reference

In either case the copy of the object is not created. The actual object can be modified within the function, In case 1 the pointer in the function points to the address of the object being passed while in case 2 the reference argument is merely an alias to the object being passed.

Can we overload a function like fn(int& a,char& b) and fn(int a,int b)?

No, you cannot because the compiler cannot understand which function version you intend to call when you call it as:

int i = 10;
int j = 20;
fn(i,j);

I misread, as fn(int& a,int& b) and fn(int a,int b) instead of fn(int& a,char& b) and fn(int a,int b).
Ofcourse you can. They have distinct types and hence qualify as valid overloaded functions.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • Hehe. I made the same mistake :) I duplicated probably because i was writing answer while you posted. Editing it now. – fkl May 06 '13 at 04:42
  • `Can we overload a function like fn(int& a,char& b) and fn(int a,int b)?` I guess we can not, because when we call the `fn` , it will be `fn(A,B)` for both the cases, my copiler complained.. `$ make g++ -Wall Trial.cpp -o Trial Trial.cpp: In function `int main()': Trial.cpp:19: error: call of overloaded `fn(int&, char&)' is ambiguous Trial.cpp:5: note: candidates are: void fn(int, char) Trial.cpp:6: note: void fn(int*, char*) ` for three overloaded functions , `fn(int a, int b)`, `fn(int* a,int* b)` and `fn(int& a,int& b)` – Gaurav K May 06 '13 at 04:49
  • 1
    @GauravK: There is a mismatch between code example you cited and the error you provide.Please provide a [online code sample](http://ideone.com/9DzHiV) which demonstrates the error. – Alok Save May 06 '13 at 04:53
  • @AlokSave See my Edit in the main question statement – Gaurav K May 06 '13 at 04:56
  • @GauravK The error you see is because merely on the base of one function receiving by value, and the other by reference, compiler cannot decide which one to call. However, in your comment above, the second parameter is a char & vs an int which should qualify for overloading. – fkl May 06 '13 at 05:05
  • @fayyazkl That error is when I tried to use `fn(int a,cahr b)`, `fn(int* a,char* b)` and `fn(int& a,char& b)` all together , when the compiler can not decide whether to call `fn(int a, char b)` or `fn(int& a,char& b)` by a call `fn(A,B)` - it means it did not succeed in overloading – Gaurav K May 06 '13 at 05:13
  • @GauravK You can call them like `f(1, 'a')` because that will have to call `f(int, char)`, it can't call `f(int&, char&)` so it will be able to compile. You could also do `const int a = 0; const char c = 'a'; f(a, c)` and it would compile. But you can't do `int a; char c; f(a, c)` because of the ambiguity. That doesn't stop you from overloading them though, you just can't use them in certain ways. So the answer is "yes, you can overload them". – Seth Carnegie May 06 '13 at 05:14
  • `fn(1,'c'); fn(a,c);` PRODUCED `$ make g++ -Wall Trial.cpp -o Trial Trial.cpp: In function `int main()': Trial.cpp:21: error: call of overloaded `fn(int&, char&)' is ambiguous Trial.cpp:5: note: candidates are: void fn(int, char) Trial.cpp:7: note: void fn(int&, char&) make: *** [Trial] Error 1 ` - i can conclude , it can not be overloaded – Gaurav K May 06 '13 at 05:17
  • @GauravK yes, that is because you have the `fn(a,c)`. If you remove that, the `f(1, 'c')` will work. As I mentioned, the `f(a, c)` is the one that will cause ambiguity. – Seth Carnegie May 06 '13 at 05:19
  • @SethCarnegie `fn(1,'a')` calls `fn(int a,char b)` but whenever we are doing `fn(A,B)` it complains ambiguity so there is no way to call `fn(int& a,char& b)` – Gaurav K May 06 '13 at 05:20
  • @GauravK yes, that's what I said. So you can _overload_ them, you just can't _call_ them in every way you could otherwise. – Seth Carnegie May 06 '13 at 05:21
  • @SethCarnegie That is what I am saying there is no way then, that we can call `fn(int& a,char& b)` if a function `fn(int a,char b)` is present or can we? And you mean to say we can overload but can not access `fn(int& a,char& b)` – Gaurav K May 06 '13 at 05:21
  • @GauravK yes, you can, by casting it to the exact type, like this: `static_cast(f)(a, c);` then there will be no ambiguity. – Seth Carnegie May 06 '13 at 05:24
  • Also when you're using other types besides `int` and `char`, which cannot be copied (because the copy constructor is inaccessible or deleted) then you can pass by reference but not by value. That will also resolve the ambiguity. – Seth Carnegie May 06 '13 at 05:30
  • @SethCarnegie `static_cast(fn)(a, c); static_cast(fn)(a, c);` I can access `fn(int a, int b)` and `fn(int& a,int& b)` respectively.. But can you explain .. what exactly it is doing here and also why do we need void (*) .. I have never typecasted a function – Gaurav K May 06 '13 at 06:05
  • @GauravK that is just the syntax for a pointer-to-function. You are casting an overloaded name to a certain type, which lets you get the right function to call (that's how you take the address of an overloaded function by the way) then you can call it with the parentheses after the cast. – Seth Carnegie May 06 '13 at 08:18
0

To begin with, your concept is slightly incorrect.

i.e. Stack is not created with a function call. Rather each thread of execution has its own stack already. It is even there when a single main is called. However an ACTIVATION record is pushed on the stack when a function is called. And the same is popped when returning from a function.

So for

  1. Stack is already there and an activation record is pushed on the stack for each function call. The variables live throughout the lifetime of the object.

  2. If your function takes a pointer as argument (i.e. call by reference), there will be a pointer variable pushed on the stack which is passed the address of the original variable. The original variable remains intact and modifying its value via pointer would change the original variable.

  3. You can only overload functions when their signatures are different. This means type, number or order of parameters. In the e.g. you quoted, it is not possible to differentiate whether a passed int is a variable or it is an address of a variable. Hence this overload won't work.

EDIT: Point 3 above has as slight mistake. The e.g. quoted in question has second parameter different and hence qualifies as valid overload. Note that the criteria is not just the name of data type (i.e. int vs. int * is also different types), but rather the fact that given an input value, compiler should be able to differentiate and chose which overloaded version to call.

fkl
  • 5,412
  • 4
  • 28
  • 68
  • I guess you are talking about large complex systems where multiple processes are run, for simple architecture such as 16 bit microcontroller, when you call a function the program execution is shifted to the address where the function code is stored , and before that, certain parameters are stored (which help in returning to correct location i.e. the next command to function which was called). For this the return address is stored, some register contents are stored, Stack Pointer is stored , local variables are created and when returned from the function are popped . – Gaurav K May 06 '13 at 04:33
  • No that is not the case. Stack is part of a program's image in memory irrespective of the architecture. May be this should help. http://en.wikipedia.org/wiki/Call_stack. Your description above is correct about each function call and all this info is stored in the stack. – fkl May 06 '13 at 04:37
  • That is for multi process system, a simple embedded system which just runs one code (No OS ) , that is the standard process, for Multiprocess systems, each process maintains its own stack where function can create its own little stack(- I can say) , with return address,frame pointer n all .. http://www.tenouk.com/Bufferoverflowc/Bufferoverflow2a.html – Gaurav K May 06 '13 at 04:40
  • Yup ..That is correct .. stack is in RAM, not created for each function rather stays there, The part of this stack where the function stores its parameter - I am calling as its own little function stack .. – Gaurav K May 06 '13 at 04:43
  • **Just Now as per my previouscomment: `fn(int a,char b)` & `fn(int& a,char& b)` will be called as `fn(A,B)` from `main()` so the compiler will complain which` fn`** – Gaurav K May 06 '13 at 04:54
  • Yes compiler will complain with the example you quote now in the above comment. But it won't have complained with the parameters you posted earlier i.e. char & vs int. I dont see what caused the downvote though. – fkl May 06 '13 at 06:58