PATH Documentation > Release Notes

Mac OS X 10.3 Xcode Developer Preview:
GCC 3.3

These notes describe Apple's GCC 3.3, which is based on version 3.3 of the Free Software Foundation's GNU Compiler Collection. GCC 3.3 will be the default compiler on Mac OS X for C, C++, Objective-C, and Objective-C++ source code after this package is installed. GCC 3.1, which was the default compiler in the Mac OS X 10.2 Development Tools, continues to be provided for backward compatibility. GCC 2.95 is also still provided for backward compatibility.

These release notes are not comprehensive. For a complete list of compiler changes, please also consult the release notes for the compiler in the Mac OS X Developer Tools 10.1 release.

The actual FSF GCC versions that each compiler in this release is based on are:

Compiler    Base FSF GCC version
gcc22.95.2 final release
gcc33.1 prerelease snapshot dated 2002-10-03
gcc-3.33.3 prerelease snapshot dated 2003-03-04

Switching to GCC 3.3

The Xcode Tools package provides three compilers: GCC 2, based on version 2.95 of the Free Software Foundation's GCC compiler suite, GCC 3 (also called GCC 3.1), based on version 3.1 of the Free Software Foundation's GCC compiler suite, and GCC 3.3, which is based on version 3.3 of the Free Software Foundation's GCC compiler suite.

Here are some important things to keep in mind before you switch from GCC 2 or GCC 3.1 to GCC 3.3:

Switching between compilers

All three compilers may coexist on the same system. GCC 3.3 is always available as /usr/bin/gcc-3.3, GCC 3.1 is always available as /usr/bin/gcc-3.1 and /usr/bin/gcc3, and GCC 2 is always available as /usr/bin/gcc2. In addition, there are symbolic links at /usr/bin/cc and /usr/bin/gcc that point to the selected compiler. By default, the selected compiler is GCC 3.3.

However, if you have a lot of make files and shell scripts that refer to /usr/bin/cc or /usr/bin/gcc, changing all those references to your compiler of choice may be impractical. In that case, use the gcc_select command to change the selected compiler.

To use GCC 2 as the selected compiler:

To use GCC 3.1 as the selected compiler:

To use GCC 3.3 as the selected compiler:

To see which compiler version you are using, enter gcc -v. For more help on gcc_select, enter /usr/sbin/gcc_select -h.

Switching between compilers in Xcode

To set the compiler for your target for a classic (Jambase) target, double-click on the target in the project window to open it in an editor. Choose Settings -> Simple View -> GCC Compiler Settings. Select the compiler with which you wish to build the target using the Compiler version popup.

To set the compiler for your target for a native target, bring up the inspector for the target. Select the Build Rules tab. If the compiler shown in the System C Rule is not the desired compiler, then add a new build rule by clicking on the + button. Configure your new build rule to process "C source files" using the desired version of GCC. If you wish to revert to using the system compiler, you can delete the build rule.

Documentation

Documentation for the 3.3 compiler is available in /Developer/Documentation/DeveloperTools/gcc-3.3. Documentation for the 3.1 compiler is available in /Developer/Documentation/DeveloperTools/gcc-3.1.

Compiler option compatibility issues

Source code compatibility issues

Some source code will need to be changed when moving to GCC 3.3 because the new compiler adheres more closely to the rules of the relevant language standards. Here are some specific areas where you may notice a difference:

Precompiled headers

Apple's 3.3 compilers support a new form of precompiled headers. The new form is available from Xcode; refer to the Xcode documentation for more information. If you're using some other build system, such as make, see the procompiled header documentation for information on specific compiler options.

cpp-precomp is no longer supported in the GCC 3.3 compiler. GCC 3.3 ignores cpp-precomp specific options.

GCC 3.1's form of precompiled headers, "PFE", is no longer supported in GCC 3.3; use the new form instead.

New language features

ObjC/ObjC++ exception and synchronization support

The Objective-C language now offers syntactic support for structured exception handling that is similar to what is offered by C++ and Java. To enable the new syntax, you must pass the '-fobjc-exceptions' options to the ObjC/ObjC++ compiler, and/or set the MACOSX_DEPLOYMENT_TARGET environment variable to "10.3".

   @try {
       ...
          @throw expr;
       ...
    }
    @catch (AnObjCClass *exc) {
       ...
         @throw expr;
       ...
         @throw;
       ...
     }
     @catch (AnotherClass *exc) {
       ...
      }
     @catch (id allOthers) {
       ...
     }
     @finally {
       ...
     }

The @throw statement may appear anywhere in an Objective-C program; when used inside of a @catch block, the @throw may appear without an argument (as show above), in which case the object caught by the @catch will be rethrown.

Note that only (pointers to) Objective-C objects may be thrown and caught using this scheme. When an object is thrown, it will be caught by the nearest @catch clause capable of handling objects of that type, just as is the case in C++ and Java. A @catch(id) clause (as shown above) may also be provided to catch any and all Objective-C exceptions not caught by previous @catch clauses.

The @finally clause, if present, will be executed upon exit from the immediately preceding @try-@catch section. This will happen regardless of whether any exceptions are thrown, caught or rethrown inside the @try-@catch section, just as is the case in Java.

There are several caveats to using the new exception mechanism:

The '-fobjc-exceptions' switch also enables the use of synchronization blocks for thread-safe execution:

   ObjCClass *lockObject = ...;
   ...
   @synchronized (lockObject) {
     ...
   }
Unlike Java, Objective-C does not allow for entire methods to be marked @synchronized. Note that throwing exceptions out of @synchronized blocks is allowed, and will cause the guarding object to be unlocked properly.

Inline Assembly

In addition to the traditional GCC syntax for inline assembly, Apple GCC 3.3 now supports inline assembly using syntax as in CodeWarrior, which allows you to write assembly instructions in function bodies the same way as you do for assembly source files. Both asm functions and asm blocks within functions are available. This feature is not turned on by default; use -fasm-blocks to enable.

In general, the syntax and capabilities are exactly the same as what is documented for CodeWarrior, and so the assembly code can refer to variables and local parameters, use structure fields for offsets, and so forth. (The Apple GCC manual includes a short section describing the basics of the syntax.) However, the implementation is new, and some bugs did not get fixed in time for this release.

1. Function names cannot be referenced in the block; they will be interpreted as (undefined) labels, resulting in an error. There is no workaround.

2. Macros whose expansions include one or more instruction opcodes will result in syntax errors. For instance,

#define INSN_SEQ(X,Y) \
  mr r9,X \
  mr Y,r9

asm void fn() {
  INSN_SEQ(r3,r4)
}
should work, but fails. This is a side-effect of the preprocessor being integrated in 3.3; a slow but reliable workaround is to use -save-temps. Beware that -save-temps will leave preprocessor output and assembly files behind, and you will need to clean those up manually.

Compilation speed

Compilation speed in GCC 3.3 is significantly faster than it was in GCC 3.1, particularly for C++ projects that use precompiled headers. In addition to the general speedup, there are several special features that are related to compilation speed.

The following features are available from Xcode:

Symbol Separation

Symbol Separation is not yet available from Xcode, but it is available by explictly providing command-line options to the compiler.

If your project contains large headers that are included in many different source files, Symbol Separation makes it possible to put the debug symbols from those headers in a separate repository. The compiler can thus save disk space and I/O time, because it no longer has to put the debug symbols into every object file where the headers are included. Symbols repositories are themselves normal object files, and can be supplied to the linker so that the debug information is included in the final executable.

To create the symbol repository for a header file foo.h, use the following command:

    gcc-3.3 <other flags> -fsave-repository=cinfo_dir_name  foo.h  

This command will create two files:

To use the repository in subsequent compilations, you must provide the -grepository command line option. The compiler will then search for .cinfo files in all include paths.

Major bugs fixed in this release

Optimization

GCC 3.3 has greatly improved code optimization, especially for Altivec code. If you've turned off optimization before, particularly if you are switching from GCC2, it's recommended that you turn it on now. Many bugs and inefficiencies have been fixed.

Xcode automatically chooses the recommended optimization level for you. Just be sure to build with the pbxbuild tool or to choose the Deployment build style before building your final product.

For deployment builds, the recommended setting is -Os, which produces the smallest possible binary size. Generally, a binary that's smaller is also faster. That's because a large application spends much of its time paging its binary code in and out of memory. The smaller the binary, the less the application needs to page. For example, say a binary uses aggressive function inlining. That binary saves time with fewer function calls, but it could easily spend far more time paging the binary code containing those inlined functions in and out of memory.

For debugging versions, the recommended optimization level is -O0.

Here are the different levels for C, C++, Objective-C and Objective-C++:

When performing function inlining, GCC 3 inlines forward-referenced functions in addition to the functions it inlined before. A function is inlined if it's smaller than the inlining limit. The default limit is 600 internal GCC instructions. To raise the limit, add -finline-limit=number to the command line. Raising this limit too high can slow down compiling, increase the size of your executables with too much inlining, and lower execution speed.

Here are some interesting optimizations that aren't included by -O2 or -O3:

-faltivec
Optimizes code for Altivec. Code built with this flag might not run on G3 processors.

-mtune=7400 -mtune=7450 -mtune=750 -mtune=970
or alternatively:
-mtune=G3 -mtune=G4 -mtune=G5
Optimizes for speed on the indicated chip (750 is G3, 7400 is G4, 7450 is G4+, 970 is G5). The default is close to 7400, but produces slightly smaller and slower code. Code built with these flags will still run on any processor; if you only want code that runs on one processor, you may use -mcpu=7400 and similar.

When -mtune=G5 is used in conjunction with -O3, the following alignment flags should also be enabled for optimum performance:

    -falign-loops-max-skip=32
    -falign-jumps-max-skip=32
    -falign-loops=16
    -falign-jumps=16
    -falign-functions=32

-mdynamic-no-pic
Produces better code for references to static and global data. Generally, you should use this option when building an executable. Do not use it when building shared libraries or plug-ins because the produced code is not valid for them.

-funroll-loops
Unrolls loops. Unrolling makes the code larger, but may make it faster by reducing the number of branches executed.

-ffast-math
Enables some floating point optimizations that are not IEEE754-compliant, but which usually work. Programs which require strict IEEE compliance may not work with this option.

-fstrict-aliasing
Optimize code by making more aggressive assumptions about whether pointers can point to the same objects as other pointers. Programs which use pointers a lot may benefit from this, but programs that don't strictly follow the ISO C rules about the type with which an object may be accessed may behave unexpectedly.

How to build the compiler from source

The source code for the Apple GCC 3.3 compiler is available for download using anonymous CVS from :pserver:anonymous@anoncvs.opensource.apple.com:/cvs/root using password anonymous and module gcc3. See the compiler documentation for more information about how to obtain specific compiler versions using CVS. The opensource.apple.com repository may also contain compilers that are more up-to-date (and less stable) than the compiler in this release.

The file README.Apple, in the top level source directory, explains how to build the compiler.

Ways in which Apple GCC 3.3 differs from gcc on other platforms


Copyright © 2001–2003 Apple Computer, Inc. All rights reserved. Xcode, Apple, the Apple logo, Mac, and Macintosh are trademarks of Apple Computer, Inc., registered in the U.S. and other countries.