Tru64 UNIX
Compaq C Language Reference Manual


Previous Contents Index

8.2.6 The #endif Directive

The #endif directive has the following syntax:

#endif newline

This directive ends the scope of the #if , #ifdef , #ifndef , #else , or #elif directive.

The number of necessary #endif directives changes according to whether the elif or #else directive is used. Consider the following equivalent examples:


#if true                             #if true 
.                                    . 
.                                    . 
.                                    . 
#elif true                           . 
.                                    #else 
.                                    #if false 
.                                    . 
#endif                               . 
                                     . 
                                     #endif 
                                     #endif 

8.2.7 The defined Operator

Another way to verify that a macro is defined is to use the defined unary operator. The defined operator has one of the following forms:

defined name


defined (name)

An expression of this form evaluates to 1 if name is defined and to 0 if it is not.

The defined operator is especially useful for checking many macros with just a single use of the #if directive. In this way, you can check for macro definitions in one concise line without having to use many #ifdef or #ifndef directives.

For example, consider the following macro checks:


#ifdef  macro1 
printf( "Hello!\n" ); 
#endif 
 
#ifndef  macro2 
printf( "Hello!\n" ); 
#endif 
 
#ifdef  macro3 
printf( "Hello!\n" ); 
#endif 

Another use of the defined operator is in a single #if directive to perform similar macro checks:


#if  defined (macro1)  || !defined (macro2) || defined (macro3) 
printf( "Hello!\n" ); 
#endif 

Note that defined operators can be combined in any logical expression using the C logical operators. However, defined can only be used in the evaluated expression of an #if or #elif preprocessor directive.

8.3 File Inclusion (#include)

The #include directive inserts the contents of a specified file into the text stream delivered to the compiler. Usually, standard headers and global definitions are included in the program stream with the #include directive. This directive has two forms:

#include "filename" newline


#include <filename> newline

The format of filename is platform-dependent. If the filename is enclosed in quotation marks, the search for the named file begins in the directory where the file containing the #include directive resides. If the file is not found there, or if the file name is enclosed in angle brackets (< >), the file search follows platform-defined search rules. In general, the quoted form of #include is used to include files written by users, while the bracketed form is used to include standard library files.

See your platform-specific Compaq C documentation for information on the search path rules used for file inclusion.

Macro substitution is allowed within the #include preprocessor directive.

For example, the following two directives can be used to include a file:


#define  macro1  "file.ext" 
 
#include macro1 

Defined macros used in #include directives must evaluate to one of the two following acceptable #include file specifications or an error is reported:

"filename"


<filename>

An included file may itself contain #include directives. Although the Compaq C compiler imposes no inherent limitation on the nesting level of inclusion, the permitted depth depends on hardware and operating system restrictions.

8.4 Explicit Line Numbering (#line)

The compiler keeps track of information about line numbers in each file involved in the compilation, and uses the line number when issuing diagnostic messages to the terminal or, when compiling in batch mode, to a log file.

The #line directive can be used to alter the line numbers assigned to source code. This directive gives a new line number to the following line, which is then incremented to derive the line number for subsequent lines. The directive can also specify a new file specification for the program source file. The #line directive does not change the line numbers in your compilation listing, only the line numbers given in diagnostic messages sent to the terminal screen or log file. This directive is useful for referring to original source files that are preprocessed into C code.

The #line directive has three forms:

#line integer-constant newline


#line integer-constant "filename" newline


#line pp-tokens newline

In the first two forms, the compiler gives the line following a #line directive the number specified by the integer constant. The optional filename in quotation marks indicates the name of the source file that the compiler will provide in its diagnostic messages. If the file name is omitted, the file name used is the name of the current source file or the last file name specified in a previous #line directive.

In the third form, macros in the #line directive are expanded before it is interpreted. This allows a macro call to expand into the integer-constant, filename, or both. The resulting #line directive must match one of the other two forms, and is then processed as appropriate.

8.5 Implementation-Specific Preprocessor Directive (#pragma)

The #pragma directive is a standard method for implementing platform-dependent features. This directive has the following syntax:

#pragma pp-tokensopt newline

The supported pragmas vary across platforms. All unrecognized pragmas are diagnosed with an informational message. See your platform-specific Compaq C documentation for a list of supported pragmas.

Some pragma directives are subject to macro expansion. They are:


builtins            inline                 linkage       standard 
dictionary          noinline               module        nostandard 
extern_model        member_alignment       message       use_linkage 
extern_prefix       nomember_alignment 

The following pragmas are also subject to macro expansion, primarily for use in preprocess-only mode (that is, with the /PREPROCESS_ONLY qualifier on OpenVMS systems or the -E switch on Tru64 UNIX systems), and are not normally used when generating an object module with the Compaq C compiler:

Note



An _nm suffix can be appended to any of the above-listed macros to prevent macro expansion. For example, to prevent macro expansion on #pragma inline , specify it as #pragma inline_nm .

Also, to provide macro-expansion support to those pragmas not listed above, all pragmas (including those that are already specified as undergoing macro expansion) have a pragma-name _m version, which makes the pragma subject to macro expansion. For example, #pragma assert is not subject to macro expansion, but #pragma assert_m is.

A macro reference can occur anywhere after the keyword pragma . For example:


#define opt inline 
#define f func 
#pragma opt(f) 

After both macros are expanded, the #pragma directive becomes #pragma inline (func) .

Note

Macro expansion is a feature of pragmas introduced in early versions of DEC C and is retained for backward compatibility.

Pragmas added in more recent versions of the compiler and pragmas added in the future have changed that practice to conform to the defacto industry standard of not performing macro expansion. (ANSI C places no requirement on macro expansion of pragmas.)

The following describes how the compiler decides whether or not to macro-expand a given pragma:

In compilation modes other than /STANDARD=COMMON (OpenVMS systems) or -std0 (Tru64 UNIX systems), do Step 1:

Step 1:

The token following the keyword pragma is first checked to see if it is a currently-defined macro. If it is a macro and the identifier does not match the name of a pragma that is not subject to macro expansion, then just that macro (with its arguments, if function-like) is expanded. The tokens produced by that macro expansion are then processed along with the rest of the tokens on the line in Step 2.

In all compilation modes, do Step 2:

Step 2:

The first token following the keyword pragma is checked to see if it matches the name of a pragma that is subject to macro expansion. If it does, then macro expansion is applied to that token and to the rest of tokens on the line.

The test for matching a known pragma permits an optional double leading underscore. For example, #pragma __nostandard is equivalent to #pragma standard .

Example

The following example illustrates that for pragmas coded directly with a name that matches a known pragma, the macro-expansion behavior is generally the same in all modes and is backward-compatible. It is only in cases where a pragma was coded with a name that was not the name of a known pragma, expecting macro expansion to produce the pragma name, that backward-compatibility is broken, and then only in common mode. The exception is made in common mode to maintain compatibility with the Tru64 UNIX preprocessor.


  #define pointer_size error 
  #define m1 e1 
  #define e1 pointer_size 32 
  #define standard message 
  #define x disable(all) 
  #define disable(y) enable(y) 
 
  #pragma pointer_size 32  /* In common mode, Step 1 skipped. 
                              In other modes, Step 1 finds that pointer_size 
                                   is known not to expand. 
                              In any mode, Step 2 finds pointer_size is 
                                   not a pragma requiring expansion. */ 
 
  #pragma m1   /* In common mode, Step 1 skipped. 
                  In other modes, Step 1 expands m1 to pointer_size 32. 
                  In common mode, Step 2 finds m1 is not a pragma requiring 
                         expansion. 
                  In other modes, Step 2 finds pointer_size is not a pragma 
                         requiring expansion. */ 
 
  #pragma standard x  /* In common mode, Step 1 skipped. 
                         In other modes, Step 1 expands to message x. 
                         In common mode, Step 2 expands to message enable(all). 
                         In other modes, Step 2 expands message x to 
                            message enable(all). */ 

8.6 Error Directive (#error)

The #error preprocessor directive issues an E-level diagnostic message and continues compilation, but no object module is produced. This directive has the following syntax:

#error messageopt newline

8.7 Null Directive (#)

A preprocessing directive of the form # newline is a null directive and has no effect.

8.8 Predefined Macro Names

The following sections describe the predefined macro names that are provided to assist in transporting code and performing simple tasks common to many programs.

8.8.1 The __DATE__ Macro

The __DATE__ macro evaluates to a string literal specifying the date on which the compilation started. The date has the following format:

"Mmm dd yyyy"

The names of the months are the same as those generated by the asctime library function. The first d is a space if dd is less than 10. For example:


printf("%s",_ _DATE_ _); 

The value of this macro remains constant throughout the translation unit.

8.8.2 The __FILE__ Macro

The __FILE__ macro evaluates to a string literal specifying the file specification of the current source file. For example:


printf("file %s", _ _FILE_ _); 

8.8.3 The __LINE__ Macro

The __LINE__ macro evaluates to a decimal constant specifying the number of the line in the source file containing the macro reference. For example:


printf("At line %d in file %s", _ _LINE_ _, _ _FILE_ _); 

8.8.4 The __TIME__ Macro

The __TIME__ macro evaluates to a string specifying the time that the compilation started. The time has the following format (the same as the asctime function):

hh:mm:ss

For example:


printf("%s", _ _TIME_ _); 

The value of this macro remains constant throughout the translation unit.

8.8.5 The __STDC__ Macro

The __STDC__ macro evaluates to the integer constant 1, which indicates a conforming implementation.

The value of this macro remains constant throughout the translation unit.

8.8.6 The __STDC_HOSTED__ Macro

The __STDC_HOSTED__ macro evaluates to the integer constant 1 if the implementation is a hosted implementation, or to the integer constant 0 if it is not.

8.8.7 The __STDC_VERSION__ Macro

The __STDC_VERSION__ macro evaluates to the integer constant 199901L.

8.8.8 The __STDC_ISO_10646__ Macro

The __STDC_ISO_10646__ macro evaluates to an integer constant of the form yyyymmL (for example, 199712L), intended to indicate that values of type wchar_t are the coded representations of the characters defined by ISO/IEC 10646, along with all amendments and technical corrigenda as of the specified year and month.

8.8.9 System-Identification Macros

Compaq C defines platform-specific macros that can be used to identify the system on which the program is running. These macros can assist in writing code that executes conditionally depending on whether the program is running on an HP system or some other system, or one Compaq C platform or another.

These macro definitions can be used to separate portable and nonportable code in a C program by enclosing the nonportable code in conditionally compiled sections.

They can also be used to conditionally compile sections of C programs used on more than one operating system to take advantage of system-specific features. See Section 8.2 for more information about using the conditional-compilation preprocessor directives.

See your platform-specific Compaq C documentation for a list of the system-identification macros.

8.9 The __func__ Predeclared Identifier

The __func__ predeclared identifier evaluates to a static array of char initialized with the spelling of the function's name. It is visible anywhere within the body of a function definition.

For example, a function defined as follows will print "f1".


void f1(void) {printf("%s\n", __func__);} 


Previous Next Contents Index