The COMPILE_OPT statement allows you to give the IDL compiler information that changes some of the default rules for compiling the function or procedure within which the COMPILE_OPT statement appears.

We recommend the use of

COMPILE_OPT IDL2

in all new code intended for use in a reusable library. We further recommend the use of

COMPILE_OPT idl2, HIDDEN

in all such routines that are not intended to be called directly by regular users (e.g. helper routines that are part of a larger package).

Syntax


COMPILE_OPT opt1 [, opt2, ..., optn]

Arguments


optn

This argument can be any of the following:

  • IDL2: A shorthand way of saying:
   COMPILE_OPT DEFINT32, STRICTARR
  • DEFINT32: IDL should assume that lexical integer constants default to the 32-bit type rather than the usual default of 16-bit integers. This takes effect from the point where the COMPILE_OPT statement appears in the routine being compiled and remains in effect until the end of the routine. The following table illustrates how the DEFINT32 argument changes the interpretation of integer constants.

    Constant

    Normal Type

    DEFINT32 Type

    Without type specifier:

     

     

    42

    INT

    LONG

    '2a'x

    INT

    LONG

    42u

    UINT

    ULONG

    '2a'xu

    UINT

    ULONG

    With type specifier:

     

     

    0b

    BYTE

    BYTE

    0s

    INT

    INT

    0l

    LONG

    LONG

    42.0

    FLOAT

    FLOAT

    42d

    DOUBLE

    DOUBLE

    42us

    UINT

    UINT

    42ul

    ULONG

    ULONG

    42ll

    LONG64

    LONG64

    42ull

    ULONG64

    ULONG64

  • HIDDEN: This routine should not be displayed by HELP, unless the FULL keyword to HELP is used. This directive can be used to hide helper routines that regular IDL users are not interested in seeing.

A side-effect of making a routine hidden is that IDL will not print a “Compile module” message for it when it is compiled from the library to satisfy a call to it. This makes hidden routines appear built-in to the user.

  • LOGICAL_PREDICATE: When running this routine, from the point where the COMPILE_OPT statement appears until the end of the routine, treat any non-zero or non-NULL predicate value as “true,” and any zero or NULL predicate value as “false.”

Background

A predicate expression is an expression that is evaluated as being “true” or “false” as part of a statement that controls program execution. IDL evaluates such expressions in the following contexts:

  • IF...THEN...ELSE statements
  • ? : inline conditional expressions
  • WHILE...DO statements
  • REPEAT...UNTIL statements
  • when evaluating the result from an INIT function method to determine if a call to OBJ_NEW successfully created a new object

By default, IDL uses the following rules to determine whether an expression is true or false:

  • Integer: An integer is considered true if its least significant bit is 1, and false otherwise. Hence, odd integers are true and even integers (including zero) are false. This interpretation of integer truth values is sometimes referred to as “bitwise,” reflecting the fact that the value of the least significant bit determines the result.
  • Other: Non-integer numeric types are true if they are non-zero, and false otherwise. String and heap variables (pointers and object references) are true if they are non-NULL, and false otherwise.

The LOGICAL_PREDICATE option alters the way IDL evaluates predicate expressions. When LOGICAL_PREDICATE is set for a routine, IDL uses the following rules to determine whether an expression is true or false:

  • Numeric Types: A number is considered true if its value is non-zero, and false otherwise.
  • Other Types: Strings and heap variables (pointers and object references) are considered true if they are non-NULL, or false otherwise.

Note on the NOT Operator

When using the LOGICAL_PREDICATE compile option, you must be aware of the fact that applying the IDL NOT operator to integer data computes a bitwise negation (1’s complement), and is generally not applicable for use in logical computations. Consider the common construction:

  WHILE (NOT EOF(lun)) DO BEGIN
  ...
  ENDWHILE 

The EOF function returns 0 while the file specified by LUN has data left, and returns 1 when hits the end of file. However, the expression “NOT 1” has the numeric value ‑2. When the LOGICAL_PREDICATE option is not in use, the WHILE statement sees -2 as false; if the LOGICAL_PREDICATE is in use, ‑2 is a true value and the above loop will not terminate as desired.

The proper way to write the above loop uses the ~ logical negation operator:

  WHILE (~ EOF(lun)) DO BEGIN
  ...
  ENDWHILE 

Note that this version will work properly whether or not the LOGICAL_PREDICATE compile option is in use. Logical negation operations should always use the ~ operator in preference to the NOT operator, reserving NOT exclusively for bitwise computations.

  • NOSAVE: If this directive is set, then by default the routine will not be saved into IDL code save files. You can override this behavior by specifying the routine name as one of the input arguments to SAVE. In that case the NOSAVE compile option will be ignored.
  • OBSOLETE: If the user has !WARN.OBS_ROUTINES set to True, attempts to compile a call to this routine will generate warning messages that this routine is obsolete. This directive can be used to warn people that there may be better ways to perform the desired task.
  • STATIC: The STATIC compile option indicates that the user is allowed to call this method as a static class method. This compile option is only useful for methods and is ignored for regular functions and procedures. Note that methods marked as STATIC can also be called on an object instance as a "normal" instance method. However, if you attempt to make a static call to a method that is not marked as STATIC, you will receive a runtime error. See Creating Static Methods and Static Methods for details.
  • STRICTARR: While compiling this routine, IDL will only allow square brackets to be used to index arrays, and will not allow parentheses. If IDL encounters parentheses, it will assume that this is being used for a function call, and will add the identifier to the global function table.

Use of STRICTARR can eliminate many uses of the FORWARD_FUNCTION definition.

Note: If you have a library of legacy code that you want to convert to using brackets for array indexing, you should be careful to convert all parentheses to square brackets before turning on STRICTARR. Otherwise, because the function table is global, any other use of that name in other routines will be assumed to refer to a function call and will cause runtime errors.

Note: STRICTARR has no effect on the use of parentheses to reference structure tags using the tag index, which is not an array indexing operation. For example, no syntax error will occur when compiling the following code:

    COMPILE_OPT STRICTARR            
    mystruct = {a:0, b:1}            
    byindex_0 = mystruct.(0)            
  • STRICTARRSUBS: When IDL subscripts one array using another array as the source of array indices, the default behavior is to clip any out-of-range indices into range and then quietly use the resulting data without error. This behavior is described in Understanding Array Subscripts. Specifying STRICTARRSUBS will instead cause IDL to treat such out-of-range array subscripts within the body of the routine containing the COMPILE_OPT statement as an error. The position of the STRICTARRSUBS option within the module is not important: All subscripting operations within the entire body of the specified routine will be treated this way.

Version History


5.3

Introduced

5.6

Added STRICTARRSUBS option

6.0

Added LOGICAL_PREDICATE option

8.3 Added STATIC option

8.4

Added NOSAVE option