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 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]
| 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. |
| 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, |
| 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 |
Prepend | |
| Prepend |
| Link against |
| Link against static libraries only. See Chapter 8 for details. |
| Include debugging information. The |
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. | |
| Instruct gcc to optimize your code. By default, gcc does a few optimizations; specifying a number ( |
gcc does not implement inline functions unless at least minimal optimization | |
| 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 |
| Give all warnings and errors required by the ANSI/ISO C standard. This does not enforce absolute ANSI/ISO compliance. |
| 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. |
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.
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.
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)
.
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.
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.
3.145.2.87