• Aucun résultat trouvé

Predefined Macros

Dans le document For Mary (Page 83-88)

The GCC compiler predefines a large number of macros. Exactly which ones are defined, and what values they contain, depends on the language being compiled, the command-line options specified, the platform being used, the target platform, which version of the compiler is running, and what environment variables have been set. You can use the-dM option on the preprocessor to view the entire list by entering a command like the following:

cpp -E -dM myprog.c | sort | more

The list output by this command contains#definedirectives for every macro that became defined in the preprocessor after processing the specified input source file and all the headers it included.

Table 3-2 lists the macros that are almost always defined, along with a description of the contents of each one.

Macro Description

__BASE_FILE__ A quoted string containing the full path name of the source file specified on the command line (not necessarily the file in which the macro is used). Also see __FILE__.

__CHAR_UNSIGNED__ This macro is defined to indicate that the char data type is unsigned on the target machine. This is used bylimits.hto determine the values ofCHAR_MINand CHAR_MAX.

__cplusplus Defined only when the source code is a C++

program. It is defined as 1 if the compiler does not fully conform to a standard;

otherwise, it is defined with the month and year of the standard in the same manner as__STDC_VERSION__for C.

__DATE__ An 11-character quoted string containing the date the program was compiled. It has the form"May 3 2002".

Table 3-2. The Basic Set of Predefined Macros

USINGTHECOMPILERCOLLECTION

Macro Description

__FILE__ A quoted string containing the name of the source file in which the macro is used. Also see__BASE_FILE__.

__func__ The same as__FUNCTION__.

__FUNCTION__ A quoted string containing the name of the current function.

__GNUC__ This macro is always defined as the major version number of the compiler. For example, if the compiler version number is 3.1.2, this macro is defined as 3.

__GNUC_MINOR__ This macro is always defined as the minor version number of the compiler. For example, if the compiler version number is 3.1.2, this macro is defined as 1.

__GNUC_PATCHLEVEL__ This macro is always defined as the revision level of the compiler. For example, if the compiler version number is 3.1.2, this macro is defined as 2.

__GNUG__ Defined by the C++ compiler. This macro is defined whenever both__cplusplusand __GNUC__are also defined.

__INCLUDE_LEVEL__ An integer value specifying the current depth level of theincludefile. The value at the base file (the one specified on the command line) is 0 and is increased by 1 inside each file input by an#includedirective.

__LINE__ The line number of the file in which the macro is used.

__NO_INLINE__ This macro is defined as 1 when no functions are to be expanded inline, either because there is no optimization or inlining has been specifically disabled.

__OBJC__ This macro is defined as 1 if the program is being compiled as Objective-C.

Table 3-2. The Basic Set of Predefined Macros (continued)

Macro Description

__OPTIMIZE__ This macro is defined as 1 whenever any level of optimization has been specified.

__OPTIMIZE_SIZE__ This macro is defined as 1 if optimization is set for size instead of speed.

__REGISTER_PREFIX__ This macro is a token (not a string) that is the prefix for register names. It can be used to write assembly language that’s portable to more than one environment.

__STDC__ Defined as 1 to indicate that the compiler is conforming to standard C. This macro is not defined when compiling C++ or Objective-C, and it is also not defined when the

-traditionaloption is specified.

__STDC_HOSTED__ Defined as 1 to signify a “hosted”

environment (one that has the complete standard C library available).

__STDC_VERSION__ A long integer specifying the standards version number in terms of its year and month. For example, the 1999 revision of the standard is the value199901L. This macro is not defined when compiling C++ or Objective-C, and it is also not defined when the-traditionaloption is specified.

__STRICT_ANSI__ Defined if and only if either-ansior-std has been specified on the command line. It is used in the GNU header files to restrict the definitions to those defined in the standard.

__TIME__ A seven-character quoted string containing the time the program was compiled. It has the form"18:10:34".

__USER_LABEL_PREFIX__ This macro is a token (not a string) that is used as the prefix on symbols in assembly language. The token varies depending on the platform, but it’s usually an underscore character.

Table 3-2. The Basic Set of Predefined Macros (continued)

Table 3-3 lists a collection of C++ keywords that can be used as the names of operators normally written with punctuation characters. They are treated by the preprocessor as if they were macros created by the#definedirective. If you want to have these same operators available in C or Objective-C, they are defined in the header fileiso646.h.

USINGTHECOMPILERCOLLECTION

Macro Description

__USING_SJLJ_EXCEPTIONS__ This macro is defined as 1 if the mechanism for handling exceptions issetjmp

andlongjmp.

__VERSION__ The complete version number. There is no specific format for this information, but it will at least include the major and minor release numbers.

Table 3-2. The Basic Set of Predefined Macros (continued)

Operator Name Equivalent Punctuation Form

and &&

and_eq &=

bitand &

bitor |

compl ~

not !

not_eq !=

or ||

or_eq |=

xor ^

xor_eq ^=

Table 3-3. The Named Form of the Logical Operators

Including a Header File Only Once

Because header files will include other header files, it is very easy to have a program that includes the same header file more than once. This can lead to error messages because items that have already been defined are being defined again. To prevent this from happening, a header file can be written to detect whether it has already been included. The following is an example of how this can be done:

/* myheader.h */

#ifndef MYHEADER_H

#define MYHEADER_H

/* The body of the header file */

#endif /* MYHEADER_H */

In this example, the header file is namedmyheader.h. The first line tests whether MYHEADER_Hhas been defined. If it has, the entire header file is skipped. IfMYHEADER_H has not been defined, it is immediately defined and the header file is processed.

The system header files all use this technique. The names defined in them all begin with an underscore character to prevent them from interfering with any names you define. The convention is for the defined name to be in all uppercase and to contain the name of the file.

The GNU preprocessor recognizes this construction and keeps track of the header files that use it. This way, it can optimize processing the headers by recognizing the file name and not even reading header files that have already been included.

Including Location Information in Error Messages

The predefined macros can be used to automate the construction of error messages that contain detailed information about the location at which the error occurred. The predefined macros__FILE__,__LINE__, and__func__contain the information, but they must be used at the point the message is created. Therefore, if you write a function that contains them all, error messages will be reported as happening in that function.

The perfect solution is to define a macro that contains them. That way, when the preprocessor expands the macros, they will all be in the correct place and have the correct information. The following is an example of an error macro that writes messages to standard error:

#define msg(str) \

fprintf(stderr,"File: %s Line: %d Function: %s\n%s\n", \ __FILE__,__LINE__,__func__,str);

To invoke this macro from any place in the code, it is only necessary to specify a string describing the error:

USINGTHECOMPILERCOLLECTION msg("There is an error here.");

Another advantage of doing it this way is that your method for handling error conditions can be changed by simply changing the macro. It could be converted to throw exceptions or log the error messages to a file. The message produced from this example will look something like the following:

File: hamlink.c Line: 822 Function: hashDown There is an error here

Dans le document For Mary (Page 83-88)