Re: Determining a functions calling address

From: Jack Klein (jackklein_at_spamcop.net)
Date: 08/02/04


Date: Mon, 02 Aug 2004 00:46:21 -0500

On Mon, 2 Aug 2004 00:02:28 -0500, "Stephen Tyndall"
<swtyndall@hotmail.com> wrote in comp.lang.c++:

> "Jack Klein" <jackklein@spamcop.net> wrote in message
> news:alcrg0hdkl00q3n6k4bahuvov7ok5d2l5g@4ax.com...
> > On Sun, 1 Aug 2004 21:43:19 -0500, "Stephen Tyndall"
> > <swtyndall@hotmail.com> wrote in comp.lang.c++:
> >
> > > "johny smith" <princetonharvard@charter.net> wrote in message
> > > news:10gr0k1rv0brjf7@corp.supernews.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(void* vp);
> > >
> > > template<class T>
> > >
> > > void doThisStuff(T* ptr) {
> > >
> > > cout << "Error. doStuff(T* ptr) called from address " << ptr << "\n";
> > >
> > > }
> > >
> > > int main() {
> > >
> > > doThisStuff(&main);
> > >
> > > doThatStuff(&main);
> >
> > 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(void* 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(void* 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\CBuilderX\mingw\bin\g++ -c -o
C:\prog\CBuilderX\projects\simple2\windows\Debug_Build\simple2.cpp.obj
-g2 -O0 -MD -BC:\prog\CBuilderX\MinGW\bin
-IC:\prog\CBuilderX\mingw\include
-IC:\prog\CBuilderX\mingw\include\c++\3.2
windows\Debug_Build\simple2.cpp.cpp
windows/Debug_Build/simple2.cpp.cpp: In function `void my_main()':
"simple2.cpp.cpp": 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_EVALUATION_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.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html


Relevant Pages

  • Re: is there a way to do this...
    ... >>void change ... i is a pointer to int, and on this platform, consumes a place in a ... This defines ptr to be a pointer to characters, ... the compiler intended us to go. ...
    (comp.lang.c)
  • Re: something to do with void *
    ... Either a warning ... it's allowed to produce any additional diagnostics it likes. ... If a compiler in conforming mode doesn't produce a diagnostic for the ... to have a void expression in some contexts, ...
    (comp.lang.c)
  • Re: gcc knows about malloc()
    ... and may prevent the compiler from ... void *malloc; ... different effect than a different piece of C syntax in a declaration. ... and converting the bogus pointer to a pointer to function ...
    (comp.lang.c)
  • Re: Microchip Introduces First 16-bit Microcontroller Product Line - the PIC24
    ... >>> with a ram pointer, and sometimes with a flash pointer. ... >> time the compiler knows that pointer by its attributes. ... > Exactly where in the ANSI C standards documents is the "near" pointer ... > void sendString; ...
    (comp.arch.embedded)
  • Re: large files: when ubiquitous?
    ... > optimizations performed by the compiler. ... > pointer to a float, and another pointer to a long, the ... void* is a contractural promise that it's 4-aligned. ... If we pass char* instead to f, then we would be implictly saying that we ...
    (comp.os.linux.development.system)