New version of the GNU compilers

[10/27/2006: current version is gcc 4.1.1]

As of version 3.x the GNU compilers (gcc, g++ etc.) behave slightly differently than versions 2.x, which have been the default on our system for a long time. If you do software development, please read on.

Dynamic vs. static libraries

Most C and C++ functions such as I/O, string and character manipulation etc. are not a part of the language proper, but reside in external libraries. The code needed to execute such functions is normally pulled out of the library at the time when the program is "linked" (at the end of compiling), and becomes a part of the executable file.

In recent years there has been a trend towards "dynamic linkage", i.e. building executables which only contain a reference to those external functions; the code for the functions is pulled out of the libraries at run time. This has many advantages but also some drawbacks. One of the advantages is that the executables can be smaller, since much of the code is not directly inside them. Also, should a bug be discovered in the libraries, simply compiling and installing a new version of the library will fix the bug; the individual executables won't need to be rebuilt.

As of version 3.x, the GNU compilers by default use dynamic linkage on the Suns. This means that the program must be able to locate the library when it runs. For various reasons this won't happen automatically. When compiling such code, you need to specify with a separate flag where the dynamic object can be found.

For example,

g++ -o myprog myprog.cc utils.cc
will compile a C++ program, even if you use function calls from the external standard C++ library; but at runtime it will give an error such as "ld.so.1: ./a.out: fatal: libstdc++.so.5: open failed", because it doesn't know where to look for that library. The way around it is to compile with
g++ -o myprog myprog.cc utils.cc -R /usr/local/gnu/lib
thus telling the program that runtime GNU libraries are in the directory "/usr/local/gnu/lib". Note that when you compile several object files and then link them, you only need to use the -R flag in the last (link) step:
gcc -c file1.c
gcc -c file2.c
gcc -o myprog file1.o file2.o -R /usr/local/gnu/lib
Another option is to forego the advantages of dynamic linkage and use
g++ -static -o myprog myprog.cc utils.cc
This will instruct the compiler to use the traditional static linkage, essentially forcing the old behavior. The downside is that the executables will typically be much larger, and that the program has to be recompiled when the linked-in libraries change (e.g. due to bug fixes).

Stricter compliance with standards

The new compilers also enforce some rules of the C++ standard much more strictly. As an example, they will no longer assume that "const a = 10;" implicitly means "const int a = 10;" If you have lots of such "shortcuts" in your source, you will see many compile-time errors which will have to be fixed. Sorry about this, but overall it's a good idea to clean up such code.

Finally, gcc will no longer look at the standard C++ library (although g++ will). If, for some reason, you want to use gcc rather than g++ to compile C++ code, you will usually have to explicitely say

gcc -static -o myprog myprog.cc utils.cc -lstdc++
or else you will see errors about undefined symbols and objects.

Fortran

Even though the old g77 will still work for a while, the preferred GNU Fortran compiler is now gfortran. It implements the Fortran 95 standard, while being capable of compiling most legacy Fortran 77 code. It also uses dynamic linkage by default, so a typical simple invocation will look like

gfortran -o myprog myprog.f -R /usr/local/gnu/lib

Please let the system manager know as soon as possible if you have problems with the new compilers or any other utilities.

1/3/2003