473,663 Members | 2,800 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Determining a functions calling address

I am trying to figure out a way to print the address of what called a
certain function once inside the function.

I am assuming that this information is on the stack somewhere. But can
someone give me some
advice? I don't know where to go to look this information up.

Do I need to access the stack, and hence do some kind of inline assembly
code to get the calling address?
For example:

int main()
{

myFunction(); // I need the address of this location or the next
line to be printed in the myFunction function.
Jul 22 '05 #1
12 2454
"johny smith" <pr************ **@charter.net> wrote in message
news:10******** *****@corp.supe rnews.com...
[snip]
void myFunction()
{
// print out the calling functions address in main or the address of
the location that made this function call.
// basically, I am trying to figure out who called this function based on the address. This is used in debugging
// so I can track down who (what location) made the call if I get an
error in this function.
}


There is no portable way to do what you want to do. I would recommend
sprinkling your code with informative output/log statements. For example:

log("In main(), calling myFunction() the first time.");
myFunction();

log("In main(), calling myFunction() the second time.");
myFunction();

That approach would probably make your logs more readable, and the code
would be more portable.

--
David Hilsee
Jul 22 '05 #2
"johny smith" <pr************ **@charter.net> wrote in message
news:10******** *****@corp.supe rnews.com...
I am trying to figure out a way to print the address of what called a
certain function once inside the function.


Couldn't you just pass the address of the caller to the function? For
example, the following shows two versions: a template version and a normal
function version. Hope this helps.

#include <iostream>

using std::cout;

void doThatStuff(voi d* vp);

template<class T>

void doThisStuff(T* ptr) {

cout << "Error. doStuff(T* ptr) called from address " << ptr << "\n";

}

int main() {

doThisStuff(&ma in);

doThatStuff(&ma in);

return 0;

}

void doThatStuff(voi d* vp) {

cout << "Error. doStuff(void* vp) called from address " << vp << "\n";

}

//mike tyndall
Jul 22 '05 #3
"Stephen Tyndall" <sw*******@hotm ail.com> wrote in message
news:L_******** ************@co mcast.com...
"johny smith" <pr************ **@charter.net> wrote in message
news:10******** *****@corp.supe rnews.com...
I am trying to figure out a way to print the address of what called a
certain function once inside the function.


Couldn't you just pass the address of the caller to the function? For
example, the following shows two versions: a template version and a normal
function version. Hope this helps.

#include <iostream>

using std::cout;

void doThatStuff(voi d* vp);

template<class T>

void doThisStuff(T* ptr) {

cout << "Error. doStuff(T* ptr) called from address " << ptr << "\n";

}

int main() {

doThisStuff(&ma in);

doThatStuff(&ma in);

return 0;

}

void doThatStuff(voi d* vp) {

cout << "Error. doStuff(void* vp) called from address " << vp << "\n";

}

//mike tyndall


BTW, I realize this is totally impractical for any large-scale project, but
maybe it'll help somehow. Maybe you could put #ifdef DEBUG directives in
the code, where extra function arguments are added if DEBUG is defined.
Good luck!
Jul 22 '05 #4
On Sun, 1 Aug 2004 21:43:19 -0500, "Stephen Tyndall"
<sw*******@hotm ail.com> wrote in comp.lang.c++:
"johny smith" <pr************ **@charter.net> wrote in message
news:10******** *****@corp.supe rnews.com...
I am trying to figure out a way to print the address of what called a
certain function once inside the function.


Couldn't you just pass the address of the caller to the function? For
example, the following shows two versions: a template version and a normal
function version. Hope this helps.

#include <iostream>

using std::cout;

void doThatStuff(voi d* vp);

template<class T>

void doThisStuff(T* ptr) {

cout << "Error. doStuff(T* ptr) called from address " << ptr << "\n";

}

int main() {

doThisStuff(&ma in);

doThatStuff(&ma in);


There are two problems with this. One is that there is no need to
apply the & operator to the name of a free-standing function to take
its address. The second is more important. There is no defined
conversion between pointer to any type of function and pointer to
void, or indeed pointer to any other object type. The code above will
not compile.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 22 '05 #5
"Jack Klein" <ja*******@spam cop.net> wrote in message
news:al******** *************** *********@4ax.c om...
On Sun, 1 Aug 2004 21:43:19 -0500, "Stephen Tyndall"
<sw*******@hotm ail.com> wrote in comp.lang.c++:
"johny smith" <pr************ **@charter.net> wrote in message
news:10******** *****@corp.supe rnews.com...
I am trying to figure out a way to print the address of what called a
certain function once inside the function.


Couldn't you just pass the address of the caller to the function? For
example, the following shows two versions: a template version and a normal function version. Hope this helps.

#include <iostream>

using std::cout;

void doThatStuff(voi d* vp);

template<class T>

void doThisStuff(T* ptr) {

cout << "Error. doStuff(T* ptr) called from address " << ptr << "\n";

}

int main() {

doThisStuff(&ma in);

doThatStuff(&ma in);


There are two problems with this. One is that there is no need to
apply the & operator to the name of a free-standing function to take
its address. The second is more important. There is no defined
conversion between pointer to any type of function and pointer to
void, or indeed pointer to any other object type. The code above will
not compile.


It compiles; I wrote it in VC++.NET and it works with no problems. BTW, I
know that the & wasn't necessary, but there's nothing wrong with making it
obvious that an address is being passed.
Jul 22 '05 #6
On Mon, 2 Aug 2004 00:02:28 -0500, "Stephen Tyndall"
<sw*******@hotm ail.com> wrote in comp.lang.c++:
"Jack Klein" <ja*******@spam cop.net> wrote in message
news:al******** *************** *********@4ax.c om...
On Sun, 1 Aug 2004 21:43:19 -0500, "Stephen Tyndall"
<sw*******@hotm ail.com> wrote in comp.lang.c++:
"johny smith" <pr************ **@charter.net> wrote in message
news:10******** *****@corp.supe rnews.com...
> I am trying to figure out a way to print the address of what called a
> certain function once inside the function.

Couldn't you just pass the address of the caller to the function? For
example, the following shows two versions: a template version and a normal function version. Hope this helps.

#include <iostream>

using std::cout;

void doThatStuff(voi d* vp);

template<class T>

void doThisStuff(T* ptr) {

cout << "Error. doStuff(T* ptr) called from address " << ptr << "\n";

}

int main() {

doThisStuff(&ma in);

doThatStuff(&ma in);
There are two problems with this. One is that there is no need to
apply the & operator to the name of a free-standing function to take
its address. The second is more important. There is no defined
conversion between pointer to any type of function and pointer to
void, or indeed pointer to any other object type. The code above will
not compile.


Now that I think of it, taking the address of main() in a C++ program
is illegal no matter what you do with the address.
It compiles; I wrote it in VC++.NET and it works with no problems. BTW, I
know that the & wasn't necessary, but there's nothing wrong with making it
obvious that an address is being passed.


Apparently you are not using a real C++ compiler, or you are not using
the one you have in a standard conforming mode.

First you should have received diagnostics along these lines:

========
Borland C++ 5.6.4 for Win32 Copyright (c) 1993, 2002 Borland
simple.cpp:
"simple.cpp ": E2012 Cannot take address of 'main' in function main()
at line 16
"simple.cpp ": E2012 Cannot take address of 'main' in function main()
at line 17
*** 2 errors in Compile ***
BCC32 exited with error code: 1
Build cancelled due to errors
========

Interestingly enough when I modify your source code to remove the
illegality of taking the address of main, like this:
========
#include <iostream>

using std::cout;

void doThatStuff(voi d* vp);

template<class T>

void doThisStuff(T* ptr)
{
cout << "Error. doStuff(T* ptr) called from address " << ptr <<
"\n";
}

void my_main()
{
doThisStuff(my_ main);
doThatStuff(my_ main);
}

int main()
{
my_main();
return 0;
}

void doThatStuff(voi d* vp)
{
cout << "Error. doStuff(void* vp) called from address " << vp <<
"\n";
}
========

Borland's C++ Builder X accepts it without complaint, as does
Microsoft's Visual C++ 2005 Express Beta. The MINGW 3.2 included with
C++ Builder X generates a proper diagnostic:

========
C:\prog\CBuilde rX\mingw\bin\g+ + -c -o
C:\prog\CBuilde rX\projects\sim ple2\windows\De bug_Build\simpl e2.cpp.obj
-g2 -O0 -MD -BC:\prog\CBuild erX\MinGW\bin
-IC:\prog\CBuild erX\mingw\inclu de
-IC:\prog\CBuild erX\mingw\inclu de\c++\3.2
windows\Debug_B uild\simple2.cp p.cpp
windows/Debug_Build/simple2.cpp.cpp : In function `void my_main()':
"simple2.cpp.cp p": windows/Debug_Build/simple2.cpp.cpp invalid
conversion from `void (*)()' to at line 17
`void*'
Build cancelled due to errors
========

Testing it online with Comeau Computing's EDG front-end, arguably the
most standard conforming implementation readily accessible, also
results in a correct, and better presented, diagnostic:

========
Your Comeau C/C++ test results are as follows:

Comeau C/C++ 4.3.3 (Aug 6 2003 15:13:37) for ONLINE_EVALUATI ON_BETA1
Copyright 1988-2003 Comeau Computing. All rights reserved.
MODE:strict errors C++
"ComeauTest .c", line 17: error: argument of type "void (*)()" is
incompatible with
parameter of type "void *"
doThatStuff(my_ main);
^
1 error detected in the compilation of "ComeauTest .c".
========

Note that ISO/IEC 14882 determines what is and is not legal C++, not
just what some compilers happen to accept. In particular, Windows
based compilers (Microsoft and Borland) seem to let a lot slip by,
such as an implicit conversion from "pointer to function returning
void and accepting no arguments" to "pointer to void".

The fact that compiler accepted it without issuing a diagnostic only
means that there is a serious error in your compiler. The fact that
it allowed you to take the address of main() in a C++ program is
another serious error. Microsoft's C++ compilers prior to 7.1 did not
put a great deal of emphasis on C++ standard conformance.

Regardless of what you think, the sample code you posted had two
serious errors.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 22 '05 #7
"Jack Klein" <ja*******@spam cop.net> wrote in message
news:cq******** *************** *********@4ax.c om...
On Mon, 2 Aug 2004 00:02:28 -0500, "Stephen Tyndall"
<sw*******@hotm ail.com> wrote in comp.lang.c++:
"Jack Klein" <ja*******@spam cop.net> wrote in message
news:al******** *************** *********@4ax.c om...
On Sun, 1 Aug 2004 21:43:19 -0500, "Stephen Tyndall"
<sw*******@hotm ail.com> wrote in comp.lang.c++:

> "johny smith" <pr************ **@charter.net> wrote in message
> news:10******** *****@corp.supe rnews.com...
> > I am trying to figure out a way to print the address of what called a > > certain function once inside the function.
>
> Couldn't you just pass the address of the caller to the function? For > example, the following shows two versions: a template version and a normal
> function version. Hope this helps.
>
> #include <iostream>
>
> using std::cout;
>
> void doThatStuff(voi d* vp);
>
> template<class T>
>
> void doThisStuff(T* ptr) {
>
> cout << "Error. doStuff(T* ptr) called from address " << ptr << "\n"; >
> }
>
> int main() {
>
> doThisStuff(&ma in);
>
> doThatStuff(&ma in);

There are two problems with this. One is that there is no need to
apply the & operator to the name of a free-standing function to take
its address. The second is more important. There is no defined
conversion between pointer to any type of function and pointer to
void, or indeed pointer to any other object type. The code above will
not compile.
Now that I think of it, taking the address of main() in a C++ program
is illegal no matter what you do with the address.
It compiles; I wrote it in VC++.NET and it works with no problems. BTW,

I know that the & wasn't necessary, but there's nothing wrong with making it obvious that an address is being passed.


Apparently you are not using a real C++ compiler, or you are not using
the one you have in a standard conforming mode.


I'm using VC++.NET 2003, and I haven't fiddled with any options.
First you should have received diagnostics along these lines:

======== [error listing snipped] ========

Interestingly enough when I modify your source code to remove the
illegality of taking the address of main, like this:
========
#include <iostream>

using std::cout;

void doThatStuff(voi d* vp);

template<class T>

void doThisStuff(T* ptr)
{
cout << "Error. doStuff(T* ptr) called from address " << ptr <<
"\n";
}

void my_main()
{
doThisStuff(my_ main);
doThatStuff(my_ main);
}

int main()
{
my_main();
return 0;
}

void doThatStuff(voi d* vp)
{
cout << "Error. doStuff(void* vp) called from address " << vp <<
"\n";
}
========

Borland's C++ Builder X accepts it without complaint, as does
Microsoft's Visual C++ 2005 Express Beta. The MINGW 3.2 included with
C++ Builder X generates a proper diagnostic:

======== [error listing snipped] ========

Testing it online with Comeau Computing's EDG front-end, arguably the
most standard conforming implementation readily accessible, also
results in a correct, and better presented, diagnostic:

======== [error listing snipped] ========
You went to a lot of effort. I couldn't have checked these, as I don't have
those compilers and I don't know where to get them.

Note that ISO/IEC 14882 determines what is and is not legal C++, not
just what some compilers happen to accept. In particular, Windows
based compilers (Microsoft and Borland) seem to let a lot slip by,
such as an implicit conversion from "pointer to function returning
void and accepting no arguments" to "pointer to void".

The fact that compiler accepted it without issuing a diagnostic only
means that there is a serious error in your compiler. The fact that
it allowed you to take the address of main() in a C++ program is
another serious error. Microsoft's C++ compilers prior to 7.1 did not
put a great deal of emphasis on C++ standard conformance.
I had no way of knowing this. I can't afford a copy of the C++ Standard;
all I do is compile and check for errors. Other than that, I learn what I
can from the newsgroups and books.
Regardless of what you think, the sample code you posted had two
serious errors.


Regardless of what you think, I wasn't trying to argue with you. All I said
was that it compiled with VC++.NET.

//mike tyndall
Jul 22 '05 #8
johny smith wrote:
I am trying to figure out a way to print the address of what called a
certain function once inside the function.

I am assuming that this information is on the stack somewhere. But can
someone give me some
advice? I don't know where to go to look this information up.

Do I need to access the stack, and hence do some kind of inline assembly
code to get the calling address?


As far as I know, there is no standard/portable way of doing this. There
may be some extension in the compiler you are using (I don't know of any
that do this, but who knows).

If you don't need your code to be portable but need to get this working,
google for subroutine calling convention for your hardware architecture,
or, perhaps, for stack layout. This should give you a clue of how to get
this sort of information.

Another thing you might try, is ask folks in some newsgroup, which deals
with your architecture (perhaps assembly, or something like that)

-d
Jul 22 '05 #9
johny smith wrote:
I am trying to figure out a way to print the address of what called a
certain function once inside the function.

I am assuming that this information is on the stack somewhere. But can
someone give me some
advice? I don't know where to go to look this information up.

Do I need to access the stack, and hence do some kind of inline assembly
code to get the calling address?
For example:

int main()
{

myFunction(); // I need the address of this location or the next
line to be printed in the myFunction function.
.
.

}

void myFunction()
{
// print out the calling functions address in main or the address of
the location that made this function call.
// basically, I am trying to figure out who called this function based
on the address. This is used in debugging
// so I can track down who (what location) made the call if I get an
error in this function.
}


There is no standard or portable way to do this. But if you are using a
debugger you could just take a peek at the call stack (I would be
surprised if the debugger you are using doesn't support this).

If you use Windows you might find this article interesting:
http://www.codeguru.com/Cpp/V-S/debu...cle.php/c4429/

--
Peter van Merkerk
peter.van.merke rk(at)dse.nl
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

66
4976
by: Darren Dale | last post by:
Hello, def test(data): i = ? This is the line I have trouble with if i==1: return data else: return data a,b,c,d = test()
5
4647
by: Praveen Srinivasan | last post by:
Hi all, Are there any important issues that one should be aware of when calling C++ functions from C? In particular, I'm passing a function pointer to a C routine in a library, and in that function I do C++ type stuff, e.g. utilizing operator overloading. Is that reasonable, or are there some pitfalls I need to watch out for? Thanks, Praveen Srinivasan
47
3852
by: Richard Hayden | last post by:
Hi, I have the following code: /******************************** file1.c #include <iostream> extern void dummy(); inline int testfunc() {
19
4245
by: Ross A. Finlayson | last post by:
Hi, I hope you can help me understand the varargs facility. Say I am programming in ISO C including stdarg.h and I declare a function as so: void log_printf(const char* logfilename, const char* formatter, ...); Then, I want to call it as so:
0
5400
by: Mike S | last post by:
I've seen examples of using the CallWindowProc Windows API function to call functions through their addresses in VB6 -- a clever workaround to emulate C-like function pointer semantics. A well-known example is the use of CallWindowProc to call a function gotten via LoadLibrary/GetProcAddress. For example, I've seen code similar to the following which can register/unregister a COM DLL where the path to the DLL is known only at runtime -- in...
17
3526
by: Jess | last post by:
Hello, If I have a class that has virtual but non-pure declarations, like class A{ virtual void f(); }; Then is A still an abstract class? Do I have to have "virtual void f() = 0;" instead? I think declaring a function as "=0" is the same
13
2518
by: JohnQ | last post by:
The implementation of classes with virtual functions is conceptually easy to understand: they use vtables. Which begs the question about POD structs: how are they associated with their member functions in common implementations? And where is the 'this' ptr tucked away at for POD structs with member functions? John
4
1634
by: lord trousers | last post by:
I'm implementing a garbage collector in C++ for a fun new language (don't ask), and I've found that it spends a good amount of time calling "finalize" on objects that are freed/not relocated. The default implementation does nothing and always will, and most types won't need to override it. It'd be nice if I could test for overrides, but the obvious thing doesn't work: class Object { // ... virtual void finalize() { }
127
4864
by: sanjay.vasudevan | last post by:
Why are the following declarations invalid in C? int f(); int f(); It would be great if anyone could also explain the design decision for such a language restricton. Regards, Sanjay
0
8436
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8345
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8858
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8771
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8548
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
6186
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4182
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4349
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
1757
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.