Chapter 5. gcc Options and Extensions

To use gcc, the standard C compiler used with Linux, you need to know the command-line options. Also, gcc extends the C language in several ways. Even if you intend to write only ANSI-C-compliant source code, you will need to know some of the extensions to understand the Linux header files.

Most of gcc’s command-line options are normal, as C compilers go. For a few options, there do not appear to be any standards. We cover the most important options, options that are used on a day-to-day basis.

Standard—ISO-standard—C is a useful goal, but as low-level as C is, there are situations in which it is not expressive enough. There are two areas in Linux in which gcc’s extensions get particular use: interfacing with assembly-language code (covered in Brennan’s Guide to Inline Assembly[1]) and building shared libraries (covered in Chapter 8). Because header files are parts of those shared libraries, some of the extensions show through in the system header files, as well.

Of course, there are also lots of extensions that are useful in all sorts of other everyday coding, as long as you do not mind being gratuitously nonstandard. For more documentation about these extensions, see the gcc Texinfo documentation.

gcc Options

gcc has a multitude of command-line options. Fortunately, the set you usually need to know about is much smaller, and we cover those options here. Most of the options are generally the same or similar on other compilers, as well. gcc has voluminous documentation on its options available with info gcc.[2]

-o filename

Specify the output file name. This is not usually needed if you are compiling to an object file because the default is to substitute filename.o for filename.c. However, if you are creating an executable, the default (for historical reasons) is to create an executable named a.out. It is also useful if you wish to put output files in another directory.

-c

Compile, without linking, the source files specified on the command line, creating an object file for each source file. When using make, it is common to use one invocation of gcc per object file, because it is easy to see which file failed to compile if an error occurs. However, when you are typing commands by hand, it is commonly useful to specify many files in one invocation of gcc. In cases in which specifying many input files on the command line would be ambiguous, specify only one, or gcc may get confused. For instance, gcc -c -o a.o a.c b.c is equivalent to gcc -c -o a.o b.c.

-Dfoo

Define a preprocessor macro on the command line. You may need to escape characters that are special to the shell. For instance, if you want to define a string, you will have to escape the " characters that delimit the string. Two common ways to do this are '-Dfoo="bar"' and -Dfoo="bar". Note that the first works much better if there are any spaces in the string, because spaces are treated specially by the shell.

-Idir

Prepend dir to the list of directories in which to search for include files.

-Ldir

Prepend dir to the list of directories in which to search for libraries. Unless otherwise instructed, gcc uses shared libraries in preference to static libraries.

-lfoo

Link against libfoo. Unless otherwise instructed, gcc links against shared libraries (libfoo.so) in preference to static libraries (ibfoo.a). The linker searches for functions in all the libraries listed, in the order in which they are listed, until each function is found.

-static

Link against static libraries only. See Chapter 8 for details.

-g, -ggdb

Include debugging information. The -g option instructs gcc to include standard debugging information. The -ggdb option instructs gcc to include a large amount of information that only the gdb debugger is capable of understanding. Use -g if you have limited disk space, expect to use a debugger other than gdb, or are willing to trade away some functionality in gdb for linking speed. Use -ggdb if you need all the help you can get debugging, and gcc will pass more information to gdb.

 

Note that unlike most compilers, gcc is willing to include debugging information in optimized code. However, following the debugger as it traces through optimized code can be challenging—the code path may jump around and completely miss sections of code you expected to be executed. It can also give you a better understanding of your code, and of how optimizing compilers change the way your code executes.

-O, -On

Instruct gcc to optimize your code. By default, gcc does a few optimizations; specifying a number (n) instructs gcc to optimize to a certain level. The most common optimization level is 2; with the standard version of gcc, 3 is currently the highest optimization level. Unless you wish to compile quickly at the expense of run-time speed, you expect to use a debugger on the output file, or you have found a bug in the optimizer, we recommend using -02 or -03 when compiling; -03 may increase the size of your application, so if this is a concern, we recommend that you test both ways. You may also consider -Os, which optimizes for minimum code size instead of for speed, if memory or disk space is at a premium for your application.

 

gcc does not implement inline functions unless at least minimal optimization (-0) has been enabled.

-ansi

Support all standard ANSI (X3.159-1989) or the technically equivalent ISO (ISO/IEC 9899:1990) C programs (often abbreviated C89 or occasionally C90). Note that this does not enforce complete ANSI/ISO compliance. The -ansi option turns off gcc extensions that officially conflict with the ANSI/ISO standard. (Because many of these extensions are also supported by other C compilers, this is rarely a problem in practice.) It also defines the __STRICT_ANSI__ feature macro (as described on page 49), which the header files use to provide an ANSI/ISO- compliant environment.

-pedantic

Give all warnings and errors required by the ANSI/ISO C standard. This does not enforce absolute ANSI/ISO compliance.

-Wall

Turn on all the generally useful warning messages that gcc can provide. It does not turn on options that are useful only in specific cases. This provides a similar level of detail to running the lint syntax checker on your source code. gcc allows you to turn each warning message on or off individually. The gcc manual lists all the warning messages.

Header Files

You may, from time to time, find yourself browsing the Linux header files. You are likely to find some constructs there that go beyond ANSI/ISO-compliant C code. A few, at least, are worth understanding. All of the constructs documented here are more fully documented in the gcc info documentation.

long long

The long long type denotes a storage unit at least as large as a long. On Intel i86 and other 32-bit platforms, long is 32 bits wide, and long long is 64 bits wide. On 64-bit platforms, pointers and long long are 64 bits wide, and long may be 32 or 64 bits wide depending on the platform. The long long type is supported in the “C99” dialect of C (ISO/IEC 9899:1999), and has been a long-standing extension to C provided by gcc.

Inline Functions

In certain parts of the Linux header files (system-specific ones, in particular), inline functions are used pervasively. They are as fast as macros (no function call overhead is incurred) but provide all the type checking available with a normal function call. Code that calls inline functions must be compiled with at least minimal optimization on (-O).

Alternative Extended Keywords

In gcc, every extended keyword (keywords not covered by the ANSI/ISO standards) has two versions: the keyword itself and the keyword surrounded by two underscore characters on each side. When the compiler is used in standard-compliant mode (usually, because the -ansi argument was used), the normal extended keywords are not recognized. So, for example, the attribute keyword is written as _ _attribute_ _ in the header files.

Attributes

The attribute extended keyword is used to tell gcc more about a function, variable, or declared type than is possible in ANSI/ISO-compliant C code. For example, the aligned attribute tells gcc exactly how to align a variable or type; the packed attribute specifies that padding not be used; and noreturn specifies that a function never returns, which allows gcc to optimize better and avoid spurious warnings.

Function attributes are declared by adding them to the function declaration, like this:

void die_ die_die(int, char *) _ _attribute_ _ ((_ _noreturn_ _));

The attribute declaration is placed between the closing parenthesis and the semicolon of the declaration and consists of the attribute keyword followed by the attributes in double parentheses. If there are multiple attributes, use a comma-separated list.

int printm(char *, ...)
__attribute__((const,
               format (printf, 1, 2)))
;

This says that printm does not examine any values other than its arguments and has no side effects related to code generation (const), that gcc should check the arguments given to it as it checks the arguments to printf(), and that the first argument is the format string and the second argument is the first substituted parameter (format).

We cover some attributes in context (for instance, building shared libraries in Chapter 8), and you can find all the documentation on attributes in the gcc Texinfo documentation.



[2] man gcc has them too, but the man page is not updated as often as the Texinfo documentation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset