GCC 3.3 Release Notes

PATH Documentation > Release Notes

# Mac OS X 10.3 Developer Tools Release Notes:
GCC 3.3

These notes describe GCC 3.3, which is based on version 3.3 of the Free Software Foundation's GCC compiler suite. 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 backwards 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.

## Switching to GCC 3.3

The Development 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:

- Recompile all your C++ code, including libraries and frameworks. GCC 3 has a new application binary interface (ABI) for C++, including changes to name mangling, exception handling, and class layout and alignment. You do not need to recompile C or Objective-C code.
- Do not ignore warnings. GCC 3.3 enforces the C and C++ standards much more strictly. New warnings may point out errors that GCC 2 or GCC 3.1 overlooked.
- Test your code. Even if the compiler doesn't raise any errors or warnings, your code may rely on idiosyncrasies in GCC 2 or GCC 3.1 that GCC 3.3 handles differently.
- If you're creating kernel extensions that must run on Mac OS X 10.1 and earlier, you must use GCC 2. If the extensions will run only on Mac OS X 10.2 and later, you should use GCC 3.1 or GCC 3.3.
- The C++ ABI changed between GCC 2 and GCC 3.1, and again between GCC 3.1 and GCC 3.1. Do not link C++ modules compiled with one of these compilers against modules compiled with any of the other two compilers. The changes between GCC 3.1 and GCC 3.3 were small, but, even if the modules appear to link correctly, C++ ABI differences may cause problems in exception handling that will not manifest themselves until run time. (Note that this warning does not apply to kernel extensions, but to ordinary non-kernel C++. The restrictions for kernel extensions are different, and are given above.)

### 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:

- Open the Terminal, and enter sudo /usr/sbin/gcc_select 2. If you're asked, enter your password.
- This command line logs in as root, makes the neccesary changes, and leaves you logged in under your original account. When it's done, /usr/bin/cc and /usr/bin/gcc use GCC 2.

To use GCC 3.1 as the selected compiler:

- Open the Terminal, and enter `sudo /usr/sbin/gcc_select 3.1` or `sudo /usr/sbin/gcc_select 3`. If you're asked, enter your password.
- This command line logs in as root, makes the neccesary changes, and leaves you logged in under your original account. When it's done, /usr/bin/cc and /usr/bin/gcc use GCC 3.1.

To use GCC 3.3 as the selected compiler:

- Open the Terminal, and enter `sudo /usr/sbin/gcc_select 3.3`. If you're asked, enter your password.
- This command line logs in as root, makes the neccesary changes, and leaves you logged in under your original account. When it's done, /usr/bin/cc and /usr/bin/gcc use GCC 3.3.

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

To switch between compiler versions in Project Builder: to be written

## 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

All of this is just a sketch of what we need to say. It needs to be filled in.

- -traditional-cpp has changed.
- -nostdinc is enforced more strictly by GCC 3.3
- The Apple build number is now output with the --version option, --> --and the format of the -v output has --> --changed. The --version output is intended to be machine-parseable.
- The compiler now checks that an option is valid for the current language, and warns if an invalid option is passed. For instance, -frtti is no longer silently accepted by the C and objective-C compilers.
- Changes in warnings, and switches that control warnings.
- What else?

## 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:

- C++: in-class initialization of things that aren't integer constant expressions
- C++: address of cast
- C++: phase 2 name lookup of members of a base class template
- C99: floating-point hex constants
- GCC inserts new #pragma GCC set_debug_pwd as part of new Distributed Builds feature. This may surprise tools and scripts that depend on the exact form of preprocessed output from GCC.
- GCC 3.3 warns about nested comments with -Wall turned on
- GCC 3.3 does not support token pasting to create new invalid tokens.
- GCC 3.3 enforces #import and #include semantics strictly compared to cpp-precomp.
- Because of the removal of cpp-precomp, the 3.3 compiler's preprocessor is stricter and more standards compliant (similar to the preprocessor used in 3.1 when -no-cpp-precomp or PFE was in use).
- What else?

## Precompiled headers

Apple's 3.3 compilers support a new form of precompiled headers. The new form is used automatically by Project Builder if you specify a prefix header; if you're using some other build system, such as `make`, see /Developer/Documentation/DeveloperTools/gcc-3.3/gcc/Precompiled-Headers.html.

cpp-precomp is no longer supported in the 3.3 compilers; use precompiled headers instead. Do we need more detail here?

GCC 3.1's form of precompiled headers, "PFE", is no longer supported in GCC 3.3; use the new form instead. Do we need to say something about how the PCH usage model differs from PFE, and how to adapt PFE makefiles?

## 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:

- Although currently designed to be binary compatible with NS_HANDLER-style idioms provided by the NSException class, the new exceptions can only be used on Mac OS X 10.3 (Panther) and later systems, due to additional functionality needed in the Objective-C runtime.
- As mentioned above, the new exceptions do not support handling types other than Objective-C objects. The Objective-C exception model does not interoperate with C++ exceptions at this time. This means you cannot throw and catch exceptions between the two exception-handling mechanisms.

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

       @synchronized (ObjCClass *lock) {
            ...
       }

### CodeWarrior-style inline assembly

## Compilation speed

We've improved compilation speed in general. Additionally, we need to say something about the usage model of these new features:

- DistCC
- Speculative Compilation
- ZeroLink
- Fix&Continue
- Symbol Separation (no IDE support but available from command line)

## Major bugs fixed in this release

- Type checking has been fixed and improved in many situations involving Objective-C message dispatching and protocol lookup.
- Type checking has been fixed and improved in may situations involving Objective-C protocols.
- In Objective-C when -Wselector is used, check the whole list of selectors at the end of compilation, and emit a warning if a @selector() is not known.

## 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.

Project Builder 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++:

- No optimization (-O0). This option level is intended for debugging; it ensures that the debugger works as you would expect.
- Simple optimizations (-O) performs simple optimizations, including automatic register allocation and jump threading. This optimization level makes a trade-off between compile speed and execution speed.
- More optimizations (-O2)performs all of GCC's optimizations that don't involve a space-time trade-off. In addition to all the optimizations for level 1, it performs common subexpression elimination, strength reduction, and loop optimizations. It also considers any function declared with the inline keyword for inlining.
- Optimization for speed (-O3) performs still more optimizations. It can be best for code that contains lots of loops and computation. In addition to all the optimizations for level 2, it considers all functions for inlining, even if they aren't declared with the inline keyword.
- Optimization for code size (-Os) produces the smallest binary size. It performs no loop unrolling, scheduling optimizations, or register renaming. The performance is similar to -O2.

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.

-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 yourself

We need to say where to get the source. Do we know?

## Areas where we differ from gcc on other platforms

- The Darwin developer tools use STABS as their debugging format, and do not support DWARF.
- Altivec implementation is different Details?
- Apple's version of GCC 3.3 supports precompiled headers (PCH). In the "generic" FSF GCC, precompiled headers will not appear until version 3.4.

Copyright (c) 2001,2002,2003 Apple Computer, Inc.