Sun WorkShop Compiler C 5.0 User's Guide

Preprocessing Directives

This section describes assertions, pragmas, and predefined names.

Assertions

A line of the form:


#assert predicate (token-sequence) 

associates the token-sequence with the predicate in the assertion name space (separate from the space used for macro definitions). The predicate must be an identifier token.


#assert predicate 

asserts that predicate exists, but does not associate any token sequence with it.

The compiler provides the following predefined predicates by default (not in -Xc mode):


#assert
system (unix)
#assert machine (sparc)(SPARC)
#assert machine (i386)(Intel)
#assert cpu (sparc)(SPARC)
#assert cpu (i386)(Intel)

lint provides the following predefinition predicate by default (not in -Xc mode):


#assert lint (on)

Any assertion may be removed by using #unassert, which uses the same syntax as assert. Using #unassert with no argument deletes all assertions on the predicate; specifying an assertion deletes only that assertion.

An assertion may be tested in a #if statement with the following syntax:


#if #predicate(non-empty token-list) 

For example, the predefined predicate system can be tested with the following line:


#if #system(unix) 

which evaluates true.

Pragmas

Preprocessing lines of the form:


#pragma pp-tokens 

specify implementation-defined actions.

The following #pragmas are recognized by the compilation system. The compiler ignores unrecognized pragmas. Using the -v option will give a warning on unrecognized pragmas.

#pragma align integer (variable[, variable])

The align pragma makes all the mentioned variables memory aligned to integer bytes, overriding the default. The following limitations apply:

#pragma does_not_read_global_data (funcname [, funcname])

This pragma asserts that the specified list of routines do not read global data directly or indirectly. This allows for better optimization of code around calls to such routines. In particular, assignment statements or stores could be moved around such calls.

This pragma is permitted only after the prototype for the specified functions are declared. If the assertion about global access is not true, then the behavior of the program is undefined.

#pragma does_not_return (funcname [, funcname])

This pragma is an assertion to the compiler backend that the calls to the specified routines will not return. This allows the optimizer to perform optimizations consistent with that assumption. For example, register life-times will terminate at the call sites which in turn allows more optimizations.

If the specified function does return, then the behavior of the program is undefined.

This pragma is permitted only after the prototype for the specified functions are declared as the following example shows:


extern void exit(int);
#pragma does_note_return(exit);

extern void __assert(int);
#pragma does_not_return(__assert);

#pragma does_not_write_global_data (funcname [, funcname])

This pragma asserts that the specified list of routines do not write global data directly or indirectly. This allows for better optimization of code around calls to such routines. In particular, assignment statements or stores could be moved around such calls.

This pragma is permitted only after the prototype for the specified functions are declared. If the assertion about global access is not true, then the behavior of the program is undefined.

#pragma error_messages (on|off|default, tag... tag)

The error message pragma provides control within the source program over the messages issued by the C compiler and lint. For the C compiler, the pragma has an effect on warning messages only. The -w option of the C compiler overrides this pragma by suppressing all warning messages.

#pragma fini (f1[, f2...,fn])

Causes the implementation to call functions f1 to fn (finalization functions) after it calls main() routine. Such functions are expected to be of type void and to accept no arguments, and are called either when a program terminates under program control or when the containing shared object is removed from memory. As with "initialization functions," finalization functions are executed in the order processed by the link editors.

#pragma ident string

Places string in the .comment section of the executable.

#pragma init (f1[, f2...,fn])

Causes the implementation to call functions f1 to fn (initialization functions) before it calls main(). Such functions are expected to be of type void and to accept no arguments, and are called while constructing the memory image of the program at the start of execution. In the case of initializers in a shared object, they are executed during the operation that brings the shared object into memory, either program start-up or some dynamic loading operation, such as dlopen(). The only ordering of calls to initialization functions is the order in which they were processed by the link editors, both static and dynamic.

#pragma inline (funcname[, funcname])

This pragma controls the inlining of routine names listed in the argument of the pragma. The scope of this pragma is over the entire file. Only global inlining control is allowed, call-site specific control is not permitted by this pragma.

This pragma provides a suggestion to the compiler to inline the calls in the current file that match the list of routines listed in the pragma. This suggestion may be ignored under certain cases. For example, the suggestion is ignored when the body of the function is in a different module and the crossfile option is not used.

This pragma is permitted only after the prototype for the specified functions are declared as the following example shows:


static void foo(int);
static int bar(int, char *);
#pragma inline_routines(foo, bar);

#pragma int_to_unsigned (funcname)

For a function that returns a type of unsigned, in -Xt or -Xs mode, changes the function return to be of type int.

(SPARC) #pragma MP serial_loop

Refer to "Serial Pragmas" for details.

(SPARC) #pragma MP serial_loop_nested

Refer to "Serial Pragmas" for details.

(SPARC) #pragma MP taskloop

Refer to "Parallel Pragmas" for details.

#pragma no_inline (funcname[, funcname])

This pragma controls the inlining of the routine names listed in the argument of the pragma. The scope of this pragma is over the entire file. Only global inlining control is allowed, call-site specific control is not permitted by this pragma.

This pragma provides a suggestion to the compiler to not inline the calls in the current file that match the list of routines listed in the pragma.

This pragma is permitted only after the prototype for the specified functions.

(SPARC) #pragma nomemorydepend

This pragma specifies that for any iteration of a loop, there are no memory dependences. That is, within any iteration of a loop there are no references to the same memory. This pragma will permit the compiler (pipeliner) to schedule instructions, more effectively, within a single iteration of a loop. If any memory dependences exist within any iteration of a loop, the results of executing the program are undefined. The pragma applies to the next for loop within the current block. The compiler takes advantage of this information at optimization level of 3 or above.

(SPARC) #pragma no_side_effect (funcname)

funcname specifies the name of a function within the current translation unit. The function must be declared prior to the pragma. The pragma must be specified prior to the function's definition. For the named function, funcname, the pragma declares that the function has no side effects of any kind. The compiler can use this information when doing optimizations using the function. If the function does have side effects, the results of executing a program which calls this function are undefined. The compiler takes advantage of this information at optimization level of 3 or above.

#pragma optlevel (funcname[, funcname])

The value of opt specifies the optimization level for the funcname subprograms. You can assign opt levels zero, one, two three, four, and five. You can turn off optimization by setting level to 0. The funcname subprograms must be prototyped prior to the pragma.

The level of optimization for any function listed in the pragma is reduced to the value of -xmaxopt. The pragma is ignored when -xmaxopt=off.

#pragma pack(n)

Use #pragma pack(n), to affect member packing of a structure. By default, members of a structure are aligned on their natural boundaries; one byte for a char, two bytes for a short, four bytes for an integer etc. If n is present, it must be zero or a power of 2 specifying the strictest natural alignment for any structure member.

You can use #pragma pack(n) to specify a different aligned of a structure member. For example, #pragma pack(2) aligns int, long, long long, float, double, long double, and pointers on two byte boundaries instead of their natural alignment boundaries.

If n is the same or greater than the strictest alignment on your platform, (four on Intel, eight on SPARC v8, and 16 on SPARC v9), the directive has the effect of natural alignment. Also, if n is omitted, member alignment reverts to the natural alignment boundaries.

The #pragma pack(n) directive applies to all structure definitions which follow it until the next pack directive. If the same structure is defined in different translation units with different packing, your program may fail in unpredictable ways. In particular, you should not use #pragma pack(n) prior to including a header the defines the interface of a precompiled library. The recommended usage of #pragma pack(n) is to place it in your program code immediately before any structure to be packed. Follow the packed structure immediately with #pragma pack( ).

(SPARC) #pragma pipeloop(n)

This pragma accepts a positive constant integer value, or 0, for the argument n. This pragma specifies that a loop is pipelinable and the minimum dependence distance of the loop-carried dependence is n. If the distance is 0, then the loop is effectively a Fortran-style doall loop and should be pipelined on the target processors. If the distance is greater than 0, then the compiler (pipeliner) will only try to pipeline n successive iterations. The pragma applies to the next for loop within the current block. The compiler takes advantage of this information at optimization level of 3 or above.

#pragma rarely_called(funcname[, funcname])

This pragma provides a hint to the compiler backend that the specified functions are called infrequently. This allows the compiler to perform profile-feedback style optimizations on the call-sites of such routines without the overhead of a profile-collections phase. Since this pragma is a suggestion, the compiler optimizer may not perform any optimizations based on this pragma.

The #pragma rarely_called preprocessor directive is only permitted after the prototype for the specified functions are declares. The following is an example of #pragma rarely_called:


extern void error (char *message);
#pragma rarely_called(error);

#pragma redefine_extname old_extname new_extname

This pragma causes every externally defined occurrence of the name old_extname in the object code to be replaced by new_extname. As a result, the linker only sees the name new_extname at link time. If #pragma redefine_extname is encountered after the first use of old_extname, as a function definition, an initializer, or an expression, the effect is undefined. (This pragma is not supported in -Xs mode.)

When #pragma redefine_extname is available, the compiler provides a definition of the predefined macro PRAGMA_REDEFINE_EXTNAME which lets you write portable code that works both with and without #pragma redefine_extname.

The purpose of #pragma redefine_extname is to allow an efficient means of redefining a function interface when the name of the function cannot be changed. For example, when the original function definition must be maintained in a library, for compatibility with existing programs, along with a new definition of the same function for use by new programs. This can be accomplished by adding the new function definition to the library by a new name. Consequently, the header file that declares the function uses #pragma redefine_extname so that all of the uses of the function are linked with the new definition of that function.


#if    defined(__STDC__)

#ifdef __PRAGMA_REDEFINE_EXTNAME
extern int myroutine(const long *, int *);
#pragma redefine_extname myroutine __fixed_myroutine
#else /* __PRAGMA_REDEFINE_EXTNAME */

static int
myroutine(const long * arg1, int * arg2)
{
    extern int __myroutine(const long *, int*);
    return (__myroutine(arg1, arg2));
}
#endif /* __PRAGMA_REDEFINE_EXTNAME */

#else /* __STDC__ */

#ifdef __PRAGMA_REDEFINE_EXTNAME
extern int myroutine();
#pragma redefine_extnmae myroutine __fixed_myroutine
#else /* __PRAGMA_REDEFINE_EXTNAME */

static int
myroutine(arg1, arg2)
    long *arg1;
    int *arg2;
{
    extern int __fixed_myroutine();
    return (__fixed_myroutine(arg1, arg2));
}
#endif /* __PRAGMA_REDEFINE_EXTNAME */

#endif /* __STDC__ */

#pragma returns_new_memory (funcname[, funcname])

This pragma asserts that the return value of the specified functions does not alias with any memory at the call site. In effect, this call returns a new memory location. This informations allows the optimizer to better track pointer values and clarify memory location. This results in improved scheduling, pipelining, and parallelization of loops. However, if the assertion is false, the behavior of the program is undefined.

This pragma is permitted only after the prototype for the specified functions are declared as the following example shows:


void *malloc(unsigned);
#pragma returns_new_memory(malloc);

#pragma unknown_control_flow (name[, name])

Specifies a list of routines that violate the usual control flow properties of procedure calls. For example, the statement following a call to setjmp() can be reached from an arbitrary call to any other routine. The statement is reached by a call to longjmp(). Since such routines render standard flowgraph analysis invalid, routines that call them cannot be safely optimized; hence, they are compiled with the optimizer disabled.

(SPARC) #pragma unroll (unroll_factor)

This pragma accepts a positive constant integer value for the argument unroll_factor. The pragma applies to the next for loop within the current block. For unroll factor other than 1, this directive serves as a suggestion to the compiler that the specified loop should be unrolled by the given factor. The compiler will, when possible, use that unroll factor. When the unroll factor value is 1, this directive serves as a command which specifies to the compiler that the loop is not to be unrolled. The compiler takes advantage of this information at optimization level of 3 or above.

#pragma weak (symbol1 [= symbol2])

Defines a weak global symbol. This pragma is used mainly in source files for building libraries. The linker does not produce an error message if it is unable to resolve a weak symbol.


#pragma weak symbol

defines symbol to be a weak symbol. The linker does not produce an error message if it does not find a definition for symbol.


#pragma weak symbol1 = symbol2

defines symbol1 to be a weak symbol, which is an alias for the symbol symbol2. This form of the pragma can only be used in the same translation unit where symbol2 is defined, either in the sourcefiles or one of its included headerfiles. Otherwise, a compilation error will result.

If your program calls but does not define symbol1, and symbol1 is a weak symbol in a library being linked, the linker uses the definition from that library. However, if your program defines its own version of symbol1, then the program's definition is used and the weak global definition of symbol1 in the library is not used. If the program directly calls symbol2, the definition from the library is used; a duplicate definition of symbol2 causes an error.

Predefined Names

The following identifier is predefined as an object-like macro:

Table 3-4 Predefined Identifier

Identifier 

Description 

 __STDC__

__STDC__ 1 -Xc 

__STDC__ 0 -Xa, -Xt 

Not defined -Xs

The compiler will issue a warning if __STDC__ is undefined (#undef __STDC__). __STDC__ is not defined in -Xs mode.

Predefinitions (not valid in -Xc mode):

The following predefinitions are valid in all modes:

The compiler also predefines the object-like macro _ _PRAGMA_REDEFINE_EXTNAME

to indicate that the pragma will be recognized.

The following is predefined in -Xa and -Xt modes only:

_ _RESTRICT