Back to CFM home             Brown University

Programming in C

C has been the de facto standard for system programming for more than 2 decades. While some of its features (like dynamic memory allocation, structures etc.) have made it increasingly attractive for the implementation of scientific codes, the lack of built-in complex arithmetic (unlike Fortran), the absence of an established standard complex arithmetic library, the fact that in most cases the simplicity of Fortran makes the job of optimizing compilers easier (and hence a Fortran code is more likely than not to be faster than its C equivalent) and the huge volume of Fortran-based scientific library subroutines make a lot of scientists & engineers program in mixed mode: partly C (mostly the basic structure of the code, including memory allocation) and partly Fortran (for the compute intensive parts).

  1. Compiling & Linking
  2. To compile a C program in file c_program.c (note C programs on most systems need to be in files with a .c extension):
    	% cc c_program.c -o executable_name
    If you omit -o executable_name the executable binary will be called a.out by default.
    If your program is split over more than one file, you can either compile them all on the same line:
    	% cc c_program1.c c_program2.c -o executable_name
    or compile them separately and then link the resulting object files (".o" files) together:
    	% cc -c c_program1.c
    	% cc -c c_program2.c
    	% cc c_program1.o c_program2.o -o executable_name
    If some of the include files that you require (by # include <include_file.h> statements in your C source code) are not in the standard include file search paths the C preprocessor cpp (called by the C compiler automatically) searches in, you can specify them by the -Iinclude_search_path flag:
    	% cc -I/usr/local/mpich/include -c mpi.c 
    Similarly, if some of the librariy functions that your program uses are not to be found among the standard libraries the linker looks in for a C program, you have to specify them yourself, sometimes including the path to the library if it not in the standard directory the linker looks in:
    	% cc mathc_program1.o mathc_program2.o -o executable_name -lm
    	% cc mpi.o -o mpi-test -L/usr/local/mpich/lib/IRIX/ch_shmem -lmpi -lm
    If you are using a library whose filename is libblas.a, you specify it as -lblas.

  3. Compilers
  4. cc is the standard name for a C compiler but not the only option:

  5. Optimization flags
  6. Please make sure that once you've developed and debugged a code you compile it optimized for any production runs you make. Running unoptimized production code is a waste of your time as well as well as CFM computing resources. One only needs to take care when using optimization flags as high optimization levels can alter the semantics of your code and produce significantly different and hence erroneous results. You should check the respective man pages for each compiler to see which optimization flags pose such a threat. In that case it is necessary to test your optimized code by comparing the results of one or more of its runs with those of the code compiled with no optimization. If the difference in the results is small (machine or algorithmic accuracy) then go ahead and use the optimized code. If the difference is large enough for the results to be wrong, choose a lower optimization level and try again. Despite the extra trouble you may have to go through, please try and compile your code optimized, you may be very surprised by how much the time it takes to run (especially if it is well written) decreases! And of course always remember that usually the best optimization is a better algorithm. It is suggested that you look up the man pages for the compiler you plan to use for the best results. (Note that sometimes even supposedly safe optimization options could cause problems due to bugs in the optimizer.) Suggestions for optimization flags for the C compilers on our systems are as follows:
  7. On the IBMs:

  8. For more C related information