[net.micro.atari16] Re.: C++ preprocessor wanted

bs@alice.UucP (Bjarne Stroustrup) (10/11/86)

Moshe Braner writes:

> Regarding the need for a C compiler that would handle long
> identifiers, y'all might not know that Megamax recognizes
> the first 10 chars, and allows very long total length.
> That may still not be enough for C++ - I dunno.

You can survive with C++ and only 31 significant characters in your C
compiler and linker. Don't try with less. If you have only 31 significant
characters complain (politely) to your compiler and linker supplier. Such
complaints have been known to have a positive effect - eventually.

> (and you still need to get that C++ preprocessor...)

The C++ translator, known as cfront, is a preprocessor only in the sense
that the UNIX C compiler is a preprocessor for an assembler. Calling it
a preprocessor is misleading.

Probably the best way of thinking of cfront is as the first pass in a
classical two pass compiler: cfront does a complete syntax check, a
complete type check, expands inline functions, adds temporary variables
where necessary, makes implicit initializations explicit, makes implicit
type coercions explicit, etc.; finally it produces an intermediate form
of the program to be read by the second pass. Using C as the intermediate
form is very useful for portability.

Any error messages produced by a C compiler while processing cfront output
is considered a bug in either cfront or the C compiler. By definition cfront
does not rely on the C compiler for anything but code generation.

> BTW: I devised a method to do object-oriented programming in C.
> Not fancy but simple, and you get inheritance and even late binding
> of sorts with high efficiency (about 100 microSecs for a typical
> invocation of a method).  If anybody is interested let me know.

This made me curious about what the cost of a C++ virtual function call
really is so I ran this example on a VAX11/750:

struct s {
	virtual f();
};

s::f() {}

main() {
	s* p = new s;

	for (int i = 100000; 0<i; i--) p->f();
}

It took 4 seconds; that is, about 4 microseconds per iteration.
For comparison I also ran

f() {}

main() {
	for (int i = 100000; 0<i; i--) f();
}

It took 3 seconds; that is, about 3 microseconds per iteration.
Finally I ran:

main() {
	for (int i = 100000; 0<i; i--) ;
}

It took .5 second. All timings are averages of several several runs.

These times were a bit disappointing in that I could measure the difference
between a virtual function call and a ``normal'' function call but, I think,
not bad. You can do a fair bit of work with a million function calls.

Maybe I ought to mention that with virtual functions there is no difference
between calling one virtual function twice compared with calling two virtual
functions once (many schemes for method lookup involves a slow first call
followed by fast subsequent calls so that simply invoking the same method
a million times would be a too easy test). No trickery, inlining, optimizing,
etc. was involved.

braner@batcomputer.TN.CORNELL.EDU (braner) (10/15/86)

[]

If 100000 calls take 4 seconds, that's 40 uS per call, not 4.

BTW, the 100 uS time I mentioned is for sending a method-token
to an object, complete with the lookup and the late binding.
And it is on the Atari ST.  For comparision, a standard C function
call (passing an integer both ways) has a 25 uS overhead, approximately.
Of course, any useful function (or method) would take at least another
20 uS to do its thing, and usually a lot longer.

- Moshe Braner

PS: I got many requests for the Object-Oriented C Programming.
I'll prepare a posting, one of these days.

gnu@hoptoad.uucp (John Gilmore) (10/17/86)

> >                        ...you get inheritance and even late binding
> > of sorts with high efficiency (about 100 microSecs for a typical
> > invocation of a method).

In article <6174@alice.uUCp>, bs@alice.UucP (Bjarne Stroustrup) writes:
> This made me curious about what the cost of a C++ virtual function call
> really is so I ran this example on a VAX11/750:
> 
> 	for (int i = 100000; 0<i; i--) p->f();
> 
> It took 4 seconds; that is, about 4 microseconds per iteration.

Uh, if you run a loop 100,000 times in 4 seconds, that is *40* microseconds
per iteration, which sounds a lot more reasonable on a 750.  Remember that
this time includes the loop overhead, a function call, and a function return,
and Vaxes are slow about function calls.

Scale all the other "per iteration" numbers by a factor of 10 too.
-- 
John Gilmore  {sun,ptsfa,lll-crg,ihnp4}!hoptoad!gnu   jgilmore@lll-crg.arpa
(C) Copyright 1986 by John Gilmore.             May the Source be with you!