WWDC2001 Session 704
Transcript
Kind: captions
Language: en
thank you
and thank you for it for coming this
morning we're on the fourth day at WWDC
I imagine a lot of you are beginning to
hit information overload I hope you
still have a lot of energy because we
have a lot to present in this session
compilers and compilers are such an
essential part of development tools were
all affected by their performance we
have a lot of things to say about that
we'd be interested to know how many
people in the audience have downloaded
the Darwin the darwin source set just
raise your hands how about half two
thirds okay how many people actually
contribute to the Darwin repositories a
lot fewer okay with no further ado I'd
like to introduce John Graziano the
manager of the compiler team so today
we're going to be talking about Mac OS
10 compiler technologies and I just
wanted to say a little bit about what
those are on my team we handle the
compiler which is GCC the assembler the
linker the dynamic loader which is
responsible for starting up your
application and a lot of utilities like
strip nm o'toole and a few others the
point that we want to make throughout
this talk is that while all of these are
usable as command-line tools the
recommended way that we want for people
to use GCC is through project builder
we've got a lot of nice things in
project builder to integrate with it so
we're not going to cover all of these
things today but what we will talk about
is how to use GCC and give you a little
overview of the architecture touch a
little bit on dynamic linking and pre
binding popular subject and also talk
about some of the upcoming features
Thanks okay there's two slides on
upcoming features they don't get too
excited
so the the GNU C compiler this is this
the main compiler for Mac OS 10 and for
those of you that are curious looking
for it it's a basically user bin CC for
UNIX heads in the audience it's free
software by the free software foundation
if you're curious about that you can go
to the new org on the web and look
around there
it supports ANSI C C++ and Objective C
it's got a very robust C++
implementation very robust C++ front-end
it's got many years of work and testing
compiles for tons and tons of platforms
it's basically the reference compiler
for many developers it's used in
education all over the place and the
most important thing is it compiles all
of Mac OS 10 every piece of source code
that runs on Mac OS 10 goes through GCC
so a little overview of GCC for those of
you that aren't familiar with it it is a
command-line tool and it basically takes
C files for and puts out dot o files or
object files which we then send to the
linker but behind the scenes which
actually going on is GCC is a driver
that first invokes there we go it's the
only graphic I have today I want it to
work if first invokes a preprocessor
which outputs pre-process source code
that then is fed into the compiler which
outputs assembler code it then invokes
the link the assembler which outputs
object code and finally that goes to the
linker which binds everything together
and creates your application or your
library or whatever your you're making
all this happens behind the scenes but
the important thing to keep in mind is
that there are a lot of switches if you
look at the documentation that can be
sent to any portion of these these sub
processes to control a lot of what goes
on during this process so what we've
done at Apple is we've taken C
see and we've extended it in a few ways
we've added project builder integration
we've added objective-c this has been
added for a while but now I'd like to
I'm happy to say that we are the owners
of Objective C for the Free Software
Foundation we're the maintainer --zz we
support our frameworks we support our
version of precompiled headers we have
support in for the velocity engine which
most of the compiler people in the
audience know is altivec and of course
we support our Mach ole object file
format there's a few differences that
you have to be that you have to keep in
mind for GCC the first one is that we
have some stricter an C C++ compliance
so if you're used to compiling on Mac OS
9 you may find out that you get a few
more warnings and maybe a few more
errors compiling your source code on Mac
OS 10 mostly in the area of C++ syntax
and especially type checking another
thing to keep in mind that will bite a
few people rarely is that our static
initializers will execute possibly in a
different order from mac os9 because of
the way that we link because of the fact
that we have pre binding which I'll talk
about a little bit later if you have
static initializers which have implicit
reliance on one another's not explicit
if you have a dependency graph that we
can follow we get that right but if you
have implicit dependencies through
global variables or something you may
find out that the behavior will be a
little different when you build and run
on Mac OS 10 so that's something to be
careful about so since public beta we've
added a few things and done a lot of
work on GCC the first thing is we're
fully based now on GCC tu-95 2 we used
to be running then think the driver and
the preprocessor from 272 and now we're
running everything in the 295 to code
base we've also added a lot of C++
improvements coalesce symbols zero
overhead exceptions and we've made pre
comps usable from C++ which has a
dramatic effect on compile time for C++
the first thing we added is coalesce
symbols
what this does is removes multiple
copies of functions that has been
created through inlining and templates
what we've seen is a finder binary went
down about 300k from two megabytes to
1.7 megabytes and we've seen similar
reductions in other C++ programs
especially power client programs and
this is giving us an overall reduction
in the system memory footprint and
you're going to hear this theme return -
over and over through this talk the most
important thing you can do to optimize
your application on Mac os10
to make it run really fast is to reduce
the system memory footprint reduce the
working set in memory because you know
you can optimize the CPU uses as much as
you want but as soon as your app starts
paging in and out through the virtual
memory system you're gonna get slower so
another thing we've done along this
route is added zero overhead exceptions
before what we do is put a set jump in a
system call when you'd have a try block
now we've removed that so tribe locks
are basically free as free is you know
any code that's not inside of a try
block the common case is very fast so
we've seen in about 2x improvement in
some real-world apps for leaf functions
we've actually seen about a 20x
improvement if it's just a barely
function that has a try block in it
we've also seen size reduction we
knocked the finder size down by an
additional 400 K when we added zero
overhead exceptions the big thing to
keep in mind though is for throws this
will add a memory penalty and a speed
penalty especially for the first time
you throw because we do page in a lot of
code to unwind the stack at that point
so what would our basic policy is we
treat exceptions as exceptional
conditions for error messages if you
have something that's in your main line
of processing that uses C++ exceptions
you may see a slight performance lose
with zero overhead exceptions but the
vast majority of people are going to see
a big win
what we've also added our precompiled
headers usable from C++ what we've seen
in here is a compile times improve as
much as 5x four-carbon applications good
so the way that we did this is pre comps
can be accessed from C++ now we have an
extra C++ aware precompiled header and
all of our umbrella frameworks but they
cannot contain C++ syntax due to a
limitation on the way that we do
precompiled headers and the other thing
is is that macros and compiler flags
have to match as with most as with most
precompiled headers if you change a
macro setting the precompiled header
will not be able to be used we'll have
to go back to the the standard text
header so I'd like to talk a little bit
about how we use GCC on Mac OS 10 so in
some of the things I'm going to cover
just project builder integration how you
can use and take advantage of
precompiled headers optimization and
I'll touch a little bit on altivec as
well so GCC and project builder have
been designed for a while to work very
well together project builder is our
preferred way to use GCC on Mac OS 10
it's got a lot of nice integration for
you
it handles most of the command-line
switches with with gooeys most of the
most common command line switches and
there's also ways to access some of the
uncommon pan alliance which is directly
from project builder it has integrated
error messages so that when GCC has an
error syntax error it comes up in
project builder and those of you have
been at the project builder session how
many of you have been at the project
builder session so we didn't you know
call that out this year just because
it's been around for a while now but
basically GCC actually sends a message
up to project builder and project
builder will display the error message
and jump to the jump to the line and
source code GCC also provides source
code indexing information to project
builder so for any
reference information that you need
doing global searches or running the new
class browser that we have in project
builder all of that comes off of
information that the compiler supplies
let's talk a little bit about the pre
compiler the pre compiler creates a file
of pre process and tokenized headers so
it basically takes the the group of
headers that we have for say carbon or
cocoa and it token eise's them and puts
them all into one big file that we can
then access the big thing for us is that
it not only does this which reduces some
of our I o costs and reduces some of our
lexing costs but it also at compile time
selectively unpark own what's used some
of our measurements when we're working
on compile time we see that 174 thousand
lines of declarations get brought in
from carbon so not everyone uses
obviously even even a small fraction of
that so the big win and the pre compiler
is it can selectively pull in those
declarations that you're using what this
does is it reduces the size of that pre
processed file that we generate and
reduces the overall memory footprint of
the compiler itself so it doesn't have
to push out the IDE to make room for for
the parsing that it has to do so when
we're using precompiled headers we
already supply you with precompiled
headers for the frameworks that we ship
for the major umbrella frameworks so
carbon and cocoa already have their
precompiled headers if you if anybody's
gone nosing around inside of the the
framework you'll see a dot P file living
in there and now a dot PP file which is
the C++ version of those precompiled
headers project builder also supports
creating your own set of precompiled
headers you can actually have more than
one precompiled header and in a minute
I'll bring dabangg up to show how we do
that and the preprocessor will
automatically find these precompiled
headers so you don't have to worry about
you know telling project builder or
telling the preprocessor where these
headers are it will look for them if
they're in
same spot as the dot H that was created
from so again there are some limitations
to precompiled headers the macro
settings compiler settings and the time
stamps that they were built on have to
match if there's a change in them we
have a fallback position where we go to
using the text-based header which is
going to slow down your compile times
they can be included from C++ files but
they cannot contain C++ syntax so now
I'd like to bring up the vein patel and
we're going to go through how you create
your own precompiled header with project
builder
[Applause]
my demo script here so can we have demo
2 up on both of the screens here great
so what we have is just the example
project appearance sample and we brought
it up in project builder and the first
thing we've done is we've precooked a
small header and if those of you can
read this what devane's gone in and done
is set set a macro to be debug level 2
what this is going to do is basically
break the relationship between this
project and the precompiled header that
we ship with the carbon framework so the
compiler will fall back on using the
text base header and bring in all
174,000 lines and declarations so let's
see what that looks like we've basically
just tweaked one file and let's go ahead
and build that
so we're going ahead and building that
and you're seeing as this happens that
we get a lot of warnings saying that we
can't use the precompiled header and
there we're done and that was one file
just to compile all of those
declarations so what to look for if
you're seeing slow compile times with
C++ is definitely look for those
warnings make sure that you're using the
precompiled header now what we're going
to do is go to the the build settings
for this target and actually make our
own precompiled header now the first
thing that's done that's a new feature
in project builder is that you can
actually add an implicitly included
header so that every header comes into
the project so that every source file in
the project uses this header some people
are softly clapping this is a good thing
the other thing that we have is we've
got a switch that you can just click and
you can pre-compile this a turn you can
obviously add you know as many of these
as you want to this table and you can
pre compile all of them so well what
dabangg has done is he's actually
clicked that he's going to pre compile
this and what we'll go do is go back and
click build again and you'll see that in
addition to doing some of the prep work
what it's saying now is it's running
pre-compile header and it's actually
creating the two pre comps that we use
that we'll use in this project so that's
done so now let's go back and run the
same build again so debating is just
going to tweak this a little bit and
command s
and there we go so what we're seeing is
on average about 5x improvement in your
compile times when you're using a
precompiled header and this is you know
the the sort of preferred way that a lot
of ideas get to compile times up is by
building precompiled headers and the big
thing for you is getting getting out the
the you know the huge amount of
declarations we have in carbon and and
and cocoa and being able to get those in
a tokenized fashion you can selectively
use them and and speed up your compile
time significantly now the other thing
that Devane is highlighting because we
didn't have a slide on this is for those
of you that are interested there's a
there is a command line tool called P
dump if you're not able to use your
precompiled header for some reason you
can't figure it out
or if you just want to poke around
inside of the pre-comp and see what's in
there you can use you can use P dump and
P dump - help - - help which will give
you a lot of information on what you can
pull out of there so it might be an
interesting exercise just to poke around
inside the pre-comp and see what's in
there and how this stuff is is recorded
so that's it for the demo thanks to bang
[Applause]
let's talk about optimization so the two
things I want to talk about here are
controlling the compiler optimization
levels and actually what they do
so I'll warn you this will descend a
little bit into compiler D curry but not
not much so the first one is
optimization level 0 it's basically the
default for GCC if you pass no
optimization flag on the command line
you get no optimization you can also
pass - oh is zero the reason they have
that is allows you to override a
previous previously passed optimization
flag it does no optimization so what you
get is slower and bigger code but code
that you can easily follow in the
debugger it also gives you the fastest
turnaround time but compared to
something like using a precompiled
header versus not using precompiled
header it's basically in the noise and
it's a default setting for a project
builder deployment build so our project
builder development build so when you
set the build style and project builder
to be the development build what you get
is unoptimized code so optimization
level 1 basically - code or - oh 1 on
the command line turns on a bunch of
basic optimizations it turns on register
allocation turns on data flow analysis
dead code elimination some jump
optimizations and also peephole
optimization I won't get into for those
of you that don't know what that is
don't worry about it basically turns on
some sort of basic level of statement
level optimization the key point here is
it it results in much smaller and faster
code than level 0 so for those of you
that can read the bottom the bottom line
here it says a binary sizes can reduce
as much as 50% we did some initial
testing on the finder front-end and a
couple other things we built them
unoptimized we built them with - o1 and
the size of the binary
I went down by 50% and you should expect
that your code execution just raw CPU
throughput will will go up by about a
factor of 2 between unoptimized code and
optimizing it at - oh 1 for optimization
level 2 this provides a sort of function
level optimizations it brings in common
sub-expression elimination loop
optimization strength reduction and it
turns on the instruction scheduler it
produces faster they're not necessarily
smaller code than - oh 1 so we'll see
some benchmarks that rely on these
optimizations going up by about 10 to
15% but the code will not get that much
smaller and in fact in some cases if you
have a lot of loop unrolling going on
the code actually grows by a little bit
the other thing is because we're doing
doing statement level optimization at
this point we're doing things which
which will move statements around will
move variable settings outside of loops
to it what you'll see in the debugger is
that sometimes as you're stepping you
may not go exactly where you think the
source code is going to go you also may
have trouble finding variables that have
been hoisted into registers so the other
optimization level that we support
inside of GCC is optimization level 3
which turns on the inline ER so this is
automatic function inlining not just
when you say inline inside of C++ so in
some cases this can result in faster
code but the thing to keep in mind is it
might increase your binary size so you
may get faster code on a benchmark or
faster code when you test one particular
piece of of your application but overall
you may bloat your binary enough that
you start paging a little more and
cancel out the results of getting this
extra inlining so profiling is very
important measuring this is very
important to see what kind of
performance you're getting if you're
using - oh 3 just to make sure that you
do
doing the right thing for your
particular application and I'll point
you to a session that's happening in
here at five o'clock today on the
performance tools or Robert voltage is
going to get up and talk about some of
the tools you can use to measure your
application and of course when we're
talking about doing automatic inlining
debugging we'll get again a little more
difficult for you when you're tracing
through inside of the debugger so some
recommendations are for optimization we
always use internally no optimization
when we're building when we're just
doing development builds this lets us
get access to all the stuff in the
debugger there's no statement movement
or anything that confuses us it gives us
the the best turnaround time and it's
it's generally you know what we
recommend for external developers as
well our build style gives you - oh 0
when you choose the development build
style
we also recommend for deployment builds
for most people to use - OH - it doesn't
have it doesn't have a big effect on the
size of your binary but what it does do
is decides your binary / - l1 but
turning on any optimization is a big win
turning on - OH - gives it a extra 10 to
15% again it has that trade-off that if
you're using - oh - and then trying to
debug it you may run into a couple
confusing situations and again - oh
three when you have CPU critical cases
when you're trying to get you know that
last ounce of performance out of it but
definitely make sure that you're not
loading your binary to the point where
it's not it's it's cancelling out the
results of the change so just a little
bit on altivec in GCC the big thing to
keep keep in mind is that we support all
of the altivec intrinsics and GCC
so if you're used to using altivec
through Cold War the same thing applies
you'll be able to use that same code
inside a project builder inside of GCC
and again it requires though that you
pass a - a fault of that flag - project
builder which we can show you how to do
if I can bring the van back up here so
we're going to do a quick demo now on
compiler settings inside a project
village so sending those optimization
flags how you would set the ultimate
flag how you would set up some of the
other flags that you used to setting
from the command line on GCC or for
those of you that are not using GCC how
you can avoid having to access the
command line or having to worry about
the command line so what devane's done
is brought up again the target editor
and he's clicked on the build settings
pane of the target editor and we've got
a lot of things in here to control the
compiler settings you can just look
there's a big section labeled compiler
settings the first thing that we can
control is optimization so you basically
can just go to this pop-up and set no
optimization which of course is the
default for development builds all the
way up to optimization level three for
the particular thing that you're
building you can turn on and off
debugging information if you want to
generate debugging information if you
don't want to generate debugging
information for though for those of you
that are looking at deployment binaries
and wondering why they're so big you
might want to checks that flag because
there's a lot of debugging information
that goes into a binary if you turn this
on you definitely want to make sure that
that's off for the binaries that you're
deploying we also again have whoa we
also again have the the implicitly
included headers and again you can add
as many of those as you want and you can
pre compile them and also to set some of
the preprocessor flags what are the
search paths where we look for headers
and you can set all that up so down here
in there's a sort of a general table
called build settings and for the
compiler flags that aren't represented
inside of GUI you can actually get at
these through this table this is sort of
an expert view for people
but all these flags basically correspond
all of these uppercase variables on the
left hand side correspond to variables
that get passed into our build system
and expanded some of the stuff that
you're going to be interested in looking
at our other C flags and other LD flags
and then optimization C Flags what you
can do there is basically set here
dabangg is setting the dash F altivec
flag for those of you that can can see
the font the other thing that's nice if
you really if you're really a gearhead
is you can pass in flags that turn on
and off any of the individual
optimization passes that GCC does so if
you want to turn on loop unrolling but
you don't want to have strength
reduction for example you can pass in
the individual flags inside of these C
flags for those of you that are
wondering where are all these things
documented in the in the project builder
release notes there's a build a CH tml
file and if you go and look at that the
settings that are listed here are all
documented so you know what's going to
happen
when you set some of these different
some of these different settings again
this is just basically an expert view
but if there are flags that you want to
get at that aren't represented in the
GUI this is where you go and you should
be able to basically you know for people
who are used to using GCC from the
command-line this gives you access to
all the flags that you want to use so
thanks to me so I want to say a couple
things on dynamic linking this is
something that happens outside of the
compiler this happens with our dynamic
linking process called D yld and this is
how your app starts up basically when
your app is compiled the references are
not resolved and this is how we actually
use shared libraries basically if you
compile your app that has dynamic
references into shared libraries when
your app starts up what happens is we
first bind the references to functions
and data at
startup time the function references
allow us to do lazy initialization so in
the basic case when you start up your
application the function references are
not resolved until you actually call
through to those functions the thing to
keep in mind is that any data references
if you're referencing global data those
references have to be resolved at
startup time before you hit main because
we have no way to trap on first use and
go and run any initialization routines
that have to happen
so if you're accessing data some library
and it routines may have to be run
before main actually starts up so the
reason we're talking about this is
because I also want to mention this
thing we have called pre binding what
pre binding does is it actually sets the
dynamic link addresses at static link
time so if you're running against a
shared library the linker will actually
go out and grab those addresses and set
them up at static link time this can
give you a dramatic improvement in
launch times because you're not having
to search through the symbol tables of
the libraries at all and most
importantly again getting back to the
memory theme you're not having to page
in those symbol tables to do the search
the trade-off is this gives you no lazy
initialization all this stuff has to be
set up at compile time so we're just
going out through addresses at that
point so we can't trap on first use so
we have to actually initialize the
libraries and the modules before before
the app actually hits main in in a lot
of cases this doesn't give your dramatic
slowdown it's still a big win to do pre
binding but that's definitely something
that is a trade off applications are
built by default pre bound in project
builder so this will give you pre
binding if you're building application
that links against the system libraries
this will give you a pre-bout
application but the big thing to keep in
mind is that binaries which are pre
bound have to be updated when the
libraries change so for those of you
that have been poking around the web and
seeing
this thing on what is all the system
optimization that's going on I just
downloaded the developer package and
it's optimizing my system again it's
basically happening is it's going
through and it's reprimanding those
binaries so it goes through it looks for
binaries on the system and it basically
fixes up the addresses to the libraries
as they've been updated so you know once
that's been run the libraries are pre
bound the Mac OS 10 GM ship free bond so
running that on a stock Mac OS 10 GM
system isn't going to get you anything
but when libraries are updated going
through and reap rebinding this actually
is a way that helps us fix up our
binaries so that they run as fast as
possible let's talk a little bit about
upcoming features in the compiler and in
the compiler tool chain so the first
thing we're going to talk about is GCC 3
what's coming with that we'll talk about
a feature in the linker called two-level
namespace which most of you who have
worked in the CFM world are already used
to and of course what a lot of you are
here to hear about is Objective C plus
plus and then we'll talk about some
things that are coming further down the
running soft applause for Objective C
plus plus so GCC 3 is what we're
currently working on we've got a
building some of Mac OS 10 but not all
of it right away
what this gives us is an integrated
preprocessor it gives us some better C++
support better C++ compliance it has a
lot of cogent improvements especially
for the PowerPC and something keep in
mind for people as we're rolling this
out is it does give you C++ ABI changes
so if you're using a shared library that
contains exported C++ calls exported C++
classes or anything like that
there will be ABI changes you'll have to
ship a new binary for that if you
compile it with GCC 3.0 the other thing
we've added is two level namespace
before what we had on Mac OS 10
public beta and on GM is a flat
namespace so all of your libraries and
all of your and all your application
just basically all the symbols went up
into a big pool and if there were any
name collisions you basically lost at
that point the thing to keep in mind is
that if you're loading bundles if you're
loading plugins we actually have a
two-level namespace implemented for
plugins so things like QuickTime and
other applications with load plugins
already can take advantage of this what
we're doing is having is expanding this
feature to the rest of your binary the
way that it works on Mac OS 9 so we
linked now by symbol name and library
name what this does is it protects
against name collisions in modules so if
we add a new API to our libraries that
conflicts with a function that you call
in your application it doesn't break
your applicationnow so as we update
libraries moving forward it won't mess
up the applications that you already
have this also speeds dynamic linking
for non pre bound applications because
instead of having to search the entire
set of symbol tables we go right to the
library and we look for it there the
thing to keep in mind for people who are
used to compiling and the flat namespace
coming over from Mac os10 server or
having done some other unix applications
there is one restriction that you have
to keep in mind that if you reference a
symbol now out of a library you have to
explicitly include it on the link line
so in case you're wondering about
compatibility Mac OS 10 GM apps work
just fine on the GNU system so we'll
have a two-level namespace system things
that have shipped for Mac OS 10 GM will
work just fine
two level apps will also work just fine
on GM system so you build your app for
two-level namespace when this is rolled
out and it'll run fine on Mac OS 10 GM
and any combination of flat and
two-level libraries will work as well so
you can have a two-level app the links
against a flat library that links
against another you know our system
libraries which will be two-level at
that point and that will all work just
just fine
so Kevin under B is the engineer that
that that worked on this and you did a
really good job making sure that all
these corner cases got covered he'll be
on stage later so you can ask him some
questions about this so now what I'd
like to do is bring up zem Lasky who is
the responsible engineer for objective
C++ and he's going to walk you through
what we've been doing our objective C++
and what some of the details are there
so welcome Sam thank you well as John
mentioned I did do most of the work so
at least for the initial release if
things break you can blame me so
basically what I'd like to do is just
give you a really broad a really quick
overview of what objective C++ is and
what it is not so the most important
thing to remember actually are two very
important things the first one is that
it's really just a combination of C++
and Objective C or perhaps more
accurately it's a superimposition of
objective-c on C++ with C++ sort of
being the senior partner and the reason
we did this is is very simple we would
like to allow C++ programmers to utilize
the numerous objective-c frameworks that
we have on the system most notably cocoa
in conjunction with this rollout we
concocted a new file extension dot mm
which should be used for objective C++
source code there's a timer here some of
you who are coming over from the next
days might also have seen that dot cap M
as an extension but we hereby declare
this to be no longer politically correct
the HFS file system is case preserving
but not case-sensitive there are also
other issues so we certainly encourage
you to move away from dot cap am a few
words about the implementation as it
currently exists it is a separate
compiler a separate front-end that I was
working on which is separate from the
C++ front-end and the other ones and now
I come to the second important point the
first one being the combination of the
two languages the second important point
is that an object for C++ program
once you compile and run it interacts
with two runtimes the C++ runtime and
the objective-c runtime now I'm not sure
how much you're a way of one or the
other which direction you're coming from
if you're coming from this plus plus
world then you probably know more about
the person one if you're coming from the
coco slash next step world we probably
know a bit more about the second one but
the important thing here is that these
two runtimes are separate they are
different they have different semantics
at at least at present they are mutually
unaware of one another or as I like to
say nutri oblivious of one another
syntactically the the objective-c
constructs and C++ constructs are also
separate in the sense that you can
easily tell just by looking at a
construct which languages belongs to
which is of course makes life a lot
easier for us and implementing it and
also for you in terms of figuring out
what is what and what semantics go with
it so first off I'd like to give you
sort of the good news the ways and you
can mix C++ and Objective C code so
first of all you can declare an instance
of an objective-c
object which is really a reference or a
pointer to that object like in Java you
can declare that anywhere you have a C++
declaration so wherever you can declare
C++ variable you can declare the
objective-c variables secondly Objective
C classes the declarations of the
classes themselves may contain within
them C++ classes or c structs there are
some exceptions to that which I will get
into later Objective C message sense
which you see in the square bracket
notation there if you haven't seen this
before this really is a typed expression
so you can use that anywhere you have
C++ expressions in your code and an
examples forthcoming
and finally objective C++ relies on the
C++ type checking semantics for some of
the lower-level type checking and the
reason I bring this up is that if you're
used to objective-c coding it relies on
C type checking so for instance if you
have a sign character and you assign it
to an unsigned character in C that's
usually fine
the C compiler would not complain what
you'll find here is that the seat you
know the C++ part of objective C++ will
you know raise its head and complain in
other words some objective some code
that is valid Objective C code might not
necessarily be valid objective C++ code
because of the increased C++ strictness
so here I I concocted sort of a too
slight example showing you what an
objective C++ program looks like and for
ease of understanding I've color-coded
it so that the Objective C part of it is
in blue and the C++ part is in yellow so
you see first off we you know we call
this hello world as we always should
then we import cocoa cocoa that H that's
a typical Objective C thing and by the
way John mentioned before that you can
use precompiled headers with c++ now you
will also be able to use it with
objective c++ so you know there will be
a cocoa PP on your system and this whole
thing is released so this will go very
fast Danny in yellow you see a four word
declaration of a c++ class then we get
to a declaration of an objective-c class
which we called print log we derive it
from Anna's object which is sort of the
root of the cocoa object hierarchy and
we have a pointer to the C++ class we
previously mentioned and then we you
know declare prototypes for two methods
in Objective C then here this is the
second part of the example first we you
know flash out the C++ class so you have
fellow world here we have an ID and you
know a member variable of type ID which
is sort of analogous to java.lang object
if you've used java it's sort of a
generic pointer that can point to any
objective-c object and we define any now
I can structure an instructor so you can
see in a constructor for this c++ class
we actually allocate an init the
corresponding objective-c class and that
is by the way how you usually create an
objective-c object to this alloc init
idiom and then we sort of you know we
you know we say hi so we call printf
which is a standard C function of course
then you have say hello which basically
caught you know turns around and
folks a method called say hi in the
objective-c class and then below we have
a an implementation of the projective
c-class which is in blue so you can sort
of see the notation here you know NS log
is also a standard Cocoa function it's
actually a C function if you look at it
so it basically prints hello world on
the screen and the example is sort of
silly as all examples are but it kind of
shows you how you can mix and match so
you can see within the Objective C we
actually use P arrow say hi to call the
C++ method and vice-versa on CL from a
C++ class you can invoke an objective-c
method right okay and now we get to the
sort of the important part of this talk
in the sense that we'd like to sort of
emphasize why certain things cannot be
done in Objective C plus plus and the
reason most of these things cannot be
done is what I mentioned at the outset
is that the runtimes are separate
because they are separate they do not
know of one another and therefore
certain things really cannot happen so
you know the number one obviously you
can't do is mix up class hierarchies if
you have a you know higher gifts you've
got class objects that's fine if you
have a you know a hierarchy of
objective-c objects that's fine too you
cannot mix them because it will just be
very confusing for the compiler in the
runtime as far as exception handling we
really encourage you to use the C++
runtime for this the you know the try
throw catch paradigm objective-c does
have some set some long jump based
exceptions which are basically macros
that expand and we really do not
discourage you from using this because
C++ just won't know what's going on when
you when you do this and one thing to
keep in mind is that when you use C++
exceptions you have to clean up any
objective-c objects that you have flying
around so here you have a try block
where we you know instantiate an
objective-c object and then we have a
catch clause which frees it and then you
re throw the C++ exception to be
possibly caught by some other handler in
an enclosing scope or you know in your
in your stack you have to do this
because again the C++ runtime will not
know about my objects that it's an
objective-c class or what to do with it
this is a recurring theme C++ classes
cannot receive objective-c messages or
vice-versa this is fairly trivial I mean
you cannot the functions in c++ that you
call an object and the methods in the
objective-c land are really semantically
different you cannot treat one as if it
were the other did this but reckon ISM
is different it's it they do not mix so
I mean and the compiler will diagnose
this correctly so you shouldn't run into
any problems there
you cannot statically allocate new or
delete Objective C objects and actually
the UN delete keyword should be in
yellow because that's in C++ construct
and the reason again is if you if you
create an object in you have to
initialize the Objective C object which
the C++ runtime wouldn't know how to do
if you're familiar with virtual
functions in c++ there is always sort of
a v table pointer at the beginning of
your object Objective C has something
analogous that needs to be initialized
and C++ you know wouldn't know what to
do with that I believe this is my final
restriction type slide I mentioned
earlier that you can embed C++ classes
within Objective C classes but there is
a there is a catch you may not do this
if you have any virtual functions again
this is because you would have a V table
pointer and and in this case the
objective-c runtime wouldn't know what
to do with the v table pointer so this
really goes both ways if you have a
non-virtual constructor like in the
struct class two example there we will
let it slide
however we will give you a warning
because that constructor won't be called
so if you're expecting to have the class
two member initialized that won't happen
and the reason we allow this is because
in the objective-c you can put C structs
in like this and of course that's fine
because you don't expect any
initialization semantics and C is this
my final example I believe so so this is
the most important slide probably how
you get your hands on this stuff we are
really very close to starting seeding
this thing having people try it out and
if you're interested in being one of our
early victims and I'm really joking it's
actually quite stable at this point
we've used it as a C++ compiler on our
system very successfully so it's it's
you know I'm really proud of it anyway
if you're interested in becoming a seek
partner with us please approach Godfrey
our session manager at the end of our
session here after the Q&A and now I'll
hand it back to John for some closing
thoughts thanks to them I I just want to
say that we brought them on in February
and he started on this in March
basically using the old crufty 2.72
objective C++ implementation crufty
because the 2.72 C++ implementation in
GCC was pretty pretty bad and he
actually got this up and running and
just last week we were able to compile
the the full finder codebase which is
all powerplant as well with this
compiler so it's not only compiling all
of our objective C++ code but it's also
a real honest-to-god C++ compiler so zem
did a great job and I think we should
give him a hand for a cream
so all of you who are who are interested
in those guys like you too so all of you
that are interested in bringing your C++
applications your c++ UNIX tools and
putting a cocoa front-end on them this
is your path to success this will get
you there and it's a very nice thing I
personally have written a lot of
objective C++ code using the old
compiler and I'm really looking forward
to being able to use this at this new
compiler it's gonna be really great so
just a couple notes on what we're still
going to be working on the biggest thing
on our player right now is still
reducing compile time so I think the C++
pre comps have been huge they've done a
lot of good to getting removing most of
the pain involved with doing you know a
full carbon C++ build but again you saw
that restriction where we currently
cannot handle C++ code in there so if
you want to have your power plant pre
comp we can't do that right now in GCC
so the first thing we're working on is
getting that capability into GCC so you
can have precompiled compile times with
large C++ code bases the next thing is
we're continuing to work on code quality
improvements GCC 300 will get us there
some of the way but we're also working
on just bringing GCC up into more of a
you know getting it up to the commercial
quality that people have come to expect
on Mac OS 9 for all of the code gen it's
pretty good in most cases but there's
some cases where we leave a little bit
on the table and we're still working on
that and finally we were working again
on tighter and tighter project builder
integration being able to semantically
browse through different language
constructs and basically using GCC
especially the front end of GCC to
supply as much of the semantic
information the cross-referencing
information that you need in project
builder and having project builder take
advantage of that
so just to wind it up GCC is our road
tested open compiler for Mac OS 10 you
can go on and get the sources today if
you want them it works from the command
line it's a usable command-line tool it
works even better from project builder
we have a lot of support in there that
is actually difficult to access from the
command line where we take advantage of
a lot of the things that the IDE
provides and really use the features in
GCC and the big thing to keep in mind is
that Apple is fully committed to GCC as
our main line compiler we run all of Mac
OS 10 through GCC every binary that you
bring up when you install the Mac OS 10
GM has been run through the good new
compiler it does everything all of our
Objective C C++ C and now it's going to
be doing all of our objective C++ as
well so with that turn it back over to
Goffe
thank you very much Jeff a big hand for
the team I think they've done a
fantastic job some information resources
as usual information pages for all the
Mac os10
tools are available at the Apple
developer website under the tools area
we also for this scene because GCC is an
open source project we wanted to give
you the pointer for open source at the
Apple webpages and the new project web
sources well since they're the is their
the the baseline for all the new stuff
and another pointer also to our mailing
list main server we have several mailing
lists that are germane to the to the
development development tasks project
building users is the one that has been
very heavily used got over over 500
subscribers now cocoa dev and carbon to
over a thousand thank you Dave cocoa dev
and carbon dev are also getting
populated very rapidly as well roadmap
for more tool sessions a very important
session this afternoon at 5:00 robber
bondage in 705 will show you how to use
the performance tools that we're
supplying on disk this has tremendous
benefit for everyone tomorrow
7:06 in the main hall at nine o'clock
debugging on Mac OS 10 using gdb the
darwin documentation project and also
the feedback form tomorrow afternoon are
also very good opportunities for you to
for you to talk to the development team
and get more questions and answers with
that and especially for the objective
c++ seeding this is my contact
information on top I would ask again as
we put in the slide if you're looking to
be a candidate for as an objective-c e C
and Objective C + + seed site that's a
mouthful please put that in the subject
line so that I can identify them easily
and manage the seed program my group
technology management does all the
management of a seeding for Apple
Computer the Mac OS 10 tools feedback
address sends your email directly to the
Keith key personnel in the development
teams in our tools groups as a good way
to get feature enhancements ideas
Express directly to us and the URL at
the bottom of the screen which reappears
on the on the QA
slide is a master page of all the URLs
organized by session for the show so if
there's one URL that you should write
down you should write down the last one
because that will allow you to get to
all the all the URLs and all the
information resources that we distribute
throughout the entire show
you