Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Learning what goes on "behind the scenes"

7 views
Skip to first unread message

Tony Minkoff

unread,
Mar 29, 1997, 3:00:00 AM3/29/97
to

Can somebody recommend a good book (or article) for learning what goes
on "behind the scenes" in C++? I.e., *how* are various features
implemented?

I'm just now making the migration from "old" C++ to "new" C++ (i.e.,
exceptions, RTTI, etc.).

One of the features I like about "old" C++ was that I can look at the
C++ source and understand the code the compiler was going to generate.
This is useful in forseeing potential performance issues, and especially
in debugging. (For example, if I'm debugging and get a protection fault
when attempting to step into a virtual function and never get to the
function body, or if I get to the wrong function body, I suspect that I
have a bad pointer, or that the virtual function pointer has been
overwritten. If I didn't know about the virtual function pointer, and
simply relied on "C++ magic" to get to the right function body, I
wouldn't know what to do when the magic failed.)

So now I'm learning the features of the new C++, but I don't understand
how they are implemented. For example, I know that "throw" destroys any
objects on the stack above the highest appropriate "catch" and then
resets the stack pointer and instruction pointer to continue execution
from that catch. What I don't know is *how* the throw mechanism knows
where the objects are located and what destructors to call, or how it
knows which catch to use as the handler, or how it knows where to set
the stack pointer and instruction pointer.

I imagine some of this is compiler-dependent, but I'm hoping that there
is enough commonality between implementations, or that there is a small
enough number of common variations, that it's possible to write a good
book (article) about it, and that somebody has done so.
--
Tony Minkoff
tmin...@cts.com
anthony...@ccmail.mitchell.com

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]


Les Matheson

unread,
Mar 31, 1997, 3:00:00 AM3/31/97
to

My favorite recommendation for people going from C to C++ who insist on
understanding what's going on (how old-fashioned!) is Bruce Eckel's "C++
Inside
and Out" from Osborne Press. Its a little bit dated now that the standards
committee
has been so creative of late, but it has the following advantages:

-- Bruce knows his material
-- He doesn't insult the intelligence of C programmers
-- He does a decent job of explaining how the various C++ mechanisms work
as well
as how to use them.
-- He writes well enough

Tony Minkoff <tmin...@cts.com> wrote in article
<5hjkc2$n...@netlab.cs.rpi.edu>...

{ Don't quote banners & sigs! -vdv }

David A. Cuthbert

unread,
Mar 31, 1997, 3:00:00 AM3/31/97
to

Tony Minkoff <tmin...@cts.com> wrote:
>Can somebody recommend a good book (or article) for learning what goes
>on "behind the scenes" in C++? I.e., *how* are various features
>implemented?
>
>I'm just now making the migration from "old" C++ to "new" C++ (i.e.,
>exceptions, RTTI, etc.).
[...]

>I imagine some of this is compiler-dependent, but I'm hoping that there
>is enough commonality between implementations, or that there is a small
>enough number of common variations, that it's possible to write a good
>book (article) about it, and that somebody has done so.

I haven't come across such a book or article, but I have found looking
that at the assembly output and stepping through simple test programs
using a debugger to provide some interesting insight into how these
features are implemented. Compiling with debug options on may or may
not provide additional insight (my own experience with Borland is that
it isn't very beneficial, unless you're trying to figure out how
Borland implements symbol tables).

As for RTTI, I suspect most implementations just return a pointer to
a vtbl (or a ptr to a structure containing a ptr to a vtbl, etc.).
Exceptions, in my experience, vary quite a bit between platforms.
--
David A. Cuthbert (henry.ece.cmu.edu!dacut)
Graduate Student, Electrical and Computer Engineering
Data Storage Systems Center, Carnegie Mellon University

Larry Brasfield

unread,
Mar 31, 1997, 3:00:00 AM3/31/97
to

Tony Minkoff <tmin...@cts.com> wrote in article <5hjkc2$n...@netlab.cs.rpi.edu>...
> Can somebody recommend a good book (or article) for learning what goes
> on "behind the scenes" in C++? I.e., *how* are various features
> implemented?

"Inside the C++ Object Model" by Stanley Lippman.



> I'm just now making the migration from "old" C++ to "new" C++ (i.e.,
> exceptions, RTTI, etc.).
>

> One of the features I like about "old" C++ was that I can look at the
> C++ source and understand the code the compiler was going to generate.

You can get assembler output from several C++ compilers. If you
are willing to learn a small subset of the target's instruction
set (load, store, move, mainly), you can get a pretty good idea
of what is going on, especially when the asm output is annotated
with the source lines.

[why wanted cut]



> I imagine some of this is compiler-dependent, but I'm hoping that there
> is enough commonality between implementations, or that there is a small
> enough number of common variations, that it's possible to write a good
> book (article) about it, and that somebody has done so.

Lippman covers the most practical variations and discusses the
tradeoffs involved. It's a good read.
--
-- Larry Brasfield
The aforementioned views are mine alone.

Oleg Zabluda

unread,
Mar 31, 1997, 3:00:00 AM3/31/97
to

Tony Minkoff <tmin...@cts.com> wrote:
: Can somebody recommend a good book (or article) for learning what goes

: on "behind the scenes" in C++? I.e., *how* are various features
: implemented?

My personal favorites are:
Stroustrup, "Design and implementation of C++".
Lippman, "Inside the C++ object model".
"C++ gems", - collected from the 7 years of "The C++ report" by Lippman.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.

Marcelo Cantos

unread,
Apr 1, 1997, 3:00:00 AM4/1/97
to

tmin...@cts.com (Tony Minkoff) writes:

> So now I'm learning the features of the new C++, but I don't understand
> how they are implemented. For example, I know that "throw" destroys any
> objects on the stack above the highest appropriate "catch" and then
> resets the stack pointer and instruction pointer to continue execution
> from that catch. What I don't know is *how* the throw mechanism knows
> where the objects are located and what destructors to call, or how it
> knows which catch to use as the handler, or how it knows where to set
> the stack pointer and instruction pointer.
>

> I imagine some of this is compiler-dependent, but I'm hoping that there
> is enough commonality between implementations, or that there is a small
> enough number of common variations, that it's possible to write a good
> book (article) about it, and that somebody has done so.

Actually there are some very different techniques used in this area.
The simplest implementation is a hidden flag. For instance:

class A { public: A(); };

double f(int n) { return 1.0 / n; }
double g(int n) {
if (n == 0) throw 1;
return f(n);
}
double h(double n) {
A a1;
double d = g(n * n);
A a2;
return sin(d);
}

Could be implemented as:

class A // ...

char* f(double* __result, int n) { *__result = 1.0 / n; return NULL; }
char* g(double* __result, int n) {
if (n == 0) return "int";
return f(__result, n);
}
char* h(double* __result) {
char* __ex;
struct __class__A a1;
struct __class__A a2;
double d;

// A a1;
__A__ctor(&a1);

// double d = g(n * n);
__ex = g(&d, n * n);
if (__ex) goto __cleanup_1:

// A a2;
__A__ctor(&a2);

// return sin(d);
__result = sin(d);

__cleanup_2:
__A__dtor(&a);
__cleanup_1:
__A__dtor(&a);
return __ex;
}

Where the return value becomes a reference argument and the function
returns a string describing the type that has been thrown, or NULL if
one hasn't been thrown. A catch clause:

try { cout << h(0.0); } catch(int& i) { cerr << "Error: " << i; }

could then become:

union __tag_exception_object {
int e_int;
double e_double;
// ...
void* e_class;
} __global_exception_object;

// ...

char *__ex;
double __temp_1;

__ex = h(&__temp_1, 0.0);
if (__ex) goto __eh_1;
__ostream__oplsh__dbl(&cout, __temp_1);
goto __noex_1;

__eh_1:
// catch(int&)
if (match_type(__ex, "int")) {
__ostream__oplsh__int(&cout, __global_exception_object.e_int);
}

__noex_1:
// ...

As you can probably surmise, EH is not at all simple. The above
implementation (which is probably buggy, since I did it off the top of
my head) is not the most efficient possible implementation, since it
requires that the return value of every function call be checked for
an exception. It also uses strings to identify classes. This could
be improved by direct implementation of a class graph (with special
cases for builtin types) but the string version is easier to
understand.

Another implementation which favours normal flow of execution makes
use of static function maps which allow the EH mechanism to examine
the stack and determine from the return address, which function called
the current one, and what point in the function had been reached.
This thereby enables the system to determine which objects within that
function had been fully constructed. It is then able to further
examine the stack to access those objects and call their respective
destructor code.

It would be far too complicated to describe this using pseudo code
since it requires direct representation of the stack and code
addresses.


--
______________________________________________________________________
Marcelo Cantos, Research Assistant __/_ mar...@mds.rmit.edu.au
Multimedia Database Systems Group, RMIT / _ Tel 61-3-9282-2497
723 Swanston St, Carlton VIC 3053 Aus/ralia ><_> Fax 61-3-9282-2490
Acknowledgements: errors - me; wisdom - God; funding - RMIT

0 new messages