Sun Studio 12: C User's Guide

2.8 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 for unrecognized pragmas.

2.8.1 align

#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 align 64 (aninteger, astring, astruct)
int aninteger;
static char astring[256];
struct astruct{int a; char *b;};

2.8.2 c99

#pragma c99(“implicit” | “no%implicit”)

This pragma controls diagnostics for implicit function declarations. If the c99 pragma value is set to “implicit”, note the use of quotation marks, a warning is generated when the compiler finds an implicit function declaration. If the c99 pragma value is set to “no%implicit”, note the use of quotation marks, the compiler silently accepts implicit function declaration until the pragma value is reset.

The value of the -xc99 option impacts this pragma. If -xc99=all, the pragma is set to #pragma c99(“implicit”) and when -xc99=none, the pragma is set to #pragma c99(“no%implicit”).

This pragma is set to c99=(“implicit”) by default.

2.8.3 does_not_read_global_data

#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.

The specified functions must be declared with a prototype or empty parameter list prior to this pragma. If the assertion about global access is not true, then the behavior of the program is undefined.

2.8.4 does_not_return

#pragma does_not_return (funcname [, funcname])

This pragma is an assertion to the compiler that the calls to the specified routines will not return. This allows the compiler 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 specified functions are declared with a prototype or empty parameter list as the following example shows:


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

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

2.8.5 does_not_write_global_data

#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.

The specified functions must be declared with a prototype or empty parameter list prior to this pragma. If the assertion about global access is not true, then the behavior of the program is undefined.

2.8.6 error_messages

#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.

2.8.7 fini

#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.

You should be careful when a finalization function affects the global-program state. For example, unless an interface explicitly states what happens when you use a system-library finalization-function, you should capture and restore any global state information, such as the value of errno, that the system-library finalization-function may change.

2.8.8 hdrstop

#pragma hdrstop

The hdrstop pragma must be placed after the last header file to identify the end of the viable prefix in each source file that is to share the same precompiled-header file. For example, consider the following files:


example% cat a.c
#include "a.h"
#include "b.h"
#include "c.h"
#include <stdio.h>
#include "d.h"
.
.
.
example% cat b.h
#include "a.h"
#include "b.h"
#include "c.h"

The viable source prefix ends at c.h so you would insert a #pragma hdrstop after c.h in each file.

#pragma hdrstop must only appear at the end of the viable prefix of a source file that is specified with the cc command. Do not specify #pragma hdrstop in any include file.

2.8.9 ident

#pragma ident string

Places string in the .comment section of the executable.

2.8.10 init

#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.

You should be careful when an initialization function affects the global-program state. For example, unless an interface explicitly states what happens when you use a system-library initialization-function, you should capture and restore any global state information, such as the value of errno, that the system-library initialization-function may change.

2.8.11 inline

#pragma [no_]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.

If you use #pragma inline, it 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.

If you use #pragma no_inline, it 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.

Both #pragma inline and #pragma no_inline are permitted only after the function is declared with a prototype or empty parameter list as the following example shows:


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

See also -xldscope, -xinline, -xO, and -xcrossfile.

2.8.12 int_to_unsigned

#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.

2.8.13 MP serial_loop

(SPARC) #pragma MP serial_loop


Note –

The Sun-specific MP pragmas have been deprecated and are no longer supported. However, the compiler supports the APIs specified by the OpenMP 2.5 standard instead. See the OpenMP API User’s Guide for migration information to the directives of the standard.


Refer to 3.8.3.1 Serial Pragmas for details.

2.8.14 MP serial_loop_nested

(SPARC) #pragma MP serial_loop_nested


Note –

The Sun-specific MP pragmas have been deprecated and are no longer supported. However, the compiler supports the APIs specified by the OpenMP 2.5 standard instead. See the Sun Studio 12: OpenMP API User’s Guidefor migration information to the directives of the standard.


Refer to 3.8.3.1 Serial Pragmas for details.

2.8.15 MP taskloop

(SPARC) #pragma MP taskloop


Note –

The Sun-specific MP pragmas have been deprecated and are no longer supported. However, the compiler supports the APIs specified by the OpenMP 2.5 standard instead. See the OpenMP API User’s Guide for migration information to the directives of the standard.


Refer to 3.8.3.2 Parallel Pragma for details.

2.8.16 nomemorydepend

(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 compiler takes advantage of this information at optimization level of 3 or above.

The scope of this pragma begins with the pragma and ends with which ever of the following occurs first: the beginning of the next block, the next for loop within the current block, the end of the current block. The pragma applies to the next for loop prior to the end of the pragmas scope.

2.8.17 no_side_effect

(SPARC) #pragma no_side_effect(funcname[, funcname…])

funcname specifies the name of a function within the current translation unit. The function must be declared with a prototype or empty parameter list 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. This means that funcname returns a result value that depends only on the passed arguments. In addition, funcname and any called descendants:

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.

2.8.18 opt

#pragma opt level (funcname[, funcname])

funcname specifies the name of a function defined within the current translation unit. The value of level specifies the optimization level for the named function. You can assign optimization levels 0, 1, 2, 3, 4, 5. You can turn off optimization by setting level to 0. The functions must be declared with a prototype or empty parameter list prior to the pragma. The pragma must proceed the definitions of the functions to be optimized.

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.

2.8.19 pack

#pragma pack(n)

Use #pragma pack(n)to affect member packing of a structure or a union. By default, members of a structure or union 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 a power of 2 specifying the strictest natural alignment for any structure or union member. Zero is not accepted.

You can use #pragma pack(n) to specify an alignment boundary for a structure or union 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 x86, 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 or union definitions which follow it until the next pack directive. If the same structure or union 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 that 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 or union to be packed. Follow the packed structure immediately with #pragma pack( ).

Note that when you use #pragma pack, the alignment of the packed structure or union itself is the same as its more strictly aligned member. Therefore any declaration of that struct or union will be at the pack alignment. For example, a struct with only chars has no alignment restrictions, whereas a struct containing a double would be aligned on an 8-byte boundary.


Note –

If you use #pragma pack to align struct or union members on boundaries other than their natural boundaries, accessing these fields usually leads to a bus error on SPARC. In order to avoid such an error, be sure to also specify the -xmemalign option. See B.2.111 -xmemalign=ab , for the optimal way to compile such programs.


2.8.20 pipeloop

(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 pipelineable 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 compiler takes advantage of this information at optimization level of 3 or above.

The scope of this pragma begins with the pragma and ends with which ever of the following occurs first: the beginning of the next block, the next for loop within the current block, the end of the current block. The pragma applies to the next for loop prior to the end of the pragmas scope.

2.8.21 rarely_called

#pragma rarely_called(funcname[, funcname])

This pragma provides a hint to the compiler 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 may not perform any optimizations based on this pragma.

The specified functions must be declared with a prototype or empty parameter list prior to this pragma. The following is an example of #pragma rarely_called:


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

2.8.22 redefine_extname

#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_extname 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__ */

2.8.23 returns_new_memory

#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 specified functions are declared with a prototype or empty parameter list as the following example shows:


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

2.8.24 unknown_control_flow

#pragma unknown_control_flow (funcname[, funcname])

In order to describe procedures that alter the flow graphs of their callers, the C compiler provides the #pragma unknown_control_flow directive. Typically, this directive accompanies declarations of functions like setjmp(). On Sun systems, the include file <setjmp.h> contains the following:


extern int setjmp();
#pragma unknown_control_flow(setjmp)

Other functions with properties like those of setjmp() must be declared similarly.

In principle, an optimizer that recognizes this attribute could insert the appropriate edges in the control flow graph, thus handling function calls safely in functions that call setjmp(), while maintaining the ability to optimize code in unaffected parts of the flow graph.

The specified functions must be declared with a prototype or empty parameter list prior to this pragma.

2.8.25 unroll

(SPARC) #pragma unroll (unroll_factor)

This pragma accepts a positive constant integer value for the argument unroll_factor. 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.

The scope of this pragma begins with the pragma and ends with which ever of the following occurs first: the beginning of the next block, the next for loop within the current block, the end of the current block. The pragma applies to the next for loop prior to the end of the pragmas scope.

2.8.26 warn_missing_parameter_info

#pragma [no_]warn_missing_parameter_info

When you specify #pragma warn_missing_parameter_info, the compiler issues a warning for a function call whose function declaration contains no parameter type information. Consider the following example:


exmaple% cat -n t.c
     1    #pragma warn_missing_parameter_info
     2    
     3    int foo();
     4    
     5    int bar () {
     6    
     7       int i;
     8    
     9       i = foo(i);
    10    
    11       return i;
    12    }
% cc t.c -c -errtags
"t.c", line 9: warning: function foo has no prototype (E_NO_MISSED_PARAMS_ALLOWED)
example%

#pragma no_warn_missing_parameter_info turns off the effect of any previous #pragma warn_missing_parameter_info.

By default, #pragma no_warn_missing_parameter_info is in effect.

2.8.27 weak

#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.