VMS Help
CC, Language topics, Preprocessor
*Conan The Librarian (sorry for the slow response - running on an old VAX)
|
|
The Compaq C preprocessor uses directives to affect the compilation
of a source file. For Compaq C on OpenVMS systems, these
directives are processed by an early phase of the compiler, not by
a separate program.
The preprocessor directives begin with a number sign (#) and do not
end with a semicolon. The number sign must appear in the first
column of the source line.
A preprocessing directive of the form # <newline> is a null
directive and has no effect.
2 - Conditional Compilation
|
Conditional compilation is provided by the following directives:
#if constant-expression
Checks whether the constant expression is nonzero (true).
#ifdef identifier
Checks whether the identifier is defined.
#ifndef identifier
Checks whether the identifier is undefined.
#else
Introduces source lines to be compiled as an alternative to the
conditions tested by the previous directives.
#elif constant-expression
Delimits alternative source lines to be compiled if the constant
expression in the corresponding #if, #ifdef, or #ifndef
directive is false and if the additional constant expression
presented in the #elif directive is true. An #elif directive is
optional.
#endif
Ends the scope of the previous directives.
If the condition checked by #if, #ifdef, or #ifndef is true, then
all lines between the #else, #elif, and #endif are ignored. If the
condition is false, then any lines between the conditional
directive and the #else or #elif (if any) are ignored. If there is
no #else, then the lines between the conditional and the #endif are
ignored.
The #define preprocessor directive has the form:
#define identifier token-string
The preprocessor substitutes the token string everywhere in the
program that it finds the identifier except within comments,
character constants, or string constants.
Macro replacements are defined in a #define directive of the
following form:
#define name([parm1[,parm2,...]]) token-string
Within the program, all macro references that have the following
form are replaced by the token string. The arguments in the macro
reference replace the corresponding parameters in the token string.
name([arg1[,arg2,...]])
The #dictionary directive is retained for compatibility with VAX C
and is supported only when running the Compaq C compiler in VAX C
mode (/STANDARD=VAXC). See also the ANSI C equivalent #pragma
dictionary directive.
The #dictionary directive extracts Common Data Dictionary (CDD)
definitions from the specified dictionary. These definitions are
then translated into Compaq C and included in the program.
The #dictionary directive has the following form:
#dictionary "cdd_path"
The cdd_path is a character string that gives the path name of the
CDD record. It can also be a macro that resolves to such a
character string.
The #error directive issues an optional diagnostic message, and
ends compilation. This directive has the following form:
#error [message] <newline>
The #include directive instructs the preprocessor to insert the
contents of the specified file or module into the program. An
#include directive can have one of three forms:
#include "filespec"
#include <filespec>
#include module-name
The first two forms are ANSI-compliant methods of file inclusion
and are therefore more portable. In these forms, .h is the default
file type, unless the compiler is instructed to supply no default
type (that is, a type of just ".") by the
/ASSUME=NOHEADER_TYPE_DEFAULT qualifier.
The third form is specific to OpenVMS systems for specifying the
inclusion of a module from a text library, and is not generally
needed or recommended because the ANSI forms also cause the text
libraries to be searched.
For the order of search, see /INCLUDE_DIRECTORY.
There is no defined limit to the nesting level of #include files
and modules.
The #line directive applies a specified line number and optional
file specification to the next line of source text. This can be
useful for diagnostic messages. The #line directive has the
following 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 filename is omitted, the file name used is the
name of the current source file or the last filename 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.
The #module directive is retained for compatibility with VAX C and
is supported only when running the Compaq C compiler in VAX C mode
(/STANDARD=VAXC). See also the ANSI C equivalent #pragma module
directive.
The #module directive passes information about an object module to
the compiler.
The #module directive can have one of the following forms:
#module identifier identifier
#module identifier string
The first argument of the directive is a Compaq C identifier or
macro that resolves to an identifier. It gives the
system-recognized (for example, internally recognized by the
debugger and the librarian) name of the module; the object file
name remains the same. The second argument specifies the optional
identification that appears on listings. This may be either a VAX
C identifier, a character-string constant with no more than 31
characters, or a macro that resolves to one of these.
There can be only one #module directive per compilation. It can
appear anywhere before the C language text.
The #pragma directive performs compiler-specific tasks as
designated by each implementation of the C language.
All pragmas have a <pragma-name>_m version, which makes the pragma
subject to macro replacement. For example, #pragma assert is not
subject to macro expansion, but #pragma assert_m is.
Compaq C for OpenVMS Systems supports the following pragmas:
#pragma assert[_m]
Lets you specify assertions that the compiler can make about a
program to generate more efficient code. Can also be used to
verify that certain compile-time conditions are met; this is
useful in detecting conditions that could cause run-time
faults.
The #pragma assert directive is never needed to make a program
execute correctly, however if a #pragma assert is specified,
the assertions must be valid or the program might behave
incorrectly.
Syntax:
#pragma assert non_zero(constant-expression) string-literal
When the compiler encounters this directive, it evaluates the
constant-expression. If the expression is zero, the compiler
generates a message that contains both the specified
string-literal and the compile-time constant-expression. For
example:
#pragma assert non_zero(sizeof(a) == 12) "a is the wrong size"
In this example, if the compiler determines that the sizeof a
is not 12, the following diagnostic message is output:
CC-W-ASSERTFAIL, The assertion "(sizeof(a) == 12)" was not
true. a is the wrong size.
The #pragma assert non_zero directive can appear either inside
or outside a function body. When used inside a function body,
the pragma can appear wherever a statement can appear, but the
pragma is not treated as a statement. When used outside a
function body, the pragma can appear anywhere a declaration can
appear, but the pragma is not treated as a declaration.
Because macro replacement is not performed on #pragma assert,
you might need to use the #pragma assert_m directive to obtain
the results you want. Consider the following program that
verifies both the size of a struct and the offset of one of its
elements:
#include <stddef.h>
typedef struct {
int a;
int b;
} s;
#pragma assert non_zero(sizeof(s) == 8) "sizeof assert failed"
#pragma assert_m non_zero(offsetof(s,b) == 4) "offsetof assert
failed"
Because offsetof is a macro, the second pragma must be #pragma
assert_m so that offsetof will expand correctly.
#pragma builtins[_m]
Enables the Compaq C built-in functions that directly access
processor instructions.
The #pragma builtins directive is provided for VAX C
compatibility.
Compaq C implements #pragma builtins by including the
<builtins.h> header file, and is equivalent to #include
<builtins.h> on OpenVMS systems.
This header file contains prototype declarations for the
built-in functions that allow them to be used properly. By
contrast, VAX C implemented this pragma with special-case code
within the compiler, which also supported a #pragma nobuiltins
preprocessor directive to turn off the special processing.
Because declarations cannot be "undeclared", Compaq C does not
support #pragma nobuiltins. Furthermore, the names of all the
built-in functions use a naming convention defined by ANSI C to
be in a namespace reserved to the C language implementation.
#pragma dictionary[_m]
Allows you to extract CDD data definitions and include these
definitions in your program.
The ANSI C compliant #pragma dictionary directive is equivalent
to the VAX C compatible #dictionary directive, but is supported
in all compiler modes. (The #dictionary directive is retained
for compatibility and is supported only when compiling with the
/STANDARD=VAXC qualifier.)
Syntax:
#pragma dictionary "cdd_path" [null_terminate]
[name(structure_name)] [text1_to_array | text1_to_char]
The cdd_path is a character string that gives the path name of
the CDD record. It can also be a macro that resolves to such a
character string.
The optional null_terminate keyword can be used to specify that
all string data types should be null-terminated.
The optional name() can be used to supply an alternate tag name
or a declarator, struct_name for the outer level of a CDD
structure.
The optional text1_to_char keyword forces the CDD type "text"
to be translated to char, rather than "array of char" if the
size is 1. This is the default if null_terminate is not
specified.
The optional text1_to_array keyword forces the CDD type "text"
to be translated to type "array of char" even when the size
is 1. This is the default when null_terminate is specified.
#pragma environment[_m]
Sets, saves, or restores the states of context pragmas. This
directive protects include files from contexts set by
encompassing programs, and protects encompassing programs from
contexts that could be set in header files that they include.
The #pragma environment directive affects the following
pragmas:
o #pragma extern_model
o #pragma extern_prefix
o #pragma member_alignment
o #pragma message
o #pragma names
o #pragma pointer_size
o #pragma required_pointer_size
Syntax:
#pragma environment command_line
#pragma environment header_defaults
#pragma environment restore
#pragma environment save
command_line
Sets, as specified on the command line, the states of all
the context pragmas. You can use this pragma to protect
header files from environment pragmas that take effect
before the header file is included.
header_defaults
Sets the states of all the context pragmas to their
default values. This is almost equivalent to the
situation in which a program with no command-line options
and no pragmas is compiled, except that this pragma sets
the pragma message state to #pragma nostandard, as is
appropriate for header files.
save
Saves the current state of every pragma that has an
associated context.
restore
Restores the current state of every pragma that has an
associated context.
#pragma extern_model[_m]
Controls the compiler's interpretation of objects that have
external linkage. This pragma lets you choose the global
symbol model to be used for externs.
Syntax:
#pragma extern_model common_block [attr[,attr]...]
#pragma extern_model relaxed_refdef [attr[,attr]...]
#pragma extern_model strict_refdef "name" [attr[,attr]...]
#pragma extern_model strict_refdef
#pragma extern_model globalvalue
#pragma extern_model save
#pragma extern_model restore
The default model on Compaq C is #pragma relaxed_refdef noshr.
This is different from the model used by VAX C, which is common
block, shr.
The [attr[,attr]...] are optional psect attribute
specifications chosen from the following (at most one from each
line):
o gbl lcl (Not allowed with relaxed_refdef)
o shr noshr
o wrt nowrt
o pic nopic (Not meaningful for Alpha)
o ovr con
o rel abs
o exe noexe
o vec novec
o 2 long 3 quad 4 octa 9 page
See the Compaq C User's Guide for more information on the
#pragma extern_model directive.
#pragma extern_prefix[_m]
Controls the compiler's synthesis of external names, which the
linker uses to resolve external name requests.
When you specify #pragma extern_prefix with a string argument,
the compiler prepends the string to all external names
produced by the declarations that follow the pragma
specification.
This pragma is useful for creating libraries where the
facility code can be attached to the external names in the
library.
Syntax:
#pragma extern_prefix "string" [(id[,id]...)]
#pragma extern_prefix save
#pragma extern_prefix restore
Where "string" prepends the quoted string to external names in
the declarations that follow the pragma specification.
You can also specify an extern prefix for specific identifiers
using the optional list [(<emphasis>(id)[,<emphasis>(id)]...)].
The save and restore keywords can be used to save the current
pragma prefix string and to restore the previously saved pragma
prefix string, respectively.
The default external prefix, when none has been specified by a
pragma, is the null string.
#pragma [no]inline[_m]
Expands function calls inline. The function call is replaced
with the function code itself.
Syntax:
#pragma inline (id,...)
#pragma noinline (id,...)
If a function is named in an inline directive, calls to that
function will be expanded as inline code, if possible.
If a function is named in a noinline directive, calls to that
function will not be expanded as inline code.
If a function is named in both an inline and a noinline
directive, an error message is issued.
For calls to functions named in neither an inline nor a
noinline directive, DEC C expands the function as inline code
whenever appropriate as determined by a platform-specific
algorithm.
#pragma [no]member_alignment[_m]
Tells the compiler to align structure members on the next
boundary appropriate to the type of the member rather than the
next byte. For example, a long variable is aligned on the next
longword boundary; a short variable on the next word boundary.
Syntax:
#pragma nomember_alignment [base_alignment]
#pragma member_alignment [save | restore]
The optional base_alignment parameter can be used with #pragma
nomember_alignment to specify the base alignment of the
structure. Use one of the following keywords to specify the
base_alignment:
o BYTE (1 byte)
o WORD (2 bytes)
o LONGWORD (4 bytes)
o QUADWORD (8 bytes)
o OCTAWORD (16 bytes)
The optional save and restore keywords can be used to save the
current state of the member_alignment and to restore the
previous state, respectively. This feature is necessary for
writing header files that require member_alignment or
nomember_alignment, or that require inclusion in a
member_alignment that is already set.
#pragma message[_m]
Controls the issuance of individual diagnostic messages or
groups of messages. Use of this pragma overrides any
command-line options that may affect the issuance of messages.
Syntax:
#pragma message option1 message-list
#pragma message option2
#pragma message (quoted-string)
where option1 is:
disable Suppresses the issuance of the indicated
messages.
Only messages of severity Warning (W) or
Information (I) can be disabled. If the
message has severity of Error (E) or
Fatal (F), it is issued regardless of
any attempt to disable it.
enable Enables the issuance of the indicated
messages.
emit_once Emits the specified messages only once
per compilation.
emit_always Emits the specified messages at every
occurrence of the condition.
error Sets the severity of each message in the
message-list to Error.
fatal Sets the severity of each message on the
message-list to Fatal.
informational Sets the severity of each message in the
message-list to Informational.
warning Sets the severity of each message in the
message-list to Warning.
The message-list can be any one of the following:
o A single message identifier (within parentheses or not).
o A single message-group name (within parentheses or not).
Message-group names are:
ALL All the messages in the compiler
ALIGNMENT Messages about unusual or inefficient
data alignment.
C_TO_CXX Messages reporting the use of C features
that would be invalid or have a
different meaning if compiled by a C++
compiler.
CDD Messages about CDD (Common Data
Dictionary) support.
CHECK Messages reporting code or practices
that, although correct and perhaps
portable, are sometimes considered
ill-advised because they can be
confusing or fragile to maintain. For
example, assignment as the test
expression in an "if" statement.
NOTE: The check group gets defined by
enabling level5 messages.
DEFUNCT Messages reporting the use of obsolete
features: ones that were commonly
accepted by early C compilers but were
subsequently removed from the language.
NEWC99 Messages reporting the use of the new
C99 Standard features.
NOANSI Messages reporting the use of non-ANSI
Standard features. The NOANSI message
group is a synonym for NOC89. Also see
message groups NEWC99, NOC89, NOc99.
NOC89 Messages reporting the use of non-C89
Standard features.
NOC99 Messages reporting the use of non-C99
Standard features.
OBSOLESCENT Messages reporting the use of features
that are valid in ANSI Standard C, but
which were identified in the standard as
being obsolescent and likely to be
removed from the language in a future
version of the standard.
OVERFLOW Messages that report assignments and/or
casts that can cause overflow or other
loss of data significance.
PERFORMANCE Messages reporting code that might
result in poor run-time performance.
PORTABLE Messages reporting the use of language
extensions or other constructs that
might not be portable to other compilers
or platforms.
PREPROCESSOR Messages reporting questionable or
non-portable use of preprocessing
constructs.
QUESTCODE Messages reporting questionable coding
practices. Similar to the check group,
but messages in this group are more
likely to indicate a programming error
rather than just a non-robust style.
Enabling the QUESTCODE group provides
lint-like checking.
RETURNCHECKS Messages related to function return
values.
UNINIT Messages related to using uninitialized
variables.
UNUSED Messages reporting expressions,
declarations, header files, CDD records,
static functions, and code paths that
are not used.
Note, however, that unlike any other
messages, these messages must be enabled
on the command line
(/WARNINGS=ENABLE=UNUSED) to be
effective.
o A single message-level name (within parentheses or not).
Note: There is a core of very important compiler messages
that are enabled by default, regardless of anything
specified with /WARNINGS or #pragma message. Referred to as
message level 0, it includes all messages issued in header
files, and comprises what is known as the nostandard group.
All other message levels add additional messages to this
core of enabled messages.
You cannot disable level 0. However, you can disable
individual messages in level 0 that are not errors or
fatals.
Message-level names are:
LEVEL1 Important messages. These are less
important than level 0, because messages
in this group are not displayed if #pragma
nostandard is active.
LEVEL2 Moderately important messages. This level
is used to introduce new messages that
will be output in the DIGITAL UNIX V4.0
release. LEVEL2 is the default for
DIGITAL UNIX and Tru64 UNIX platforms.
LEVEL3 Less important messages. In general,
these are the messages output by default
in DEC C Version 5.5 for OpenVMS Systems.
LEVEL3 is the default message level for
Compaq C for OpenVMS systems.
LEVEL4 Useful check/portable messages.
LEVEL5 Not so useful check/portable messages.
LEVEL6 All messages in LEVEL5 plus additional
"noisy" messages.
Enabling a level also enables all the messages in the levels
below it. So enabling LEVEL3 messages also enables messages
in LEVEL2 and LEVEL1.
Disabling a level also disables all the messages in the
levels above it. So disabling LEVEL4 messages also disables
messages in LEVEL5 and LEVEL6.
o A comma-separated list of message identifiers, group names,
and messages levels, freely mixed, enclosed in parentheses.
option2 is:
save -- saves the current state of which messages are
enabled and disabled.
restore -- restores the previous state of which messages
are enabled and disabled.
The save and restore options are useful primarily within header
files.
The #pragma message (quoted-string) form outputs the
quoted-string as a compiler message. This form of the pragma is
subject to macro replacement. For example, the following is
valid:
#pragma message ("Compiling file " __FILE__)
#pragma module[_m]
The ANSI C compliant #pragma module directive is equivalent to
the VAX C compatible #module directive, but is supported in all
compiler modes. (The #module directive is retained for
compatibility and is supported only when compiling with the
/STANDARD=VAXC qualifier.) The #pragma module directive is
specific to Compaq C for OpenVMS Systems and is not portable.
Use the #pragma module directive to change the
system-recognized module name and version number. You can find
the module name and version number in the compiler listing file
and the linker load map.
Syntax:
#pragma module identifier identifier
#pragma module identifier string
The first parameter must be a valid Compaq C identifier. It
specifies the module name to be used by the linker. The second
parameter specifies the optional identification that appears on
listings and in the object file. It must be either a valid
Compaq C identifier of 31 characters or less, or a
character-string constant of 31 characters or less.
Only one #pragma module directive can be processed per
compilation unit, and that directive must appear before any C
language text. The #pragma module directive can follow other
directives, such as #define, but it must precede any function
definitions or external data definitions.
#pragma names[_m]
Provides the same kinds of control over the mapping of external
identifiers' object-module symbols as does the /NAMES
command-line qualifier, and it uses the same keywords (except
that the "lowercase" keyword is not supported). But as a
pragma, the controls can be applied selectively to regions of
declarations.
This pragma should only be used in header files and is intended
for use by developers who supply libraries and/or header files
to their customers.
The pragma has a save/restore stack that is also managed by
#pragma environment, and so it is well-suited for use in header
files. The effect of #pragma environment header_defaults is to
set NAMES to "uppercase,truncated", which is the compiler
default.
Syntax:
#pragma names <stack-option>
#pragma names <case-option>
#pragma names <length-option>
Where
<stack-option> is one of:
o save - save the current names state
o restore - restore a saved names state
<case-option> is one of:
o uppercase - uppercase external names
o as_is - do not change case
<length-option> is one of:
o truncated - truncate at 31 characters
o shortened - shorten to 31 using CRC
#pragma pack[_m]
Specifies the byte boundary for packing members of C
structures.
Syntax:
#pragma pack [n]
The n specifies the new alignment restriction in bytes:
1 - align to byte
2 - align to word
4 - align to longword
8 - align to quadword
16 - align to octaword
A structure member is aligned to either the alignment specified
by #pragma pack or the alignment determined by the size of the
structure member, whichever is smaller. For example, a short
variable in a structure gets byte-aligned if #pragma pack 1 is
specified. If #pragma pack 2, 4, or 8 is specified, the short
variable in the structure gets aligned to word.
When #pragma pack is specified with a value of 0, packing
reverts to that specified by the /[NO]MEMBER_ALIGNMENT
qualifier setting (either explicit or default) on the command
line.
#pragma [no]standard[_m]
Directs the compiler to define regions of source code where
portability diagnostics are not to be issued.
Use #pragma nostandard to suppress diagnostics about non-ANSI C
extensions, regardless of the /STANDARD qualifier specified,
until a #pragma standard directive is encountered.
Use #pragma standard to reinstate the setting of the /STANDARD
qualifier that was in effect before before the last #pragma
nostandard was encountered.
Every #pragma standard directive must be preceded by a
corresponding #pragma nostandard directive.
Note that this pragma does not change the current mode of the
compiler or enable any extensions not already supported in that
mode.
The #undef directive cancels a previously defined macro
replacement. Any other macro replacements that occurred before the
#undef directive remain.
The #undef directive has the following syntax:
#undef identifier
[legal]
[privacy]
[GNU]
[policy]
[netiquette]
[sponsors]
[FAQ]
Polarhome, production since 1999.
Member of Polarhome portal.