Go to main content
Oracle® Developer Studio 12.6: C User's Guide

Exit Print View

Updated: July 2017
 
 

6.2 Using Pragmas for Finer Control

For cases in which type-based analysis can benefit from more detail, you can use the pragmas described in this section to override the alias level in effect and specify the aliasing relationships between individual types or pointer variables in the translation unit. These pragmas provide the most benefit when the use of pointers in a translation unit is consistent with one of the available alias levels while a few specific pointer variables are used in an irregular way not allowed by one of the available levels.


Note - If you do not declare the named type or variable prior to the pragma, a warning message is issued and the pragma is ignored. The results of the program are undefined if the pragma appears after the first memory reference to which its meaning applies.

The terms listed in the following table are used in the pragma definitions.

Term
Meaning
level
Any of the alias levels listed under -xalias_level[=l].
type
Any of the following:
  • char, short, int, long, long long, float, double, long double

  • void, which denotes all pointer types

  • typedef name, which is the name of a defined type from a typedef declaration

  • struct name, which is the keyword struct followed by a struct tag name

  • union, which is the keyword union followed by a union tag name

pointer_name
The name of any variable of pointer type in the translation unit.

6.2.1 #pragma alias_level level (list)

Replace level with one of the seven alias levels: any, basic, weak, layout, strict, std, or strong. You can replace list with either a single type or pointer, or a comma-delimited list of types or pointers. For example, you can issue #pragma alias_level as follows:

  • #pragma alias_level level (type [, type])

  • #pragma alias_level level (pointer [, pointer])

This pragma specifies that the indicated alias level applies either to all of the memory references of the translation unit for the listed types, or to all of the dereferences of the translation unit where any of the named pointer variables are being dereferenced.

If you specify more than one alias level to be applied to a particular dereference, the level that is applied by the pointer name, if any, has precedence over all other levels. The level applied by the type name, if any, has precedence over the level applied by the option. In the following example, the std level applies to p if the program is compiled with #pragma alias_level set higher than any.

typedef int * int_ptr;
int_ptr p;
#pragma alias_level strong (int_ptr)
#pragma alias_level std (p)

6.2.1.1 #pragma alias (type, type [, type]…)

This pragma specifies that all the listed types alias each other. In the following example, the compiler assumes that the indirect access *pt aliases the indirect access *pf.

#pragma alias (int, float)
int *pt;
float *pf;

6.2.1.2 #pragma alias (pointer, pointer [, pointer]…)

This pragma specifies that at the point of any dereference of any of the named pointer variables, the pointer value being dereferenced can point to the same object as any of the other named pointer variables. However, the pointer is not limited to only the objects contained in the named variables and can point to objects that are not included in the list. This pragma overrides the aliasing assumptions of any applied alias levels. In the following example, any indirect accesses of p and q after the pragma are considered to alias regardless of their type.

#pragma alias(p, q)

6.2.1.3 #pragma may_point_to (pointer, variable [, variable]…)

This pragma specifies that at the point of any dereference of the named pointer variable, the pointer value being dereferenced can point to the objects that are contained in any of the named variables. However, the pointer is not limited to only the objects contained in the named variables and can point to objects that are not included in the list. This pragma overrides the aliasing assumptions of any applied alias levels. In the following example, the compiler assumes that any indirect access of *p, aliases any direct accesses a, b, and c.

#pragma alias may_point_to(p, a, b, c)

6.2.1.4 #pragma noalias (type, type [, type]…)

This pragma specifies that the listed types do not alias each other. In the following example, the compiler assumes that any indirect access of *p does not alias the indirect access *ps.

struct S {
   float f;
   ...} *ps;

#pragma noalias(int, struct S)
int *p;

6.2.1.5 #pragma noalias (pointer, pointer [, pointer]…)

This pragma specifies that at the point of any dereference of any of the named pointer variables, the pointer value being dereferenced does not point to the same object as any of the other named pointer variables. This pragma overrides all other applied alias levels. In the following example, the compiler assumes that any indirect access of *p does not alias the indirect access *q regardless of the types of the two pointers.

#pragma noalias(p, q)

6.2.1.6 #pragma may_not_point_to (pointer, variable [, variable]…)

This pragma specifies that at the point of any dereference of the named pointer variable, the pointer value being dereferenced does not point to the objects that are contained in any of the named variables. This pragma overrides all other applied alias levels. In the following example, the compiler assumes that any indirect access of *p does not alias the direct accesses a, b, or c.

#pragma may_not_point_to(p, a, b, c)

6.2.1.7 #pragma ivdep

The ivdep pragmas tell a compiler to ignore some or all loop-carried dependences on array references that it finds in a loop for purposes of optimization. This enables a compiler to perform various loop optimizations such as microvectorization, distribution, software pipelining, and so on, which would not be otherwise possible. It is used in cases where the user knows either that the dependences do not matter or that they never occur in practice.

The interpretation of #pragma ivdep directives depend upon the value of the —xivdep option.