Home Page

Visual Fortran graphic Compaq Visual Fortran Version 6.6

Home Page

Compaq Visual Fortran (also referred to as Visual Fortran; previously called DIGITAL Visual Fortran) includes the following online documentation:

  • Programmer's Guide
  • Language Reference
  • Error Messages

©2001 Compaq Computer Corporation

For information on new features, see New Features for Compaq Visual Fortran Version 6.6.

For more information on Compaq Visual Fortran, see http://www.compaq.com/fortran.

Compaq Fortran provides an Web site that offers timely and comprehensive information about all Compaq Fortran products, including product features, frequently asked questions, technical support, and other information.

For information on IMSL routines and CXML routines, see The IMSL Routines and CXML Routines Online PDF Documentation.

Related Home Pages:

Compaq Array Visualizer

Visual C++ User's Guide (for Visual Fortran)


Copyright Information

Confidential computer software. Valid license from Compaq required for possession, use or copying. Consistent with FAR 12.211 and 12.212, Commercial Computer Software, Computer Software Documentation, and Technical Data for Commercial Items are licensed to the U.S. Government under vendor's standard commercial license.

Compaq shall not be liable for technical or editorial errors or omissions contained herein. The information in this document is provided "as is" without warranty of any kind and is subject to change without notice. The warranties for Compaq products are set forth in the express limited warranty statements accompanying such products. Nothing herein should be construed as constituting an additional warranty.

© 2001 Compaq Computer Corporation

Visual Fortran Home Page, Photographic images: Copyright © 1997 PhotoDisc, Inc.

Visual Fortran Home Page, Image: CERN, European Laboratory for Particle Physics: ALICE detector on CERN's future accelerator, the LHC, Large Hadron Collider.

Compaq, the COMPAQ logo, DEC, DEC Fortran, DIGITAL, OpenVMS, Tru64, VAX, VAX FORTRAN, and VMS are trademarks of Compaq Information Technologies Group, L.P. in the United States and other countries.

ActiveX, Microsoft, Microsoft Press, MS-DOS, PowerPoint, Visual Basic, Visual C++, Visual J++, Visual Studio, Win32, Win32s, Windows, and Windows NT are trademarks of Microsoft Corporation in the United States and other countries.

Intel and Pentium are trademarks of Intel Corporation in the United States and other countries.

AMD and Athlon are trademarks of Advanced Micro Devices, Inc.

Borland and Delphi are trademarks of Borland Software Corporation.

CRAY is a registered trademark of Cray Research, Inc.

IBM is a registered trademark of International Business Machines, Inc.

IEEE is a registered trademark of the Institute of Electrical and Electronics Engineers, Inc.

IMSL and Visual Numerics are registered trademarks of Visual Numerics, Inc.

Linux is a registered trademark of Linus Torvalds.

OpenGL is a registered trademark of Silicon Graphics, Inc.

OpenMP and the OpenMP logo are trademarks of OpenMP Architecture Review Board.

Sun Microsystems is a registered trademark and Java is a trademark of Sun Microsystems, Inc.

UNIX is a trademark of the Open Group in the United States and other countries.

All other product names mentioned herein may be trademarks of their respective companies.


New Features for Compaq Visual Fortran Version 6.6

New features added to Compaq Visual Fortran (Visual Fortran) Version 6.6 (since Visual Fortran Version 6.5 and 6.5A) include the following:

  • Support has been added for 8-byte integer and 8-byte logical intrinsic data types.
  • The Windows API interface header files DFWINTY.F90 and DFWIN.F90 (and its component files) have been extensively revised to work in both a 32-bit and a 64-bit environment.
  • A new version of the Compaq Extended Math Library (CXML) is included with Visual Fortran Version 6.6. CXML Version 5.0 includes improved performance for many CXML routines, a new set of routines for solving sparse matrix problems using direct methods, sample files that show how to invoke the direct sparse solver routines from Fortran and C, changes to certain sparse iterative solver functions, changes in how messages can be printed with the iterative solver functions (including changes to the argument iounit), and other changes. The skyline solver routines are no longer supported. The auxiliary LAPACK routine XLAENV is no longer supplied by CXML; instead, the LAPACK routines DLAMCH and SLAMCH have been modified to return compile-time constants instead of computing values on each call.
  • The types of Visual Fortran run-time libraries displayed in the visual development environment Fortran tab (Project menu, Settings dialog box) more closely match the run-time libraries available in Visual C++ (C/C++ tab). Also, the types of run-time libraries linked against while linking against debug versionsof DLL libraries have changed, as described in Visual Fortran/Visual C++ Mixed-Language Programs and Specifying Consistent Library Types.
  • The following new graphics functions let you draw Bezier curves (based on fitting a cubic curve to four points):
    • POLYBEZIER and POLYBEZIER_W
    • POLYBEZIERTO and POLYBEZIERTO_W
  • The following compiler options have changed or have been added:
    • /annotations now provides information about optimizations in a listing file.
    • /architecture and /tune options now support the pn4 keyword for Pentium 4 systems. In addition, the pn1, pn2, and pn3 keywords have been added (pn is an abbreviation for Pentium) as the preferred keywords in place of p5, p6, and p6p.
    • The /ccdefault:default option now allows other options, such as /vms, to set the default carriage control.
    • The keyword /fpscomp:ldio_spacing, for list-directed output, controls whether a blank is inserted at run-time after a numeric value before a character value. This option is set by /fpscomp:general.
    • /integer_size now supports a value of 64 to allow INTEGER and LOGICAL declarations to be treated as 8 bytes long (KIND=8).
    • Specifying the /stand option (without keywords) now sets /stand:f95 (Fortran 95 standards checking) instead of /stand:f90 (Fortran 90 standards checking).
    • If you specify /fast with /stand, /align:dcommons and /align:sequence (usually set by /fast) are not set.
  • A derived-type variable that is data initialized via default initialization of any of its components will no longer be saved by default. A RECORD variable that is data initialized via default initialization specified in its STRUCTURE declaration will no longer be saved by default.
  • The Fortran preprocessor fpp supports the macros __DATE__ and __FILE__. When you request that fpp expand macros using "-fpp:-m", these expand into character literals that give the name of the source file being processed and the current date/time respectively.
  • For additional new features and details, see the online release notes (relnotes.txt or relnotes.htm).
  • New or significantly revised sections in the Programmer's Guide include Copying Projects and Viewing Fortran Data Types in the Debugger.

Beginning with Version 6.6, Visual Fortran no longer supports Windows NT Alpha systems.

Changes to Compaq Array Visualizer are described separately in the Array Visualizer HTML Help documentation.


Introduction to the Programmer's Guide

The Programmer's Guide contains the following information:

  • How to build and debug efficient applications:

    • Building Programs and Libraries
    • Using the Compiler and Linker from the Command Line
    • Compiler and Linker Options
    • Debugging Fortran Programs
    • Performance: Making Programs Run Faster

  • Special coding and related considerations for certain Visual Fortran project types:

    • Using QuickWin
    • Creating Fortran DLLs
    • Creating Windows Applications

  • Topics about programming with Visual Fortran on Windows® 2000, Windows NT® 4.0, Windows Me, Windows 98, and Windows 95 systems:

    • Portability and Design Considerations
    • Using Dialogs
    • Drawing Graphics Elements
    • Using Fonts from the Graphics Library
    • Using National Language Support Routines
    • Portability Library
    • Files, Devices, and I/O Hardware
    • Using COM and Automation Objects
    • Creating a COM Server
    • Programming with Mixed Languages
    • Creating Multithread Applications

  • Topics related to data types and handling run-time errors:

    • Data Representation
    • Handling Run-Time Errors
    • The Floating-Point Environment
    • Advanced Exception and Termination Handling Considerations
    • Converting Unformatted Numeric Data
    • Hexadecimal-Binary-Octal-Decimal Conversions

  • Topics discussing how to use IMSL® and CXML library routines:

    • Using the IMSL Mathematical and Statistical Libraries
    • Using the Compaq Extended Math Library (CXML)

  • Topics discussing compatibility and tools:

    • Compatibility Information
    • Using Visual Fortran Tools

Note: Visual Fortran contains many extensions to the full ANSI/ISO standard language. In this book, the Visual Fortran extensions to the Fortran 95 standard appear in this color.


Programmer's Guide Conventions

This section discusses the following:

  • General Conventions
  • Syntax Conventions
  • Platform labels

General Conventions

The Programmer's Guide uses the following general conventions. (Note that in most cases, blanks are not significant in Fortran 90 or 95.)

When You See This | Here Is What It Means
Extensions to Fortran 95 | Dark teal type indicates extensions to the Fortran 95 Standard. These extensions may or may not be implemented by other compilers that conform to the language standard.
DF, LINK, FL32 | Uppercase (capital) letters indicate filenames and MS®-DOS®-level commands used in the command console.
expression | Words in italics indicate placeholders for information that you must supply. A file-name is an example of this kind of information. Italics are also used to introduce new terms.
[optional item] | Items inside single square brackets are optional. In some examples, square brackets are used to show arrays.
{choice1 | choice2} | Braces and a vertical bar indicate a choice among two or more items. You must choose one of the items unless all of the items are also enclosed in square brackets.

s[, s]...
A horizontal ellipsis (three dots) following an item indicates that the item preceding the ellipsis can be repeated. In code examples, a horizontal ellipsis means that not all of the statements are shown.
compiler option | This term refers to Windows options, OpenVMS qualifiers, and Tru64 UNIX and Linux options that can be used on the compiler command line.
!  Comment line
WRITE (*,*) 'Hello &
&World'
This kind of type is used for program examples, program output, and error messages within the text. An exclamation point marks the beginning of a comment in sample programs. Continuation lines are indicated by an ampersand ( & ) after the code at the end of a line to be continued and before the code on the following line.
AUTOMATIC, INTRINSIC, WRITE Bold capital letters indicate Compaq® Fortran statements, functions, subroutines, and keywords. Keywords are a required part of statement syntax, unless enclosed in brackets as explained above.
In the sentence, "The following steps occur when a DO WHILE statement is executed," the phrase DO WHILE is a Compaq Fortran keyword.
Bold lowercase letters are used for keywords of other languages. In the sentence, "A Fortran subroutine is the equivalent of a function of type void in C," the word void is a keyword of C.
Fortran | This term refers to language information that is common to ANSI FORTRAN 77, ANSI/ISO Fortran 95 and 90, and Compaq Fortran (formerly DIGITAL Fortran).
Fortran 95/90 | This term refers to language information that is common to ANSI/ISO Fortran 95 and ANSI/ISO Fortran 90.
Fortran 95 | This term refers to language information that is common to ANSI/ISO Fortran 95.
Fortran 90 | This term refers to language information that is common to ANSI/ISO Fortran 90.
Compaq Fortran, DIGITAL Fortran | These terms refer to the same language.
OpenVMS, VMS | These terms refer to the same operating system.
Tru64 UNIX, DIGITAL UNIX | These terms refer to the same operating system.
Windows systems | This term refers to all supported Microsoft® Windows® operating systems. (See labels WNT and W9* in Platform Labels below.)
integer | This term refers to the INTEGER(KIND=1), INTEGER(KIND=2), INTEGER (INTEGER(KIND=4)), and INTEGER(KIND=8) data types as a group.
real | This term refers to the REAL (REAL(KIND=4)) and DOUBLE PRECISION (REAL(KIND=8)) data types as a group.
complex | This term refers to the COMPLEX (COMPLEX(KIND=4)), DOUBLE COMPLEX (COMPLEX(KIND=8)), and COMPLEX(KIND=16) data types as a group.
logical | This term refers to the LOGICAL(KIND=1), LOGICAL(KIND=2), LOGICAL (LOGICAL(KIND=4)), and LOGICAL(KIND=8) data types as a group.

Syntax Conventions

The Programmer's Guide uses certain conventions for language syntax. For example, consider the following syntax for the PARAMETER statement:

PARAMETER [(] c = expr [, c = expr ]...[)]

This syntax shows that to use this statement, you must specify the following:

  • The keyword PARAMETER
  • An optional left parenthesis
  • One or more c=expr items, where c is a named constant and expr is a value; note that a comma must appear between c=expr items.
    The three dots following the syntax means you can enter as many c=expr items as you like.
  • An optional terminating right parenthesis

The dark teal brackets ([ ]) indicate that the optional parentheses are an extension to standard Fortran.

Platform Labels

A platform is a combination of operating system and central processing unit (CPU) that provides a distinct environment in which to use a product (in this case, a language). For example, Microsoft® Windows® 98 on x86 is a platform.

Information applies to all supported platforms unless it is otherwise labeled for a specific platform (or platforms), as follows:

VMS | Applies to OpenVMSTM on Alpha processors.
U*X | Applies to Tru64 UNIX® and Linux® on Alpha processors.
TU*X | Applies to Tru64 UNIX® on Alpha processors.
WNT | Applies to Microsoft 2000 and Windows NT® 4.0 operating systems on AMD and Intel® x86 processors, and 64-bit Windows operating systems on Intel IA-64 processors.
W9* | Applies to Microsoft Windows 98, Windows Millennium Edition (Me), and Windows 95 operating systems on AMD and Intel x86 processors.
Alpha | Applies to operating systems on Alpha processors.
ia32 | Applies to 32-bit Windows operating systems on AMD and Intel x86 processors (see "System Requirements and Optional Software" in Compaq Visual Fortran Installing and Getting Started).
ia64 | Applies to 64-bit Windows operating systems on IA-64 processors.


Building Programs and Libraries

Visual Fortran includes the Microsoft visual development environment (also used by the same version of Visual C++®) and associated Visual Studio software development tools. This industry-leading environment makes it easy for you to create, debug, and execute your programs. It includes a full-feature text editor, debugger, and interactive help. You can build your source code into several types of programs and libraries, either using the visual development environment or working from the command line. For an introduction to this environment, see Compaq Visual Fortran Installing and Getting Started.

This section describes how to use the visual development environment to define a project, open and close a project workspace, and build a project:

  • Overview of Building Projects
  • Types of Projects you can build
  • Defining Your Project and selecting project features with the visual development environment
  • Errors During the Build Process
  • Compiler Limits
  • Running Fortran Applications
  • Copying Projects
  • Visual Fortran Samples

For more information on:

  • Building programs and libraries at the command line, see: Using the Compiler and Linker from the Command Line and Using Visual Fortran Tools.
  • Using the Debugger, see Debugging Fortran Programs.
  • Details about using the development environment, see the Visual C++ User's Guide.


Overview of Building Projects

The Microsoft Visual C++TM Development Environment (also called Developer Studio) organizes development into projects. A project consists of the source files required for your application, along with the specifications for building the project. The build process involves defining your project, setting options for it, and building the program or library.

Each project can specify one or more configurations to build from its source files. A configuration specifies such things as the type of application to build, the platform on which it is to run, and the tool settings to use when building. Having multiple configurations lets you extend the scope of a project but still maintain a consistent source code base from which to work.

When you create a new project, the Microsoft visual development environment automatically creates Debug and Release configurations for you. The default configuration is the Debug configuration. To specify the current configuration, select Set Active Configuration from the Build menu.

Projects are contained in a workspace. When you create a new project, you indicate whether the project is created in a new workspace or an existing workspace. To open an existing project, you open its workspace. A workspace can contain multiple projects.

Once you open a workspace, the development environment displays a FileView pane, which displays the files contained in the project, and lets you examine visually the relationships among the files in your project. Modules, include files, or special libraries your program uses are automatically listed as dependencies. The output window displays information produced by the compiler, linker, Find in Files utility, and the profiler.

You can specify build options in the Project menu Settings dialog box, for one of the following:

  • The entire project
  • For certain configurations
  • For certain files

For example, you can specify certain kinds of compiler optimizations for your project in general, but turn them off for certain configurations or certain files.

Once you have specified the files in your project, the configurations that your project is to build, and the tool settings for those configurations, you can build the project with the commands on the Build menu.

In addition to using the visual development environment, you can also use the command line (DF command). You can also develop the application from the visual development environment and export a makefile for use in command-line processing (NMAKE command). Your choice of development environment determines what you can do at each stage.

The following diagram illustrates the development process for using the visual development environment or command line:

Example of Development Process

Notes in the diagram point to places where you can read more about a particular part of the development process:

  1. Building Programs and Libraries (the current chapter)
  2. Using the Compiler and Linker from the Command Line
  3. Using Visual Fortran Tools
  4. The Floating-Point Environment and Handling Run-Time Errors
  5. Debugging Fortran Programs
  6. Profiling Code from the Command Line
  7. Analyze Program Performance

For more overview information about building projects with the visual development environment, see:

  • How Information Is Displayed
  • Menu Options
  • Using the Shortcut Menu


How Information Is Displayed

The Microsoft visual development environment displays information in windows, panes, and folders. One window can contain several panes, and each pane can display one or more folders. A pane is a separate and distinct area of a window; a folder is a visual representation of files in a project. Folders show the order in which Visual Fortran compiles the files, and the relationship of source files to their dependent files, such as modules.

When you initially create a project, the Project Workspace window contains some default panes, accessible through tabs at the bottom of the window, to display information about the content of the project. You can also open an output window, which has panes that display build output, debug output, Find in Files output, and profiler output. In addition to the default panes, you can create customized panes to organize and display project information in ways most useful to you.

You can access information about components of the project from the panes in the project window. Double-clicking any item in a pane displays that item in an appropriate way: source files in a text editor, dialog boxes in the dialog editor, help topics in the information window, and so on.

Be sure to select the appropriate pane when using the menu commands, in particular the Save and Save As commands. Commands on the File menu affect only the window that currently has the focus.


Menu Options

Menu options that are available to you may look different, depending on which window or pane has current focus. The Debug menu, for example, is only visible when you are debugging.

The visual development environment has the following menu bars and toolbars:

  • Standard menu bar
  • Standard toolbar
  • Build toolbar
  • Build minibar
  • Resource toolbar
  • Edit toolbar
  • Debug toolbar
  • Browse toolbar
  • Fortran toolbar
  • Controls toolbar

To select or deselect the menu bars and toolbars:

  • In the Tools menu, click Customize item
  • Click the Toolbar tab
  • Select (click) the toolbar name


Using the Shortcut Menu

The project window has a shortcut menu that lists commands appropriate for the current selection in the window. This is a quick method to display commands that are also available from the main menu bar.

To display the shortcut menu:

  • Move the mouse pointer into the project window and click the right mouse button.

You can now select project commands that are appropriate for your current selection in the project window.


Types of Projects

When you create the project, you must choose a project type. You need to create a project for each binary executable file to be created. For example, the main Fortran program and a Fortran dynamic-link library (DLL) would each reside in the same workspace as separate projects.

The project type specifies what to generate and determines some of the options that the visual development environment sets by default for the project. It determines, for instance, the options that the compiler uses to compile the source files, the static libraries that the linker uses to build the project, the default locations for output files, defined constants, and so on.

You can build seven kinds of projects with Visual Fortran. You specify the project type when you create a new project. They are summarized in the following table:

Project Type | Key Features
Fortran Console Application (.EXE) | Single window main projects without graphics (resembles character-cell applications). Requires no special programming expertise. For a Visual Fortran Sample of a Console Application, see ...\COMMON\MSdev98\MYPROJECTS\CELSIUS, as described in "Opening an Existing Project" in Compaq Visual Fortran Installing and Getting Started.
Fortran Standard Graphics Application (.EXE) | Single window main projects with graphics. The programming complexity is simple to moderate, depending on the graphics and user interaction used. Samples of Standard Graphics Applications (QuickWin single window) resemble those for QuickWin Applications (see below).
Fortran QuickWin Application(.EXE) | Multiple window main projects with graphics. The programming complexity is simple to moderate, depending on the graphics and user interaction used. Samples of QuickWin Applications (QuickWin multiple window) are in ...\DF98\SAMPLES\QUICKWIN, such as QWPIANO and QWPAINT.
Fortran Windows Application (.EXE) | Multiple window main projects with full graphical interface and access to all Win32 API routines. Requires advanced programming expertise and knowledge of the Win32 routines. Samples of Win32 Applications are in ...\DF98\SAMPLES\ADVANCED\Win32, such as PLATFORM or POLYDRAW.
Fortran COM Server (.DLL) | Uses the Component Object Model (COM) to implement a COM server. COM supports client-server interaction between a user of an object, the client, and the implementor of the object, the server. Clients may be written in Visual Fortran using the Fortran Module Wizard or in other languages, such as Visual C++ and Visual Basic. Requires advanced knowledge of COM. Samples of Fortran COM Server (and COM client) applications are in ...\DF98\SAMPLES\ADVANCED\COM, such as Adder.
Fortran Static library (.LIB) | Library routines to link into .EXE files.
Fortran Dynamic-Link Library (.DLL) | Library routines to associate during execution.

The first four projects listed in the preceding table are main project types, requiring main programs. The last two are library projects, without main programs. The project types are discussed in detail in:

  • Fortran Console Application
  • Fortran Standard Graphics Application
  • Fortran QuickWin Application
  • Fortran Windows Application
  • Fortran COM Server
  • Fortran Static library
  • Fortran Dynamic-Link Library

When migrating legacy applications, choosing a project type that will minimize porting effort depends on what the application does. A character-cell application that does not use any graphics (such as a program ported from a UNIX system) can usually be converted into a Fortran Console Application. When a legacy Windows 3.1 (or older) application uses graphics calls, you can try a Fortran Standard Graphics Application or a Fortran QuickWin Application project type. However, be aware that with such legacy graphics applications:

  • The routine names of certain legacy graphic QuickWin routines might need to be changed to the current routine names (and their current argument lists). For example, the following table lists some of known obsolete routines and their supported replacement routines:
    Obsolete QuickWin Routine | Replacement Routine
    SETGTEXTVECTOR | SETGTEXTROTATION
    GETGTEXTVECTOR | GETGTEXTROTATION
    GETHANDLEQQ | GETHWNDQQ
    WGGETACTIVE | GETACTIVEQQ
    WGSETACTIVE | SETACTIVEQQ
    INITIALMENU | INITIALSETTINGS
    SETTEXTROWS | SETWINDOWCONFIG

  • The character-oriented method of user interaction can be modernized with menus, mouse clicks, and dialog boxes. If the routine uses the PEEKCHARQQ routine, see the PEEKAPP or PEEKAPP3 Visual Fortran Samples in the QuickWin folder.

After you select your project type, you need to define your project (see Defining Your Project).

If you need to use the command line to build your project, you can:

  • Initially use the visual development environment and later create a makefile (see The Project Makefile)
  • Use the DF command compiler options to specify the project type (see Specifying Project Types with DF Command Options)
  • Create the application from the DF command line (see Using the Compiler and Linker from the Command Line)


Fortran Console Application Projects

A Fortran Console application (.EXE) is a character-based Visual Fortran program that does not require screen graphics output. It looks similar to a program running on a UNIX® workstation or a terminal connected to a mainframe computer.

Fortran Console projects operate in a single window, and let you interact with your program through normal read and write commands. Console applications are better suited to problems that require pure numerical processing rather than graphical output or a graphical user interface. This type of application is also more transportable to other platforms than the other types of application.

Fortran Console applications can be faster than Fortran Standard Graphics or Fortran QuickWin graphics applications, because of the resources required to display graphical output (see Using the Console).

Any graphics routine that your program calls will produce no output, but will return error codes. A program will not automatically exit if such an error occurs, so your code should be written to handle this condition.

With a Fortran Console project, you can use static libraries, DLLs, and dialog boxes, but you cannot use the QuickWin functions. You can select the multithreaded libraries with this and all of the other Fortran project types.

As with all Windows command consoles, you can toggle between viewing the console in a window or in full-screen mode by using the ALT+ENTER key combination.

A sample Fortran Console project is Celsius (see \MYPROJECTS\CELSIUS), as described in "Opening an Existing Project" in Compaq Visual Fortran Installing and Getting Started or Defining Your Project.


Fortran Standard Graphics Application Projects

A Fortran standard graphics application (.EXE) is a Visual Fortran QuickWin program with graphics that runs in a single QuickWin window. A standard graphics (QuickWin single document) application looks similar to an MS-DOS program when manipulating the graphics hardware directly, without Windows.

A Fortran standard graphics application allows graphics output (such as drawing lines and basic shapes) and other screen functions, such as clearing the screen. Standard Graphics is a subset of Quickwin, sometimes called Quickwin single window. You can use all of the QuickWin graphics functions in these projects. You can use dialog boxes with these and all other project types (see Using Dialogs).

You can select displayed text either as a bitmap or as text. Windows provides APIs for loading and unloading bitmap files. Standard graphics applications should be written as multithreaded applications. (For information about multithreaded programs, see Creating Multithread Applications.)

Fortran standard graphics (QuickWin single document) applications are normally presented in full-screen mode. The single window can be either full-screen or have window borders and controls available. You can change between these two modes by using ALT+ENTER.

If the resolution selected matches the screen size, the application covers the entire screen; otherwise, it is a resizable window with scroll bars. You cannot open additional windows in a standard graphics application. Standard graphics applications have neither a menu bar at the top of the window, nor a status bar at the bottom.

Fortran standard graphics applications are appropriate for problems that:

  • Require numerical processing and some graphics
  • Do not require a sophisticated user interface

When you select the Fortran standard graphics project type, the visual development environment includes the QuickWin library automatically, which lets you use the graphics functions. When building from the command line, you must specify the /libs:qwins option. You cannot use the run-time functions meant for multiple-window projects if you are building a standard graphics project. You cannot make a Standard Graphics application a DLL.

For more information about Standard Graphics (QuickWin single window) applications, see Using Quickwin.


Fortran QuickWin Application Projects

Fortran QuickWin graphics applications (.EXE) are more versatile than standard graphics (QuickWin single document) applications because you can open multiple windows (usually called multiple-document interface or MDI) while your project is executing. For example, you might want to generate several graphic plots and be able to switch between them while also having a window for controlling the execution of your program. These windows can be full screen or reduced in size and placed in various parts of the screen.

QuickWin library routines lets you build applications with a simplified version of the Windows interface with Visual Fortran. The QuickWin library provides a rich set of Windows features, but it does not include the complete Windows Applications Programming Interface (API). If you need additional capabilities, you must set up a Windows application to call the Win32 API directly rather than using QuickWin to build your program. For more information on QuickWin programming, see Using QuickWin.

Fortran QuickWin graphics applications (.EXE) have a multiple-document interface. Applications that use a multiple-document interface (MDI) have a menu bar at the top of the window and a status bar at the bottom. The QuickWin library provides a default set of menus and menu items that you can customize with the QuickWin APIs. An application that uses MDI creates many "child" windows within an outer application window. The user area in an MDI application is a child window that appears in the space between the menu bar and status bar of the application window. Your application can have more than one child window open at a time.

Fortran QuickWin applications can also use the DFLOGM.F90 module to access functions to control dialog boxes. These functions allow you to display, initialize, and communicate with special dialog boxes in your application. They are a subset of Win32 API functions, which Windows applications can call directly. For more information on using dialog boxes, see Using Dialogs.

When you select the Fortran QuickWin project type, the visual development environment includes the QuickWin library automatically, which lets you use the graphics functions. QuickWin applications should be written as multithreaded applications. (For information about multithreaded programs, see Creating Multithread Applications.)

When building from the command line, you must specify the /libs:qwin compiler option to indicate a QuickWin application (or /libs:qwins option to indicate a Fortran Standard Graphics application). A Fortran QuickWin application that uses the compiler option is similar to a Fortran Standard Graphics application in that it has no menu bar or status bar. (A Fortran Standard Graphics application is a QuickWin application with a set of preset options that is offered in the program types list for your convenience.)

As with a Fortran Standard Graphics application, the application covers the entire screen if the resolution selected matches the screen size; otherwise, it is a resizable window with scroll bars.

You cannot make a Fortran QuickWin application a DLL.

For information on how to use QuickWin functions, including how to open and control multiple windows, see Using Quickwin.


Fortran Windows Application Projects

Fortran Windows applications (.EXE) are main programs selected by choosing the Fortran Windows Application project type. This type of project lets you calls the Windows APIs directly from Visual Fortran. This provides full access to the Win32 APIs, giving you a larger (and different) set of functions to work with than QuickWin.

Although you can call some of the Win32® APIs from the other project types, Fortran Windows applications allow you to use the full set of Win32 routines and use certain system features not available for the other project types.

The DFWIN.F90 module contains interfaces to the most common Win32 APIs. If you include the USE DFWIN statement in your program, nearly all of the Win32 routines are available to you. The DFWIN.F90 module gives you access to a full range of routines including window management, graphic device interface, system services, multimedia, and remote procedure calls.

Window management gives your application the means to create and manage a user interface. You can create windows to display output or prompt for input. Graphics Device Interface (GDI) functions provide ways for you to generate graphical output for displays, printers, and other devices. Win32 system functions allow you to manage and monitor resources such as memory, access to files, directories, and I/O devices. System service functions provide features that your application can use to handle special conditions such as errors, event logging, and exception handling.

Using multimedia functions, your application can create documents and presentations that incorporate music, sound effects, and video clips as well as text and graphics. Multimedia functions provide services for audio, video, file I/O, media control, joystick, and timers.

Remote Procedure Calls (RPC) gives you the means to carry out distributed computing, letting applications tap the resources of computers on a network. A distributed application runs as a process in one address space and makes procedure calls that execute in an address space on another computer. You can create distributed applications using RPC, each consisting of a client that presents information to the user and a server that stores, retrieves, and manipulates data as well as handling computing tasks. Shared databases and remote file servers are examples of distributed applications.

Writing Fortran Windows applications is much more complex than other kinds of Visual Fortran projects. For more information on how to create Fortran Windows applications, see Creating Windows Applications.

You can access the Windows API online documentation help file, Platform SDK, included with Visual Fortran. You can also obtain information through the Microsoft Developer Network. Microsoft offers Developer Network membership, which includes a development library and a quarterly CD containing technical information for Windows programming.

For information on calling Win32 routines, see Calling Win32 Routines.


Fortran Static Library Projects

Fortran static libraries (.LIB) are blocks of code compiled and kept separate from the main part of your program. The Fortran static library is one of the Fortran project types.

Static libraries offer important advantages in organizing large programs and in sharing routines between several programs. These libraries contain only subprograms, not main programs. A static library file has a .LIB extension and contains object code.

When you associate a static library with a program, any necessary routines are linked from the library into your executable program when it is built. Static libraries are usually kept in their own directories.

If you use a static library, only those routines actually needed by the program are incorporated into the executable image (.EXE). This means that your executable image will be smaller than if you included all the routines in the library in your executable image. Also, you do not have to worry about exactly which routines you need to include — the Linker takes care of that for you.

Because applications built with a static library all contain the same version of the routines in the library, you can use static libraries to help keep applications current. When you revise the routines in a static library, you can easily update all the applications that use it by relinking the applications.

A static library is a collection of source and object code defined in the FileView pane. The source code is compiled when you build the project. The object code is assembled into a .LIB file without going through a linking process. The name of the project is used as the name of the library file by default.

If you have a library of substantial size, you should maintain it in a dedicated directory. Projects using the library access it during linking.

When you link a project that uses the library, selected object code from the library is linked into that project's executable code to satisfy calls to external procedures. Unnecessary object files are not included.

When compiling a static library from the command line, include the /c compiler option to suppress linking. Without this option, the compiler generates an error because the library does not contain a main program.

To debug a static library, you must use a main program that calls the library routines. Both the main program and the static library should have been compiled using the debug option. After compiling and linking is completed, open the Debug menu and choose Go to reach breakpoints, use Step to Cursor to reach the cursor position, or use the step controls on the Debug toolbar.

Using Static Libraries

You add static libraries to a main project in the visual development environment with the Add to Project, Insert Files option in the Project menu. You can enter the path and library name in the Insert Files into Project dialog box with a .LIB extension on the name. If you are using a foreign makefile, you must add the library by editing the makefile for the main project. If you are building your project from the command line, add the library name with a .LIB extension and include the path specification if necessary.

For an example of a static library project, see the Visual Fortran Samples folder ...\DF98\Samples\Scigraph\Scigraph, which creates a static library.

To create a static library from the command line, use the /c compiler option to suppress linking and use the LIB command (see Managing Libraries with LIB).

To create a static library from the visual development environment, specify the Fortran Static Library project type.


Fortran Dynamic-Link Library Projects

A dynamic-link library (.DLL) is a source-code library that is compiled and linked to a unit independently of the applications that use it. A DLL shares its code and data address space with a calling application. A DLL contains only subprograms, not main programs.

A DLL offers the organizational advantages of a static library, but with the advantage of a smaller executable file at the expense of a slightly more complex interface. Object code from a DLL is not included in your program's executable file, but is associated as needed in a dynamic manner while the program is executing. More than one program can access a DLL at a time.

When routines in a DLL are called, the routines are loaded into memory at run-time, as they are needed. This is most useful when several applications use a common group of routines. By storing these common routines in a DLL, you reduce the size of each application that calls the DLL. In addition, you can update the routines in the DLL without having to rebuild any of the applications that call the DLL.

With Visual Fortran, you can use DLLs in two ways:

  1. You can build a DLL with your own routines. In the visual development environment, select Fortran Dynamic-Link Library as your project type. From the command line, use the /DLL option with the DF command.

  2. You can build applications with the run-time library stored in a separate DLL instead of in the main application file. In the visual development environment, after you open a workspace:
    • From the Project menu, click Settings to display the project settings dialog box
    • Click the Fortran tab
    • Select the Library category
    • In the Use Fortran Run-Time Libraries box, select DLL

    From the command line, use the /libs:dll compiler option to build applications with the run-time library stored in a separate DLL.

For more information about DLLs, see:

  • Creating Fortran DLLs


Defining Your Project

To define your project, you need to:

  1. Create the project
  2. Populate the project with files
  3. Choose a configuration
  4. Define build options, including project settings
  5. Build (compile and link) the project

To create a new project:

  1. Click the File menu and select New. A dialog box opens that has the following tabs:
    • Files
    • Projects
    • Workspaces
    • Other Documents

  2. The Projects tab displays various project types. Click the type of Fortran project to be created. If you have other Visual tools installed, make sure you select a Fortran project type. You can set the Create New Workspace check box to create a new Workspace.

  3. Specify the project name and location.

  4. Click OK to create the new project. Depending on the type of project being created, one or more dialog boxes may appear allowing you to only create the project without source files or create a template-like source file.

    If a saved Fortran environment exists for the Fortran project type being created, you can also import a Fortran environment to provide default project settings for the new project (see Saving and Using the Project Setting Environment for Different Projects).

    This action creates a project workspace and one project. It also leaves the project workspace open.

To discontinue using this project workspace, click Close Workspace from the File menu.

To open the project workspace later, in the File menu, click either Open Workspace or Recent Workspaces.

To add files to an existing project:

  • To add an existing file to the project:
    1. If not already open, open the project workspace (use the File menu).
    2. In the Project menu, select Add to Project and click Select Files... from the submenu.
    3. The Insert Files into Project dialog box appears. Use this dialog box to select the Fortran files to be added to the Project. To add more than one file to the project, hold down the Ctrl key as you select each file name.

  • To add a new file to the project:
    1. If not already open, open the project workspace (use the File menu).
    2. In the Project menu, select Add to Project and click New... from the submenu.
    3. The New dialog box appears. Specify the file name and its location.
    4. Click (select) the type of file (Fortran Fixed Format Source or Fortran Free Format Source).
    5. Click OK. The editor appears, letting you type in source code. The file name appears in the FileView pane.

To define a project from a set of existing or new source files:

  1. On the File menu, click New...
  2. Click the Projects tab.
  3. Select the type of project.
  4. Name the project.
  5. Click OK. Depending on the type of project being created, one or more dialog boxes may appear allowing you to only create the project without source files or create template-like source files.

    If a saved Fortran environment exists for the project type being created, you can also import a Fortran environment to provide default project settings for the new Fortran project (see Saving and Using the Project Setting Environment for Different Projects).

  6. Add existing files and/or new files to the project.

    To add an existing file to the project:

    1. In the Project menu, select Add to Project and click Files... from the submenu.
    2. The Insert Files into Project dialog box appears. Use this dialog box to select the Fortran files to be added to the Project. To add more than one file to the project, hold down the Ctrl key as you select each file name.

    To add each new file to the project:

    1. In the Project menu, select Add to Project and click Select New... from the submenu.
    2. The New dialog box appears. Specify the file name and its location.
    3. Click the type of file (Fortran Fixed Format Source or Fortran Free Format Source).
    4. Click OK. The editor appears allowing you to type in source code. The file name appears in the FileView pane.
  7. You can now select "Build filename" from the Build Menu to build your application.

You need to add these kinds of files to your project:

  • Program files with .F90, .FOR, or .F extension
  • A resource file with an .RC extension
  • If your project references routines or data in a Fortran dynamic-link library (DLL), you need to add the import library (.LIB file created while building the DLL) as a file to your project (see Building and Using Dynamic-Link Libraries)

For information on:

  • How to use icon files, see Using QuickWin.
  • Using binary files, see Files, Devices, and I/O Hardware.
  • Using the Dialog Editor, Graphics Editor, or other Resource Editors, see the Visual C++ User's Guide.

For more information on defining and building projects, see:

  • Files in a Project
  • Selecting a Configuration
  • Setting Build Options
  • Specifying Consistent Library Types
  • Creating the Executable Program


Files in a Project

When you create a project, the Microsoft visual development environment always creates the following files:

File | Extension | Description
Project workspace file | .DSW | Stores project workspace information.
Project file | .DSP | Used to build a single project or subproject.
Workspace options file | .OPT | Contains environment settings for Visual Fortran, such as window sizes and positions, insertion point locations, state of project breakpoints, contents of the Watch window, and so on.

Directly modifying the .DSW and .DSP files with a text editor is not supported.

For information on creating (exporting) a makefile, see The Project Makefile.

When you create a project, you also identify a project subdirectory. If the subdirectory does not exist, the visual development environment creates it. Project files that the visual development environment creates are put into this directory.

When you create a project, the visual development environment also specifies subdirectories for intermediate and final output files for the various configurations that you specify. These subdirectories allow you to build configurations without overwriting intermediate and final output files with the same names. The General tab in the Project Settings dialog box lets you modify the subdirectories, if you choose.

If you have existing source code, you should organize it into directories before building a project, although it is easy to move files and edit your project definitions if you should later decide to reorganize your files.

If your program uses modules, you do not need to explicitly add them to your project, they appear as dependencies (.mod files).

For a newly created project (before you request a Update Dependencies), the visual development environment scans the file list for modules and compiles them before program units that use them. The visual development environment automatically scans the added project files recursively for modules specified in USE statements, as well as any INCLUDE statements. It scans both source files (.FOR, .F, .F90) and the resource file (.RC), and adds all the files it finds to a Dependencies folder. You cannot directly add or delete the files listed in this folder.

Module files are a precompiled, binary version of a source file, stored as a .mod file. When you change the source definition of a module, you can update the .mod file before you rebuild your project by compiling that source file separately by clicking (selecting) the file in the FileView pane and select Compile from the Build menu.

To control the placement of module files in directories, use the /[no]module compiler option.

To control the search for module files in directories, use the /[no]include and the /assume:source_include compiler options.

The Project Makefile

The visual development environment speeds and simplifies the task of building programs and libraries outside of the visual development environment by allowing you to export a makefile, which is a set of build instructions for each project. Makefiles contain the names of the source, object, and library files needed to build a program or library, plus the compiler and linker options selected in the Project Settings dialog boxes.

The visual development environment updates the build instructions in internal makefiles when you add or remove project files in the project window, and when you make changes to the compiler or linker options in the Project Settings dialog boxes. To get an updated version of a makefile, update project dependencies (use the Build menu) and from the Project menu, select Export Makefile. The makefile is used by the external program maintenance utility, NMAKE.EXE.

You can edit the makefile generated by the visual development environment if you need to perform unusual or exceptional builds. Remember, however, that once you have edited a makefile, exporting the makefile again from the visual development environment will overwrite your changes.

If you use a foreign makefile for a project, the visual development environment calls NMAKE to perform the build. You can run NMAKE from the console command line to perform builds either with makefiles exported by the visual development environment or with foreign makefiles that you have edited. For more about the external program maintenance utility, see Building Projects with NMAKE.

Note: When you use a foreign makefile, the project is considered to be foreign. You cannot use the Project Settings dialog box to make changes to the build options, or use the Add to Project dialog box to add files.


Selecting a Configuration

A configuration defines the final binary output file that you create within a project. When you create a new project, the visual development environment creates the following configurations:

Debug configuration | By default, the debug configuration sets project options to include the debugging information in the debug configuration. It also turns off optimizations. Before you can debug an application, you must build a debug configuration for the project.
Release configuration | The release configuration does not include the debugging information, and it uses any optimizations that you have chosen.

Select the configuration in the Build menu, Set Active Configuration item. Only one configuration can be active at one time.

When you build your project, the currently selected configuration is built:

  • If you selected the debug configuration, a subfolder called Debug contains the output files created by the build for the debug version of your project.
  • If you selected the release configuration, a subfolder called Release contains the output files created by the build for the release version of your project.

A configuration has the following characteristics:

  • Project type: specifies the type of Fortran application to build, such as a Fortran Static Library, Fortran Console application, Fortran QuickWin application, Fortran Windows application, and so on.
  • Build options: specifies the build options, which include the compiler and linker options (project settings).

Although debug and release configurations usually use the same set of source files, the information about project settings usually differs. For example, the default debug configuration supplies full debug information and no optimizations, whereas the default release configuration supplies minimal debug information and full optimizations.

You can also define new configurations within your project. These configurations can use the existing source files in your project, the existing project settings, or other characteristics of existing configurations. A new configuration does not have to share any of the characteristics or content of existing configurations, however.

You could, for instance, create an initial project with debug and release configurations specifying an application for the Win32 environment, and add source files to the project. Later, within the project, you could create debug and release configurations specifying a DLL for the Win32 environment, add an entirely disjoint set of files to this configuration, and make these configurations dependencies of the application configurations.

Platform Types

The platform type specifies the operating environment for a project. The platform type sets options required specifically for a given platform, such as options that the compiler uses for the source files, the static libraries that the linker uses for the platform, the default locations for output files, defined constants, and so on. Visual Fortran supports the Win32 platform type.

For more information:

  • On viewing and changing the project build options for the current configuration, use the Project settings dialog box (see Setting Build Options).
  • On errors during the build process, see Errors During the Build Process.


Setting Build Options

When you create a new configuration, you specify options for file creation and build settings by selecting the Settings item in the Project menu.

For the currently selected configuration of a project, the Project Settings dialog box (see Categories of Compiler Options) allows you to specify the compile and link options, optimization, or browse information.

Configurations have a hierarchical structure of options. The options set at the configuration level apply to all files within the configuration. Setting options at the configuration level is sufficient for most configurations. For instance, if you set default optimizations for the configuration, all files contained within the configuration use default optimizations.

However, you can set different options for files within a configuration, such as specific optimization options — or no optimization at all — for any individual files in the configuration. The options that you set at the file level in the configuration override options set at the configuration level.

The FileView pane shows the files associated with the project configuration and allows you to select certain files.

You can set some types of options, such as linking or requesting browse information, only at the configuration level.

You can set options at the following levels within a configuration:

Configuration level | Any options set for the current configuration apply to every file in the configuration unless overridden at the file level. Options set for the configuration apply to all actions, such as compilation, linking, and requesting browser information.
File level | Any options set for a file apply only to that file and override any options set at the configuration level. Options set for selected files apply to file-level actions, such as compiling.

You can insert both source files (.FOR, .F90, .F, .FI, .FD) and object files (.OBJ) by using the Project menu Add to Project, Files item.

You should always insert all source files used by your application into the project. For example, when you update a source file, the next time you build your application, the visual development environment will create a new object file and link it into your project.

You should also insert the names of any necessary static libraries and DLLs with .LIB extensions to be linked with your project. Use only the library names, not the names of any files within the libraries.

If you have installed the same version of Microsoft Visual C++ and Visual Fortran (in the same directory tree), you can include C/C++ source code files. If the same version of Microsoft Visual C++ is not installed, include C/C++ object code instead.

You can set and save project settings as described in the following sections:

  • Compile and Link Options for a Configuration or Certain Files
  • Saving and Using the Project Setting Environment for Different Projects
  • Source Browser Information for a Configuration


Compile and Link Options for a Configuration or Certain Files

You can set compiler or linker options by using the Project Settings dialog box.

To display the Project Settings dialog box:

  1. Open your project workspace.
  2. In the Project menu, click Settings.

The Fortran tab of this dialog box presents options grouped under different categories. Select the category from the Category drop-down list:

project settings, fortran tab, showing categories

You can choose compiler and linker options through the various categories in the Fortran and Link tabs. For details about the compiler options, see Categories of Compiler Options.

If a compiler option is not available in the Project Settings dialog box you can enter the option in the lower part of the window under Project Options: just as you would using the command line.

The FileView pane shows the files associated with the project configuration and lets you select certain files. The options that you set at the file level in the configuration override options set at the configuration level. Linking options only be applied at the configuration level (not the file level).

The linker builds an executable program (.EXE), static library (.LIB), or dynamic-link library (.DLL) file from Common Object File Format (COFF) object files and other libraries identified in the linker options. You direct the linker by setting linker options either in the visual development environment, in a build instructions file, or on the console command line. For example, you can use a linker option to specify what kind of debug information to include in the program or library.

For more information on compiler and linker options, see Compiler and Linker Options.


Saving and Using the Project Setting Environment for Different Projects

You can set any of the compiler or linker options described in Compiler and Linker Options in the Project menu, Settings dialog box. The Fortran tab of this dialog box presents several categories of options to set.

Visual Fortran provides a facility to save and re-use the Project settings for multiple projects of the same project type. For example, you can save your Project settings environment for a Fortran QuickWin project and use those saved settings as defaults when you create a new Fortran QuickWin project type.

The saved Fortran environment project settings are those associated with the Fortran tab and the displayed tool tab(s) in the Project Settings dialog box. You can:

  • Save a Fortran project settings environment for an existing project
  • Use a previously saved project settings environment for a new project
  • Manage the current set of saved Fortran environment settings

To save a project settings Fortran environment:

  1. Open the appropriate workspace.
  2. Modify the Project Settings dialog box as needed. If you specify actual file names for output files, consider changing them to use the default file naming conventions.
  3. In the File menu, click Save Fortran Environment or click the green tree on the Fortran toolbar. A window resembling the following dialog box appears:

    Saving a Project Settings Environment

    project settings environment dialog box

  4. The Tool Combo box allows you to view the project settings for either the Fortran or the displayed tools (such as Linker). The Release and Debug configuration values are displayed for the selected tab. Verify that the displayed values are acceptable.
  5. The edit box titled Saved Fortran Console Environment allows you to specify the name of the environment to be saved.
  6. Click the Save Settings button to save the settings as a project settings environment.

To use an existing Fortran environment when creating a new project:

  1. If a Fortran environment exists for the specified new Fortran project type, you will be asked whether you want to apply project settings options from a saved Fortran environment. If you click Yes, a window resembling the following dialog box appears:

    Using an Existing Fortran Project Settings Environment

    applying a previously saved fortran project settings environment

  2. For the selected Fortran project type, a list of saved Fortran environments appears. Select a Fortran environment. Verify that the selected environment is correct by viewing the Project Settings options.
  3. After selecting the appropriate Fortran environment for the Fortran project being created, click the Apply button to use the saved settings for the new project.
  4. Complete other tasks associated with creating a new project, such as adding source files, and so on.

To manage saved Fortran environments:

  1. In the Tools menu, click Managed Saved Fortran Environment or click the saw on the Fortran toolbar. A dialog box resembling the following appears:

    Managing Saved Fortran Project Settings Environments

    managing saved fortran environments

  2. Initially, this dialog box displays the project types for which there are saved Fortran environments. Double-click on the project type name to view the saved Fortran environments for that project type.

    This dialog box allows you to display the Fortran environments associated with each project type. Double-click the name of a project type to display the Fortran environments associated with that project type.

  3. To display the project settings for a Fortran environment:
    • Click the name of a Fortran environment.
    • View the project settings for the Fortran tab.
    • Click the other tool tab (such as Linker) and view that tool's project settings.
    • If needed, click (select) a different Fortran environment.
  4. To determine whether a duplicates exist for a Fortran environment:
    • Click (select) the name of an environment or a project type.
    • Click the Display Environments with Duplicate Settings button.
    • If the Fortran environments have different project settings, No Duplicates Found is displayed.
    • If the Fortran environments have identical project settings, the duplicate environments are displayed.
  5. To delete a Fortran environment:
    • Click (select) the name of an environment or the project type.
    • Click the Delete button.
    • Click OK to the delete confirmation box.


Source Browser Information for a Configuration

The Source Browser generates a listing of all symbols in your program; information that can be useful when you need to debug it, or simply to maintain large volumes of unwieldy code. It keeps track of locations in your source code where your program declares, defines, and uses names. You can find references to variables or procedures in your main program and all subprograms it calls by selecting one of the files in your project, then using the Go to Definition or Go to Reference button on the Browse toolbar. Source Browser information is available only after you achieve a successful build.

Browser information is off by default for projects, but you can turn it on if you wish. To set the browse option for the current configuration:

  • In the visual development environment:

    1. In the Project menu, click Settings.
    2. In the General category of the Fortran tab, set the Generate Source Browse Information check box.
    3. Click the BrowseInfo tab and set the Build Browse info check box.
    4. Click OK.
    5. Build your application.
    6. In the Tools menu, click Source Browser.
    7. Near the bottom on the Browse window, locate the Case sensitive check box. Since Fortran is a case-insensitive language, make sure the Case sensitive check box is clicked off.
    8. When you are done using the Browse window, click OK. The Browse window allows you to view graphs of calling relationships between functions and view the symbols contained within the file, and perform other functions.

  • On the command line:

    1. Specify the /browser option.
    2. Use the Browse Information File Maintenance Utility (BSCMAKE) utility to generate a browse information file (.BSC) that can be examined in browse windows in the visual development environment.

When the browse option is on, the compiler creates intermediate .SBR files when it creates the .OBJ files; at link time, all .SBR files in a project are combined into one .BSC file. These files are binary, not readable, but they are used when you access them through the Browser menu.


Specifying Consistent Library Types

There are a number of Visual C++ run-time libraries that offer the same entry points but have different characteristics. The default Visual C++ library is libc.lib, which is single threaded, non-debug, and static. The Visual C++ and Visual Fortran libraries must be the same types. The incompatible types are:

  • Mixing single-threaded with multi-threaded versions of the libraries
  • Mixing static and dynamic-link versions of the libraries
  • Mixing debug with non-debug versions of the libraries

The default Fortran libraries depend on the project type:

Fortran Project Type | Default Libraries Used
Fortran Console | Static, single-threaded libraries dfor.lib and libc.lib
Fortran Standard Graphics | Static, multithreaded libraries dformt.lib and libcmt.lib
Fortran QuickWin | Static, multithreaded libraries dformt.lib and libcmt.lib
Fortran Windows | Static, multithreaded libraries dformt.lib and libcmt.lib
Fortran DLL | Dynamic-link libraries dfordll and msvcrt (and their import libraries)
Fortran Static Library | Static, single-threaded libraries dfor.lib and libc.lib

Pure Fortran applications can have mismatched types of libraries. One common scenario is a Fortran QuickWin application that links with a Fortran Static library. Fortran QuickWin (and Fortran Standard Graphics) applications must use the static, multithreaded libraries, and by default, Fortran Static libraries are built using static, single-threaded libraries. This causes a conflict, so the Fortran Static library and the QuickWin application must both be built using static, multithreaded libraries.

Similarly, different C/C++ applications link against different C libraries. If you mix the different types of applications without modifying the defaults, you can get conflicts. The debug version of a library has a letter "d" appended to its base file name:

  • Static, single-threaded: libc.lib and libcd.lib
  • Static, multithreaded: libcmt.lib and libcmtd.lib
  • Dynamic-link libraries: msvcrt and msvcrtd (.lib import library and .dll)

When using a Debug configuration, Visual C++ selects the debug libraries. Visual Fortran does not select debug libraries for any configuration, but provides a Project Settings option to request their use. To specify different types of Fortran libraries in the visual development environment, open the Project Settings dialog box, click the Fortran tab, and select the Libraries category:

  • To specify static libraries, select the appropriate type of static (non-DLL) library under Use Run-Time Libraries (see /libs:static)
    • .
  • To specify dynamic-link libraries, select the appropriate type of DLL library under Use Run-Time Libraries (see /libs:dll)
    • .
  • To specify multithreaded libraries, select the appropriate type of Multi-thread library under Use Fortran Run-Time Libraries (see /threads).
  • To specify the debug libraries, select the appropriate type of Debug library under Use Run-Time Libraries (see /[no]dbglibs). If you specify debug libraries (/dbglibs) and also request DLL libraries (/libs:dll) (Use Run-Time Libraries that include both Debug and DLL), be aware that this combination selects the debug versions of the Fortran DLLs. These Fortran DLL files have been linked against the C debug DLLs.
  • When you specify QuickWin or Standard Graphics libraries under Use Run-Time Libraries, this selection implicitly requests Multi-threaded libraries.

For details about the Visual C++ libraries used and compiler options available, see Visual Fortran/Visual C++ Mixed-Language Programs.


Creating the Executable Program

When you are ready to create an executable image of your application, select the Build menu. You can:

  • Compile a file without linking
  • Build a project
  • Rebuild all parts of a project
  • Batch build several configurations of a project
  • Clean extra files created by project builds
  • Execute the program, either in debug mode or not
  • Update program dependencies
  • Select the active project and configuration
  • Edit the project configuration
  • Define and perform profiling

When you have completed your project definition, you can build the executable program.

When you select Build projectname from the Build menu (or one of the Build toolbars), the visual development environment automatically updates dependencies, compiles and links all files in your project. When you build a project, the visual development environment processes only the files in the project that have changed since the last build.

The Rebuild All mode forces a new compilation of all source files listed for the project.

You either can choose to build a single project, the current project, or you can choose multiple projects (requires batch build) to build in one operation.

You can execute your program from the visual development environment using Ctrl+F5 or Execute from the Build menu (or Build toolbar), or from the command line prompt.

Compiling Files In a Project

You can select and compile individual files in any project in your project workspace. To do this, select the file in the project workspace window (FileView tab). Then, do one of the following:

  • Press Ctrl+F7.

    – or –

  • Choose Compile from the Build menu (or Build toolbar).

    – or –

  • Click the right mouse button to display the pop-up menu and select Compile.

You can also use the Ctrl+F7 or Compile from the Build menu (or Build toolbar) options when the source window is active (input focus).


Errors During the Build Process

Compiler and linker errors are displayed in the Build pane of the output window. If the Output window is not displayed, in the View menu, click Output.

To quickly locate the source line causing the error, follow these steps:

  1. Double-click the error message text in the Build pane of the output window.

    - or -

  2. Press F4. The editor window appears with a marker in the left margin that identifies the line causing the error. You can continue to press F4 to scroll through additional errors.

If you need to set different compiler options for some of your source files, you can highlight the source file name and select the Project menu, Settings item. Options set in this manner are valid only for the file you selected.

After you have corrected any compiler errors reported during the previous build, choose Build from the Build menu. The build engine recompiles only those files that have changed, or which refer to changed include or module files. If all files in your project compile without errors, the build engine links the object files and libraries to create your program or library.

You can force the build engine to recompile all source files in the project by selecting Rebuild All from the Build menu. This is useful to verify that all of your source code is clean, especially if you are using a foreign makefile, or if you use a new set of compiler options for all of the files in your project.

If your build results in Linker errors, be aware that the project type selected and the project settings in the Libraries category (see Categories of Compiler Options) determine the libraries linked against. Also, you can specify additional user-created libraries.

To view the include file and library directory paths in the visual development environment:

  1. In the Tools menu, click Options.
  2. Click the Directories tab.
  3. In the drop-down list for Show Directories For, select Include files and view the include file paths.
  4. In the drop-down list for Show Directories For, select Library files and view the library paths.
  5. Click OK if you have changed any information.

To view the libraries being passed to the linker in the visual development environment:

  1. If not already open, open your Project Workspace (File menu, Open Workspace).
  2. In the Project menu, click Settings.
  3. Click the Link tab
  4. In Link tab's Project Options box, type the following option:
    /verbose:lib
  5. Click OK. The next time you build the project, the list of libraries will be displayed with other build-related messages in the output pane (bottom of screen).

If you have trouble linking CXML libraries, see also Using CXML from Visual Fortran.

With the Professional and Enterprise Editions, if you have trouble linking IMSL libraries, specify the /imsl option and see Using the IMSL Libraries from Visual Fortran.

If you encounter linker errors, see Linker Diagnostic Messages and Error Conditions.

To view a description of build and run-time messages, see Error Messages or, in the visual development environment, highlight the error identifier (such as LNK2001) in the output pane and press F1.


Compiler Limits

The following table lists the limits to the size and complexity of a single Visual Fortran program unit and to individual statements contained in it.

The amount of data storage, the size of arrays, and the total size of executable programs are limited only by the amount of process virtual address space available, as determined by system parameters:

Language Element | Limit
Actual number of arguments per CALL or function reference | No limit
Arguments in a function reference in a specification expression | No limit
Array dimensions | 7
Array elements per dimension | 9,223,372,036,854,775,807 or process limit
Constants; character and Hollerith | 2000 characters
Constants; characters read in list-directed I/O | 2048 characters
Continuation lines | 511
DO and block IF statement nesting (combined) | 128
DO loop index variable | 9,223,372,036,854,775,807 or process limit
Format group nesting | 8
Fortran source line length | 132 characters
INCLUDE file nesting | 20 levels
Labels in computed or assigned GOTO list | 500
Lexical tokens per statement | 3000
Named common blocks | 250
Parentheses nesting in expressions | 40
Structure nesting | 20
Symbolic name length | 63 characters


Running Fortran Applications

You can execute programs built with this version of Visual Fortran only on a computer running the Microsoft Windows 2000, Windows NT, Windows Me, or Windows 9x operating system. You can run the programs from the command console, Start ... Program ... group, Windows Explorer, and the Microsoft visual development environment.

Each program is treated as a protected user application with a private address space and environment variables. Because of this, your program cannot accidentally damage the address space of any other program running on the computer at the same time.

Environment variables defined for the current user are part of the environment that Windows sets up when you open the command console. You can change these variables and set others within the console session, but they are only valid during the current session.

If you run a program from the console, the operating system searches directories listed in the PATH user environment variable to find the executable file you have requested. You can also run your program by specifying the complete path of the .EXE file. If you are also using DLLs, they must be in the same directory as the .EXE file or in one specified in the path.

You can easily recover from most problems that may arise while executing your program.

If your program is multithreaded, Windows NT and Windows 2000 starts each thread on whichever processor is available at the time. On a computer with one processor, the threads all run in parallel, but not simultaneously; the single processor switches among them. On a computer with more than one processor, the threads can run simultaneously.

If you specified the /fpscomp:filesfromcmd option (Compatibility category in Project Settings, Fortran tab), the command line that executes the program can also include additional filenames to satisfy OPEN statements in your program in which the filename field (FILE specifier) has been left blank. The first filename on the command line is used for the first such OPEN statement executed, the second filename for the second OPEN statement, and so on. In the visual development environment, you can provide these filenames in the Project menu Settings item, Debug tab, in the Program Arguments text box.

Each filename on the command line (or in a visual development environment dialog box) must be separated from the names around it by one or more spaces or tab characters. You can enclose each name in double quotation marks ("filename"), but this is not required unless the argument contains spaces or tabs. A null argument consists of an empty set of double quotation marks with no filename enclosed ("").

The following example runs the program MYPROG.EXE from the console:

  MYPROG "" OUTPUT.DAT

Because the first filename argument is null, the first OPEN statement with a blank filename field produces the following message:

  File name missing or blank - please enter file name<R>
  UNIT number  ?

The number is the unit number specified in the OPEN statement. The filename OUTPUT.DAT is used for the second such OPEN statement executed. If additional OPEN statements with blank filename fields are executed, you will be prompted for more filenames. Programs built with the QuickWin library prompt for a file to open by presenting a dialog box in which you can browse for the file or type in the name of a new file to be created.

Instead of using the /fpscomp:filesfromcmd option, you can:

  • Call the GETARG library routine to return the specified command-line argument. To execute the program in the visual development environment, provide the command-line arguments to be passed to the program in the Project menu Settings item, Debug tab, in the Program Arguments text box.
  • Call the GetOpenFileName Win32 routine to request the file name using a dialog box. For an example of how to call the GetOpenFileName routine, see the Visual Fortran Sample GetOpenFileName in ...Df98\Samples\Advanced\Win32\GetOpenFileName.

If you use the visual development environment debugger and need to specify a working directory that differs from the directory where the executable program resides, specify the directory in the Project menu Settings item, Debug tab, in the Working Directory text box.

Run-time error messages are displayed in the console or in a message box depending upon the project type of the application you build (see Run-Time Message Display and Format). If you need to capture these messages, you can redirect stderr to a file. For example, to redirect run-time error messages from a program called BUGGY.EXE to a file called BUGLIST.TXT, you would use the following syntax:

  BUGGY.EXE > BUGLIST.TXT

The redirection portion of the syntax must appear last on the command line. You can append the output to an existing file by using two greater-than signs (>>) instead of one. If the file does not exist, one is created. For more information about command-line redirection, see Redirecting Command-Line Output to Files.

To run (deploy) your application on another Windows system, use the VFRUN tool to install the necessary run-time DLLs and related files. The VFRUN tool provides the run-time redistributable files for Visual Fortran applications, in the form of a self-installing kit. You can download the run-time redistributable files VFRUN kit from the Visual Fortran Web page (click Downloads area). VFRUN and the deployment of Visual Fortran applications is further described in the Compaq Visual Fortran Installing and Getting Started guide.

For more information:

  • On using the debugger with Fortran programs, see Debugging Fortran Programs.
  • Locating errors in the debugger, see Locating Run-Time Errors in the Debugger.
  • On locating the source of exceptions, see Locating Run-Time Errors and Using Traceback Information.
  • On handling run-time errors with source changes, see Methods of Handling Errors
  • On environment variables recognized during run-time, see Run-Time Environment Variables
  • On each Visual Fortran run-time message, see Run-Time Errors


Copying Projects

You need to follow certain procedures to move a project's location, whether you copy a project to:

  • Another disk or directory location on the same PC system
  • Another PC system where Visual Fortran is also installed

To copy an existing Visual Fortran project to another disk or system:

  1. Copy all project files to the new location. You do not need to copy the subdirectories created for each configuration.

    Keep the folder/directory hierarchy intact by copying the entire project tree to the new computer. For example, if a project resides in the folder \MyProjects\Projapp on one computer, you can copy the contents of that directory, and all subdirectories, to the \MyProjects\Projapp directory on another computer.

  2. After copying all of the files, delete the following files from the main directory at the new location. These files are disk- and computer-specific and should not be retained:
    • *.opt files
    • *.ncb files (if present)
  3. After copying the files, if you copied the subdirectories associated with each configuration, you need to delete these contents of subdirectories at the new location, such as the Debug and Release subdirectories. The files contained in these subdirectories are disk- and computer-specific files and should not be retained. For example, Visual Fortran module (.MOD) files contained in these subdirectories should be recreated by the Visual Fortran compiler, especially if a newer version of Visual Fortran has been installed. The internal structure of module files can change for Visual Fortran releases.

    If you copied the project files to the same system or a system running the same platform or major Visual Fortran version, do the following steps to remove most or all of the files in the configuration subdirectory:

    • Open the appropriate project workspace. In the File menu, either select Open Workspace or select Recent Workspaces. If you use Open Workspace, select the appropriate .DSW file.
    • For each configuration, select the appropriate configuration by selecting Set Active Configuration in the Build menu.
    • For the current configuration, select Clean in the Build menu.
    • Repeat the previous two steps for other configurations whose subdirectories have been copied.
  4. If you copied the project from a PC running a Visual Fortran 5, you should open the project at its new location using Visual Fortran 5, before you convert the project to Visual Fortran Version 6 format.

    If you open a project created with Visual Fortran 5 with Visual Fortran Version 6, Visual Fortran 6 will convert the project to Visual Fortran Version 6 format. Converting the project back to Version 5 format is not easily performed (must be done manually).

    If possible, open the project under Visual Fortran Version 5 after you move it, before you convert the project to Version 6 format. This ensures that the project has been moved successfully and minimizes the chance of conversion problems. An alternative is to make an archive copy of the Visual Fortran 5 project files before you open and convert the project to Visual Fortran Version 6 format.

  5. View the existing configurations. To view the existing configurations associated with the project:
    • Open the project workspace. In the File menu, either select Open Workspace or select Recent Workspaces. If you use Open Workspace, specify the appropriate .DSW file (navigate to the appropriate project directory and double-click the .DSW file).
    • Select Configurations from the Build menu.
    • View the available configurations. You can also remove or add configurations.
  6. If you copied the project to a PC running a different platform, specify new configurations.

    If you copied the project to the same system or to a system where the same major version of Visual Fortran is installed that uses the same platform, you may not need to create any new configurations.

    If you copy the files to a different platform, opening the project reveals that the target platform is still set to the original platform. Although this is not obvious, you can tell this is so because the Build, Compile, and Execute options are grayed out in the Build menu. Before you can build the application on the new platform, you must first specify one or more new configurations for the project on the new platform.

    To create Debug and Release targets for this project, you create a new configuration while running Visual Fortran on the new platform. The platform for a new configuration is assumed to be the current platform. This same behavior applies when moving projects between any two platforms.

    To create a new project configuration:

    1. In the Configurations dialog box, click the Add button. The Add Project Configuration dialog box appears.
    2. In the Configuration box, type a new configuration name. The names do not matter, as long as they differ from existing configuration names.
    3. Select the configuration from which to copy the settings for this configuration and click OK. Usually, you will want to copy the settings from a similar configuration. For example, if this new configuration is a release configuration, you will usually copy settings from an existing release configuration.
    4. The Projects dialog box appears with the new project configuration.
      Repeat the process as necessary to create as many configurations as you need.
  7. Check and reset project options.

    Because not all settings are transportable across different disks, systems, or platforms, you should verify your project settings on the new platform. To verify your project settings:

    1. From the Project menu, choose Settings. The Project Settings dialog box appears.
    2. Review the tabs and categories to ensure that the project settings you want are selected. Pay special attention to the following items:

      • General Tab – Review the directories for intermediate and output files. If you moved the project to a different system, be aware that any absolute directory paths (such as C:\TEMP or \Myproj\TEMP) will most likely need to be changed. Instead, use relative path directory names (without a leading back slash), such as Debug.
      • Custom Build Tab – Review for any custom commands that might change between platforms.
      • Fortran and Linker tabs – Nonstandard options in the original configurations must be replicated (as applicable) in the new configurations.

        For example, if you moved a project from a Windows NT Alpha system running Visual Fortran 6.5A or earlier, a few Alpha-only compiler options are either not needed (such as /synchronous_exceptions and /granularity) or are not available on ia32 systems (such as /rounding_mode, /pipeline, and /math_library:accurate). You also might find new compiler options that might benefit your application (see Compiler Options).

      • Pre-link and Post-build Step tabs – Review for any custom commands that might change between platforms.
  8. If you are copying your project between systems, check your source code for directory paths referenced in INCLUDE or similar statements. Developer Studio provides a multi-file search capability called Find in Files, available from the Edit menu.


Visual Fortran Samples

On the Visual Fortran media CD-ROM, Samples are located in folders under Info\Df\Samples. After a Custom installation, the Samples are installed by default in folders under ...\Microsoft Visual Studio\Df98\Samples.

You can view and copy the source code samples for use with your own projects. Use a text editor to view the sample programs (Samples); they are not listed as topics in HTML Help Viewer.

If you do not install Samples, you can copy appropriate Samples folders or files from the Visual Fortran CD-ROM to your hard disk (remove the Read-Only attribute file property for the files copied).

For a description (roadmap) of the Samples, see Roadmap to the Visual Fortran Samples (Samples.htm) or in a Web browser open the file Samples.htm (use File menu, Open). The following table shows where to locate Samples.htm and the Samples on the Visual Fortran CD-ROM (at any time) or on your hard disk (after installation):

To Locate: | Look:
Roadmap to the Samples | On the Visual Fortran CD-ROM, open the file: Info\Df\Samples\Samples.htm On your hard disk (after installation), open the file: ...\Microsoft Visual Studio\Df98\Samples\Samples.htm
Samples folders | On the Visual Fortran CD-ROM, locate folders under: Info\Df\Samples On your hard disk (after installation), locate folders under: ...\Microsoft Visual Studio\Df98\Samples

For example, after a Custom installation, the ...\Df98\Samples\Tutorial folder contains short example programs, called Tutorial samples. The Tutorial samples describe (as source comments) how they can be built. Unlike other samples, all Tutorial samples are contained in a single directory.

Longer sample programs are also provided in their own subdirectories and include a makefile (for command-line use) as well as the source files. Many samples include a project workspace file, allowing you to open the project workspace in the visual development environment, view the source files in the FileView pane, build the sample, and run it.

Samples for the Compaq Array Visualizer (Professional and Enterprise Editions) are located in folders under ...\ArrayVisualizer\Samples.

For a description of the Samples, see the Roadmap to the Visual Fortran Samples.


Roadmap to the Visual Fortran Samples

The Visual Fortran kit provides a number of source code sample programs (samples) that cover a variety of topics. These samples are provided for illustration purposes only, although they can be freely used as a basis for other programs. You can copy the samples as needed. Use a text editor to view the samples; they are not listed as topics in HTML Help viewer.

On the Visual Fortran media CD-ROM, samples are located in folders under Info\Df\Samples. If you request that samples be installed using a Custom installation, the samples are by default installed in subdirectories under ...\Microsoft Visual Studio\Df98\Samples.

Visual Fortran samples include the following:

  • Advanced Samples:
    • Samples Using Component Object Model
    • Samples Showing Direct Fortran 90 Descriptor Manipulation
    • Samples Using OpenGL®
    • Samples Using Win32 API Calls
  • Dialog Box Samples
  • DLL Samples
  • Exception Handling
  • ISO Varying Strings
  • Mixed-Language Programming Samples
  • QuickWin Programming Samples
    • Includes the Postmini graphical postprocessing software, which can be used to examine the output of a number of process, device and circuit simulation (TCAD) programs, as well as import data from ASCII files.
  • Scientific Graphing (SciGraph) Utility Samples
  • Tutorial Samples (illustrate Fortran language constructs)
  • Miscellaneous Samples:
    • Includes a sample that converts data files created by Lahey Fortran to unformatted files which can be read by CVF

Advanced

Within the Advanced category, there are several other categories of samples. Each category is described below, and the specific samples within each are described in its section. Each category is contained within its own subdirectory of ...\Df98\Samples\Advanced:

  • Samples using Component Object Model (advanced\com)
  • Samples Showing Direct Fortran 90 Descriptor Manipulation (advanced\descript)
  • Samples Using OpenGL (advanced\opengl)
  • Samples Using Win32 API Calls (advanced\win32)

Component Object Model (Advanced\Com)

The COM samples demonstrate use of the Component Object Model from within Visual Fortran:

  • adder: The Adder sample demonstrates a Fortran COM server and its use by Visual Fortran, Visual C++, and Visual Basic clients. The COM server implements a very simple "adding machine" object. Each client displays a dialog box that uses the server. Adder is used as an example in Creating a COM Server.
  • autodice: The autodice sample demonstrates interactions between Fortran and Excel 97. This program takes 12 numbers and uses Automation to tell Excel 97 to draw a histogram of the numbers. The EXCEL97A module generated by the Fortran Module Wizard is used as the interface to EXCEL. You must have Microsoft Excel 97 installed on your computer in order to successfully run this sample.
  • dlines: The dlines sample demonstrates interactions between Fortran and the Developer Studio. This program converts Debug lines to IFDEF directives (metacommands). It uses COM to drive Microsoft Developer Studio to edit the source file.
    The COM interfaces defined in DSAPP.F90 are taken from:
    ...\Microsoft Visual Studio\Common\Msdev98\Bin\devshl.dll
    The COM interfaces defined in DSTEXT.F90 are taken from:
    ...\Microsoft Visual Studio\Common\Msdev98\Bin\devedit.pkg

    The dlines sample program is invoked with the following command line:
    dlines inputsource outputsource debugchar ifdefname

    Where: Inputsource is the filename of the input source file. Note: The source file must be fixed form.
    outputsource is the filename of the output source file.
    debugchar is the the debug character in the source file to replace with IFDEF directives (metacommands)
    ifdefname is the name to use with the IFDEF directives

    This program is useful as a tool to edit PowerStation Fortran files that used something other than "C" or "D" as the comment character.

  • dsbuild: The dsbuild sample demonstrates using Automation to drive Developers Studio to rebuild a project configuration.
    The Automation interfaces defined in DSAPPA.F90 are taken from:
    ...\Microsoft Visual Studio\Common\Msdev98\Bin\devshl.dll
    The Automation interfaces defined in DSBLDA.F90 are taken from:
    ...\Microsoft Visual Studio\Common\Msdev98\Bin\devbld.pkg
    The dsbuild program is invoked with the following command line:
    dsbuild project.dsw configuration
    Where: project.dsw is the file specification of the project file.
    configuration is the name of the configuration to rebuild.
  • ErrorInfo: The ErrorInfo sample demonstrates a Fortran COM Server that supports COM ErrorInfo objects. For information about COM ErrorInfo objects, see Adding Support for COM ErrorInfo Objects and the Platform SDK online documentation.
  • iweb: The iweb sample uses the COM interfaces in SHDOCVW.DLL to start a Web Browser and direct the browser to navigate to a specified URL. The iweb program is invoked with the following command line:
    iweb url
    Where: url is the URL to display

    Any arguments not provided on the command line will be prompted for.

  • safearray: The safearray sample demonstrates converting a Fortran two-dimensional array to a COM SafeArray and reading the data back from the SafeArray.
  • variant: The variant sample demonstrates using the VARIANT manipulation routines in Visual Fortran. VARIANTs are used in COM interfaces.

Direct Fortran 90 Descriptor Manipulation (Advanced\Descript)

In other languages, such as C or Pascal, pointers are simple memory addresses with no notion of how the information is organized at the address pointed to. Fortran 90 pointers differ dramatically, by not just containing a memory address, but also keeping track of the bounds and strides of each dimension of an array. To accomplish this, the Fortran 90 compiler uses something called an Array Descriptor, which stores the details of how the array is organized. Array Descriptors may also be called Dope Vectors in other implementations.

By manipulating the contents of a descriptor directly, you can perform operations that would otherwise not be possible in strict Fortran 90. You can associate a Fortran 90 pointer with any piece of memory, organized in any way desired (so long as it is rectangular in terms of array bounds). You can also pass Fortran 90 pointers to other languages, such as C, and have the other language correctly interpolate the descriptor to obtain the information it needs. Important for mixed-language programming, you can create a Fortran 90 pointer associated with an array which is accessed in C's row order, rather than Fortran's traditional column order, allowing the same array to be used with the same subscripts from both C and Fortran.

The descript workspace has three subprojects. Each creates its own executable, and there are no dependencies between them:

  • cassign: A Fortran 90 pointer is associated with a C array, in row order. This pointer is then passed back to Fortran, which reads the values written by C in exactly the same way that C wrote them. This project uses descript.h, which provides the C prototypes, routines, and structure definitions to the Fortran 90 pointers.
  • fassign: A Fortran 90 pointer is associated with a Fortran 90 array, in row order, and then passed to a C routine which can read the array in natural C notation.
  • cube: Through use of the Bitmap module a Fortran 90 pointer is created that points to an internal .BMP file, with its special structure (rows reversed). Once this pointer is setup, the .BMP can be written to directly and then quickly displayed on a QuickWin child window. This method is used to show a flicker-free spinning cube.

OpenGL (Advanced\Opengl)

OpenGL is a protocol for performing advanced 3-dimensional graphics. Visual Fortran includes Fortran 90 modules and link libraries for using OpenGL from Fortran. The sample programs included in this section illustrate programs that take advantage of these facilities.

All OpenGL samples will run under Windows NT, Windows 2000, Windows Me, and Windows 98, but require the OSR2 release of Windows 95 to run there. Refer to our Frequently Asked Questions at http://www.compaq.com/fortran/visual/faq.html for more information.

  • 3dcube: The 3dcube sample displays a three-dimensional box on a black background. It uses QuickWin to create the window and draw the shapes using primitive 3D graphics.
  • olympic: The olympic sample displays 5 rings on a window that rotate and move towards each other, ultimately creating the Olympic symbol. It illustrates calls to the OpenGL libraries, techniques for supporting code on 32- and 64-bit systems, techniques for reading arguments from the command line, and interface blocks, among other Fortran 90 concepts. This sample must be compiled with /fpscomp:logicals due to a difference in the way that Visual Fortran and Microsoft PowerStation Fortran interpret logical values. It must also be linked against the QuickWin libraries.
  • puzzle: The puzzle sample displays a Rubik's Cube, and allows you to try and solve it. There is currently a problem with the colors in this sample. It uses Win32 calls to manage the windowing interface. Again, it illustrates techniques for supporting code on 32- and 64-bit systems.
  • simple: The simple sample displays some points, lines, and simple shapes in a window. It uses QuickWin to manage the windowing interface. It is, as it sounds, a very simple example, using primitive 2-D graphics. One interesting aspect of it is the use of color and how to set some of the standard colors.
  • wave: The wave sample displays a window with a surface waving. It uses QuickWin to manage the windowing interface. Beyond the usage of OpenGL, here are many interesting demonstrations in this sample, including the animation and the trapping of characters typed while the window has focus. The keys that are trapped are:
    • C, which changes the contour of the wave
    • [space], which pauses the animation. To resume, hit space again
    • S, which changes the shading of the wave
    • A, which causes the wave to spin. To stop spinning, hit A again
    • L, which changes the color of the wave.

Win32 API Calls (Advanced\Win32)

Visual Fortran includes Fortran 90 modules and libraries for doing Windows programming at the Win32 API level. For information on calling Win32 routines from a Fortran application, see Calling Win32 Routines. These samples presented here show Win32 API examples of how this is done:

  • angle: The angle sample uses the Windows interface to manage the GUI. It illustrates a basic Windows program, including the event dispatcher, and the use of pens and dialog boxes. The angle sample displays a shape consisting of a straight line plus an arc, and allows the user to input X,Y coordinates, angle of the arc, and radius of the arc, and then redraws.
  • bounce: The bounce sample uses Win32 calls but creates a console application, rather than a Windows based one. It is a multi-threaded application that creates a new thread whenever the letter "A" is typed, up to a maximum of 32. Each thread bounces a happy face of a different color across the screen. All threads are terminated when the letter "Q" is typed. This particular application requires that several compatibility switches be set: /fpscomp:logicals, /fpscomp:ioformat, /fpscomp:general. These are found under the Compatibility entry on the Fortran tab of the Project Settings dialog box.
  • check_sd: The check_sd sample illustrates the use of security descriptors. The purpose of the sample is to assist people who want to manipulate security descriptors with sample code that they can start from. This sample, as is, examines the security descriptor on files, and could be easily modified to check the security descriptor on other objects. To use this sample, check_sd with no arguments checks the security descriptors on the A: device. check_sd d:\a.fil will check the d:\a.fil file. In this case, D: must be formatted with the NTFS file system because only NTFS files have security descriptors.
  • cliptext: The cliptext sample demonstrates copying text to and from the clipboard. It uses the Windows interface to manage the GUI, and as such, also demonstrates the use of WinMain and MainWndProc that contains the event dispatcher. It has an "about" box, located under the File menu item, as there is no Help.
  • cmndlg: The cmndlg sample demonstrates the use of common dialog boxes, including "About", File access dialogs, and error message dialogs. Each dialog box is demonstrated being used in three different ways: standard, using a modified template, and using a hook function. Cmndlg displays "Hello World" in a window, and allows the user to change the text and colors, etc.
  • consolec: The consolec sample demonstrates the use of the SetConsoleTxtAttribute and GetConsoleScreenBufferInfo APIs to set or get the console text color attributes. This is a console application that is linked against dfwin.lib. If no arguments are passed to consolec, it prints out a color sample in a command window. The arguments are FOREGROUND color and BACKGROUND color, and the valid options are BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, YELLOW or WHITE. The color argument passed must be in uppercase, or an error will be output.
  • crypto: The crypto sample demonstrates using the Cryptography API to encrypt and decrypt files.
  • cursor: The cursor sample demonstrates how to manipulate a cursor and select a region. It uses the Windows interface to manage the GUI. The program will either let the user draw boxes (regions) or will calculate 1027 prime numbers when RETURN is entered. During that calculation, the cursor is turned into an hourglass.
  • drives: The drives sample determines all drives on the system, both local and remote, and determines their file system type. This is a console application that links against dfwin.lib.
  • event: The event sample demonstrates the basic concepts involved when using asynchronous I/O. It reads one file asynchronously and writes another synchronously. This is a console application that links against dfwin.lib and requires two arguments, the input file and output file. This executable transfers one file to another. Refer to the readme.txt for information on how to set it up in the Developer Studio.
  • exitwin: The exitwin sample demonstrates how to shut down applications. When run, it will ask whether you want to continue, as it will log you off. Optionally, you can compile it to reboot the system. This is a Windows application that uses Windows to manage the GUI.
  • floppy: The floppy sample demonstrates how to access a physical floppy disk using the Win32 API set. It has two major functions:
    1. It can be used to display the geometry of a disk, floppy -g a:
    2. It can be used to produce a disk image or to write a disk image to a floppy, floppy -c a: bootdisk (produces a disk image of a:) or floppy -c bootdisk a: (make a: identical to bootdisk image).

    This is a Fortran Console program that is linked against dfwin.lib.

  • generic: The generic sample demonstrates the basic concepts required in building a Windows application and could be used as a basis for building a first Windows program. The specific features that generic implements are:
    1. Custom icon
    2. Standard Menu Bar
    3. Standard Help Menu
    4. Full WinHelp Support
    5. Keyboard Accelerator Usage
    6. Version Control Information
  • getdev: The getdev sample demonstrates the GetDeviceCaps() API. Also, in this sample, the main window is a dialog box, and all the interesting code is in the window procedure for that dialog box. This is different than many of the other Windows-based samples, which use MainWndProc to handle the events.
  • getopenfilename: The getopenfilename sample demonstrates the use of the API GetOpenFileName(). When run, it brings up a dialog box listing either text files or Fortran files in the project directory. It also gives you the option of opening the file read-only.
  • getsys: The getsys sample demonstrates the APIs GetSysColor(), GetSystemDirectory(), GetSystemInfo(), GetSystemMetrics(), GetSystemPaletteEntries(), and GetSystemTime(). Also, in this sample, the main window is a dialog box, and all the interesting code is in the window procedure for that dialog box. This is different than many of the other Windows-based samples, which use MainWndProc to handle the events.
  • inherit: The inherit sample demonstrates inheritance of file handles from one process to a child process. It also demonstrates the use of anonymous pipes as stdout and stderr replacements. It contains two projects, child and inherit. The inherit project creates inherit.exe, which can be run without the other project. To run inherit, specify two parameters:
    1. Trace file to write stdout and stderr
    2. Command to execute

    The inherit program is run within QuickWin so that it can be a "console-less" parent. Otherwise, there are configuration problems when trying to pipe.
    To use this sample, first set the current project to child and build it, then set the current project to inherit and build it. Before you run it, read the readme.txt file in the project; this will tell you what changes you need to make to your project configuration in order to run this sample.

  • input: The input sample is a basic Windows application that does very general processing on mouse button events and keyboard events. It demonstrates how input messages are received, and what additional information comes with the message. When run, it displays the current pointer location, whether the right or left mousebutton was clicked, and outputs a message based on a 5 second timer.
  • maskblt: The maskblt sample is intended to demonstrate masked bit block transfers. It is unclear that it is working correctly, either in its current form, or as received from Microsoft. However, it does demonstrate basic calls to functions that support bitmaps and keyboard accelerators used by clipboard functions.
  • MDI: The MDI sample demonstrates the multiple document interface. It creates a simple window that can create child windows within itself. It also can set the titles on these child windows.
  • menu: The menu sample demonstrates the use of popup menus, user defined menus and menu functions. It is a very simple program that allows you to select items off a menu, invoke a pop-up menu, and basically do little else, but is a good example of how to start with menus.
  • mltithrd: The mltitrhd sample demonstrates the use of multiple threads. The main routine, mltithrd.f90, has a brief guide to writing multi-threaded applications at the top of the file. It uses the multi-document interface to create child windows, and bounces colored traces through each one.
  • output: The output sample demonstrates using TextOut() and DrawText() to write to a window. It is a very simple sample, outputting text and a few simple shapes, such as a rectangle, ellipse, and pie-wedge.
  • owncombo: The owncombo sample demonstrates the use of functions and messages for combo boxes and owner-draw control styles. It brings up a window and lets you play with the different combo box styles.
  • paths: The paths sample demonstrates the use of paths and clipping regions. A path is one or more figures or shapes that are filled, outlined, or both filled and outlined. Paths are used in various drawing and painting applications. This sample demonstrates how 6 different types of paths can be set up. With this release, when the application first runs, the window is too small for the titles on the paths, and must be manually resized.
  • platform: The platform sample demonstrates some very simple menu choices, and the popup dialog boxes that you can create from them. This sample displays "menus" that give you information about which platform you are running on.
  • plgdraw: The plgdraw sample demonstrates the PlgBlt() API. The PlgBlt function performs a bit-block transfer of the bits of color data from the specified rectangle in the source device context to the specified parallelogram in the destination device context. The sample displays a rendered version of the contents of the middle grid in the leftmost grid.
  • polydraw: The polydraw sample demonstrates capturing mouse clicks and movement, and combining that with some keyboard input (the Ctrl or Shift keys). It is a very simple program that allows the user to draw lines, curves, and move some points around on the screen.
  • process: The process sample demonstrates creating and terminating processes from within another program. The user interface is very simple, a dialog box with two buttons "Create" and "Terminate", and window with the list of created processes.
  • registry: The registry sample demonstrates the Registry API. This sample displays information from the system registry, allowing the user to traverse the various trees. It is a fairly simple sample, but could be used as an example.
  • select: The select sample demonstrates how to manipulate a cursor and select a region. This sample has two projects under it:
    1. Select, which provides a dynamic link library (dll) of routines for selecting a region
    2. Demo, which contains an executable program that uses the select library above.

    To use this sample, first set select as the current project and build select.dll, then set demo as the current project to build the executable.
  • setinfo: The setinfo sample demonstrates how to set the attributes of a file. It has a simple interface, allowing the user to enter a filename in an edit field. The GetInfo button will retrieve information about the file and display it. To set file information, modify the values in the Time and Date edit fields, and click the SetInfo button. To set file attributes, set the appropriate check boxes and click on the SetAttr button.
    This sample also demonstrates the use of the GetFileTime() and SetFileTime() API calls.
  • sharemem: The sharemem sample demonstrates the use of named shared memory between two independent processes. There are two projects in this sample, sharemem and othrproc. These can be built in either order; neither depends on the other. To use this sample, first start Sharemem, then start Othrproc. (Note, this is best done outside of Developer Studio.) The visual effect is better if the focus remains with Othrproc, while the mouse moves with Sharemem. A "shadow" mouse is displayed on Othrproc with the same coordinates as the mouse on Sharemem.
  • startp: The startp sample demonstrates various CreateProcess() parameters, including starting processes in a given priority class. This is very similar to the "start" command but with added functionality. It is best run from outside Developer Studio, but when run from within Developer Studio, will give usage information in a console window.
  • streblt: The streblt sample demonstrates the use of the StretchBlt function. This Block Transfer function goes beyond a simple BitBlt, giving the option of stretching or compressing a bitmap to fit a different area in the destination device context.
  • subclass: The subclass sample demonstrates subclassing of standard windows controls, such as button, edit field, and list box. It allows the user to create an arbitrary number of child controls on the main window. These controls are subclassed, and the subclass procedure provides the user a way to move and size the controls. A menu item switches in and out of "Test Mode". When this is on, the subclass procedure passes all message through to the standard procedure, and the controls act just like normal.
  • takeown: The takeown sample demonstrates how to give an Administrator access to a file that has been denied to all. It must be run from an Administrator account. There is a sample file provided named takeown.txt which may be used by the sample.
  • termproc: The termproc sample demonstrates how to terminate a process, given its process id. Although this can be built within the Developer Studio, it is best run from the command line.
  • threads: The threads sample demonstrates suspending, resuming, and setting the priorities of threads. The display shows two threads, red and green, which draw paths across the window. There are menu items to suspend, resume, and set the priority of the two threads. Caution, if the priority of one or the other of the threads is set too high little else will run on the system.
  • timers: The timer sample demonstrates the use of the SetTimer() and KillTimer() APIs. It creates 4 rectangles on its window, each with a different and inverts the color whenever the timer goes off. This sample demonstrates two timer mechanisms.
  • tls: The tls sample demonstrates multiple threads calling into a single DLL. It also demonstrates the use of DLLEXPORT to export entry points from a DLL, rather than using .DEF files. The tls sample has two projects, tlsdll and tls. The workspace is configured such that the tls project is dependent on the tlsdll project. If you build tls, it will automatically build tlsdll. When running, each thread is blocked waiting for the user to click OK in a message box. The thread may be running in a minimized window.
  • virtmem: The virtmem sample demonstrates the use of various virtual memory APIs. The sample has a main window with menu items that will modify a set page to have different attributes. In order to write to memory, the page must be committed and set to read/write access. Attempting to write to a read only page will cause an access error, "memory cannot be read".
  • world: The world sample demonstrates scaling and translating an image from a metafile with world coordinate transforms. It uses the calls SetWorldTransform() and PlayEnhMetaFile() to do the linear transformation between world space and page space, and to play the enhanced metafile. The sample provides a single sample metafile, sample.emf, although others could be used.
  • wxform: The wxform sample demonstrates world transforms. It has three dialog boxes that display help, track mouse movements, or allow the user to enter transform information. The different quadrants of the screen have different properties, as described in the help box. This sample also demonstrates using messages to communicate between different window procedures.

Dialog Boxes (Dialog)

The Dialog samples demonstrate several of the newer dialog controls available through Visual Fortran. There is also a sample that demonstrates how to use modeless dialog boxes. The dialog samples can be found in the directory ...\Df98\Samples\Dialog:

  • CelsiCon: The CelsiCon sample is a Fortran Console application that uses a dialog box. It uses an undocumented hook into the dialog initialization event WM_INITDIALOG. It also sets special customizations on that dialog box by using Win32 calls. With a simple modification to the source program, it can also be built as a QuickWin application.
  • dllprgrs: The dllprgrs sample demonstrates using the Visual Fortran Dialog Procedures in a DLL. The public routines in the DLL can be called to:
    • DisplayProgressBox – Display a dialog box containing a progress bar
    • SetProgress – Set the current progress bar value
    • DestroyProgressBox – Destroy the dialog box
  • fxplorer: The fxplorer sample demonstrates an SDI Fortran Windows application using the Visual Fortran Dialog Procedures. It uses an Internet Explorer ActiveX control in the main window of the application. The Internet Explorer control is installed with Internet Explorer. If Internet Explorer is not installed, this sample will not run.
  • mmplayer: The mmplayer sample demonstrates a dialog-based Fortran Windows application using the Visual Fortran Dialog Procedures. It uses an ActiveMovie control in the main window of the application. The ActiveMovie control is installed with Internet Explorer. If Internet Explorer is not installed, this sample will not run.
  • progress: The progress sample program demonstrates a "dialog-based" Fortran application using the Visual Fortran Dialog Routines, including the progress bar. The main window of the application is a dialog box. It contains Start, Stop, and Exit buttons plus a progress bar. The Start button begins a lengthy operation that is broken into 100 steps. In this simple example, each step is sleeping for .25 seconds.
  • showfont: The showfont sample demonstrates a "dialog-based" Fortran application using the Visual Fortran Dialog Routines. The main window of the application is a dialog box. This program demonstrates the use of a Tab control. The Tab control is used to select the properties of a font. The font is used to display a sample text string.
  • therm: The therm program demonstrates a "dialog-based" Fortran application using various Visual Fortran Dialog Routines, including several that are new to CVF V6.0. The main window of the application is a dialog box. This program uses a Spin control, a Slider control, a Progress bar control, and Picture controls. It also demonstrates using multiple modeless dialog boxes.
  • whizzy: The whizzy sample demonstrates many of the controls available with the dialog manager module provided by Visual Fortran. Note that it is built with the "Logical Values" compatibility switch set. This is required for correct interaction with the dialog manager routines.

DLL Examples (DLL)

Within Visual Fortran you can create and use dynamically linked libraries (DLLs). A DLL is loaded at run time by its calling modules (.EXE or .DLL). When a DLL is loaded, it is mapped into the address space of the calling process. There are generally two ways to bring in a DLL, either at image activation time or at run-time. If an image is linked against the import library for a DLL the code is mapped into the image's address space at image activation time. If the import library is not available, the DLL needs to be mapped in with Windows API calls.
The following DLL examples can be found in subdirectories under ...\Df98\Samples\DLL:

  • DLLEXP1: The DLLEXP1 sample demonstrates a workspace that contains two projects: one that creates a DLL and a second that uses that DLL, linking against the import library created by the first project. Note that for the Fortran Console application to run, the DLL created by the first project must be found somewhere along the PATH.
  • DLLEXP2: The DLLEXP2 sample demonstrates how COMMON variables defined in a DLL can be shared between multiple programs. Two programs are built against the same DLL. The first program is run, and then PAUSEs. The second program is run and changes the COMMON variables, and exits. When the first program resumes, it displays the changed values.
  • LoadExp1: The LoadExp1 sample demonstrates how to dynamically map a DLL without using an import library. It is a workspace with two projects, one the DLL and the other the executable that uses it.

Exception Handling (ExceptionHandling)

Visual Fortran Version 6.5 introduces some routines to make it easier for the user to control floating-point exception handling:

  • ClearFP: The ClearFP sample demonstrates CLEARSTATUSFPQQ, a subroutine to clear the ia32 floating-point status word exception flags.
  • Cslexcp2: The Cslexcp2 sample demonstrates exception and termination handling in a Fortran Console application.
  • Cslexcp4: The Cslexcp4 sample demonstrates how to wrap a Fortran entry point inside a C try/except block to allow testing for exceptions that might occur in the protected Fortran code.
  • GetEptrs: The GetEptrs sample demonstrates how to establish a signal handler with SIGNALQQ (or the C signal() function) and use the TRACEBACKQQ and GETEXCEPTIONPTRSQQ Fortran library routines to generate a traceback display from the handler.
  • Winexcp1: The Winexcp1 sample demonstrates exception handling in a Fortran Windows application. It was based on the GENERIC sample, with structured exception handling (SEH) incorporated.
  • VBVF1: The VBVF1 sample demonstrates exception handling in a Visual Basic application that calls a Visual Fortran DLL. This is an ia32-only sample.

ISO Varying Strings (Isovar)

The Isovar samples demonstrate one possible implementation for the interface to dynamic-length character strings in Fortran 95. The publicly accessible interface defined by this module is conformant with the auxiliary standard, ISO/IEC 1539-2: 1999. The Isovar samples are in separate directories under ...\Df98\Samples\Isovar and include:

  • unittest: The unittest sample contains 80 small functions that test each of the features of the ISO varying string module. Some of the features tested are concatenation, assignment, and searching for a substring.
  • vocab: The vocab sample uses the ISO varying string module to read a text file and keep a list of each word found in the file and its frequency. When the file is completely read, it prints out the word list and the frequency of each word.
  • wrdcnt: The wrdcnt sample uses the ISO varying string module to read a text file and keep count of how many words are seen. When the file is completely read, it prints out the total number of words found in the file.

Miscellaneous (Misc)

There are a number of miscellaneous samples that demonstrate some specific aspects of Visual Fortran or its utilities. The following miscellaneous examples can be found in separate subdirectories under ...\Df98\Samples\Misc:

  • calcaver: The calcaver sample demonstrates Fortran 90 features, including an interface block, assumed shape array, and the use of modules. It does have a Developer Studio workspace associated with it, or can be built using nmake and the makefile.
  • char2: The char2 sample demonstrates the use of the utility fsplit90. This utility creates separate files for each program unit within a file. Once it has been split, it is identical to charexmp. Build this sample using nmake.
  • charexmp: The charexmp sample does some simple character handling, generating arrays of the alphabet and outputting them to the screen. It has a Developer Studio workspace associated with it, or it can be built using nmake.
  • console: The console sample demonstrates some of the basic console-manipulating routines. Console sets the size of the console, clears the console, and positions the cursor to write a line at the top of the console, and again at a line further below. A DOS command prompt is an example of a console.
  • cvt_lf_unf: The cvt_lf_unf sample converts data files created with Lahey Fortran to an unformatted binary file. There are two projects within this sample:
    • cvt_lf_unf which builds the conversion utility
    • test which uses cvt_lf_unf to convert a data file created by Lahey Fortran and then read it from CVF.
  • fctrl: The fctrl sample is a very simple one, demonstrating recursion. It is a console application, and computes and displays the factorials of the integers 1 to 12. 13! is too big for a 32-bit integer. This sample can be built either from within Developer Studio, or by using the makefile.
  • fivt: The fivt sample is a basic Installation Verification program for Visual Fortran. It compiles and links a program, and then reads the listing file to make sure the expected version of the compiler was used. It can be compiled and run from either the command line or the Developer Studio. To run fivt from the command line, either set FORT5=FIVT.INP, or invoke it as FIVT < FIVT.INP. To run from Developer Studio, refer to the README.TXT file in that directory.
  • forprint: The forprint sample is a console application that uses the OpenFile and Print dialog boxes to select and print text files, including files with Fortran carriage control. Forprint preprocesses the file, generating a text file that can be printed by any printer. This sample can be built either from within Developer Studio or by using the makefile.
  • fppdemo: The fppdemo sample demonstrates the use of the Fortran Preprocessor, FPP. FPP is a C-like preprocessor, as opposed to the preprocessing directives that are part of the Fortran 90 standard. It is easiest to build using the makefile, but there is a Developer Studio workspace for it. This workspace has 5 projects, one per variation of fpp defines. It illustrates how to pass fpp flags to the compiler from the Developer Studio; it must be done by hand from within the Settings dialog box.
  • mandel: The mandel sample demonstrates a simple Win32 application with a C main program calling a Fortran subroutine.
  • uopen: The uopen sample demonstrates the use of the USEROPEN keyword from the OPEN statement. In this particular example, the Fortran file calls a C program to do the specialized OPEN.
  • lcinfo: The lcinfo sample demonstrates the use of NLS routines to support some natural language extensions. It also demonstrates how the string order is affected by choice of natural language. The lcinfo sample is a console application that prints out information about what the different language and currency settings are on the computer.

Mixed-Language (Mixlang)

Visual Fortran can be called by a number of other languages, including Visual C/C++, Visual Basic, and MASM (Assembler). Also, it can call other languages, such as C/C++. The following samples in subdirectories under ...\Df98\Samples\Mixlang demonstrate some of the calling standards or argument definitions that must be used to effectively interwork with other languages:

  • c_call_f: The C_Call_F sample demonstrates a mixed-language application in which a C (or C++) main program calls a Fortran subroutine. It is presented in two different styles; one where the Fortran and C code are built together in the same project and one where the Fortran code is built separately into a DLL which is then called from C. This sample also demonstrates how to pass character/string arguments to Fortran.
  • delphi: This ia32-only sample demonstrates various interactions between Visual Fortran and BorlandTM Delphi. Delphi must be installed to build and run this sample:
    • CallDVF: The CallDVF sample demonstrates calling Fortran from Delphi. There are examples of an integer function, a REAL function, and a character function.
  • spline: The spline sample demonstrates mixed language programming with Visual C/C++. Spline is easiest built from within Developer Studio. The project contains four projects, Console, QuickWin, VC, and spldll. The last project, spldll, creates the dll file used by the other projects.
    The spline sample implements a "best fit curve" algorithm to a set of coordinates. The coordinates are input by clicking on a window or through a data file. Each of the first three projects within this workspace create a different program, using different paradigms:
    • Console creates an application that runs in a console window and takes input from a data file, fsplit.dat
    • QuickWin creates an application using the QuickWin interface that takes input from mouse clicks.
    • VC creates an application using Visual C/C++ and the Microsoft Foundation Classes that takes input from mouse clicks.

    This workspace and its projects also demonstrate one method of dealing with interproject dependencies. It copies the dependent .DLL file to the local directory before linking and running the project.
  • vb: This set of samples demonstrates various interactions between Visual Fortran and Visual Basic (VB). In all cases, there is an executable that is the VB program which you can run. There is also the VB Project, as well as the Visual Fortran project available so you can modify them as you wish:
    • arrays: The arrays sample demonstrates how to pass arrays of strings from VB to CVF
    • callback: The callback sample demonstrates how to invoke VB callback routines passed to a CVF subroutine
    • returnstring: The returnstring sample demonstrates how to call a Fortran character string function from Visual Basic.
    • simple: The simple sample shows very basic interactions between Visual Fortran and VB, passing numbers from one to the other
    • typearrays: The typearrays sample demonstrates how to pass an array of user-defined types from VB to Visual Fortran, including how to write into some fields of that type from within the Fortran routine.
  • MASM: This set of ia32-only samples demonstrates various interactions between Visual Fortran and MASM, Microsoft's Assembly Language. MASM must be installed to build these samples:
    • simple: The simple sample demonstrates the most simple call from Fortran to MASM.
    • vecprod: The vecprod sample demonstrates how to calculate the inner product of two vectors in a MASM program. These two vectors were passed from Fortran to MASM, and the result was passed back to the Fortran main program.
    • allocabl: The allocabl sample is a rewrite of vecprod using allocatable arrays rather than static ones.

QuickWin (Quickwin)

Visual Fortran provides a library of routines called QuickWin. QuickWin is a library that lets you build applications with a simplified version of the Windows interface with Visual Fortran. The QuickWin library provides a rich set of Windows features, but it does not include the complete Windows Applications Programming Interface (API). If you need additional capabilities, you must set up a Windows application to call the Win32 API directly rather than using QuickWin to build your program. The following samples demonstrate how to use QuickWin, and how to program around some of the strange paradigms of the package.
The following QuickWin examples can be found in subdirectories under ...\Df98\Samples\QuickWin:

  • calendar: The calendar sample is a simple QuickWin application. It displays a graphical monthly calendar for the current month.
  • chaos: The chaos sample is a QuickWin application that demonstrates the use of menus, dialog boxes for input and output, message boxes for the signaling of error states, various ways of recovering from error conditions and still keep the program running, QuickWin graphics routines, multi-threading, and Fortran 90. There is a document in the CHAOS subdirectory, README.TXT, that describes this program and its algorithms in more detail.
  • cleanwin: This sample illustrates how to use native Windows APIs to radically change the appearance of a standard QuickWin window.
  • conapp: This sample demonstrates a method for creating a console window from within a QuickWin application. The sample has two parts: a DLL which creates the console window and performs I/O to or from it, and a QuickWin program that calls that DLL. To allow the DLL to access the console using units *, 5, and 6, this sample uses a technique not recommended for any other use. The DLL is linked against the Fortran dynamic-link libraries, but the QuickWin application is linked against the Fortran static libraries. Generally this is discouraged, because using the two different libraries means that the main program and the DLL cannot share I/O units. In this case, that is the intended outcome.
  • dirkeys: This sample demonstrates a mechanism for passing directional keys from QuickWin to the user's program.
  • dirkeys2: This sample illustrates the use of a callback procedure (hook) using SetWindowsHookEx for keyboard events. It demonstrates how to get around the limitations of the PASSDIRKEYS routine, specifically how to trap for Insert, Delete, and Ctrl-C keys.
  • dirkeys4: This sample demonstrates the PASSDIRKEYSQQ routine. The PASSDIRKEYSQQ routine allows easy access to the Insert, Delete, and Ctrl-C keys.
  • menudriv: This sample illustrates three programming idioms for use in QuickWin applications. These are: using the menu to drive various functions; getting control on EXIT; using the status bar to indicate program progress.
  • peekapp: This multi-threaded sample simulates a compute loop with Peekchar and Getchar to handle input as it comes in character by character. It is intended to be used within a QuickWin program.
  • peekapp3: This multi-threaded sample is similar to peekapp, but contains a procedure to perform an orderly shutdown on the character-reading thread.
  • poker: The poker sample demonstrates the use of QuickWin and some simple controls on the window. This sample uses QuickWin to manage the windowing interface, but uses some of the Win32 API calls, and must be linked against dfwin.lib. It should be mentioned that the file CARDS.F90 takes a longer time to compile than any of the o ther files that make up the poker sample. Also, before building, you should make sure you update all dependencies, as there are many.
  • postmini: The Postmini graphical postprocessing software can be used to examine the output of a number of process, device and circuit simulation (TCAD) programs, as well as import data from ASCII files. This version of PostMini uses QuickWin for the graphical interface. Other versions are available for Compaq Tru64 UNIX and OpenVMS Alpha that use other graphical interfaces. Refer to the README file in the PostMini directory for details on this sample.
  • qwpaint: The qwpaint sample demonstrates using mouse callbacks and graphics routines in a QuickWin application. It has two windows, a "control grid" window and a "canvas" window. QuickWin's built-in File.Save option can be used to save the contents of either window as a bitmap (.BMP) file.
  • qwpiano: The qwpiano sample demonstrates using mouse callbacks and menu callbacks in a QuickWin application. It draws a graphical piano keyboard on the screen that can be played using the mouse. It should be noted that two compatibility options, "Logical Values" and "Filenames from Command Line" are set for this sample. The former affects interacting with the QuickWin routines, and the latter causes a File dialog box to come up in response to an OPEN request.
  • Resize: The resize sample demonstrates how to use Win32 API calls from within a QuickWin application to correctly size the information to be displayed to a QuickWin window.
  • testscrl: The testscrl sample demonstrates how to scroll to the last line of a window that has scroll bars. It also shows how to make a window without scroll bars.

Scientific Graphing Utility (SciGraph)

SCIGRAPH is a package of Fortran routines for drawing scientific graphs. Graph types available include line, bar, XY, and pie graphs. All graphs are fully customizable, including control over axis, log scales, data points, colors and shades, error bars, and many other aspects of a scientific graph. All graphs are drawn using Visual Fortran's QuickWin graphics routines, so they can be easily added to an already existing QuickWin application.
The SciGraph package can be found in ...\Df98\Samples\SciGraph:

  • scigraph: The SciGraph sample offers a starting scientific graphing package to support some basic forms of graphs. There are two projects in this sample:
    • Scigraph, which creates a library and some .MOD files
    • Sgdemo, which creates a program to demonstrate some of the basic forms of graphs

    Build the Scigraph project first, followed by Sgdemo. Note that the output area for the SCIGRAPH.LIB project is included as a path to find .MOD files.
    There is a .WRI file in the SCIGRAPH directory that contains basic reference information on the various SciGraph calls, including a list of error returns and possible causes.
    A known limitation of SciGraph is directly related to the known QuickWin limitation of 256 colors on the graphics device. This limitation shows itself when trying to print or save as a bitmap file; only a black screen is printed or saved.

Tutorial

All Tutorial samples are simple programs, and most of them are standalone. Each contains compilation information at the top of the file, both for command line and from within Developer Studio. If there are multiple files, this is noted at the top of the program. All tutorial samples can be found in the directory ...\Df98\Samples\Tutorial:

  • assocn: The assocn sample illustrates the non-associativity of floating-point addition.
  • cycle: The cycle sample illustrates the Fortran 90 statements CYCLE and EXIT.
  • derived: The derived sample demonstrates a derived type structure, type variables, and assign values.
  • dtypearg: The dtypearg sample demonstrates the use of SEQUENCE to allow passing a derived-type argument.
  • dtypecom: The dtypecom sample demonstrates placing derived-type objects in COMMON blocks.
  • dtypemod: The dtypemod sample demonstrates the use of a module to allow passing a derived-type argument. It also shows WRITE of a derived-type.
  • epsilon: The epsilon sample illustrates several calculations of machine epsilon.
  • internal: The internal sample illustrates the use of an internal subroutine and the CONTAINS statement.
  • interval: The interval sample demonstrates the use of rounding control. This sample must be compiled without optimizations.
  • keynames: The keynames sample demonstrates the Fortran concept of using a type structure and a subroutine defined within a module. This sample also requires NAME_SSN.F90 to build.
  • matherr: The matherr sample demonstrates handling run-time math exceptions. This sample is not a standalone application, but can be included in other programs.
  • mathtest: The mathtest sample uses matherr above to demonstrate the response to error conditions on intrinsic math calls. It uses the MATHERRQQ subroutine in MATHERR.F90.
  • mbcomp: The mbcomp sample demonstrates the use of the National Language Support (NLS) routines.
  • namelist: The namelist sample demonstrates the NAMELIST Statement.
  • percent: The percent sample demonstrates a user-defined operator, in this case a unary operator .c. that converts a floating point number to a "percentage".
  • pointer: The pointer sample demonstrates allocating and deallocating pointers and targets.
  • pointer2: The pointer2 sample demonstrates pointing at a pointer and target, and the use of the ASSOCIATED intrinsic.
  • realg: The realg sample demonstrates using coordinate graphics. This sample uses the QuickWin package to display to the screen.
  • recurs: The recurs sample is a very simple demonstration of a recursive subroutine.
  • showfont: The showfont sample uses QuickWin to display a variety of fonts. This sample demonstrates various calls to QuickWin.
  • sigtest: The sigtest sample demonstrates user-defined exception handlers. It shows how to establish the name of the exception handler as the function to be invoked if an exception happens.
  • sine: The sine sample demonstrates the use of QuickWin to output sine waves and some simple shapes.
  • testget: The testget sample illustrates the use of internal READ to convert from REAL to CHARACTER. This is best run from outside of Developer Studio, and can be built simply by df testget.f90.
  • threads: The threads sample demonstrates multiple threads with QuickWin. It is a much simpler program than advanced\win32\bounce, but is not as efficient at run time.
  • unclear: The unclear sample demonstrates the use of generic module procedures. A generic procedure called "dup" has three instances; one with real arguments, one with integer arguments, and one with character arguments.
  • where: The where sample demonstrates the Fortran 90 constructs WHERE and ELSEWHERE.


Using the Compiler and Linker from the Command Line

The DF command is used to compile and link your programs. In most cases, you will use a single DF command to invoke the compiler and linker. The DF command invokes a driver program that is the actual user interface to the compiler and linker. It accepts a list of command options and file names and directs processing for each file.

If you will be using the DF command from the command line, you can use:

  • The supplied Fortran Command Prompt window in the Compaq Visual Fortran program folder, in which the appropriate environment variables in DFVARS.BAT are preset.
  • Your own terminal window, in which you have set the appropriate environment variables by executing the DFVARS.BAT file. This file sets the environment variables (such as PATH, INCLUDE, and LIB) and allows use of IMSL and CXML libraries. By default, DFVARS.BAT is installed in \Program Files\Microsoft Visual Studio\Df98\BIN.

The driver program does the following:

  • Calls the Visual Fortran compiler to process Fortran files.
  • Passes the linker options to the linker.
  • Passes object files created by the compiler to the linker.
  • Passes libraries to the linker.
  • Calls the linker or librarian to create the .EXE or library file.

The DF command automatically references the appropriate Visual Fortran Run-Time Libraries when it invokes the linker. Therefore, to link one or more object files created by the Visual Fortran compiler, you should use the DF command instead of the LINK command.

Because the DF driver calls other software components, error messages may be returned by these other components. For instance, the linker may return a message if it cannot resolve a global reference. Using the /watch:cmd option on the DF command line can help clarify which component is generating the error.

This section contains the following information:

  • The Format of the DF Command
  • Examples of the DF Command Format
  • Input and Output Files
  • Environment Variables Used with the DF Command
  • Specifying Project Types with DF Command Options
  • Redirecting Command-Line Output to Files
  • Using the DF Command to Compile and Link
  • DF Indirect Command File Use
  • Compiler and Linker Messages


The Format of the DF Command

This section describes the format of the DF command. It also provides an alphabetical list of DF command options.

The DF command accepts both compiler options and linker options. The command driver requires that the following rules be observed when specifying the DF command:

  • Except for the linker options, options can be specified in any order.
  • Linker options must be preceded by the keyword /link and must be specified at the end of the command line, following all other options.

The DF command has the following form:

   DF options [/link options]
options

A list of compiler options (or linker options preceded by the /link option). These lists of options take the following form:

   [/option:[arg]] [filename.ext]...

Where:

/option[:arg]

Indicates either special actions to be performed by the compiler or linker, or special properties of input or output files.

The following rules apply to options and their names:

  • Options begin with a slash (/). You can use a dash (-) instead of a slash.
  • Visual Fortran options are not case-sensitive. Certain options provided for compatibility with Microsoft Fortran PowerStation options are case-sensitive, such as /FA and /Fafile.
  • You can abbreviate option names. You need only enter as many characters as are needed to uniquely identify the option.

Certain options accept one or more keyword arguments following the option name. For example, the /warn option accepts several keywords, including argument_checking and declarations.

To specify only a single keyword, specify the keyword after the colon (:). For example, the following specifies the /warn option declarations keyword:

   DF /warn:declarations test.f90

To specify multiple keywords, specify the option name once, and place each keyword in a comma-separated list enclosed within parentheses with no spaces between keywords, as follows:

   DF /warn:(argument_checking,declarations)  test.f90

Instead of the colon, you can use an equal sign (=):

   DF /warn=(argument_checking,declarations)  test.f90
filename.ext

Specifies the files to be processed. You can use wildcard characters (such as *.f90) to indicate multiple files or you can specify each file name.

The file extension identifies the type of the file. With Fortran source files, certain file extensions indicate whether that source file contains source code in free (such as .f90) or fixed (such as .for) source form. You can also specify compiler options to indicate fixed or free source form (see /[no]free).

The file extension determines whether that file gets passed to the compiler or to the linker. For example, files myfile.for and projfile.f are passed to the compiler and file myobj.obj is passed to the linker.

Compiler Options, Alphabetic List

The following table lists the DF command compiler options alphabetically:

/[no]alignment | /[no]altparam
/architecture | /[no]asmattributes
/[no]asmfile | /assume
/[no]automatic | /bintext
/[no]browser | /ccdefault
/[no]check | /[no]comments
/[no]compile_only | /convert
/cxml | /[no]d_lines
/[no]dbglibs | /[no]debug
/define | /dll
/[no]error_limit | /[no]exe
/[no]extend_source | /extfor
/extfpp | /extlnk
/[no]f66 | /[no]f77rtl
/fast | /[no]fixed
/[no]fltconsistency (ia32 only) | /[no]fpconstant
/fpe | /fpp
/[no]fpscomp | /[no]free
/help or /? | /iface
/imsl | /[no]include
/[no]inline | /[no]intconstant
/integer_size | /[no]keep
/[no]libdir | /libs
/[no]link | /[no]list
/[no]logo | /[no]machine_code
/[no]map | /math_library
/[no]module | /names
/[no]object | /[no]optimize
/[no]pad_source | /[no]pdbfile
/[no]pipeline (ia64 only) | /preprocess_only
/real_size | /[no]recursive
/[no]reentrancy | /[no]show
/source | /[no]static
/[no]stand | /[no]syntax_only
/[no]threads | /[no]traceback
/[no]transform_loops | /tune
/undefine | /unroll
/[no]vms | /[no]warn
/[no]watch | /what
/winapp

For more information:

  • On DF command examples, see Examples of the DF Command Format
  • On compiler option categories, see Categories of Compiler Options
  • On using the FL32 command, see Microsoft Fortran PowerStation Command-Line Compatibility
  • About Fortran PowerStation options (such as /MD) and their DF command equivalents, see Equivalent Visual Fortran Compiler Options


Examples of the DF Command Format

The following examples demonstrate valid and invalid DF commands:

Valid DF Commands

In the following example, the file to be compiled is test.f90 and the file proj.obj is passed to the linker:

   DF test.f90 proj.obj

In this example, the .f90 file extension indicates test.f90 is a Fortran free-form source file to be compiled. The file extension of obj indicates proj.obj is an object file to be passed to the linker. You can optionally add the /link option before the file proj.obj to indicate it should be passed directly to the linker.

In the following example, the /check:bounds option requests that the Fortran compiler generate additional code to perform run-time checking for out-of-bounds array and substring references for the files myfile.for and test.for (fixed-form source):

   DF /check:bounds myfile.for test.for

In the following example, the /link option indicates that files and options after the /link option are passed directly to the linker:

    DF myfile.for /link myobject.obj /out:myprog.exe

Invalid DF commands

The following DF command is invalid because the /link option indicates that items after the /link option are passed directly to the linker, but the file test.for should be passed to the compiler:

    DF myfile.for /link test.for /out:myprog.exe

The following DF command is invalid because the /link option is missing and the /out linker option is not recognized as a compiler option:

   DF myfile.for test.for /out:myprog.exe

A correct form of this command is:

   DF myfile.for test.for /link /out:myprog.exe

In this case, you can alternatively use one of the DF options (/exe) that specifies information to the linker:

   DF myfile.for test.for /exe:myprog.exe

For more information:

  • Environment Variables Used with the DF Command
  • Specifying Project Types with DF Command Options
  • Using the DF Command to Compile and Link
  • DF Indirect Command File Use
  • Compiler and Linker Messages


Input and Output Files

You can use the DF command to process multiple files. These files can be source files, object files, or object libraries.

When a file is not in your path or working directory, specify the directory path before the file name.

The file extension determines whether a file gets passed to the compiler or to the linker. The following types of files are used with the DF command:

  • Files passed to the compiler: .f90, .for, .f, .fpp, .i, .i90, .inc, .fi, .fd, .f77

    Typical Fortran (DF command) source files have a file extension of .f90, .for, and .f. When editing your source files, you need to choose the source form, either free-source form or fixed-source form (or a variant of fixed form called tab form). You can either use a compiler option to specify the source form used by the source files (see /fixed or /free), or you can use the following file extensions when creating or renaming your files:

    • The compiler assumes that files with an extension of .f90, .F90, or .i90 are free-form source files.
    • The compiler assumes that files with an extension of .f, .for, .FOR, or .i are fixed-form (or tab-form) files.

  • Files passed to the linker: .lib, .obj, .o, .exe, .res, .rbj, .def, .dll

    For example, object files usually have a file extension of .obj. Files with extensions of .lib are usually library files.

The output produced by the DF command includes:

  • An object file (.OBJ) if you specify the /compile_only, /keep, or /object option on the command line.
  • An executable file (.EXE) if you do not specify the /compile_only option
  • A dynamic-link library file (.DLL) if you specify the /dll option and do not specify the /compile_only option
  • A module file (.MOD) if a source file being compiled defines a Fortran 90 module (MODULE statement)
  • A program database file (.PDB) if you specify the /pdbfile or /debug:full (or equivalent) options
  • A listing file (.LST) if you specify the /list option
  • A browser file (.SBR) if you specify the /browser option

You control the production of these files by specifying the appropriate options on the DF command line. Unless you specify the /compile_only option or /keep option, the compiler generates a single temporary object file from one or more source files. The linker is then invoked to link the object file into one executable image file.

If fatal errors are encountered during compilation, or if you specify certain options such as /compile_only, linking does not occur.

When a path or file name includes an embedded space or a special character, enclose the entire file location name in double quotation marks ("). For example:

   DF "Project xyz\fortmain.f90"

For more information about naming input and output files, see:

  • Naming Output Files
  • Temporary Files


Naming Output Files

To specify a file name for the executable image file, you can use one of several DF options:

  • The /exe:file or the /out:file linker option to name an executable program file.
  • The /dll:file alone or the /dll option with the /out:file linker option to name an executable dynamic-link library.

You can also use the /object:file option to specify the object file name. If you specify the /compile_only option and omit the /object:file option, each source file is compiled into a separate object file. For more information about the output file(s) created by compiling and linking multiple files, see Compiling and Linking Multiple Fortran Source Files.

Many compiler options allow you to specify the name of the file being created. If you specify only a filename without an extension, a default extension is added for the file being created, as summarized below:

Default File Extensions for Compiler Options

Option | Default File Extension
/asmfile:file | .ASM
/browser:file | .SBR
/dll:file | .DLL
/exe:file | .EXE
/list:file | .LST
/map:file | .MAP
/pdbfile:file | .PDB (default filename is df60.pdb)


Temporary Files

Temporary files created by the compiler or linker reside in the directory used by the operating system to store temporary files. To store temporary files, the operating system first checks for the TMP environment variable.

If the TMP environment variable is defined, the directory that it points to is used for temporary files. If the TMP environment variable is not defined, the operating system checks for the TEMP environment variable. If the TEMP environment variable is not defined, the current working directory is used for temporary files. Temporary files are usually deleted, unless the /keep option was specified. For performance reasons, use a local drive (rather than using a network drive) to contain the temporary files.

To view the file name and directory where each temporary file is created, use the /watch:cmd option. To create object files in your current working directory, use the /compile_only or /keep option. Any object files (.obj files) that you specify on the DF command line are retained.


Environment Variables Used with the DF Command

The following table shows the environment variables that affect the DF command.

Environment Variables Affecting the DF Command

Environment Variable | Description
PATH | The PATH environment variable sets the search path.
LIB | The linker uses the LIB environment variable to determine the location of .LIB files. If the LIB environment variable is not set, the linker looks for .LIB files in the current directory.
LINK_F90 | The LINK_F90 environment variable contains a list of libraries used for linking IMSL libraries (Professional and Enterprise Editions), as listed in Library Naming Conventions.
INCLUDE | The make facility (NMAKE) uses the INCLUDE environment variable to locate INCLUDE files and module files. The Visual Fortran compiler uses the INCLUDE environment variable to locate files included by an INCLUDE statement or module files referenced by a USE statement. Similarly, the resource compiler uses the INCLUDE environment variable to locate #include and RCINCLUDE files.
DF | The DF environment variable can be used to specify frequently used DF options and files. The options and files specified by the DF environment variable are added to the DF command; they are processed before any options specified on the command line. You can override an option specified in the DF environment variable by specifying an option on the command line. For information about using the DF environment variable to specify frequently-used options, see Using the DF Environment Variable to Specify Options.

You can set these environment variables by using the DFVARS.BAT file or the Fortran Command Prompt command-line window (see "Using the Command-Line Interface" in Compaq Visual Fortran Installing and Getting Started).

For a list of environment variables recognized at run-time, see Run-Time Environment Variables.


Specifying Project Types with DF Command Options

This section provides the DF command options that correspond to the visual development environment project types.

When creating an application, you should choose a project type. The first four projects are main project types, requiring main programs:

  • To create a Fortran Console Application with the DF command, you do not need to specify any options (if you link separately, specify the link option /subsystem:console). This is the default project type created.
  • To create a Fortran Standard Graphics Application with the DF command, specify the /libs=qwins option (which also sets certain linker options).
  • To create a Fortran QuickWin Application with the DF command, specify the /libs:qwin option (which also sets certain linker options).
  • To create a Fortran Windows Application with the DF command, specify the /winapp option (which also sets certain linker options).

To create a Fortran COM Server, you must use Developer Studio (see Creating COM Servers); you cannot create a Fortran COM Server project type with the DF command.

The following types are library projects, without main programs:

  • To create a Fortran Dynamic-Link Library with the DF command, specify the /dll option (sets the /libs:dll option).

  • To create a Fortran Static library with the DF command:

    • If your application will not call any QuickWin or Standard Graphics routines, specify /libs:static and /compile_only options to create the object files. Use the LIB command to create the library (see Managing Libraries with LIB).
    • If your application will call QuickWin routines, specify /libs:qwin and /compile_only options to create the object files. Use the LIB command to create the library (see Managing Libraries with LIB).
    • If your application will call Standard Graphics routines, specify /libs:qwins and /compile_only options to create the object files. Use the LIB command to create the library (see Managing Libraries with LIB).

For an introduction to Visual Fortran project types, see Types of Projects.


Redirecting Command-Line Output to Files

When using the command line, you can redirect standard output and standard error into separate files or into a single file. How you redirect command-line output depends on which operating system you are using:

  • On Windows NT 4 and Windows 2000 systems, to place standard output into file one.out and standard error into file two.out, type the df command (with its filenames and options) as follows:
      df filenames /options 1>one.out 2>two.out

    You can also use a short-cut form (omit the 1):

      df filenames /options >one.out 2>two.out

    To place standard output and standard error into a single file both.out on a Windows NT 4 or Windows 2000 system, type the df command as follows:

      df filenames /options 1>both.out 2>&1

    You can also use a short-cut form (omit the 1):

      df filenames /options >both.out 2>&1
  • On Windows 98, Windows Me, and Windows 95 systems, use the EC command-line tool to place standard output and standard error into separate files or into a single file. The EC tool is located on the Visual Fortran CD-ROM in the x86\Usupport\Misc\Win95 folder. Copy ec.exe into a folder in your command-line path (PATH environment variable) on your hard disk.

    Precede the DF command line with the EC command and place the entire DF command in quotes. For example, to place standard output into the file one.out and standard error into file two.out, type the EC and DF command (with its filenames and options) as follows:

      ec "df filenames /options 1>one.out 2>two.out"

    To place standard output and standard error into a single file both.out on a Windows 98, Windows Me, or Windows 95 system, type the EC and DF commands as follows:

       ec "df filenames /options 1>both.out 2>&1"


Using the DF Command to Compile and Link

By default, when you use the DF command, your source files are compiled and then linked. To suppress linking, use the /compile_only option. The following topics show how to use the DF command:

  • Compiling and Linking a Single Source File
  • Using the DF Environment Variable to Specify Options
  • Compiling, but not Linking, a Fortran Source File
  • Compiling and Linking Multiple Fortran Source Files
  • Generating a Listing File
  • Linking Against Additional Libraries
  • Linking Object Files
  • Compiling and Linking for Debugging
  • Compiling and Linking for Optimization
  • Compiling and Linking Mixed-Language Programs


Compiling and Linking a Single Source File

The following command compiles x.for, links, and creates an executable file named x.exe. This command generates a temporary object file, which is deleted after linking:

   DF x.for

To name the executable file, specify the /exe option:

   DF x.for /exe:myprog.exe

Alternatively, you can name the executable file by using the linker /out option:

   DF x.for /link /out:myprog.exe


Using the DF Environment Variable to Specify Options

The following command-line sequences show the use of the DF environment variable. In the first command sequence, the SET command sets the DF environment variable. When the DF command is invoked, it uses the options specified by the DF environment variable, in this case, /debug:minimal and /list:

  set DF=/debug:minimal /list
  DF myprog.for

You can also specify additional options on the DF command line. In the following command sequence, the SET command sets the DF environment variable. The DF options specified are /debug:minimal and /list.

  set DF=/debug:minimal /list
  DF myprog.for /show:map

If the options specified on the command line conflict with the options specified by the DF environment variable, the option specified on the command line takes precedence. In the following command sequence, the /debug:minimal option specified by the DF environment variable is overridden by the /debug:none option specified on the command line:

  set DF=/debug:minimal /list
  DF myprog.for /debug:none


Compiling, but not Linking, a Fortran Source File

The following command compiles x.for and generates the object file x.obj. The /compile_only option prevents linking (it does not link the object file into an executable file):

   DF x.for /compile_only


Compiling and Linking Multiple Fortran Source Files

The following command compiles a.for, b.for, and c.for. It creates a single temporary object file, then links the object file into an executable file named a.exe:

  DF a.for b.for c.for

If the files a.for, b.for, and c.for were the only .for files in the current directory, you could use a wildcard character to similarly compile the three source files:

  DF  *.for

If you use the /compile_only option to prevent linking, also use the /object:file option so that multiple sources files are compiled into a single object file, allowing more optimizations to occur:

  DF /compile_only /object:a.obj  a.for b.for c.for

When you use modules and compile multiple files, compile the source files that define modules before the files that reference the modules (in USE statements).

When you use a single DF command, the order in which files are placed on the command line is significant. For example, if the free-form source file moddef.f90 defines the modules referenced by the file projmain.f90, use the following DF command line:

  DF moddef.f90 projmain.f90


Generating a Listing File

To request a listing file, specify the /list option with the DF command. When you request a listing file, a separate listing file is generated for each object file created.

The content of the listing file is affected by the /show option. For more information about this option, see Compiler and Linker Options.

The following command compiles and links a.for, b.for, and c.for. It generates one listing file for the three source files:

  DF a.for b.for c.for /list

The following command compiles a.for, b.for, and c.for. It generates three listing files (and three object files) for the three source files:

  DF a.for b.for c.for /list /compile_only

The following command sequence compiles and links a.for, b.for, and c.for. It generates one named object file (a.obj) and one listing file (a.lst). The second command links the object files into an executable file (a.exe):

  DF a.for b.for c.for /list /compile_only /object:a.obj
  DF a.obj

The following command sequence compiles and links a.for, b.for, and c.for. It generates three object files (a.obj, b.obj, and c.obj) and three listing files (a.lst, b.lst, and c.lst). The second command links the object files into an executable file (a.exe):

  DF a.for b.for c.for /list /compile_only
  DF a.obj b.obj c.obj


Linking Against Additional Libraries

By default, the DF command automatically adds the libraries needed to build a Fortran Console application to the link command that it generates.

The /libs:dll option indicates that you want to link against single-threaded DLLs; other /libs options allow you to link against other types of libraries. The /libs:static option (the default) indicates that you want to link against single-threaded static libraries.

You can link against additional libraries by listing those libraries on the command line.

For example, the following command links against static libraries. In addition to linking against the default libraries, it links against the library mylib.lib:

  DF x.f90 mylib.lib

The following command links against single-threaded DLLs:

  DF x.f90 /libs:dll

The following command links against single-threaded DLLs. It links against the default libraries and mylib.lib:

   DF x.f90 /libs:dll mylib.lib

To request the creation of a dynamic-link library, see /dll.

For more information on the types of libraries available to link against, see the following options:

  • /dbglibs
  • /libs
  • /threads
  • /winapp
  • /fpscomp:libs

For more information about compiling and linking Visual Fortran and Visual C++ programs (and the libraries used), see Specifying Consistent Library Types.


Linking Object Files

The following command links x.obj into an executable file. This command automatically links with the default Visual Fortran libraries:

   DF x.obj


Compiling and Linking for Debugging

If you use a single DF command to compile and link, specify the /debug option (/debug sets the default optimization level to /optimize:0), as follows:

   DF x.for /debug

By default, the debugger symbol table information is created in a PDB file, which is needed for the debugger integrated within the visual development environment.

If you use separate DF commands to compile and link, you will want to specify the same debugging information level for the compiler and the linker. For example, if you specify /debug:minimal to the compiler, you will also specify /link /debug:minimal. The following command sequence compiles and then links x.for for debugging with the integrated visual development environment debugger:

  DF x.for /debug:full /optimize:0 /compile_only
  DF x.obj /debug:full

For more information about preparing your command-line program for debugging, see Preparing Your Program for Debugging.


Compiling and Linking for Optimization

If you omit both the /compile_only and the /keep options, the specified Fortran source files are compiled together into a single object module and then linked. (The object file is deleted after linking.) Because all the Fortran source files are compiled together into a single object module, full interprocedural optimizations can occur. With the DF command, the default optimization level is /optimize:4 (unless you specify /debug with no keyword).

If you specify the /compile_only or /keep option and you want to allow full interprocedural optimizations to occur, you should also specify the /object option. The combination of the /compile_only and /object:file options creates a single object file from multiple Fortran source files, allowing full interprocedural optimizations. The object file can be linked later.

The following command uses both the /compile_only and /object options to allow interprocedural optimization (explicitly requested by the /optimize:4 option):

  DF /compile_only /object:out.obj /optimize:4 ax.for bx.for cx.for

If you specify the /compile_only or /keep option without specifying the /object option, each source file is compiled into an object file. This is acceptable if you specified no optimization (/optimize:0) or local optimization (/optimize:1). An information message appears when you specify multiple input files and specify an option that creates multiple object files (such as /compile_only without /object) and specify or imply global optimization (/optimize:2 or higher optimization level).

If you specify the /compile_only option, you must link the object file (or files) later by using a separate DF command. You might do this using a makefile processed by the NMAKE command for incremental compilation of a large application.

However, keep in mind that either omitting the /compile_only or /keep option or using the /compile_only option with the /object:file option provides the benefit of full interprocedural optimizations for compiling multiple Fortran source files.

Other optimization options are summarized in Software Environment and Efficient Compilation.


Compiling and Linking Mixed-Language Programs

Your application can contain both C and Fortran source files. If your main program is a Fortran source file (myprog.for) that calls a routine written in C (cfunc.c), you could use the following sequence of commands to build your application:

  cl -c cfunc.c
  DF myprog.for cfunc.obj /link /out:myprog.exe

The cl command (invokes the C compiler) compiles but does not link cfunc.c. The -c option specifies that the linker is not called. This command creates cfunc.obj. The DF command compiles myprog.for and links cfunc.obj with the object file created from myprog.for to create myprog.exe.

For more information about compiling and linking Visual Fortran and Visual C++ programs, and the libraries used, see:

  • Specifying Consistent Library Types
  • Visual Fortran/Visual C++ Mixed-Language Programs.


DF Indirect Command File Use

The DF command allows the use of indirect command files. For example, assume the file text.txt contains the following:

  /pdbfile:testout.pdb /exe:testout.exe /debug:full /optimize:0 test.f90 rest.f90

The following DF command executes the contents of file text.txt as an indirect command file to create a debugging version of the executable program and its associated PDB file:

   DF @test.txt

Indirect command files do not use continuation characters; all lines are appended together as one command.


Compiler and Linker Messages

The following sections describe compiler limits and messages:

  • Compiler Diagnostic Messages and Error Conditions
  • Linker Diagnostic Messages and Error Conditions

For information on compiler limits, see Compiler Limits.


Compiler Diagnostic Messages and Error Conditions

The Visual Fortran compiler identifies syntax errors and violations of language rules in the source program. If the compiler finds any errors, it writes messages to the standard error output file and any listing file. If you enter the DF command interactively, the messages are displayed.

Compiler messages have the following format:

  filename(n) : severity: message-text
          [text-in-error]
  --------^

The pointer (---^) indicates the exact place on the source program line where the error was found. The following error message shows the format and message text in a listing file when an END DO statement was omitted:

  echar.for(7): Severe: Unclosed DO loop or IF block
          DO I=1,5
  --------^

Diagnostic messages usually provide enough information for you to determine the cause of an error and correct it.

When using the command line, make sure that the appropriate environment variables have been set by executing the DFVARS.BAT file. These environment variables are preset if you use the Fortran Command Prompt window in the Compaq Visual Fortran program folder (see "Using the Command-Line Interface" in Compaq Visual Fortran Installing and Getting Started). For example, this BAT file sets the environment variables for the include directory paths.

For errors related to INCLUDE and module (USE statement) file use, see /[no]include.

For a list of environment variables used by the DF command during compilation, see Environment Variables Used with the DF Command.

To control compiler diagnostic messages (such as warning messages), see /[no]warn.

To view the passes as they execute on the DF command line, specify /watch:cmd or /watch:all.


Linker Diagnostic Messages and Error Conditions

If the linker detects any errors while linking object modules, it displays messages about their cause and severity. If any errors occur, the linker does not produce an executable file.

Linker messages are descriptive, and you do not normally need additional information to determine the specific error. For a description of each Linker message, see Linker Messages (LNKxxxx).

To view the libraries being passed to the linker on the DF command line, specify /watch:cmd or /watch:all.

On the command line, make sure the DFVARS.BAT file was executed to set the appropriate environment variables (see "Using the Command-Line Interface" in Compaq Visual Fortran Installing and Getting Started). For example, this BAT file sets the environment variables for the library directory paths. For a list of environment variables used by the DF command during compilation, see Environment Variables Used with the DF Command.

You specify the libraries to be linked against using compiler options in the Libraries category (see Categories of Compiler Options, Libraries category). Also, you can specify libraries (include the path, if needed) on the command line.

With the Professional and Enterprise Editions, if you have trouble linking IMSL libraries, specify the /imsl option and see also Using the IMSL Libraries from Visual Fortran.

For information on handling build errors in the visual development environment, see Errors During the Build Process.


Compiler and Linker Options

Most of the compiler and linker options can be specified within the Microsoft visual development environment or on the command line. This section contains a description of the options available to you in building programs.

You can set compiler options from:

  • Within the visual development environment, by using the Fortran tab in the Project menu, Settings dialog box.
  • The DF command line. Compiler options must precede the /LINK option.

Unless you specify certain options, the DF command line will both compile and link the files you specify. To compile without linking, specify the /compile_only (or equivalent) option.

After the /LINK option on the DF command line, you can specify linker options. Linker options and any libraries specified get passed directly to the linker, such as /NODEFAULTLIB. If you choose to use separate compile and link commands, you can also specify linker options on a separate LINK command.

This section contains the following information:

  • Compiler Options
  • Linker Options and Related information
  • Microsoft Fortran PowerStation Command-Line Compatibility


Compiler Options

This section describes the compiler options and how they are used. It includes the following topics:

  • Categories of compiler options, according to functional grouping.
  • Descriptions of each compiler option, listed alphabetically.


Categories of Compiler Options

If you will be using the compiler and linker from the command line, specify the options needed on the DF command line (as described in Using the Compiler and Linker from the Command Line). You can use the functional categories of options below to locate the options needed for your application.

If you will be using the compiler and linker from the Microsoft visual development environment, select the options needed by using the various tabs in the Project menu Settings item (see Project Settings). The following graphic shows a sample Fortran tab:

Project Settings, Fortran Tab

project settings, fortran tab

The options are grouped under functional categories (the initial Category is General, as shown) to help you locate the options needed for your application. From the Fortran tab, you can select one of the following categories from the Category drop-down list (exception: those options listed in the Miscellaneous category below):

General | Code Generation
Compatibility | Compilation Diagnostics
Debug | External Procedures
Floating Point | Fortran Data
Fortran Language | Libraries
Listing Files | Miscellaneous
Optimizations | Preprocessor
Run-Time |

If a compiler option is not available in the dialog boxes, you can enter the option in the lower part of the Project Settings dialog box just as you would at the command line (under Project Options:).

The following tables list the Visual Fortran compiler options by category in the Fortran tab:

General-Purpose Options

Debugging Level | /[no]debug
Warning Level | /warn
Optimization Level | /[no]optimize
Predefined Preprocessor Symbols | /define
Generate Source Browse Information | /[no]browser[:file]

Code Generation Options

Generate Most-Optimized Code | /[no]fast (changes multiple options)
Enable Recursive Routines | /[no]recursive
Object text string inserted into object file | /bintext:string
Math Library: Checking or Fast Performance | /math_library
Generate Code for xxx Chip | /architecture

Compatibility Options (See also Fortran Data)

Unformatted File Conversion (Nonnative Data) | /convert (also see /assume:[no]byterecl)
Enable VMS Compatibility | /[no]vms
Enable F77 Run-Time Compatibility | /[no]f77rtl
Use F77 Integer Constants | /[no]intconstant
Microsoft Fortran PowerStation V4 Compatibility Options | /[no]fpscomp (various keywords listed below)
Microsoft Fortran PowerStation: Filenames from Command Line | /fpscomp:[no]filesfromcmd
Microsoft Fortran PowerStation: I/O Format | /fpscomp:[no]ioformat
Microsoft Fortran PowerStation: Libraries | /fpscomp:[no]libs
Microsoft Fortran PowerStation: List Directed I/O Spacing | /fpscomp:[no]ldio_spacing
Microsoft Fortran PowerStation: Logical Values | /fpscomp:[no]logicals
Microsoft Fortran PowerStation: Other Run-time Behavior | /fpscomp:[no]general
Microsoft Fortran PowerStation: Predefined Preprocessor Symbols | /fpscomp:[no]symbols

Compilation Diagnostic Options

Compilation Error Limit | /[no]error_limit
Warning Levels (Ignore, Normal, Treat Warnings as Errors) | /warn:nogeneral, default settings, or /warn:errors
Fortran Standards Checking (None, Fortran 90, or Fortran 95) | /stand:keyword
Treat Fortran Standard Warnings as Errors | /warn:[no]stderrors
Argument Mismatch | /warn:[no]argument_checking
Data Alignment | /warn:[no]alignments
Inform when Compiling Files Separately (effect on interprocedure optimization) | /warn:[no]fileopt
Truncated Source | /warn:[no]truncated_source
Uncalled Routines | /warn:[no]uncalled
Undeclared Variables/Symbols | /warn:[no]declarations
Uninitialized Variables | /warn:[no]uninitialized
Unused Variables | /warn:[no]unused
Usage (Fortran language) | /warn:[no]usage

Debug Options

Debugging Level (None, Minimal, Partial, Full) | /[no]debug
Compile Lines With D in Column 1 | /[no]d_lines
Use Program Database for Debug Information and File Name | /[no]pdbfile[:file]

External Procedures (and Argument Passing) Options

Argument Passing Conventions | /[no]iface:keyword
External Names Case Interpretation | /names:keyword
String Length Argument Passing | /[no]iface:mixed_str_len_arg
Append Underscore to External Names | /assume:[no]underscore

Fortran Data Options (See also Compatibility)

Default REAL and COMPLEX Kind | /real_size:num
Default INTEGER and LOGICAL Kind | /integer_size:num
Append Underscore to External Names (under Data Options) | /assume:[no]underscore
Enable Dummy Arguments Sharing Memory Locations | /assume:[no]dummy_aliases
Extend Precision of Single-Precision Constants | /[no]fpconstant
Use Bytes as RECL= Unit for Unformatted Files | /assume:[no]byterecl
Variables Default to Automatic or Static Storage | /[no]automatic or /[no]static
Common Element Alignment | /[no]alignment:[no]common
Structure Element Alignment (Derived Type and Record Data) | /alignment:[no]records
Allow SEQUENCE Types to be Padded for Alignment | /alignment:[no]sequence

Floating-Point Options (See also Optimizations)

Floating-Point Exception Handling | /fpe
Enable Floating-Point Consistency | /[no]fltconsistency (ia32 only)
Extend Precision of Single-Precision Constants | /[no]fpconstant
Enable IEEE Minus Zero Support | /assume:[no]minus0

Fortran Language Options

Enable FORTRAN 66 Semantics | /[no]f66
Enable Alternate PARAMETER Syntax | /[no]altparam
Name Case Interpretation | /names:keyword
Source Form (File Extension, Fixed Form, or Free Form) | /[no]free or /[no]fixed
Fixed-Form Line Length | /[no]extend_source
Pad Fixed-Form Source Records | /[no]pad_source

Library Options (See also External Procedures)

Enable Reentrancy Support | /[no]reentrancy
Use Run-Time Libraries, DLL version | /libs:dll
Use Run-Time Libraries, Static library version | /libs:static
Use Run-Time Libraries, QuickWin version | /libs:qwin
Use Run-Time Libraries, Standard Graphics version | /libs:qwins
Use Run-Time Libraries, Debug version | /[no]dbglibs
Use Run-Time Libraries, Multi-Threaded version | /[no]threads
Disable Default Library Search Rules | /libdir:noauto
Disable OBJCOMMENT Library Names in Object | /libdir:nouser
Use Common Windows Libraries | /winapp
Use Compaq Extended Math Library (CXML) | /cxml
Use IMSL Math Libraries | /imsl

Listing and Assembly File Options

Source Listing | /[no]list
Contents of Source Listing File | /show:keyword... or /[no]machine_code
Annotations | /annotations:keyword
Assembly Listing | /[no]asmfile [:file] and /[no]asmattributes

Miscellaneous Linker Tab and Command-Line Options (Not Listed in Fortran Tab)

Specify Linker Options (after /link) | /link (use Linker tab)
Generate Link Map | /[no]map (use Linker tab)
Compile, Do Not Link | /compile_only or /c (use Compile in Build menu)
Create Dynamic Link Library (DLL project type) | /dll and Specifying Project Types with DF Command Options
Software Instruction Scheduling | /[no]pipeline (ia64 only; command line only)
Display Help Text File | /help or /? (command line only)
Specify Custom File Extension for Compiler | /source (command line only)
Specify Custom File Extension for Compiler | /extfor (command line only)
Specify Custom File Extension for Linker | /extlnk (command line only)
Create one object file for each input source file | /[no]keep (command line only)
Name of Executable Program or DLL File | /[no]exe[:file] (command line only)
Name of Object File | /[no]object[:file] (command line only)
Perform Syntax Check Only (No Object File) | /[no]syntax_only (command line only)
Display Copyright and Compiler Version | /nologo and /what (command line only)
Display Compilation Details | /[no]watch (command line only)
Write C-Style Comments for FPP | /comments (command line only; for FPP)
Specify Custom File Extension for FPP | /extfpp (command line only)
Only Preprocess FPP Files | /preprocess_only (command line only)
Undefine Preprocessor Symbols | /undefine (command line only)

Optimization Options (See also Code Generation)

Optimization Level | /[no]optimize
Variables Default to Automatic Storage | /[no]automatic
Enable Dummy Arguments Sharing Memory Locations | /assume:[no]dummy_aliases
Transform Loops | /[no]transform_loops
Enable I/O Buffering | /assume:[no]buffered_io
Loop Unrolling | /unroll
Math Library: Checking or Fast Performance | /math_library
Inlining Procedures | /[no]inline
Code Tuning for xxx chip | /tune
Allow Reordering of Floating-Point Operations | /assume:[no]accuracy_sensitive
Software Instruction Scheduling | /[no]pipeline (ia64 only; command line only)

Preprocessor Options

Define Preprocessor Symbols | /define
Default INCLUDE and USE Path | /assume:[no]source_include
Module path (to place module files) | /module[:file]
INCLUDE and USE Path | /[no]include
Use FPP and specify options | /fpp[:"options"]
Predefined Preprocessor Symbols to FPP Only | /nodefine

Run-Time Options

Generate Traceback Information | /[no]traceback
Default Output Carriage Control | /ccdefault:keyword
Array and String Bounds | /check:[no]bounds
Integer Overflow | /check:[no]overflow
Floating-Point Underflow | /check:[no]underflow
Power Operations | /check:[no]power
Edit Descriptor Data Type | /check:[no]format
Flawed Pentium® Chip | /check:[no]flawed_pentium (ia32 only)
Edit Descriptor Data Size | /check:[no]output_conversion

For a table of DF command options listed alphabetically, see Compiler Options, Alphabetic List.


/[no]alignment

Syntax:

/alignment[:keyword...], /noalignment, or /Zp n

The /alignment option specifies the alignment of data items in common blocks, record structures, and derived-type structures. The /Zpn option specifies the alignment of data items in derived-type or record structures.

The /alignment options are:

  • /align:[no]commons

    The /align:commons option aligns the data items of all COMMON data blocks on natural boundaries up to four bytes. The default is /align:nocommons (unless /fast is specified), which does not align data blocks on natural boundaries. In the visual development environment, specify the Common Element Alignment as 4 in the Fortran Data Compiler Option Category.

  • /align:dcommons

    The /align:dcommons option aligns the data items of all COMMON data blocks on natural boundaries up to eight bytes. The default is /align:nocommons (unless /fast is specified), which does not align data blocks on natural boundaries. Specifying /fast sets /align:dcommons. In the visual development environment, specify the Common Element Alignment as 8 in the Fortran Data Compiler Option Category.

  • /align:[no]records

    The /align:records option (the default) requests that components of derived types and fields of records be aligned on natural boundaries up to 8 bytes (for derived types with the SEQUENCE statement, see /align:[no]sequence below). The /align:norecords option requests that components and fields be aligned on arbitrary byte boundaries, instead of on natural boundaries up to 8 bytes. In the visual development environment, specify the Structure Element Alignment in the Fortran Data Compiler Option Category.

  • /align:[no]sequence

    The /align:sequence option requests that components of derived types with the SEQUENCE statement will obey whatever alignment rules are currently in use (default alignment rules will align unsequenced components on natural boundaries). The default value (unless /fast is specified) is /align:nosequence, which means that components of derived types with the SEQUENCE property will be packed, regardless of whatever alignment rules are currently in use. Specifying /fast sets /align:sequence.

    In the visual development environment, specify Allow SEQUENCE Types to be Padded for Alignment in the Fortran Data Compiler Option Category.

  • /align:recNbyte or /Zpn

    The /align:recNbyte or /Zpn options request that fields of records and components of derived types be aligned on the smaller of:

    • The size byte boundary (N) specified.
    • The boundary that will naturally align them.

    Specifying /align:recNbyte, /Zpn, or /align:[no]records does not affect whether common block fields are naturally aligned or packed. In the visual development environment, specify the Structure Element Alignment in the Fortran Data Compiler Option Category.

    Specifying | Is the Same as Specifying
    /Zp | /alignment:records or /align:rec8byte
    /Zp1 | /alignment:norecords or /align:rec1byte
    /Zp2 | /align:rec2byte
    /Zp4 | /align:rec4byte
    /alignment | /Zp8 with /align:dcommons, /alignment:all, or /alignment:(dcommons,records)
    /noalignment | /Zp1, /alignment:none, or /alignment:(nocommons,nodcommons,norecords)
    /align:rec1byte | /align:norecords
    /align:rec8byte | /align:records

When you omit the /alignment option, records and components of derived types are naturally aligned, but fields in common blocks are packed. This default is equivalent to:

  /alignment=(nocommons,nodcommons,records,nosequence)

You can also control the alignment of components in records and derived types and data items in common blocks by Using the cDEC$ OPTIONS Directive.


/[no]altparam

Syntax:

/altparam, /noaltparam, /4Yaltparam, or /4Naltparam

The /altparam option determines how the compiler will treat the alternate syntax for PARAMETER statements, which is:

  PARAMETER par1=exp1 [, par2=exp2] ...

This form does not have parentheses around the assignment of the constant to the parameter name. With this form, the type of the parameter is determined by the type of the expression being assigned to it and not by any implicit typing.

In the visual development environment, specify the Enable Alternate PARAMETER Syntax in the Fortran Language Compiler Option Category.

When the /[no]altparam or equivalent options are not specified, the compiler default will be to allow the alternate syntax for PARAMETER statements (/altparam).

To disallow use of this form, specify /noaltparam or /4Naltparam. To allow use of this form, allow the default or specify /altparam or /4Yaltparam.


/[no]annotations

Syntax:

/annotations:keyword or /noannotations

The /annotations option specifies that additional information will be added to the source listing file. This information indicates which of a set of optimizations the compiler applied to particular parts of the source file. Note that some of the values of keyword may exist for optimizations that are not supported on your platform. If so, the source listing file contains no corresponding annotations (such as feedback). In the visual development environment, specify the various annotations keywords under the Annotations list box in the Listing Compiler Option Category.

You can view the resulting annotations in the source listing file to see what optimizations the compiler performed or else why the compiler was not able to optimize a particular code sequence. The default is /noannotations, which places no annotations in the source listing file.

The /annotations option keywords are as follows:

  • /annotations:none

    Same as /noannotations, the default value.

  • /annotations:all

    Specifying /annotations all selects all of the following annotations.

  • /annotations:code

    Specifying /annotations:code annotates the machine code listing with descriptions of special instructions used for prefetching, alignment, and so on.

  • /annotations:detail

    Specifying /annotations:detail provides, where available, an additional level of annotation detail.

  • /annotations:feedback

    Specifying /annotations:feedback provides information about any feedback optimizations (not available for Windows systems).

  • /annotations:inlining

    Specifying /annotations:inlining indicates where code for a called procedure was expanded inline.

  • /annotations:loop_transforms

    Specifying /annotations:loop_transforms indicates where advanced loop nest optimizations have been applied to improve cache performance (unroll and jam, loop fusion, loop interchange, and so on).

  • /annotations:loop_unrolling

    Specifying /annotations:loop_unrolling indicates where a loop was unrolled (contents expanded multiple times).

  • /annotations:prefetching

    Specifying /annotations:prefetching indicates where special instructions were used to reduce memory latency.

  • /annotations:shrinkwrapping

    Specifying /annotations:shrinkwrapping indicates removal of code establishing routine context when it is not needed.

  • /annotations:software_pipelining

    Specifying /annotations:software_pipelining indicates where instructions have been rearranged to make optimal use of the processor's functional units (not available for ia32 systems).

  • /annotations:tail_calls

    Specifying /annotations:tail_calls indicates an optimization where a call from one routine to another can be replaced with a jump.

  • /annotations:tail_recursion

    Specifying /annotations:tail_recursion indicates an optimization that eliminates unnecessary routine context for a recursive call.

The /annotations option is ignored unless you also specify the /list[:file] option or select the equivalent Source Listing option in the Listing File category in the visual development environment.


/architecture

Syntax:

/architecture:keyword

The /architecture (/arch) option controls the types of processor-specific instructions generated for this program unit. The /arch:keyword option uses the same keywords as the /tune:keyword option.

All processors of a certain architecture type (ia32) implement a core set of instructions. Certain (more recent) processor versions include additional instruction extensions.

Whereas the /tune:keyword option is primarily used by certain higher-level optimizations for instruction scheduling purposes, the /arch:keyword option determines the type of machine-code instructions generated for the program unit being compiled.

In the visual development environment, specify the Generate Code For in the Code Generation Compiler Option Category.

For ia32 (Intel and AMD) 32-bit processor systems, the supported /arch keywords are:

  • /arch:generic

    Generates code (sometimes called blended code) that is appropriate for processor generations for the architecture type in use. This is the default. Programs compiled on an ia32 system with the generic keyword will run on all ia32 systems.

  • /arch:host

    Generates code for the processor generation in use on the system being used for compilation. Depending on the host system used on ia32 systems, the program may or may not run on other ia32 systems. Using /arch:host on a:

    • Intel Pentium processor system selects the pn1 keyword
    • Intel Pentium Pro, Intel Pentium II, or AMD K6 processor system selects the pn2 keyword
    • Intel Pentium III processor system selects the pn3 keyword
    • AMD K6_2 or AMD K6_III processor system selects the k6_2 keyword
    • AMD Athlon processor system selects the k7 keyword
    • Intel Pentium 4 processor system selects the pn4 keyword

  • /arch:pn1

    Generates code for the Pentium processor systems. Programs compiled with the pn1 keyword will run correctly on Pentium, Pentium Pro, Pentium II, Pentium III, AMD K6, and higher processors, but should not be run on 486 processors. The pn1 keyword replaces the p5 keyword (specifying /arch:pn1 and /arch:p5 are equivalent).

  • /arch:pn2

    Generates code for the Pentium Pro, Pentium II, and AMD K6 processor systems only. Programs compiled with the pn2 or k6 keyword will run correctly on Pentium Pro, Pentium II, AMD K6, Pentium III, and higher processors, but should not be run on 486 or Pentium processors. The pn2 keyword replaces the p6 keyword (specifying /arch:pn2 and /arch:p6 are equivalent).

  • /arch:k6

    Generates code for the AMD K6 (same as Pentium II systems) processor systems only. Programs compiled with the k6 or pn2 keyword will run correctly on Pentium Pro, Pentium II, AMD K6, Pentium III, and higher processors, but should not be run on 486 or Pentium processors.

  • /arch:pn3

    Generates code for the Pentium III, AMD K6_2, and AMD K6_III processor systems only. Programs compiled with the pn3 keyword will run correctly on Pentium III, AMD K6_2, AMD K6_III, Pentium 4, and higher processors, but should not be run on 486, Pentium, Pentium Pro, Pentium II, or AMD K6 processors. The pn3 keyword replaces the p6p keyword (specifying /arch:pn3 and /arch:p6p are equivalent).

  • /arch:k6_2

    Generates code for the AMD K6_2 and AMD K6_III processor systems. Programs compiled with the k6_2 keyword will run correctly on AMD K6_2, AMD K6_III, and AMD AthlonTM processors, but should not be run on 486, Pentium, Pentium Pro, Pentium II (same as AMD K6), Pentium III, or Pentium 4 processors.

  • /arch:k7

    Generates code for the AMD Athlon processor systems only. Programs compiled with the k7 keyword will run correctly on AMD Athlon processors, but should not be run on 486, Pentium, Pentium Pro, Pentium II (same as AMD K6), Pentium III, Pentium 4, AMD K6_2, or AMD K6_III processors.

  • /arch:pn4

    Generates code for the Pentium 4 processor systems only. Programs compiled with the pn4 keyword will run correctly on Pentium 4 processors, but should not be run on 486, Pentium, Pentium Pro, or Pentium II (same as AMD K6), Pentium III, AMD K6_2, AMD K6_III, or AMD Athlon processors.

Other processors (not listed) that have instruction-level compatibility with the processors listed above will have results similar to those processors.

For ia64 (64-bit) systems, specify either /arch:generic or /arch:host.

The following table shows the ia32 /arch:keywords and the systems that programs using these keywords can be used on:

keyword | AMD K6 | AMD K6_2 | AMD K6_III | AMD Athlon | Intel 486 | Intel Pentium | Intel Pentium Pro and Pentium II | Intel Pentium III | Intel Pentium 4
generic | * | * | * | * | X | * | * | * | *
pn1 | * | * | * | * |  | X | * | * | *
pn2 | * | * | * | * |  |  | X | * | *
pn3 |  | * | * | * |  |  |  | X | *
pn4 |  |  |  |  |  |  |  |  | X
k6 | X | * | * | * |  |  | * | * | *
k6_2 |  | X | X | * |  |  |  |  |
k7 |  |  |  | X |  |  |  |  |
Legend: | * indicates supported combinations of keyword and processor type
 | X indicates the best code generation combination of keyword and processor type

Specifying /fast sets /arch:host.

For more information:

  • About timing program execution, see Analyze Program Performance.
  • About the types of instructions used by the various keywords, see Requesting Code Generation for a Specific Processor Generation


/[no]asmattributes

Syntax:

/asmattributes:keyword, /noasmattributes, /FA, /FAs, /FAc, or /FAcs

The /asmattributes option indicates what information, in addition to the assembly code, should be generated in the assembly listing file.

In the visual development environment, specify Assembly Options in the Listing File Compiler Option Category. The /asmattributes options are:

  • /asmattributes:source or /FAs

    Intersperses the source code as comments in the assembly listing file.

  • /asmattributes:machine or /FAc

    Lists the hex machine instructions at the beginning of each line of assembly code.

  • /asmattributes:all or /FAcs

    Intersperses both the source code as comments and lists the hex machine instructions at the beginning of each line of assembly code. This is equivalent to /asmattributes.

  • /asmattributes:none or /FA

    Provides neither interspersed source code comments nor a listing of hex machine instructions. This is equivalent to /noasmattributes.

If you omit the /asmattributes option, /asmattributes:none is used (default).

The /asmattributes option is ignored if the /[no]asmfile[:file] option is not specified. The /FA, /FAs, /FAc, or /FAcs options can be used without the /[no]asmfile[:file] option.


/[no]asmfile

Syntax:

/asmfile[:file], /noasmfile, /Fa[file], /Fc[file], /Fl[file], or /Fs[file]

The /asmfile option or equivalent /Fx option indicates that an assembly listing file should be generated. If the file is not specified, the default filename used will be the name of the source file with an extension of .asm.

In the visual development environment, specify Assembly Listing in the Listing File Compiler Option Category.

When the /asmfile option or equivalent /Fx[file] option is specified and there are multiple source files being compiled, each source file will be compiled separately. Compiling source files separately turns off interprocedural optimization from being performed.

When you specify /noasmfile or the /asmfile option is not specified, the compiler does not generate any assembly files.

To specify the content of the assembly listing file, also specify /[no]asmattributes:keyword or specify the /Fx[file] options:

  • /FA[file] provides neither interspersed source code comments nor a listing of hex machine instructions.
  • /FAs[file] provides interspersed source code as comments in the assembly listing file.
  • /FAc[file] provides a list of hex machine instructions at the beginning of each line of assembly code.
  • /FAcs[file] provides interspersed source code as comments and lists hex machine instructions at the beginning of each line of assembly code.


/assume

Syntax:

/assume:keyword

The /assume option specifies assumptions made by the Fortran syntax analyzer, optimizer, and code generator. These option keywords are:

/assume:[no]accuracy_sensitive | /assume:[no]buffered_io
/assume:[no]byterecl | /assume:[no]dummy_aliases
/assume:[no]minus0 | /assume:[no]protect_constants
/assume:[no]source_include | /assume:[no]underscore

The /assume options are:

  • /assume:[no]accuracy_sensitive

    Specifying /assume:noaccuracy_sensitive allows the compiler to reorder code based on algebraic identities (inverses, associativity, and distribution) to improve performance. In the visual development environment, specify Allow Reordering of Floating-Point Operations in the Optimizations Compiler Option Category.

    The numeric results can be slightly different from the default (/assume:accuracy_sensitive) because of the way intermediate results are rounded.

    Numeric results with /assume:noaccuracy_sensitive are not categorically less accurate. They can produce more accurate results for certain floating-point calculations, such as dot product summations. For example, the following expressions are mathematically equivalent but may not compute the same value using finite precision arithmetic:

     X = (A + B) - C
 X = A + (B - C)

    If you omit /assume:noaccuracy_sensitive and omit /fast, the compiler uses a limited number of rules for calculations, which might prevent some optimizations.

    If you specify /assume:noaccuracy_sensitive, or if you specify /fast and omit /assume:accuracy_sensitive, the compiler can reorder code based on algebraic identities to improve performance.

    For more information on /assume:noaccuracy_sensitive, see Arithmetic Reordering Optimizations.

  • /assume:[no]buffered_io

    The /assume:buffered_io option controls whether records are written (flushed) to disk as each record is written (default) or accumulated in the buffer.

    For disk devices, /assume:buffered_io (or the equivalent OPEN statement BUFFERED='YES' specifier or the FORT_BUFFERED run-time environment variable) requests that the internal buffer will be filled, possibly by many record output statements (WRITE), before it is written to disk by the Fortran run-time system. If a file is opened for direct access, I/O buffering will be ignored.

    Using buffered writes usually makes disk I/O more efficient by writing larger blocks of data to the disk less often. However, if you request buffered writes, records not yet written to disk may be lost in the event of a system failure.

    Unless you set the FORT_BUFFERED environment variable to TRUE, the default is BUFFERED='NO' and /assume:nobuffered_io for all I/O, in which case, the Fortran run-time system empties its internal buffer for each WRITE (or similar record output statement).

    The OPEN statement BUFFERED specifier applies to a specific logical unit. In contrast, the /assume:[no]buffered_io option and the FORT_BUFFERED environment variable apply to all Fortran units.

    In the visual development environment, to enable /assume:buffered_io, specify the Enable I/O Buffering in the Optimizations Compiler Option Category.

    For more information on /assume:buffered_io, see Efficient Use of Record Buffers and Disk I/O.

  • /assume:[no]byterecl

    The /assume:byterecl option applies only to unformatted files. In the visual development environment, specify the Use Bytes as Unit for Unformatted Files in the Fortran Data Compiler Option Category. Specifying the /assume:byterecl option:

    • Indicates that the units for an explicit OPEN statement RECL specifier value are in bytes.
    • Forces the record length value returned by an INQUIRE by output list to be in byte units.

    Specifying /assume:nobyterecl indicates that the units for RECL values with unformatted files are in four-byte (longword) units. This is the default.

  • /assume:[no]dummy_aliases

    Specifying the /assume:dummy_aliases option requires that the compiler assume that dummy (formal) arguments to procedures share memory locations with other dummy arguments or with variables shared through use association, host association, or common block use. The default is /assume:nodummy_aliases.

    In the visual development environment, specify Enable Dummy Argument Aliasing in the Fortran Data (or Optimizations) Compiler Option Category.

    These program semantics do not strictly obey the Fortran Standard and they slow performance. If you omit /assume:dummy_aliases, the compiler does not need to make these assumptions, which results in better run-time performance. However, omitting /assume:dummy_aliases can cause some programs that depend on such aliases to fail or produce wrong answers.

    You only need to compile the called subprogram with /assume:dummy_aliases.

    If you compile a program that uses dummy aliasing with /assume:nodummy_aliases in effect, the run-time behavior of the program will be unpredictable. In such programs, the results will depend on the exact optimizations that are performed. In some cases, normal results will occur; however, in other cases, results will differ because the values used in computations involving the offending aliases will differ.

    For more information, see Dummy Aliasing Assumption.

  • /assume:[no]minus0

    This option controls whether the compiler uses Fortran 95 standard semantics for the IEEE floating-point value of -0.0 (minus zero) in the SIGN intrinsic, if the processor is capable of distinguishing the difference between -0.0 and +0.0. The default is /assume:nominus0, where the value -0.0 or +0.0 in the SIGN function is treated as 0.0.

    To request Fortran 95 semantics to allow use of the IEEE value -0.0 in the SIGN intrinsic, specify /assume:minus0.

    In the visual development environment, specify Enable IEEE Minus Zero Support in the Floating Point Compiler Option Category.

  • /assume:[no]protect_constants

    This option specifies whether constant actual arguments can be changed. By default, actual arguments that are constants are read-only (/assume:protect_constants). To allow changes to actual arguments that are constants, specify /assume:noprotect_constants.

    In the visual development environment, specify Constant Actual Arguments are Read-Only in the Fortran Data Compiler Option Category.

  • /assume:[no]source_include

    This option controls the directory searched for module files specified by a USE statement or source files specified by an INCLUDE statement:

    • Specifying /assume:source_include requests a search for module or include files in the directory where the source file being compiled resides. This is the default.
    • Specifying /assume:nosource_include requests a search for module or include files in the current (default) directory.

    In the visual development environment, specify the Default INCLUDE and USE Paths in the Preprocessor Compiler Option Category.

  • /assume:[no]underscore

    Specifying /assume:underscore option controls the appending of an underscore character to external user-defined names: the main program name, named COMMON, BLOCK DATA, and names implicitly or explicitly declared EXTERNAL. The name of blank COMMON remains _BLNK__, and Fortran intrinsic names are not affected.

    In the visual development environment, specify Append Underscore to External Names in the External Procedures (or Fortran Data) Compiler Option Category.

    Specifying /assume:nounderscore option does not append an underscore character to external user-defined names. This is the default.

For example, the following command requests the noaccuracy_sensitive and nosource_include keywords and accepts the defaults for the other /assume keywords:

  df /assume:(noaccuracy_sensitive,nosource_include)  testfile.f90


/[no]automatic

Syntax:

/automatic, /noautomatic, /4Ya, or /4Na

The /automatic or /4Ya option requests that local variables be put on the run-time stack. In the visual development environment, specify Variables Default to Automatic in the Fortran Data (or Optimizations) Compiler Option Category.

The /noautomatic or /4Na option is the same as the /static option. The default is /noautomatic or /4Na, which causes all local variables to be statically allocated.

If you specify /recursive, the /automatic (/4Ya) option is set.


/bintext

Syntax:

/bintext:string or /V string

Specifying /bintext (or /V) places the text string specified into the object file (.OBJ) being generated by the compiler. This string also gets propagated into the executable file. For example, the string might contain version number or copyright information.

In the visual development environment, specify Object Text in the Code Generation Compiler Option Category.

If the string contains a space or tab, the string must be enclosed by double quotation marks ("). A backslash (\) must precede any double quotation marks contained within the string.

If the command line contains multiple /bintext or /V options, the last (right-most) one is used. You can specify /nobintext to override previous /bintext or /V options on the same command line.


/[no]browser

Syntax:

/browser[:filename], /nobrowser, or /FR

The /browser or /FR option controls the generation of source browser information. When the /browser option is not specified, the compiler will not generate browser files (same as /nobrowser).

In the visual development environment, specify Generate Source Browse Information in the General Compiler Option Category. Also, in the BrowseInfo tab, set Build Browse info check box.

Browser information includes:

  • Information about all the symbols in the source file
  • The source code line in which a symbol is defined
  • Each source code line where there is a reference to a symbol
  • The relationships between calling functions and called functions

The default extension for source browser files is .SBR.

The browser output is intended to be used as input to the Browse Information File Maintenance Utility (BSCMAKE), which generates a browse information file (.BSC) that can be examined in browse windows in the Microsoft visual development environment.

Instead of using BCSMAKE, you can use the Project Settings dialog box in the visual development environment:

  • Click the BrowseInfo tab.
  • Set the Build browse info file check box.

When the /browser or /FR option is specified and there are multiple source files being compiled, each source file will be compiled separately. Compiling source files separately turns off interprocedure optimizations.


/ccdefault

Syntax:

/ccdefault:keyword...

The /ccdefault option specifies the default carriage control when a file is displayed on a terminal screen.

In the visual development environment, specify the Default Output Carriage Control in the Run-Time Compiler Option Category. The /ccdefault keywords are as follows:

  • /ccdefault:default

    Allows other options, such as Compatibility option /vms, to affect this default setting:

    • If /vms is specified with /ccdefault:default, carriage control defaults to FORTRAN (/ccdefault:fortran) if the file is formatted, and the unit is connected to a terminal.
    • If /novms (default) is specified with /ccdefault:default, carriage control defaults to LIST (/ccdefault:list).
  • /ccdefault:fortran

    Uses normal Fortran interpretation of the first character, such as the character "0" resulting in a blank line before output.

  • /ccdefault:list

    Adds one line-feed between records.

  • /ccdefault:none

    Uses no carriage control processing.


/[no]check

Syntax:

/check:keyword, /nocheck, /4Yb, /4Nb

The /check, /4Yb, or /4Nb options control whether extra code is generated for certain run-time checking. Run-time checks can result in issuing run-time messages for certain conditions.

In the visual development environment, specify the Runtime Error Checking items in the Run time Compiler Option Category. The /check options are as follows:

/check:arg_temp_created (Actual Arguments use Temporary Storage) | /check:bounds (Array and String bounds)
/check:flawed_pentium (ia32 systems) (Flawed Pentium) | /check:format (Edit Descriptor Data Type)
/check:output_conversion (Edit Descriptor Data Size) | /check:overflow (Integer Overflow)
/check:power (Power Operations) | /check:underflow (Floating Point Underflow)
/4Yb | /check:none, /nocheck, or /4Nb
/check or /check:all |

If you omit these options, the default is:
/check:(noarg_temp_created,nobounds,flawed_pentium,noformat,nopower,nooutput_conversion,nooverflow,nounderflow).

When using the visual development environment debug configuration, the default for bounds checking changes from /check:nobounds to /check:bounds.

The /check keywords and /4Yb, and /4Nb options are:

  • /check:arg_temp_created

    Requests that a run-time informational message appear if actual arguments are copied into temporary storage before routine calls. Specifying /check:noarg_temp_created (the default) does not generate the extra code needed to display a message run-time when this condition occurs.

  • /check:bounds

    Requests a run-time error message if a reference to an array subscript or character substring is outside of the declared bounds. The default for the command line and the release configuration (visual development environment) is /check:nobounds, which does not issue a run-time message for this condition. The default for the debug configuration is /check:bounds, which issues a run-time message for an out-of-bounds array subscript or character substring.

  • /check:flawed_pentium (ia32 systems)

    On ia32 systems, requests a run-time error message if a flawed Pentium (586) processor is detected. The default is /check:flawed_pentium, which does issue a run-time error message for this condition and stops program execution. To allow program execution to continue when this condition occurs, set the environment variable FOR_RUN_FLAWED_PENTIUM to true and rerun the program (see Run-Time Environment Variables).

    For more information on the Pentium flaw, see Intel Pentium Floating-Point Flaw. You can also use the FOR_CHECK_FLAWED_PENTIUM routine.

  • /check:format

    Requests a run-time error message when the data type for an item being formatted for output does not match the FORMAT descriptor. Specifying /check:noformat suppresses the run-time error message for this condition.

  • /check:output_conversion

    Requests a run-time message (number 63) when format truncation occurs (when a number is too large to fit in the specified format field length without loss of significant digits). Specifying /check:nooutput_conversion does not display the message when format truncation occurs.

  • /check:overflow

    Requests a continuable run-time message when integer overflow occurs. Specifying /check:nooverflow suppresses the run-time message.

  • /check:power

    Requests a run-time error message for arithmetic expressions 0.0 ** 0.0 and negative-value ** integer-value-of-type-real. The default is /check:nopower (suppress the run-time error message), allowing the calculations to occur, where 0.0 ** 0.0 equals 1.0 and (-3.0) ** 3.0 equals -27.0.

    You can specify /check:power to allow a run-time error message to be issued for this type of expression.

  • /check:underflow

    Requests an informational run-time message when floating-point underflow occurs when /fpe:0 is specified (/check:underflow is not supported with /fpe:3). Specifying /check:nounderflow suppresses a run-time message when floating-point underflow occurs.

  • /4Yb

    Sets /check:(overflow,bounds,underflow).

  • /check:none, /nocheck, or /4Nb

    Equivalent to:
    /check:(noarg_temp_created,nobounds,noformat,nopower,nooutput_conversion,nooverflow,nounderflow).

  • /check or /check:all

    Equivalent to:
    /check:(arg_temp_created,bounds,flawed_pentium,format,power,output_conversion,overflow,underflow).


/[no]comments

Syntax:

/comments or /nocomments

The /comments option writes C-style comments to the output file. The /nocomments option does not write C-style comments to the output file. This option applies only to the FPP preprocessor.

For more information, type FPP /? to view FPP options.


/[no]compile_only

Syntax:

/compile_only, /nocompile_only, or /c

The /compile_only or /c option suppresses linking. The default is /nocompile_only (perform linking).

If you specify the /compile_only option at higher levels of optimization and also specify /object:filename, the /object:filename option causes multiple Fortran input files (if specified) to be compiled into a single object file. This allows interprocedural optimizations to occur.

However, if you use multiple source files and the /compile_only option without the /object:file option, multiple object files are created and interprocedural optimizations do not occur.

In the visual development environment, to compile (not link) a source file:

  1. In the FileView pane, select (highlight) the file to be compiled
  2. From the Build menu, select Compile filename.xxx


/convert

Syntax:

/convert:keyword

The /convert option specifies the format of unformatted files containing numeric data. On ia32 and ia64 systems, the format used in memory is always IEEE little endian format. If you want to read and write unformatted data in IEEE little endian format, you do not need to convert your unformatted data and can omit this option (or specify /convert:native).

This method affects all unit numbers that use unformatted data specified by the program. Other methods are available to specify the format for all or certain unformatted files (see Converting Unformatted Numeric Data).

In the visual development environment, specify the Unformatted File Conversion in the Compatibility Compiler Option Category. The /convert options are:

/convert:big_endian | /convert:cray
/convert:ibm | /convert:little_endian
/convert:native | /convert:vaxd
/convert:vaxg |
  • /convert:big_endian

    Specifies that unformatted files containing numeric data are in IEEE big endian (nonnative) format. The resulting program will read and write unformatted files containing numeric data assuming the following:

    • Big endian integer format (INTEGER declarations of the appropriate size).
    • Big endian IEEE floating-point formats (REAL and COMPLEX declarations of the appropriate size).

  • /convert:cray

    Specifies that unformatted files containing numeric data are in CRAY (nonnative) big endian format. The resulting program will read and write unformatted files containing numeric data assuming the following:

    • Big endian integer format (INTEGER declarations of the appropriate size).
    • Big endian CRAY proprietary floating-point formats (REAL and COMPLEX declarations of the appropriate size).

  • /convert:ibm

    Specifies that unformatted files containing numeric data are in IBM (nonnative) big endian format. The resulting program will read and write unformatted files containing numeric data assuming the following:

    • Big endian integer format (INTEGER declarations of the appropriate size).
    • Big endian IBM proprietary floating-point formats (REAL and COMPLEX declarations of the appropriate size).

  • /convert:little_endian

    Specifies that numeric data in unformatted files is in native little endian integer format and IEEE little endian floating-point format (same as used in memory), as follows:

    • Integer data is in native little endian format.
    • REAL(KIND=4) and COMPLEX(KIND=4) (SINGLE PRECISION) data is in IEEE little endian S_floating format.
    • REAL(KIND=8) and COMPLEX (KIND=8) (DOUBLE PRECISION) data is in IEEE little endian T_floating format.

  • /convert:native

    Specifies that numeric data in unformatted files is not converted. This is the default.

  • /convert:vaxd

    Specifies that numeric data in unformatted files is in VAXD little endian format, as follows:

    • Integer data is in native little endian format.
    • REAL(KIND=4) and COMPLEX(KIND=4) (SINGLE PRECISION) data is in VAX F_floating format.
    • REAL(KIND=8) and COMPLEX (KIND=8) (DOUBLE PRECISION) data is in VAX D_floating format.

  • /convert:vaxg

    Specifies that numeric data in unformatted files is in VAXG little endian format, as follows:

    • Integer data is in native little endian format.
    • REAL(KIND=4) and COMPLEX(KIND=4) (SINGLE PRECISION) data is in VAX F_floating format.
    • REAL(KIND=8) and COMPLEX(KIND=8) (DOUBLE PRECISION) data is in VAX G_floating format.

For more information on unformatted file conversion, see Converting Unformatted Numeric Data.


/cxml

Syntax:

/cxml

The /cxml option requests that the Compaq Extended Math Library (CXML) library be passed to the linker. Your program still needs to specify the INCLUDE 'CXML_INCLUDE.F90' statement. The /cxml option is provided for documentation purposes only.

For more information, see Using the Compaq Extended Math Library (CXML).

In the visual development environment, specify the Use Compaq Extended Math Library (CXML) in the Library Compiler Option Category.


/[no]d_lines

Syntax:

/d_lines, /nod_lines, /4ccD, or /4ccd

The /d_lines, /4ccD, or /4ccd options indicate that lines in fixed-format files that contain a D in column 1 should be treated as source code. Specifying /nod_lines (the default) indicates that these lines are to be treated as comment lines.

In the visual development environment, specify Compile DEBUG (D) Lines in the Debug Compiler Option Category.

The compiler does not support the use of characters other than a D or d with the /4ccstring (see the dlines Sample program in ...\Samples\Advanced\com\).


/[no]dbglibs

Syntax:

/dbglibs or /nodbglibs

The /dbglibs option controls whether the debug version or the non-debug version of the C run-time library is linked against. The default is /nodbglibs, which will link against the non-debug version of the C library, even when /debug:full is specified.

If you specify /debug:full for an application that calls C library routines and you need to debug calls into the C library, you should also specify /dbglibs to request that the debug version of the library be linked against.

In the visual development environment, specify one of the Debug library options in the Use Fortran Run-Time Libraries in the Libraries Compiler Option Category.

When you specify /dbglibs, the C debug library linked against depends on the specified /libs:keyword and /[no]threads options, and is one of: libcd.lib, libcmtd.lib, or msvcrtd.lib.

For More Information:

  • Visual Fortran/Visual C++ Mixed-Language Programs
  • Specifying Consistent Library Types


/[no]debug

Syntax:

/debug:keyword, /nodebug, /Z7, /Zd, or /Zi

The /debug, /Z7, /Zd, or /Zi options control the level of debugging information associated with the program being compiled.

In the visual development environment, specify the Debugging Level in the General or Debug Compiler Option Category. The options are:

/debug:none or /nodebug | /debug:minimal or /Zd
/debug:partial | /debug:full, /debug, /Zi, or /Z7

The /debug options:

  • /debug:none or /nodebug

    If you specify /debug:none or /nodebug, the compiler produces no symbol table information, which is needed for debugging or profiling. Only symbol information needed for linking (global symbols) is produced. The size of the resulting object module is the minimum size. If this option is specified, /debug:none is passed to the linker.

  • /debug:minimal or /Zd

    If you specify /debug:minimal or /Zd, the compiler produces minimal debug information, which allows global symbol table information needed for linking, but not local symbol table information needed for debugging. If /debug:minimal is specified, /debug:minimal and /debugtype:cv is passed to the linker.

    If you omit the /[no]debug:keyword, /Z7, /Zd, and /Zi options, /debug:minimal is the default on the command line and for a release configuration in the visual development environment.

    The /Zd option implies /nopdbfile and passes /debug:minimal /pdb:none /debugtype:cv to the linker.

    The object module size is somewhat larger than if you specified /debug:none, but is smaller than if you specified /debug:full.

  • /debug:partial

    If you specify /debug:partial, the compiler produces debugging information to allow global symbol table information needed for linking, but not local symbol table information needed for debugging. If /debug:partial is specified, /debug:partial /debugtype:cv /pdb:none is passed to the linker.

    The object module size is somewhat larger than if you specified /debug:none, but is smaller than if you specified /debug:full.

  • /debug:full, /debug, /Zi, or /Z7

    If you specify /debug:full, /debug, /Zi, or /Z7, the compiler produces symbol table information needed for full symbolic debugging of unoptimized code and global symbol information needed for linking. This is the default for a debug configuration in the visual development environment.

    If you specify /debug:full for an application that make calls to C library routines and you need to debug calls into the C library, you should also specify /dbglibs to request that the appropriate C debug library be linked against (see Specifying Consistent Library Types).

    The /Z7 option implies /nopdbfile and passes /debug:full /debugtype:cv /pdb:none to the linker.

    The /debug:full, /debug, and /Zi options imply /pdbfile and pass /debug:full and /debugtype:cv to the linker.

    If you specify /debug (with no keyword), the default optimization level changes to /optimize:0 (instead of /optimize:4) for the DF command.

To request program counter run-time correlation to source file line numbers (full traceback) for severe run-time errors, specify the /traceback option.


/define

Syntax:

/define:symbol[=value]

The /define option defines the symbol specified for use with conditional compilation directives or the Fortran preprocessor, FPP. A value specified for /define can be a character or integer value. If a value is not specified, 1 is assigned to symbol.

When only using the Fortran preprocessor FPP, to request that symbol values defined by /define apply only to FPP and are not seen by compiler directives, also specify /nodefine on the DF command line.

In the visual development environment, specify the Predefined Preprocessor Symbols in the General or Preprocessor Compiler Option Category.

You can use the directives to detect symbol definitions, such as the IF Directive Construct. Like certain other compiler options, an equivalent directive exists (DEFINE directive).

The following preprocessor symbols are predefined by the compiler system and are available to compiler directives and FPP (except _DF_VERSION_ and _VF_VERSION_):

Predefined Preprocessor Symbols

Predefined Symbol Name and Value | Conditions When this Symbol is Defined
_DF_VERSION_=660 (660 for Version 6.6) | Compiler only
_DLL=1 | Only if /libs:dll, /MDs, /MD, /dll, or /LD is specified, but not when /libs:static is specified
_INTEGRAL_MAX_BITS=32 | Only for ia32 (32-bit) systems
_INTEGRAL_MAX_BITS=64 | Only for ia64 (64-bit) systems
_ITANIUM_A3_=1 | Only for ia64 (64-bit) systems
_MSFORTRAN_=401 | Only if /fpscomp:symbols is specified or you use the FL32 command
_MT=1 | Only if /threads or /MT is specified
_M_IX86=500 | Only for ia32 (32-bit) systems
_M_IA64=64100 | Only for ia64 (64-bit) systems
_VF_VERSION_=660 (660 for Version 6.6) | Compiler only
_WIN32=1 | Always defined (both ia32 and ia64 systems)
_WIN64=1 | Only for ia64 (64-bit) systems
_WIN95=1 | Only for ia32 (32-bit) systems running the Windows 95 operating system
_WIN98=1 | Only for ia32 (32-bit) systems running the Windows 98 operating system
_WINME=1 | Only for ia32 (32-bit) systems running the Windows Me operating system
_X86_=1 | Only for ia32 (32-bit) systems

When using the non-native ia64 compiler, platform-specific symbols are set for the target platform of the executable, not for the system in use.


/dll

Syntax:

/dll[:file], /nodll, or /LD

The /dll or /LD option indicates that the program should be linked as a DLL file. The /dll or /LD option overrides any specification of the run-time routines to be used and activates the /libs:dll option. A warning is generated when the /libs=qwin or /libs=qwins option and /dll option are used together.

In the visual development environment, specify the project type as Fortran Dynamic Link Library (DLL).

If you omit file, the /dll or /LD option interacts with the /exe and the /Fe options, as follows:

  • If neither /exe nor /Fe is specified, the first file name used on the command line is used with an extension of .DLL.
  • If either /exe:file or /Fefile is specified with a file name, that name is used for the DLL file. If the specified file name does not end with a "." or have an extension, an extension of .DLL is added to it.

To request linking with multithreaded libraries, specify the /threads option.

For information about building DLL files from the visual development environment, see Fortran Dynamic-Link Library Projects and Creating Fortran DLLs.

For a list of Fortran PowerStation style options (such as /LD and /MDs) and their DF command equivalents, see Equivalent Visual Fortran Compiler Options.


/[no]error_limit

Syntax:

/error_limit[:count] or /noerror_limit

The /error_limit option specifies the maximum number of error-level or fatal-level compiler errors allowed for a given file before compilation aborts. If you specify /noerror_limit (command line), there is no limit on the number of errors that are allowed.

In the visual development environment, specify the Compilation Error Limit in the Compilation Diagnostics Compiler Option Category.

The default is /error_limit:30 or a maximum of 30 error-level and fatal-level messages. If the maximum number of errors is reached, a warning message is issued and the next file (if any) on the command line is compiled.


/[no]exe

Syntax:

/exe[:file], /noexe, or /Fe file

The /exe or /Fe option specifies the name of the executable program (EXE) or dynamic-link library (DLL) file being created. To request that a DLL be created instead of an executable program, specify the /dll option.


/[no]extend_source

Syntax:

/extend_source[:size], /noextend_source, or /4L size

The /extend_source or /4Lsize option controls the column used to end the statement field in fixed-format source files. When a size is specified, that will be the last column parsed as part of the statement field. Any columns after that will be treated as comments.

Specifying /extend_source (or /4L132 or /4L80) sets the /fixed option.

In the visual development environment, specify the Fixed-Form Line Length in the Fortran Language Compiler Option Category. The following options are equivalent:

  • /noextend_source, /extend_source:72, or /4L72 specify the last column as 72.
  • /extend_source:80 or /4L80 specify the last column as 80.
  • /extend_source, /extend_source:132, or /4L132 specify the last column as 132.


/extfor

Syntax:

/extfor:ext

The /extfor option specifies file extensions (ext) to be processed by the Compaq Fortran compiler. One or more file extensions can be specified. A leading period before each extension is optional (for and .for are equivalent).


/extfpp

Syntax:

/extfpp:ext

The /extfpp option specifies file extensions (ext) to be processed by the FPP preprocessor. One or more file extensions can be specified. A leading period before each extension is optional (fpp and .fpp are equivalent).


/extlnk

Syntax:

/extlnk:ext

The /extlnk option specifies file extensions (ext) to be processed by the linker. One or more file extensions can be specified. A leading period before each extension is optional (obj and .obj are equivalent).


/[no]f66

Syntax:

/f66 or /nof66

The /f66 option requests that the compiler select FORTRAN-66 interpretations in cases of incompatibility (default is /nof66). Differences include the following:

  • DO loops are always executed at least once (see Execution of DO Constructs)
  • FORTRAN-66 EXTERNAL statement syntax and semantics are allowed (see FORTRAN-66 Interpretation of the External Statement)
  • If the OPEN statement STATUS specifier is omitted, the default changes to STATUS='NEW' instead of STATUS='UNKNOWN'
  • If the OPEN statement BLANK specifier is omitted, the default changes to BLANK='ZERO' instead of BLANK='NULL'

In the visual development environment, specify Enable FORTRAN-66 Semantics in the Fortran Language Compiler Option Category.


/[no]f77rtl

Syntax:

/f77rtl or /nof77rtl

The /f77rtl option controls the run-time support that is used when a program is executed. Specifying /f77rtl uses the Compaq Fortran 77 run-time behavior. In the visual development environment, specify Enable F77 Run-Time Compatibility in the Compatibility Compiler Option Category.

Specifying /nof77rtl uses the Visual Fortran (Compaq Fortran) run-time behavior. Unless you specify /f77rtl, /nof77rtl is used.


/fast

Syntax:

/fast

The /fast option sets several options that generate optimized code for fast run-time performance. Specifying this option is equivalent to specifying:

  • /alignment:(dcommons, records, sequence)
  • /architecture:host
  • /assume:noaccuracy_sensitive
  • /math_library:fast
  • /tune:host

If any of the /stand options are also specified, /align:dcommons and /align:sequence are not set.

In the visual development environment, specify the Generate Most Optimized Code in the Code Generation Compiler Option Category.

If you omit /fast, these performance-related options will not be set.


/[no]fixed

Syntax:

/fixed, /nofixed, /4Nf, or /4Yf

The /fixed or /4Nf option specifies that the source file should be interpreted as being in fixed-source format. Equivalent options are as follows:

  • The /fixed, /nofree, and /4Nf options are equivalent and request fixed-source form.
  • The /nofixed, /free, and /4Yf options are equivalent and request free-source form.

In the visual development environment, specify the Source Form in the Fortran Language Compiler Option Category.

If you omit /[no]free, /[no]fixed, /4Nf, and /4Yf, the compiler assumes:

  • Files with an extension of .f90, .F90, or .i90 are free-format source files.
  • Files with an extension of .f, .for, .FOR, or .i are fixed-format files.


/[no]fltconsistency (ia32 only)

Syntax:

/fltconsistency, /nofltconsistency, or /Op

The /fltconsistency or /Op option enables improved floating-point consistency on ia32 systems. Floating-point operations are not reordered and the result of each floating-point operation is stored into the target variable rather than being kept in the floating-point processor for use in a subsequent calculation. This option is ignored on ia64 systems.

In the visual development environment, specify Enable Floating-Point Consistency in the Floating Point Compiler Option Category.

The default is /nofltconsistency, which provides better accuracy and run-time performance at the expense of less consistent floating-point results.


/[no]fpconstant

Syntax:

/fpconstant or /nofpconstant

The /fpconstant option requests that a single-precision constant assigned to a double-precision variable be evaluated in double precision. If you omit /fpconstant (or specify the default /nofpconstant), a single-precision constant assigned to a double-precision variable is evaluated in single precision. The Fortran 90 standard requires that the constant be evaluated in single precision.

In the visual development environment, specify Extended Precision of Single-Precision Constants in the Floating Point (or Fortran Data) Compiler Option Category.

Certain programs created for FORTRAN-77 compilers (including Compaq Fortran 77) may show different floating-point results, because they rely on single-precision constants assigned to a double-precision variable to be evaluated in double precision.

In the following example, if you specify /fpconstant, identical values are assigned to D1 and D2. If you omit the /fpconstant option, the compiler will obey the standard and assign a less precise value to D1:

  REAL (KIND=8) D1, D2
  DATA D1 /2.71828182846182/    ! REAL (KIND=4) value expanded to double
  DATA D2 /2.71828182846182D0/  ! Double value assigned to double


/fpe

Syntax:

/fpe:level

The /fpe:level option controls floating-point exception handling at run time for the main program. This includes whether exceptional floating-point values are allowed and how precisely run-time exceptions are reported. The /fpe:level option specifies how the compiler should handle the following floating-point exceptions:

  • When floating-point calculations result in a divide by zero, overflow, or invalid operation.
  • When floating-point calculations result in an underflow.
  • When a denormalized number or other exceptional number (positive infinity, negative infinity, or a NaN) is present in an arithmetic expression

For performance reasons:

  • On ia32 systems, the default is /fpe:3. Using /fpe:0 will slow run-time performance on ia32 systems.
  • On ia64 systems, the default is /fpe:0 (many programs do not need to handle denormalized numbers or other exceptional values). Using /fpe:3 will slow run-time performance on ia64 systems.

In the visual development environment, specify the Floating-Point Exception Handling in the Floating Point Compiler Option Category. The /fpe:level (level is 0 or 3) options are as follows:

/fpe:level Option | Handling of Underflow | Handling of Divide by Zero, Overflow, and Invalid Operation
/fpe:0 (default on ia64 systems) | Sets any calculated denormalized value (result) to zero and lets the program continue. Any use of a denormalized number in an arithmetic expression uses a value of 0.0 and execution continues. A message is displayed only if /check:underflow is also specified. | Exceptional values are not allowed. The program terminates after displaying a message.
/fpe:3 (default on ia32 systems) | Leaves any calculated denormalized value as is. The program continues, allowing gradual underflow. Use of a denormalized (or exceptional) number in an arithmetic expression results in program continuation, but with slower performance. | The program continues. No message is displayed. A NaN or Infinity (+ or -) will be generated.

When compiling different routines in a program separately, you should use the same /fpe:level value.

On ia32 systems, the /fpe option, /check:underflow option, and MATHERRQQ routine interact as follows:

Specified
/fpe:n
Option 		Was
/check:underflow
Specified? 		Is a User-Written MATHERRQQ Routine Present? Underflow Handling by the Visual Fortran Run-Time System on ia32 Systems
/fpe:0 | No | No | The underflowed result is set to zero (0). The program continues.
/fpe:0 | No | Yes | The underflowed result is set to zero (0). The program continues.
/fpe:0 | Yes | No | The underflowed result is set to zero (0). The program continues. The number of underflowed results are counted and messages are displayed for the first two occurrences.
/fpe:0 | Yes | Yes | The underflowed result is set to zero (0). The program continues. The number of underflowed results are counted and messages are displayed for the first two occurrences.
/fpe:3 | No | No | Denormalized results are allowed and the program continues. Traps are masked and no handlers are invoked.
/fpe:3 | No | Yes | Denormalized results are allowed and the program continues. Traps are masked and no handlers are invoked.
/fpe:3 | Yes | No | For Version 6, a fatal error results and the program terminates.
/fpe:3 Yes Yes Depends on the source causing the underflow:
  • If the underflow occurs in an intrinsic procedure, the undefined result is left as is. The program continues with the assumption that the user-specified MATHERRQQ handler will perform any result fix up needed.
  • If the underflow does not occur in an intrinsic procedure, for Version 6.0, a fatal error results and the program terminates.

For more information:

  • About the /fpe option on ia32 systems, see How the Floating-Point Exception Handling (/fpe) Compiler Option Works.
  • About the floating-point environment and the MATHERRQQ routine (ia32 systems), see The Floating-Point Environment.
  • About creating exception and termination handlers, see Advanced Exception and Termination Handling Considerations.
  • About routines that can obtain or set the floating-point exception settings used by Visual Fortran at run-time, see FOR_SET_FPE and FOR_GET_FPE.
  • About IEEE floating-point exception handling, see the IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Standard 754-1985).


/fpp

Syntax:

/fpp[:"options"]

The /fpp option activates the FPP preprocessor and optionally passes options to FPP as is. The FPP preprocessor can process both free- and fixed-form Fortran source files. Alternatively, you can use compiler directives, such as the IF Directive Construct, to detect symbol definitions and perform conditional compilation.

You can run FPP:

  • On the DF command line, by adding the /fpp option. By default, the specified files are compiled and linked. To retain the intermediate (.i or .i90) file, specify the /keep option.
  • In the visual development environment, by specifying the Use FPP option in the Preprocessor Compiler Option Category. By default, the file is compiled and linked. To retain the intermediate (.i or .i90) file, specify the /keep option on the command line or (in the visual development environment, Project Settings dialog box) the Project Options: box.
  • On the command line, by using the FPP command. In this case, the compiler is not invoked. When using the FPP command line, you need to specify the input file and the output intermediate (.i or .i90) file.

FPP is a modified version of the ANSI C preprocessor and supports a similar set of directives (including syntax and semantics). It supports the following directives: #define, #elif, #else, #endif, #if, #ifdef, #ifndef, #include, and #undef.

For example, the following DF command invokes FPP, specifies the /noC option to FPP, uses the /define option to define the symbol testcase, and preprocesses file cond.for before it is compiled and linked:

  DF /fpp:"/noC" /define:testcase=2 cond.for

For a list of predefined preprocessor symbols (such as _X86_), see /define.

For information on FPP options, type FPP /HELP on the command line.


/[no]fpscomp

Syntax:

/fpscomp[:keyword...] or /nofpscomp

The /fpscomp option controls whether certain aspects of the run-time system and semantic language features within the compiler are compatible with Visual Fortran or Microsoft Fortran PowerStation.

If you experience problems when porting applications from Fortran PowerStation, specify /fpscomp:keyword (or /fpscomp:all). When porting applications from Compaq Fortran, use /fpscomp:none or /fpscomp:libs (the default).

In the visual development environment, specify the PowerStation 4.0 Compatibility Options in the Compatibility Compiler Option Category. The /fpscomp options and their visual development environment names are:

/fpscomp:[no]filesfromcmd (Filenames from Command Line) | /fpscomp:[no]general (Other Run-time Behavior)
/fpscomp:[no]ioformat (I/O Format) | /fpscomp:[no]ldio_spacing (List Directed I/O Spacing)
/fpscomp:[no]libs (Libraries) | /fpscomp:[no]logicals (Logical Values)
/fpscomp:[no]symbols (Predefined Preprocessor Symbols) | /fpscomp:all and /fpscomp
/nofpscomp or /fpscomp:none |

/fpscomp:[no]filesfromcmd

Specifying /fpscomp:filesfromcmd for a file where the OPEN statement FILE specifier is blank (FILE=' '), requests that the following actions be taken at run-time:

  • The program reads a filename from the list of arguments (if any) in the command line that invoked the program. If any of the command-line arguments contain a null string (''), the program asks the user for the corresponding filename. Each additional OPEN statement with a nameless FILE specifier reads the next command-line argument.
  • If there are more nameless OPEN statements than command-line arguments, the program prompts for additional file names.
  • In a QuickWin application, a File Select dialog box appears to request file names.

Specifying /fpscomp:nofilesfromcmd disables the run-time system from using the filename specified on the command line when the OPEN statement FILE specifier is omitted, allowing the application of default directory, file name, and extensions like Compaq Fortran, such as the FORTn environment variable and the FORT.n file name (where n is the unit number).

Specifying /fpscomp:filesfromcmd affects the following Fortran features:

  • The OPEN statement FILE specifier

    For example, assume a program OPENTEST contains the following statements:

      OPEN(UNIT = 2, FILE = ' ')
  OPEN(UNIT = 3, FILE = ' ')
  OPEN(UNIT = 4, FILE = ' ')
    The following command line assigns the file TEST.DAT to Unit 2, prompts the user for a filename to associate with Unit 3, then prompts again for a filename to associate with Unit 4:
      opentest test.dat '' ''
  • Implicit file open statements such as the WRITE, READ, and ENDFILE statements

    Unopened files referred to in READ or WRITE statements are opened implicitly as if there had been an OPEN statement with a name specified as all blanks. The name is read from the command line.

    WRITE(UNIT = 8, FMT='(2I5)') int1, int2 ! Where "8" has not been
                                        ! explicitly associated with a file.

For more information about running Visual Fortran programs with the /fpscomp:filesfromcmd option or the use of alternative routines, see Running Fortran Applications.

/fpscomp:[no]general

Specifying /fpscomp:[no]general controls which run-time behavior is used when a difference exists between Visual Fortran and Microsoft Fortran PowerStation and either semantic must remain available for compatibility reasons:

  • Specify /fpscomp:general to request Microsoft Fortran PowerStation semantics.
  • Specify /fpscomp:nogeneral to request Visual Fortran semantics.

This affects the following Fortran features:

  • The BACKSPACE statement:
    • Allows files opened with ACCESS='APPEND' to be used with the BACKSPACE statement.
    • Allows files opened with ACCESS='DIRECT' to be used with the BACKSPACE statement.

    Note: Allowing files that are not opened with sequential access (such as ACCESS='DIRECT') to be used with the BACKSPACE statement violates the Fortran 90 standard and may be removed in the future. Section 9.5 states the following: "A file that is not connected for sequential access must not be referred to by a BACKSPACE, an ENDFILE, or a REWIND statement..."

  • The READ statement:
    • Formatted: READ(eunit, format [, advance][, iostat]...)
      Reading from a formatted file opened for direct access will read records that have the same record type format as Fortran PowerStation when /fpscomp:general is set. This consists of accounting for the trailing Carriage Return/Line Feed pair (<CR><LF>) that is part of the record.
      Allows sequential reads from a formatted file opened for direct access.

      Note: Allowing files that are not opened with sequential access (such as ACCESS='DIRECT') to be used with the sequential READ statement violates the Fortran 90 standard and may be removed in the future. Section 9.2.1.2.2 states the following: "Reading and writing records is accomplished only by direct access input/output statements."

    • Allows the last record in a file opened with FORM='FORMATTED' and a record type of STREAM_LF or STREAM_CR that does not end with a proper record terminator (<line feed> or <carriage return>) to be read without producing an error.
    • Unformatted: READ(eunit [, iostat]...)
      Allows sequential reads from an unformatted file opened for direct access.

      Note: Allowing files that are not opened with sequential access (such as ACCESS='DIRECT') to be read with the sequential READ statement violates the Fortran 90 standard and may be removed in the future. Section 9.2.1.2.2 states the following: "Reading and writing records is accomplished only by direct access input/output statements."

  • The INQUIRE statement:
    • The CARRIAGECONTROL specifier returns the value "UNDEFINED" instead of "UNKNOWN" when the carriage control is not known and when /fpscomp:general is set.
    • The NAME specifier returns the file name "UNKNOWN" instead of space filling the file name when the file name is not known and when /fpscomp:general is set.
    • The SEQUENTIAL specifier returns the value "YES" instead of "NO" for a direct access formatted file when /fpscomp:general is set.
    • The UNFORMATTED specifier returns the value "NO" instead of "UNKNOWN" when it is not known whether unformatted I/O can be performed to the file and when /fpscomp:general is set.

      Note: Returning the value "NO" instead of "UNKNOWN" for this specifier violates the Fortran 90 standard and may be removed in the future. See Section 9.6.1.12.

  • The OPEN statement:
    • If a file is opened with an unspecified STATUS keyword value, and is not named (no FILE specifier), the file is opened as a scratch file when /fpscomp:general is set. For example:
       OPEN (UNIT = 4)

      In contrast, when /fpscomp:nogeneral is in effect with an unspecified STATUS value with no FILE specifier, the FORTn environment variable and the FORT.n file name are used (where n is the unit number).
    • If the STATUS value was not specified and if the name of the file is "USER", the file is marked for deletion when it is closed when /fpscomp:general is set.
    • Allows a file to be opened with the APPEND and READONLY characteristics when /fpscomp:general is set.
    • If the CARRIAGECONTROL specifier is defaulted, gives "LIST" carriage control to direct access formatted files instead of "NONE" when /fpscomp:general is set.
    • Gives an opened file the additional default of write sharing when /fpscomp:general is set.
    • Gives the file a default block size of 1024 when /fpscomp:general is set as compared to 8192 (see Efficient Use of Record Buffers and Disk I/O).
    • If the MODE and ACTION specifier is defaulted and there was an error opening the file, then try opening the file read only, then write only.
    • If the CARRIAGECONTROL specifier is defaulted and if the device type is a terminal file, the file is given the default carriage control value of "FORTRAN" as compared to "LIST" when /fpscomp:general is set.
    • If a file that is being re-opened has a different file type than the current existing file, an error is returned when /fpscomp:general is set.
    • Gives direct access formatted files the same record type as Fortran PowerStation when /fpscomp:general is set. This means accounting for the trailing Carriage Return/Line Feed pair (<CR><LF>) which is part of the record.

  • The STOP statement:

    • Writes the Fortran PowerStation output string and/or returns the same exit condition values when /fpscomp:general is set.

  • The WRITE statement:
    • Formatted: WRITE(eunit, format [, advance][, iostat]...)
      • Writing to formatted direct files

        When writing to a formatted file opened for direct access, records are written in the same record type format as Fortran PowerStation when /fpscomp:general is set. This consists of adding the trailing Carriage Return/Line Feed pair (<CR><LF>) that is part of the record.

        Ignores the CARRIAGECONTROL specifier setting when writing to a formatted direct access file.

      • Interpreting Fortran carriage control characters

        When interpreting Fortran carriage control characters during formatted I/O, carriage control sequences are written which are the same as Fortran PowerStation when /fpscomp:general is set. This is true for the "Space, 0, 1 and + " characters.

      • Performing non-advancing I/O to the terminal.

        When performing non-advancing I/O to the terminal, output is written in the same format as Fortran PowerStation when /fpscomp:general is set.

      • Interpreting the backslash (\) and dollar ($) edit descriptors
        When interpreting backslash and dollar edit descriptors during formatted I/O, sequences are written the same as Fortran PowerStation when /fpscomp:general is set.

    • Unformatted: WRITE(eunit [, iostat]...)

      Allows sequential writes from an unformatted file opened for direct access.

      Note: Allowing files that are not opened with sequential access (such as ACCESS='DIRECT') to be read with the sequential WRITE statement violates the Fortran 90 standard and may be removed in the future. Section 9.2.1.2.2 states the following: "Reading and writing records is accomplished only by direct access input/output statements."

  • Specifying /fpscomp:general sets /fpscomp:ldio_spacing.

/fpscomp:[no]ioformat

Controls which run-time behavior is used for the semantic format for list-directed formatted I/O and unformatted I/O. Specify /fpscomp:ioformat to request Microsoft Fortran PowerStation semantic conventions and record formats (see Microsoft Fortran PowerStation Compatible Files). Specify /fpscomp:noioformat to request Compaq Fortran semantic conventions. This affects the following Fortran features:

  • The WRITE statement:
    • Formatted List-Directed: WRITE(eunit, * [, iostat]...)
    • Formatted Internal List-Directed: WRITE(iunit, * [, iostat]...)
    • Formatted Namelist: WRITE(eunit, nml-group [, iostat]...)

      If /fpscomp:ioformat is set, the output line, field width values, and the list-directed data type semantics are dictated according to the following sample for real constants (N below):

      • For 1 <= N < 10**7, use F15.6 for single precision or F24.15 for double.
      • For N < 1 or N >= 10**7, use E15.6E2 for single precision or E24.15E3 for double.

      See the Fortran PowerStation documentation for more detailed information about the other data types affected.

    • Unformatted: WRITE(eunit [, iostat]...)

      If /fpscomp:ioformat is set, the unformatted file semantics are dictated according to the Fortran PowerStation documentation. Be aware that the file format differs from that used by Compaq Fortran. See the Fortran PowerStation documentation for more detailed information.

      The following table summarizes the default output formats for list-directed output with the intrinsic data types:

      Default Formats for List-Directed Output

      Data Type Output Format with
      /fpscomp:noioformat       		Output Format with
      /fpscomp:ioformat
      BYTE | I5 | I12
      LOGICAL (all) | L2 | L2
      INTEGER(1) | I5 | I12
      INTEGER(2) | I7 | I12
      INTEGER(4) | I12 | I12
      INTEGER(8) | I22 | I22
      REAL(4) | 1PG15.7E2 | 1PG16.6E2
      REAL(8) | 1PG24.15E3 | 1PG25.15E3
      COMPLEX(4) '( ',1PG14.7E2, ',
      ',1PG14.7E2, ') '       		'( ',1PG16.6E2, ',
      ',1PG16.6E2, ') '
      COMPLEX(8) '( ',1PG23.15E3, ',
      ',1PG23.15E3, ') '       		'( ',1PG25.15E3, ',
      ',1PG25.15E3, ') '
      CHARACTER | Aw | Aw

  • The READ statement:
    • Formatted List-Directed: READ(eunit, * [, iostat]...)
    • Formatted Internal List-Directed: READ(iunit, * [, iostat]...)
    • Formatted Namelist: READ(eunit, nml-group [, iostat]...)

      If /fpscomp:ioformat is set, the field width values and the list-directed semantics are dictated according to the following sample for real constants (N below):

      • For 1 <= N < 10**7, use F15.6 for single precision or F24.15 for double.
      • For N < 1 or N >= 10**7, use E15.6E2 for single precision or E24.15E3 for double.

      See the Fortran PowerStation documentation for more detailed information about the other data types affected.

    • Unformatted: READ(eunit [, iostat]...)

      If /fpscomp:ioformat is set, the unformatted file semantics are dictated according to the Fortran PowerStation documentation. Be aware that the file format to read differs from that used by Compaq Fortran. See the Fortran PowerStation documentation for more detailed information.

/fpscomp:[no]ldio_spacing

For list-directed output, controls whether a blank is inserted at run-time after a numeric value before a character value (undelimited character string). The default is /fpscomp:noldio_spacing, which conforms to the Fortran 95 standard by inserting a blank after a numeric value before a character value. To request non-standard behavior for compatibility with Microsoft Fortran PowerStation and Visual Fortran releases before Version 6.6, either specify /fpscomp:ldio_spacing or specify /fpscomp:general, which sets /fpscomp:ldio_spacing.

/fpscomp:[no]libs

Controls whether the library dfport.lib (Portability library) is passed to the compiler and linker. The default is /fpscomp:libs, which passes this library. Specifying /fpscomp:nolibs does not pass this library.

/fpscomp:[no]logicals

Controls the value used for logical true. Microsoft Fortran PowerStation and Compaq Fortran with the /fpscomp:logical option set uses any non-zero value (default is 1) for true. Compaq Fortran with the /fpscomp:nological option set only looks at the low bit of the value, using a -1 for true. Differences can occur when a logical is stored into an integer. Both use 0 (zero) for false.

This affects the results of all logical expressions and affects the return value for the following Fortran features:

  • The INQUIRE statement specifiers OPENED, IOFOCUS, EXISTS, and NAMED.
  • The EOF intrinsic function.
  • The BTEST intrinsic function.
  • The lexical intrinsic functions LLT, LLE, LGT, and LGE.

/fpscomp:[no]symbols

Adds one or more symbols related to Microsoft Fortran PowerStation to preprocessor and compiler invocations. The symbol currently set by specifying /fpscomp:symbols is _MSFORTRAN_=401.

/fpscomp:all and /fpscomp

Enable full Microsoft Fortran PowerStation compatibility or /fpscomp:(filesfromcmd,general,ioformat,ldio_spacing,libs,logicals,symbols).

/nofpscomp or /fpscomp:none

Enables full Compaq Fortran compatibility or /fpscomp:(nofilesfromcmd,nogeneral,noioformat,noldio_spacing,nolibs,nologicals,nosymbols).

If you omit /fpscomp, the default is /fpscomp:libs.

The /fpscomp and /vms options are not allowed in the same command.


/[no]free

Syntax:

/free, /nofree,/4Yf, or /4Nf

The /free or /4Yf option specifies that the source file should be interpreted as being in free source format. Equivalent options are as follows:

  • The /nofixed, /free, and /4Yf options are equivalent and request free-source form.
  • The /fixed, /nofree, and /4Nf options are equivalent and request fixed-source form.

In the visual development environment, specify the Source Form in the Fortran Language Compiler Option Category.

If you omit /[no]free, /[no]fixed, /4Nf, and /4Yf, the compiler assumes:

  • Files with an extension of .f90, .F90, or .i90 are free-format source files.
  • Files with an extension of .f, .for, .FOR, or .i are fixed-format files.


/help

Syntax:

/help or /?

The /help and /? option display information about the DF command. The option can be placed anywhere on the command line.

For a table of DF command options listed alphabetically, see Options List, Alphabetic Order.


/iface

Syntax:

/iface[:keyword...]

The /iface option determines the type of argument-passing conventions used by your program for general arguments and for hidden-length character arguments.

In the visual development environment, specify the Default Calling Conventions and the String Length Argument Passing in the External Procedures Compiler Option Category. The /iface keywords are as follows:

  • The general argument-passing convention keywords are one of: cref, stdref, and default (stdref and default are equivalent). The functions performed by each are described in the following table:

    /iface:cref | /iface:default | /iface:stdref
    Arguments are passed | By reference | By reference | By reference
    Append @n to names on ia32 systems? | No | Yes | Yes
    Who cleans up stack | Caller | Callee | Callee
    Var args support? | Yes | No | No

  • To specify the convention for passing the hidden-length character arguments, specify /iface:[no]mixed_str_len_arg:
    • /iface:mixed_str_len_arg

      Requests that the hidden lengths be placed immediately after their corresponding character argument in the argument list, which is the method used by Microsoft Fortran PowerStation.

    • /iface:nomixed_str_len_arg

      Requests that the hidden lengths be placed in sequential order at the end of the argument list, which is the method used by Compaq Fortran for Tru64 UNIX systems by default. When porting mixed-language programs that pass character arguments, either this option must be specified correctly or the order of hidden length arguments changed in the source code.

If you omit the /iface option, the following is used:

  /iface=(default,mixed_str_len_arg)

For more information on argument passing, see Programming with Mixed Languages.


/imsl

Syntax:

/imsl

The /imsl option ensures that the IMSL libraries will be passed to the linker. Your program still needs to specify the appropriate USE statement(s) and set IMSL environment variables (see Using the Libraries from Visual Fortran).

In the visual development environment, specify Use IMSL Math Library in the Library Compiler Option Category.


/[no]include

Syntax:

/include[:path...], /noinclude, or /I path

The /include or /I option specifies one or more additional directories (path) to be searched for module files (USE statement) and include files (INCLUDE statement).

In the visual development environment, specify Custom INCLUDE and USE Path in the Preprocessor Compiler Option Category.

For all USE statements and for those INCLUDE statements whose file name does not begin with a device or directory name, the directories searched are as follows:

  1. The directory containing the first source file or the current directory (depends on whether /assume:source_include was specified).
  2. The current default directory where the compilation is taking place
  3. If specified, the directory or directories listed in the /include:path or /Ipath option. The order of searching multiple directories occurs within the specified list from left to right
  4. The directories indicated in the environment variable INCLUDE

To request that the compiler search first in the directory where the source file resides instead of the current directory, specify /assume:source_include.

Specifying /noinclude (or /include or /I without a path) prevents searching in the standard directory specified by the INCLUDE environment variable.


/[no]inline

Syntax:

/inline[:keyword], /noinline, or /Ob2

The /inline or /Ob2 option allows users to have some control over inlining. Inlining procedures can greatly improve the run-time performance for certain applications.

When requesting procedure inlining (or interprocedural optimizations), compile all source files together into a single object file whenever possible. With very large applications, compile as many related source files together as possible.

If you compile sources without linking (see the /compile_only option), be sure to also specify the /object[:filename] option to create a single object file.

In the visual development environment, specify the Inlining type in the Optimizations Compiler Option Category. The /inline options are:

/inline:none or /noinline | /inline:manual
/inline:size | /inline:speed or /Ob2
inline:all |

The /inline options:

  • /inline:none or /noinline

    Prevents the inlining of procedures, except for statement functions. This type of inlining occurs if you specify /optimize:0 or /optimize:1 and omit /inline options.

  • /inline:manual

    Prevents the inlining of procedures, except for statement functions. This type of inlining occurs if you specify /optimize:2 or /optimize:3 and omit /inline options.

  • /inline:size

    Inlines procedures that will improve run-time performance without significantly increasing program size. It includes the types of procedures inlined when you specify /inline:manual.

  • /inline:speed or /Ob2

    Inlines procedures that will improve run-time performance with a significant increase in program size. This type of inlining is available with /optimize:1 or higher. This type of inlining occurs if you specify /optimize:4 or /optimize:5 and omit /inline options.

  • inline:all

    Inlines absolutely every call that it is possible to inline while still getting correct code. However, recursive routines will not cause an infinite loop at compile time. This type of inlining is available with /optimize:1 or higher. It includes the types of procedures inlined when you specify other /inline options.

    Using /inline:all can significantly increase program size and slow compilation speed.

For more detailed information on this option, see Controlling the Inlining of Procedures.


/[no]intconstant

Syntax:

/intconstant or /nointconstant

The /intconstant option requests that Fortran 77 semantics (type determined by the value) be used to determine the kind of integer constants instead of Fortran 90 default INTEGER type. If you do not specify /intconstant, the type is determined by the default INTEGER type.

In the visual development environment, specify Use F77 Integer Constants in the Compatibility Compiler Option Category.


/integer_size

Syntax:

/integer_size:size or /4I2

The /integer_size or /4I2 option specifies the size (in bits) of integer and logical declarations, constants, functions, and intrinsics. In the visual development environment, specify the Default Integer Kind in the Fortran Data Compiler Option Category. These options are:

  • /integer_size:16 or /4I2

    Makes the default integer and logical variables 2 bytes long. INTEGER and LOGICAL declarations are treated as (KIND=2).

  • /integer_size:32

    Makes the default integer and logical variables 4 bytes long (default). INTEGER and LOGICAL declarations are treated as (KIND=4).

  • /integer_size:64

    Makes the default integer and logical variables 8 bytes long. INTEGER and LOGICAL declarations are treated as (KIND=8).


/[no]keep

Syntax:

/keep or /nokeep

The /keep option creates one object file for each input source file specified, which may not be desirable when compiling multiple source files. The /keep option does not remove temporary files, which might be created by the FPP preprocessor or the Visual Fortran compiler.

If the /keep option is specified, the FPP output files and object files are created in the current directory and retained. The /keep option also affects the number of files that are created and the file names used for these files.


/[no]libdir

Syntax:

/libdir[:keyword], /nolibdir, or /Zl or /Zla

The /libdir, /Zl, or /Zla option controls whether library search paths are placed into object files generated by the compiler. Specify one or more of the following options:

/libdir:all or /libdir | /libdir:none, /nolibdir, or /Zl
/libdir:automatic | /libdir:user

The /libdir options:

  • /libdir:all or /libdir

    Requests the insertion of linker search path directives for libraries automatically determined by the DF command driver and for those specified by the cDEC$ OBJCOMMENT LIB source directives. Specifying /libdir:all is equivalent to /libdir:(automatic, user). This is the default.

  • /libdir:none, /nolibdir, or /Zla

    Prevents all linker search path directives from being inserted into the object file (neither automatic nor user specified).

  • /libdir:automatic

    Requests the insertion of linker search path directives for libraries automatically determined by the DF command driver (default libraries). To prevent the insertion of linker directives for default libraries, specify /libdir:noautomatic or /Zl. In the visual development environment, specify Disable Default Library Search Rules (for /libdir:noautomatic) in the Libraries Compiler Option Category.

  • /libdir:user

    Allows insertion of linker search path directives for any libraries specified by the cDEC$ OBJCOMMENT LIB source directives. To prevent the insertion of linker directives for any libraries specified by the OBJCOMMENT directives, specify /libdir:nouser. In the visual development environment, specify Disable OBJCOMMENT Directives (for /libdir:nouser) in the Libraries Compiler Option Category.


/libs

Syntax:

/libs[:keyword], /MD, /MDd, /MDs, /ML, /MLd, /MT, /MTd, /MTs, /MW, or /MWs

The /libs option controls the type of libraries your application is linked with. The default is /libs:static (same as /libs). In the visual development environment, specify the appropriate options in Use Fortran Run-Time Libraries list (for example, an option with DLL in its name sets /libs:dll) in the Libraries Compiler Option Category. These options are:

/libs:dll or /MDs | /libs:static or /ML
/libs:qwin or /MW | /libs:qwins or /MWs

This section also contains jumps to related information about libraries.

The /libs options:

  • /libs:dll or /MDs

    The /libs:dll or /MDs option causes the linker to search for unresolved references in single threaded, dynamic link reference libraries (DLLs). If the unresolved reference is found in the DLL, it gets resolved when the program is executed (during program loading), reducing executable program size.
    Specifying /libs:dll with /threads is equivalent to /MD.
    Specifying /libs:dll with /threads and /dbglibs is equivalent to /MDd.

  • /libs:static or /ML

    The /libs:static or /ML option requests that the linker searches only in single threaded, static libraries for unresolved references. This is the default. Specifying /libs:static does not request that dynamic link libraries (DLLs), QuickWin, or Standard Graphics libraries be searched. If you use QuickWin or Standard Graphics routines, use /libs:qwin or /libs:qwins. Specifying /libs (with no keyword) is the same as specifying /libs:static.

    Specifying /libs:static with /nothreads is equivalent to /ML.
    Specifying /libs:static with /nothreads and /dbglibs is equivalent to /MLd.
    Specifying /libs:static with /threads is equivalent to /MT.
    Specifying /libs:static with /threads and /dbglibs is equivalent to /MTd.

  • /libs:qwin or /MW

    Specifying /libs:qwin or /MW requests linking with libraries required of a Fortran QuickWin multi-doc (QuickWin) application.

  • /libs:qwins or /MWs

    Specifying /libs:qwins or /MWs requests linking with libraries required of a Fortran Standard Graphics (QuickWin single-doc) application.

The following related options request additional libraries to link against:

  • /dbglibs
  • /threads
  • /winapp
  • /fpscomp:libs

To request the creation of a dynamic-link library, see /dll.

For information about compiling and linking Visual Fortran and Visual C++ programs (and the libraries used), see Specifying Consistent Library Types and Visual Fortran/Visual C++ Mixed-Language Programs.

For command-line examples of using the /libs option, see Linking Against Additional Libraries.


/[no]link

Syntax:

/link:options or /nolink

The /link option (without specifying options) precedes options to be passed to the linker as is (see Linker Options and Related Information). You can also specify the options to be passed to the linker as is using the form: /link:options.

To specify additional libraries to be linked on the command line, specify the library name on the DF command line either before or after the /link option, but the Linker option /nodefaultlib must follow the /link option:

 DF /compiler-options filename.f90  mylib.lib /link /nodefaultlib

In the visual development environment, you can specify linker options using the Linker tab in the Project menu Settings dialog box. For example, to specify additional libraries to be linked in the visual development environment:

  1. In the Project menu, click Settings to display the Project settings dialog box
  2. Click the Linker tab
  3. Select the General category
  4. Type the additional library name to be linked with under Object/Library modules, such as mylib.lib
  5. Click OK when done

The /nolink option suppresses linking and forces an object file to be produced even if only one program is compiled. Any options specified after the /nolink option are ignored.

If you encounter linker errors, see Linker Diagnostic Messages and Error Conditions.


/[no]list

Syntax:

/list[:file], /nolist, or /Fs file

The /list or /Fs option creates a listing of the source file with compile-time information appended. To name the source listing file, specify file. If you omit the /list or /Fs options (or specify /nolist), no listing file is created.

In the visual development environment, specify Source Listing in the Listing File Compiler Option Category.

When a diagnostic message is displayed, the listing file contains a column pointer (such as .....1) that points to the specific part of the source line that caused the error.

To specify the content of the listing file, see /show.

To request a listing with Assembly instructions, see /asmfile.

To request a listing with information about optimizations, see /annotations.

The name of the listing file is the same as the source file (unless specified by file), with the extension .LST (unless the extension is specified by file).

If multiple object files are created, multiple listing files are usually created. For example, if you specify multiple source files with the /compile_only and /list options without a named object file (/object:file), multiple files are created. If you specify multiple source files with the /list, /compile_only, and /object:file, a single listing file is created. For command-line examples, see Generating a Listing File.


/[no]logo

Syntax:

/nologo or /logo

The /nologo option suppresses the copyright notice displayed by the compiler and linker. This option can be placed anywhere on the command line.


/[no]machine_code

Syntax:

/machine_code or /nomachine_code

The /machine_code option requests that a machine language representation be included in the listing file. The /machine_code option is a synonym for /show:code. In the visual development environment, specify Source Listing Options, Machine Code in the Listing File Compiler Option Category.

This option is ignored unless you specify /list[:file].


/[no]map

Syntax:

/map[:file], /nomap, or /Fm file

The /map or /Fm option controls whether or not a link map is created. To name the map file, specify file.

In the visual development environment, in the Project menu Settings dialog box:

  1. Click the Linker tab
  2. Select the General category
  3. Click the Generate mapfile option check box

If you omit /map or /Fm, a map file is not created.

The link map is a text file (see the Linker option /MAP).


/math_library

Syntax:

/math_library:keyword

The /math_library option specifies whether argument checking of math routines is done on ia32 systems. This option is ignored on ia64 systems.

In the visual development environment, specify the Math Library in the Optimizations (or Code Generation) Compiler Option Category. The /math_library options are: /math_library:fast and /math_library:check:

  • /math_library:fast

    On ia32 systems, /math_library:fast improves performance by not checking the arguments to the math routines. Using /math_library:fast makes tracing the cause of unexpected exceptional values results difficult. Specifying /math_library:fast does not change the accuracy of calculated floating-point numbers.

  • /math_library:check

    On ia32 systems, /math_library:check validates the arguments to and results from calls to the Fortran math routines. This provides slower run-time performance than /math_library:fast, but with earlier detection of exceptional values. This is the default on ia32 systems.


/[no]module

Syntax:

/module[:path] or /nomodule

The /module option controls where the module files (extension .MOD) are placed. If you omit this option (or specify /nomodule), the .MOD files are placed in the directory where the source file being compiled resides.

When /module:path is specified, the path specifies the directory location where the module files will be placed.

In the visual development environment, specify the Module Path in the Preprocessor Compiler Option Category.

When /module is entered without specifying a path, it is interpreted as a request to place the MOD files in the same location that the object is being created. Should a path be specified on the /object option, that location would also be used for the MOD files.

You need to ensure that the module files are created before they are referenced when using the DF command (see Compile With Appropriate Options and Multiple Source Files).


/names

Syntax:

/names:keyword, /GNa, /GNl, or /GNu

The /names option specifies how source code identifiers and external names are interpreted and the case convention used for external names. This naming convention applies whether names are being defined or referenced. The default is /names:uppercase (same as /GNu).

In the visual development environment, specify the Name Interpretation in the External Procedures or the Fortran Language Compiler Option Category. The /names options are:

  • /names:as_is or /GNa
    Causes the compiler to:
    • Distinguish between uppercase and lowercase letters in source code identifiers (treat uppercase and lowercase letters as different).
    • Distinguish between uppercase and lowercase letters in external names.

  • /names:lowercase or /GNl
    Causes the compiler to:
    • Not distinguish between uppercase and lowercase letters in source code identifiers (treat lowercase and uppercase letters as equivalent).
    • Force all letters to be lowercase in external names.

  • /names:uppercase or /GNu (default)
    Causes the compiler to:
    • Not distinguish between uppercase and lowercase letters in source code identifiers (treat lowercase and uppercase letters as equivalent).
    • Force all letters to be uppercase in external names.

Instead of using the /names compiler option, consider using the cDEC$ ALIAS directive for the specific name needed.


/nodefine

Syntax:

/nodefine

The /nodefine option requests that all symbols specified by the accompanying /define:symbols option apply only to the Fortran preprocessor, FPP, and are not available to conditional compilation directives (such as the IF Directive Construct). For example, the following command defines the symbol release as 1, which is available only to FPP:

  DF /fpp /define:release /nodefine

If you specify /define:symbols and omit /nodefine, symbols specified by /define:symbols are available to both FPP and conditional compilation directives.

In the visual development environment, specify the Predefined Preprocessor Symbols to FPP Only in the Preprocessor Compiler Option Category.

For more information on FPP, see /fpp.


/[no]object

Syntax:

/object[:filename], /noobject, or /Fo filename

The /object or /Fo option names the object file filename. Specify /noobject to prevent creation of an object file. The default is /object, where the file name is the same as the first source file with a file extension of .OBJ.

If you omit /compile_only (or /c) and specify /object:filename or /Fofilename, the /object option names the object file filename.

If you specify /object:filename or /Fofilename and specify the /compile_only option, the /object or /Fo option causes multiple Fortran input files (if specified) to be compiled into a single object file. This allows interprocedural optimizations to occur at higher optimization levels, which usually improves run-time performance.

For information on where module files are placed, see /module[:path].


/[no]optimize

Syntax:

/optimize[:level], /nooptimize, /Od, /Ox, or /Oxp

The /optimize option controls the level of optimization performed by the compiler. To provide efficient run-time performance, Visual Fortran increases compile time in favor of decreasing run time. If an operation can be performed, eliminated, or simplified at compile time, the compiler does so rather than have it done at run time. Also, the size of object file usually increases when certain optimizations occur (such as with more loop unrolling and more inlined procedures).

In the visual development environment, specify the Optimization Level in the General or Optimizations Compiler Option Category. The /optimize options are:

/optimize:0 or /Od | /optimize:1
/optimize:2 | /optimize:3
/optimize:4, /Ox, and /Oxp | /optimize:5

The /optimize options:

  • /optimize:0 or /Od

    Disables nearly all optimizations. This is the default if you specify /debug (with no keyword). Specifying this option causes certain /warn options to be ignored. The /optimize:0 option is the default in the the visual development environment for a debug configuration. Specifying /Od sets the /optimize:0 and /math_library:check options.

  • /optimize:1

    Enables local optimizations within the source program unit, recognition of common subexpressions, and expansion of integer multiplication and division (using shifts).

  • /optimize:2

    Enables global optimization. This includes data-flow analysis, code motion, strength reduction and test replacement, split-lifetime analysis, and instruction scheduling. Specifying /optimize:2 includes the optimizations performed by /optimize:1.

  • /optimize:3

    Enables additional global optimizations that improve speed (at the cost of extra code size). These optimizations include:

    • Loop unrolling, including instruction scheduling
    • Code replication to eliminate branches
    • Padding the size of certain power-of-two arrays to allow more efficient cache use (see Use Arrays Efficiently)

    Specifying /optimize:3 includes the optimizations performed by /optimize:1 and /optimize:2.

  • /optimize:4, /Ox, and /Oxp

    Enables interprocedure analysis and automatic inlining of small procedures (with heuristics limiting the amount of extra code). Specifying /optimize:4 includes the optimizations performed by /optimize:1 /optimize:2, and /optimize:3. For the DF command, /optimize:4 is the default for the command line unless you specify /debug (with no keyword). In the the visual development environment for a release configuration, the default is /optimize:4.

    Specifying /Ox sets: /optimize:4, /math_library:fast, and /assume:nodummy_aliases.

    Specifying /Oxp sets: /optimize:4, /math_library:check, /assume:nodummy_aliases, and /fltconsistency.

  • /optimize:5

    On ia32 systems, activates the loop transformation optimizations (also set by /transform_loops). On ia64 systems, activates the loop transformation optimizations (also set by /transform_loops) and the software pipelining optimization (also set by /pipeline (ia64 only)):

    • The loop transformation optimizations are a group of optimizations that apply to array references within loops. These optimizations can improve the performance of the memory system and can apply to multiple nested loops.

      Loop transformation optimizations include loop blocking, loop distribution, loop fusion, loop interchange, loop scalar replacement, and outer loop unrolling. You can specify loop transformation optimizations without software pipelining (see /[no]transform_loops).

    • The software pipelining optimization (ia64 systems only) applies instruction scheduling to certain innermost loops, allowing instructions within a loop to "wrap around" and execute in a different iteration of the loop. This can reduce the impact of long-latency operations, resulting in faster loop execution. Software pipelining also enables the prefetching of data to reduce the impact of cache misses.

      You can specify software pipelining without loop transformation optimizations (see /[no]pipeline (ia64 only)).

    To determine whether using /optimize:5 benefits your particular program, you should compare program execution timings for the same program (or subprogram) compiled at levels /optimize:4 and /optimize:5.

    Specifying /optimize:5 includes the optimizations performed by /optimize:1, /optimize:2, /optimize:3, and /optimize:4.

For detailed information on these optimizations, see Optimization Levels: the /optimize Option.

For information about timing your program, see Analyze Program Performance.

To compile your application for efficient run-time performance, see Compile With Appropriate Options and Multiple Source Files.


/[no]pad_source

Syntax:

/pad_source or /nopad_source

For fixed-form source files, the /pad_source option requests that source records shorter than the statement field width are to be padded with spaces on the right out to the end of the statement field. This affects the interpretation of character and Hollerith literals that are continued across source records.

In the visual development environment, specify the Pad Fixed-Form Source Records in the Fortran Language Compiler Option Category.

The default is /nopad_source, which causes a warning message to be displayed if a character or Hollerith literal that ends before the statement field ends is continued onto the next source record. To suppress this warning message, specify the /warn:nousage option.

Specifying /pad_source can prevent warning messages associated with /warn:usage.


/[no]pdbfile

Syntax:

/pdbfile[:filename], /nopdbfile, or /Fd filename

The /pdbfile or /Fd option indicates that any debug information generated by the compiler should be to a program database file, filename.PDB. If you omit filename, the default file name used is df60.pdb.

In the visual development environment, specify Use Program Database for Debug Information (and optionally specify the Program Database .PDB Path) in the Debug Compiler Option Category.

When full debug information is requested (/debug:full, /debug, or equivalent), the debug information is placed in the PDB file (unless /nopdbfile is specified).

The compiler places debug information in the object file if you specify /nopdbfile or omit both /pdbfile and /debug:full (or equivalent).


/[no]pipeline (ia64 only)

Syntax:

/pipeline or /nopipeline

On ia64 systems, the /pipeline (or /optimize:5) option activates the software pipelining optimization. This optimization applies instruction scheduling to certain innermost loops, allowing instructions within a loop to "wrap around" and execute in a different iteration of the loop. This can reduce the impact of long-latency operations, resulting in faster loop execution.

In the visual development environment, specify the Apply Software Pipelining Optimizations in the Optimizations Compiler Option Category.

For this version of Visual Fortran, loops chosen for software pipelining are always innermost loops and do not contain branches, procedure calls, or COMPLEX floating-point data.

Software pipelining also enables the prefetching of data to reduce the impact of cache misses.

Software pipelining is a subset of the optimizations activated by /optimize:5. Instead of specifying both /pipeline and /transform_loops, you can specify /optimize:5.

To specify software pipelining without loop transformation optimizations, do one of the following:

  • Specify /optimize:5 with /notransform_loops.
  • Specify /pipeline with /optimize:4, /optimize:3, or /optimize:2. This optimization is not performed at optimization levels below /optimize:2.

To determine whether using /pipeline benefits your particular program, you should time program execution for the same program (or subprogram) compiled with and without software pipelining (such as with /pipeline and /nopipeline).

For certain programs that contain loops that exhaust available registers, longer execution times may result with /optimize:5, requiring use of /unroll:count to limit loop unrolling. The /pipeline option applies only to ia64 systems.

For more information, see Software Pipelining.


/preprocess_only

Syntax:

/preprocess_only

When used with the /fpp option, the /preprocess_only option runs only the FPP preprocessor and puts the result for each source file in a corresponding .i or .i90 file. The .i or .i90 file does not have line numbers (#) in it.

You need to specify /fpp with this option.


/real_size

Syntax:

/real_size:size or /4R8

The /real_size or /4R8 option controls the size (in bits) of REAL and COMPLEX declarations, constants, functions, and intrinsics. In the visual development environment, specify the Default Real Kind in the Fortran Data Compiler Option Category. The /real_size options are:

  • /real_size:32

    Defines REAL declarations, constants, functions, and intrinsics as REAL(KIND=4) (SINGLE PRECISION). It also defines COMPLEX declarations, constants, functions, and intrinsics as COMPLEX(KIND=4) (COMPLEX). This is the default.

  • /real_size:64 or /4R8

    Defines REAL declarations, constants, functions, and intrinsics as REAL(KIND=8) (DOUBLE PRECISION). It also defines COMPLEX declarations, constants, functions, and intrinsics as COMPLEX(KIND=8).

Specifying /real_size:64 causes intrinsic functions to produce a REAL(KIND=8) or
COMPLEX(KIND=8) result instead of a REAL(KIND=4) or COMPLEX(KIND=4) result, unless the
argument is explicitly typed as REAL(KIND=4) or COMPLEX(KIND=4), including CMPLX,
FLOAT, REAL, SNGL, and AIMAG. For instance, references to the CMPLX intrinsic
produce DCMPLX results (COMPLEX(KIND=8)), unless the argument to CMPLX is explicitly
typed as REAL(KIND=4), REAL*4, COMPLEX(KIND=4), or COMPLEX*8. In this case the resulting
data type is COMPLEX(KIND=4).


/[no]recursive

Syntax:

/recursive or /norecursive

The /recursive option compiles all procedures (functions and subroutines) for possible recursive execution. Specifying the /recursive option sets the /automatic option. The default is /norecursive.

In the visual development environment, specify Enable Recursive Routines in the Code Generation Compiler Option Category.


/[no]reentrancy

Syntax:

/reentrancy[:keyword] or /noreentrancy

The /reentrancy or /reentrancy:threads option requests that the compiler generate reentrant code that supports a multithreaded application. In the visual development environment, specify the Enable Reentrancy Support or Disable Reentrancy Support in the Libraries Compiler Option Category.

If you omit /reentrancy, /reentrancy:threads, or /threads, /reentrancy:none (same as /noreentrancy) is used.

Specifying /threads sets /reentrancy:threads, since multithreaded code must be reentrant.


/[no]show

Syntax:

/show:keyword... or /noshow

The /show option specifies what information is included in a listing. In the visual development environment, specify the Source Listing Options in the Listing File Compiler Option Category. The /show keywords are:

/show:code | /show:include
/show:map | /show:nomap
/show or /show:all | /noshow or /show:none

The /show keywords:

  • /show:code

    Includes a machine-language representation of the compiled code in the listing file. The default is /show:nocode. The /show:code and /machine_code options are equivalent.

  • /show:include

    Lists any text file included in the source file (unless that source is included using the INCLUDE 'filespec /NOLIST' syntax; see the /vms option). The default is /show:noinclude.

  • /show:map (default)

    Includes a symbol map in the listing file.

  • /show:nomap

    Do not include a symbol map in the listing file.

  • /show or /show:all

    Equivalent to /show:(code,include,map).

  • /noshow or /show:none

    Equivalent to /show:(nocode,noinclude,nomap).

The /show option is ignored unless you specify /list[:file] or /Fsfile.


/source

Syntax:

/source:file or /Tf file

The /source or /Tf option indicates that the file is a Fortran source file with a non-standard file extension (not one of .F, .FOR, or .F90) that needs to be compiled.

The default for any file that does not have an extension of .F90 or .f90 is to be a fixed-format Fortran file.


/[no]stand

Syntax:

/stand[:keyword], /nostand, /4Ys, or /4Ns

The /stand option issues compile-time messages for language elements that are not standard in the Fortran 90 or Fortran 95 language that can be identified at compile-time. In the visual development environment, specify the Fortran Standards Checking in the Compilation Diagnostics Compiler Option Category.

The /stand options are:

  • /stand:f90 or /4Ys

    Specifies that diagnostic messages be generated with a warning-level severity (allows an object file to be created) for extensions to the Fortran 90 standard.

  • /stand or /stand:f95

    Specifies that diagnostic messages be generated with a warning-level severity (allows an object file to be created) for extensions to the Fortran 95 standard.

  • /stand:none, /nostand, or /4Ns

    Specifies that no messages be issued for language elements that are not standard in the Fortran 90 or Fortran 95 language.

    The same effect occurs if you omit the /stand, or /stand:keyword, /warn:stderrors, or /4Ys options.

Specify /warn:stderrors to request that diagnostic messages be generated with an error-level severity (instead of warning) to prevent an object file from being created.

Specifying /stand issues warning messages for:

  • Obsolescent and deleted features specified by the Fortran standard.
  • Syntax extensions to the Fortran 95 standard. Syntax extensions include nonstandard statements and language constructs.
  • Fortran 95 standard-conforming statements that become nonstandard due to the way in which they are used. Data type information and statement locations are considered when determining semantic extensions.
  • For fixed-format source files, lines that use tab formatting.

Source statements that do not conform to Fortran language standards are detected by the compiler under the following circumstances:

  • The statements contain ordinary syntax and semantic errors.
  • A source program containing nonconforming statements is compiled with the /stand or /check options.

Given these circumstances, the compiler is able to detect most instances of nonconforming usage. It does not detect all instances because the /stand option does not produce checks for all nonconforming usage at compile time. In general, the unchecked cases of nonconforming usage arise from the following situations:

  • The standard violation results from conditions that cannot be checked at compile time.
  • The compile-time checking is prone to false alarms.

Most of the unchecked cases occur in the interface between calling and called subprograms. However, other cases are not checked, even within a single subprogram.

The following items are known to be unchecked:

  • Use of a data item prior to defining it
  • Use of the SAVE statement to ensure that data items or common blocks retain their values when reinvoked
  • Association of character data items on the right and left sides of character assignment statements
  • Mismatch in order, number, or type in passing actual arguments to subprograms with implicit interfaces
  • Association of one or more actual arguments with a data item in a common block when calling a subprogram that assigns a new value to one or more of the arguments


/[no]static

Syntax:

/static or /nostatic

The /static option is the same as the /noautomatic option. The default is /static, which causes all local variables to be statically allocated. The /nostatic option is the same as /automatic. In the visual development environment, specify /nostatic as Variables Default to Automatic in the Fortran Data Compiler Option Category.

If you specify /recursive, the /automatic option is set.


/[no]syntax_only

Syntax:

/syntax_only or /nosyntax_only

The /syntax_only option requests that only the syntax of the source file be checked. If the /syntax_only option is specified, code generation is suppressed. The default is /nosyntax_only.


/[no]threads

Syntax:

/threads or /nothreads

The /threads option requests linking with multithreaded libraries, which creates a multithreaded program or DLL. If you specify /threads, this sets the /reentrancy option.

In the visual development environment, specify one of the Multi-thread library options in Use Fortran Run-Time Libraries list in the Libraries Compiler Option Category.

The default is /nothreads, which links with single-threaded libraries to create a single-threaded program or DLL.

Related options that control the libraries used during linking include:

  • /libs
  • /winapp
  • /fpscomp:libs


/[no]traceback

Syntax:

/traceback or /notraceback or /Zt

The /traceback option requests that the compiler generate extra information in the object file that allows the display of source file traceback information at run time when a severe error occurs.

Specifying /traceback:

  • Provides source file, routine name, and line number correlation information in the text that is displayed when a severe error occurs.
  • Will increase the size of the executable program, but has no impact on run-time execution speeds.

For the DF command line and for a release configuration in the visual development environment, the default is /notraceback. For a debug configuration in the visual development environment, the default is /traceback.

If traceback is not specified, the displayed call stack hexadecimal addresses (program counter trace) displayed when a severe error occurs do not list the source file name, routine name, and line number. However, advanced users can locate the cause of the error using a .MAP file (linker option /map) and the hexadecimal addresses of the stack displayed when a severe error occurs (see Using Traceback Information).

In the visual development environment, specify Generate Traceback Information in the Run-Time Compiler Option Category.

The /traceback option functions independently of the /debug option.

If you request traceback, you should also disable incremental linking. For a Debug configuration in the visual development environment for a new project, specifying Traceback turns off incremental linking. When using the command line, specifying /traceback sets /link /incremental:no. You can disable incremental linking either in the Link tab in the Project Settings dialog box or specify DF /link /incremental:no on the command line.

If you omit /traceback (or /Zt), /notraceback is used.

For information about locating run-time errors with traceback information, see Using Traceback Information.

For request traceback information at any time by calling the TRACEBACKQQ routine, see Obtaining Traceback Information with TRACEBACKQQ.

To disable the stack traceback report for severe errors, set the FOR_DISABLE_STACK_TRACE environment variable (see Using Traceback Information).


/[no]transform_loops

Syntax:

/transform_loops or /notransform_loops

The /transform_loops (or /optimize:5) option activates a group of loop transformation optimizations that apply to array references within loops. These optimizations can improve the performance of the memory system and usually apply to multiple nested loops. The loops chosen for loop transformation optimizations are always counted loops (which include DO or IF loops), but not uncounted DO WHILE loops).

In the visual development environment, specify the Apply Loop Transformation Optimizations in the Optimizations Compiler Option Category.

Conditions that typically prevent the loop transformation optimizations from occurring include subprogram references that are not inlined (such as an external function call), complicated exit conditions, and uncounted loops.

The types of optimizations associated with /transform_loops include the following:

  • Loop blocking
  • Loop distribution
  • Loop fusion
  • Loop interchange
  • Loop scalar replacement
  • Outer loop unrolling

The loop transformation optimizations are a subset of optimizations activated by /optimize:5. On ia32 systems, instead of specifying /transform_loops, you can specify /optimize:5. On ia64 systems, instead of specifying both /pipeline and /transform_loops, you can specify /optimize:5.

On ia64 systems, to specify loop transformation optimizations without software pipelining, do one of the following:

  • Specify /optimize:5 with /nopipeline.
  • Specify /transform_loops with /optimize:4, /optimize:3, or /optimize:2. This optimization is not performed at optimization levels below /optimize:2.

To determine whether using /transform_loops benefits your particular program, you should time program execution for the same program (or subprogram) compiled with and without loop transformation optimizations (such as with /transform_loops and /notransform_loops).

For more information, see Loop Transformations.


/tune

Syntax:

/tune:keyword

The /tune option specifies the type of processor-specific machine-code instruction tuning for implementations of the processor architecture in use.

Tuning for a specific implementation can improve run-time performance; it is also possible that code tuned for a specific processor may run slower on another processor. Regardless of the /tune:keyword option you use, the generated code runs correctly on all implementations of the processor architecture.

If you omit /tune:keyword, /tune:generic is used. In the visual development environment, specify the Optimize For in the Optimizations Compiler Option Category.

For ia32 (32-bit Intel and AMD) systems, the /tune keywords are:

  • /tune:generic

    Generates and schedules code (sometimes called blended code) that will execute well for all ia32 systems. This provides generally efficient code for those applications where all ia32 processor generations are likely to be used. This is the default.

  • /tune:host

    Generates and schedules code optimized for the processor type in use on the processor system being used for compilation.

  • /tune:pn1

    Generates and schedules code optimized for the Pentium (586) processor systems. The pn1 keyword replaces the p5 keyword (specifying /tune:pn1 and /tune:p5 are equivalent).

  • /tune:pn2

    Generates and schedules code optimized for Pentium Pro, Pentium II, and AMD K6 processor systems. The pn2 keyword replaces the p6 keyword (specifying /tune:pn2 and /tune:p6 are equivalent).

  • /tune:k6

    Generates and schedules code optimized for AMD K6, Pentium Pro, and Pentium II processor systems (/tune:pn2 and /tune:k6 are the same).

  • /tune:pn3

    Generates and schedules code optimized for Pentium III, AMD K6_2, and AMD K6_III processor systems. The pn3 keyword replaces the p6p keyword (specifying /tune:pn3 and /tune:p6p are equivalent).

  • /tune:k6_2

    Generates and schedules code optimized for AMD K6_2 and AMD K6_III processor systems.

  • /tune:k7

    Generates and schedules code optimized for AMD Athlon processor systems.

  • /tune:pn4

    Generates and schedules code optimized for Pentium IV processor systems.

Specifying /fast sets /tune:host.

For ia64 (64-bit) systems, specify either /tune:generic or /tune:host (this option is not yet fully implemented for ia64 systems).

The architecture selected by /architecture (code generation option) is the basis for the architecture used by the /tune keyword. For example, you cannot specify a /tune keyword for an architecture older than the one selected by /architecture.

For more information about this option, see Requesting Optimized Code for a Specific Processor Generation.

For information about timing program execution, see Analyze Program Performance.

To control the processor-specific type of machine-code instructions being generated, see the /architecture:keyword option.


/undefine

Syntax:

/undefine:symbol

The /undefine option removes any initial definition of symbol for the FPP preprocessor.


/unroll

Syntax:

/unroll:count

For higher optimization levels, the /unroll option allows you to specify how many times loops are unrolled. If the /unroll option is not specified, the optimizer will choose an unroll amount that minimizes the overhead of prefetching while also limiting code size expansion.

In the visual development environment, specify the Loop Unroll Count in the Optimizations Compiler Option Category.

If the /optimize:3, /optimize:4 (or equivalent), or /optimize:5 options are specified, loop unrolling occurs. The count should be an integer in the range 0 to 16. A count value of 0 is used to indicate that the compiler should determine how many times a loop is unrolled (default).

The compiler attempts to unroll certain innermost loops, minimizing the number of branches and grouping more instructions together to allow efficient overlapped instruction execution (instruction pipelining). The best candidates for loop unrolling are innermost loops with limited control flow.

On ia32 systems, specifying a higher value may improve run-time performance of certain applications. For more information, see Loop Unrolling.

You can specify the number of times a specific loop is unrolled by using the cDEC$ UNROLL Directive to Control Loop Unrolling.


/[no]vms

Syntax:

/vms or /novms

The /vms option causes the run-time system to provide functions like Compaq Fortran 77 for OpenVMS VAXTM Systems (previously called VAX FORTRANTM).

In the visual development environment, specify Enable VMS Compatibility in the Compatibility Compiler Option Category. The /vms option:

  • In the absence of other options, sets the following command-line defaults: /check:format, /check:output_conversion, /static, /norecursive, and /names:lowercase.
  • When /ccdefault:default is also specified, /vms changes the default carriage control to FORTRAN if the file is formatted and the unit is connected to a terminal.
  • Allows use of the DELETE statement for relative files. When a record in a relative file is deleted, the first byte of that record is set to a known character (currently '@'). Attempts to read that record later result in ATTACCNON errors. The rest of the record (the whole record when /vms is not set) is set to nulls for unformatted files and spaces for formatted files.
  • When an ENDFILE is performed on a sequential unit, an actual 1-byte record containing a Ctrl+D (04 hex) is written to the file. When you omit /vms, an internal ENDFILE flag is set and the file is truncated. The /vms option does not affect ENDFILE on relative files; the file is truncated.
  • Changes certain OPEN statement BLANK keyword defaults. Changes the default interpretation from BLANK='NULL' to BLANK='ZERO' for an implicit open or internal file OPEN. For an explicit OPEN, the default is always BLANK='NULL'.
  • Changes certain OPEN statement effects. If the CARRIAGECONTROL is defaulted, the file is formatted, and the unit is connected to a terminal, then the carriage control defaults to FORTRAN. Otherwise, it defaults to LIST. The /vms option affects the record length for relative organization files. The buffer size is increased by 1 to accommodate the deleted record character.
  • LIST and /NOLIST are recognized at the end of the file specification to the INCLUDE statement at compile time. If you specified /vms and if the file specification does not include the directory path, the current working directory is used as the default directory path. If you omitted /vms, the directory path is where the file that contains the INCLUDE statement resides.
  • Changes internal file writes using list-directed I/O. A list-directed write to an internal file results in removal of the first character from the first element; the field length is decremented accordingly.
  • The run-time direct access READ routine checks the first byte of the retrieved record. If this byte is '@' or NULL ('\0'), then ATTACCNON is returned. The run-time sequential access READ routine checks to see if the record it just read is 1 byte long and contains a Ctrl+D (04 hex) or a Ctrl+Z (1A hex). If this is true, it returns EOF.

The default is /novms.


/[no]warn

Syntax:

/warn[:keyword...]), /nowarn, /4Yd, /4Nd, /4Ys, /W0, /W1, or /WX

The /warn option instructs the compiler to generate diagnostic messages for defined classes of additional checking that can be performed at compile-time. It also can change the severity level of issued compilation messages.

In the visual development environment, specify the Warning Level (/warn:nogeneral, default, or /warn:error) in the General or the Compiler Diagnostic Compiler Option Category. Specify individual Warning Options in the Compiler Diagnostic Compiler Option Category. The /warn options and their visual development environment names are:

/warn:noalignments (Data Alignment) | /warn:argument_checking (Argument Mismatch)
/warn:declarations or /4Yd (Undeclared Variables) | /warn:errors or /WX (Warning Level: Errors)
/warn:nofileopt (Inform when Compiling Files Separately) | /warn:nogeneral (Warning Level: Ignore)
/warn:ignore_loc (Inform When Removing %LOC from an Argument) | /warn:stderror or /4Ys (Treat Fortran Standard Warnings as Errors)
/warn:truncated_source (Truncated Source) | /warn:nouncalled (Uncalled Routines)
/warn:nouninitialized (Uninitialized Variables) | /warn:unused (Unused Variables)
/warn:nousage (Usage) | /warn:all or /warn
/warn:none, /nowarn, or /W0

If you omit /warn, the defaults are:

  • For the DF command: /warn:(alignments,noargument_checking,nodeclarations,noerrors,fileopts, general,noignore_loc,nostderrors,notruncated_source,uncalled,uninitialized,nounused,usage)
  • In the visual development environment for a debug configuration, the default of noargument_checking changes to argument_checking.
  • In the visual development environment for a release configuration, the default of fileopts changes to nofileopts.
  • For the FL32 command: /warn:(alignments,argument_checking,nodeclarations,noerrors,nofileopts, general,noignore_loc,nostderrors,notruncated_source,uncalled,uninitialized,nounused,usage)

The /warn keywords are:

  • /warn:noalignments

    Suppresses warning messages for data that is not naturally aligned. The default is /warn:alignments.

  • /warn:argument_checking

    Enables warnings about argument mismatches between callers and callees, when compiled together. The default is /warn:noargument_checking, except in the visual development environment for a debug configuration, where the default is /warn:argument_checking.

  • /warn:declarations or /4Yd

    Issues an error message for any undeclared symbols. This option makes the default type of a variable undefined (IMPLICIT NONE) rather than using the default Fortran rules. The default is /warn:nodeclarations or /4Nd.

  • /warn:errors or /WX

    Changes the severity of all warning diagnostics into error diagnostics. The default is /warn:noerrors. Specifying /warn:errors (or /WX) sets /warn:stderrors.

  • /warn:nofileopt

    Suppresses the display of an informational-level diagnostic message when compiling multiple files separately, which can prevent interprocedure optimizations. The default is /warn:fileopt (displays the message: Some interprocedural optimizations may be disabled when compiling in this mode), except in the visual development environment for a release configuration, where the default is /warn:nofileopt.

  • /warn:nogeneral

    Suppresses all informational-level and warning-level diagnostic messages from the compiler. The default is /warn:general or /W1.

  • /warn:ignore_loc

    Requests that the compiler issues warnings when %LOC is stripped from an argument. The default is /warn:noignore_loc (does not issue a warning for this condition).

  • /warn:stderrors or /4Ys

    Requests Fortran 90 standards checking (see /stand) with error-level compilation messages instead of warning-level messages. Specifying /warn:stderrors sets /stand:f90 and is equivalent to /4Ys.

    Specifying /warn:stderrors with /stand:f95 requests error-level messages for extensions to the proposed Fortran 95 standard.

    Specifying /warn:errors sets /warn:stderrors. The default is /warn:nostderrrors.

  • /warn:truncated_source

    Requests that the compiler issue a warning diagnostic message when it reads a source line with a statement field that exceeds the maximum column width in fixed-format source files. The maximum column width for fixed-format files is column 72 or 132, depending whether the /extend_source option was specified.
    This option has no effect on truncation; lines that exceed the maximum column width are always truncated. This option does not apply to free-format source files. The default is /warn:notruncated_source.

  • /warn:nouncalled

    Suppresses the compiler warning diagnostic message when a statement function is never called. The default is /warn:uncalled.

  • /warn:nouninitialized

    Suppresses warning messages for a variable that is used before a value was assigned to it. The default is /warn:uninitialized.

  • /warn:unused

    Requests warning messages for a variable that is declared but never used. The default is /warn:nounused.

  • /warn:nousage

    Suppresses warning messages about questionable programming practices and the use of intrinsic functions that use a two-digit year (year 2000). The questionable programming practices, although allowed, often are the result of programming errors. For example, /warn:usage detects a continued character or Hollerith literal whose first part ends before the statement field ends and appears to end with trailing spaces. The default is /warn:usage. The /pad_source option can prevent warning messages from /warn:usage.

  • /warn:all or /warn

    Requests all possible warning messages, but does not set /warn:errors or /warn:stderrors. To enable all the additional checking to be performed and force the severity of the diagnostics to be severe enough to not generate an object file, specify /warn:(all,errors) or /warn:(all,stderrors).

  • /warn:none, /nowarn, or /W0

    Suppresses all warning messages.

For example, the following command requests the argument_checking and declarations keywords and accepts the defaults for the other /warn keywords:

 df /warn:(argument_checking,declarations) testfile.f90


/[no]watch

Syntax:

/watch[:keyword] or /nowatch

The /watch option requests the display of processing information to the console output window. The default is /watch:source. You can request the display of the passes (compiler, linker) with their respective command arguments and/or the input and output files by specifying any of the following /watch keywords:

/watch:cmd | /watch:source
/watch:all or /watch | /nowatch or /watch:none

The /watch options:

  • /watch:cmd
    Displays the passes (compiler, linker) with the respective command arguments.

  • /watch:source
    Displays the names of sources file(s) being processed. Source file names are listed one per line. This is the default.

  • /watch:all or /watch
    Requests /watch:(cmd, source). This displays both pass information and source file names (verbose output).

  • /nowatch or /watch:none
    Requests /watch:(nocmd, nosource).


/what

Syntax:

/what

The /what option displays Visual Fortran version number information.


/winapp

Syntax:

/winapp or /MG

The /winapp or /MG option requests the creation of a graphics or Fortran Windows application and links against the most commonly used libraries. In the visual development environment, specify the Use Common Windows Libraries in the Libraries Compiler Option Category.

The following related options request libraries:

  • /libs
  • /[no]threads
  • /[no]dbglibs
  • /fpscomp:libs

For information on Fortran Windows Applications, including requesting additional link libraries with the FULLAPI.F90 file, see Creating Windows Applications.


Linker Options and Related Information

You can set Linker options from:

  • The DF command line.

    When using the DF command line, specify linker options after the /LINK option. For example:

      DF file.f90 file.lib /LINK /NODEFAULTLIB
  • The LINK command line.

    You can specify linker options and libraries with the LINK command. For example:

      LINK file.obj file.lib /NODEFAULTLIB
  • Within the Microsoft visual development environment, in the Project menu, Settings dialog box.

    You can specify linker options and libraries by using the Linker tab in the Project menu, Settings dialog box.

The following table describes the Linker options.

Linker Option | Function
/ALIGN | Specifies the alignment of each section within the linear address space of the program.
/BASE | Sets a base address for the program, overriding the default location.
/COMMENT | Inserts a comment string into the header of an executable file or DLL, after the array of section headers.
/DEBUG | Creates debugging information for the executable file or DLL.
/DEBUGTYPE | Generates debugging information in one of three ways: Microsoft format (CV), COFF format, or both.
/DEF | Passes a module-definition (.DEF) file to the linker.
/DEFAULTLIB | Adds one or more libraries to the list of libraries that LINK searches when resolving references.
/DELAY | Controls the delayed loading of DDLs.
/DELAYLOAD | Causes delayed loading of DLLs.
/DLL | Builds a DLL as the main output file when using the command line.
/DRIVER | Used to build a Windows NT 4 or Windows 2000 kernel mode driver.
/ENTRY | Sets the starting address for an executable file or DLL.
/EXETYPE | Used when building a virtual device driver (requested by using the /VXD option).
/EXPORT | Exports a function from your program.
/FIXED | Tells the operating system to load the program only at its preferred base address.
/FORCE | Informs the linker to create a valid executable file or DLL even if a symbol is referenced but not defined or is multiply defined.
/HEAP | Sets the size of the heap in bytes.
/IMPLIB | Sets the name for the import library that LINK creates when it builds a program that contains exports.
/IMPORT | Does not apply to Visual Fortran.
/INCLUDE | Informs the linker to add a specified symbol to the symbol table.
/INCREMENTAL | Controls how the linker handles incremental linking.
/LARGEADDRESSAWARE | Informs the linker that the application can handle addresses larger than 2 gigabytes.
/LIBPATH | Overrides the environment library path.
/LINK50COMPAT | Generates import libraries in the old (Visual C++ version 5.0) format for backward compatibility.
/MACHINE | Specifies the target platform for the program.
/MAP | Informs the linker to generate a mapfile. You can also specify the file name.
/MAPINFO | Informs the linker to include the specified information in a map file (requested by /MAP).
/MERGE | Combines the first section with the second section and names the resulting section.
/NODEFAULTLIB | Informs the linker to remove all default libraries from the list of libraries it searches when resolving external references. If you specify one or more libraries, the linker only ignores the libraries you have named.
/NOENTRY | Prevents LINK from linking a reference to _main into the DLL.
/NOLOGO | Prevents the display of the copyright message and version number. It also suppresses echoing of command files.
/OPT | Controls the optimizations LINK performs during a build.
/ORDER | Lets you perform optimization by telling LINK to place certain packaged functions into the image in a predetermined order.
/OUT | Overrides the default name and location of the image file that LINK creates.
/PDB | Controls how the linker produces debugging information.
/PDBTYPE | Controls which Program Database (PDB) is used to store the debug type information.
/PROFILE | Creates an output file that can be used with the profiler.
/RELEASE | Sets the checksum in the header of an executable file.
/SECTION | Changes the attributes of a section, overriding the attributes set when the .OBJ file for the section was compiled.
/STACK | Sets the size of the stack in bytes.
/STUB | Attaches an MS-DOS stub program to a Win32 program.
/SUBSYSTEM | Tells the operating system how to run the executable file.
/SWAPRUN | Informs the operating system to first copy the linker output to a swap file, and then run the image from there (Windows NT 4 or Windows 2000).
/VERBOSE | Sends information about the progress of the linking session to the Output window.
/VERSION | Informs the linker to put a version number in the header of the executable file or DLL.
/VXD | Creates a virtual device driver (VxD).
/WARN | Determines the output of LINK warnings.
/WS | Adds the WS_AGGRESSIVE attribute to your application's image.

This table lists the Linker options with the equivalent Microsoft visual development environment category if one is available. Options not listed are usually command-line only and can be entered in the "Common Options" text box of the Project ... Settings dialog box. For instructions on how to work with the Microsoft visual development environment, see Building Programs and Libraries.

Linker Option | Visual Development Environment Category
/ALIGN | Command-line only
/BASE | Output Category
/DEBUG | Debug Category
/DEBUGTYPE | Debug Category
/DEF | Command-line only
/DEFAULTLIB | Command-line only
/ENTRY | Output Category
/FORCE | Customize Category
/INCLUDE | Input Category
/INCREMENTAL | Customize Category
/LIBPATH | Input Category
/MAP | Debug Category
/NODEFAULTLIB | Input Category
/NOLOGO | Customize Category
/OUT | Customize Category
/PDB | Customize Category
/PDBTYPE | Debug Category
/PROFILE | General Category
/STACK | Output Category
/VERBOSE | Customize Category
/VERSION | Output Category

Besides discussing linker options individually, this section also discusses Module-Definition Files and Linker Reserved Words.


Setting LINK Options in the Visual Development Environment

You can set linker options in the Microsoft visual development environment by using the Link tab in the Build Settings dialog box. The following tables list the linker options by category in the visual development environment, along with the equivalent command-line options:

General Category | Command-Line Equivalent
Output File Name | /OUT:filename
Object/Library Modules | filename on command line
Generate Debug Info | /DEBUG
Ignore All Default Libraries | /NODEFAULTLIB
Link Incrementally | /INCREMENTAL:{YES|NO}
Generate Mapfile | /MAP
Enable Profiling | /PROFILE

Output Category | Command-Line Equivalent
Base Address | /BASE:address
Entry-Point Symbol | /ENTRY:function
Stack Allocations | /STACK:reserve,commit
Version Information | /VERSION:major.minor

Input Category | Command-Line Equivalent
Object/Library Modules | filename on command line
Ignore Libraries | /NODEFAULTLIB:library
Ignore All Default Libraries | /NODEFAULTLIB
Force Symbol References | /INCLUDE:symbol
MS-DOS Stub File Name | /STUB:filename

Customize Category | Command-Line Equivalent
Use Program Database | /PDB:filename
Link Incrementally | /INCREMENTAL:{YES|NO}
Program Database Name | /PDB:filename
Output File Name | /OUT:filename
Force File Output | /FORCE
Print Progress Messages | /VERBOSE
Suppress Startup Banner | /NOLOGO

Debug Category | Command-Line Equivalent
Mapfile Name | /MAP:filename
Generate Mapfile | /MAP
Generate Debug Info | /DEBUG
Microsoft Format | /DEBUGTYPE:CV
COFF Format | /DEBUGTYPE:COFF
Both Formats | /DEBUGTYPE:BOTH


Rules for LINK Options

An option consists of an option specifier, either a dash ( - ) or a forward slash ( / ), followed by the name of the option. Option names cannot be abbreviated. Some options take an argument, specified after a colon ( : ). No spaces or tabs are allowed within an option specification, except within a quoted string in the /COMMENT option.

Specify numeric arguments in decimal or C-language notation. (The digits 1-9 specify decimal values, an integer constant preceded by a zero (0) specifies an octal value, and an integer constant preceded by zero and x (0x or 0X) specifies a hexadecimal value.) Option names and their keyword or filename arguments are not case sensitive, but identifiers as arguments are case sensitive.

LINK first processes options specified in the LINK environment variable. Next, LINK processes options in the order specified on the command line and in command files. If an option is repeated with different arguments, the last one processed takes precedence.

Options apply to the entire build. No options can be applied to specific input files.


/ALIGN

Syntax:

/ALIGN:number

Specifies the alignment of each section within the linear address space of the program. The number argument is in bytes and must be a power of 2. The default is 4K. The linker generates a warning if the alignment produces an invalid image.


/BASE

Syntax:

/BASE:{address | @filename,key}

This option sets a base address for the program, overriding the default location for an executable file (at 0x400000) or a DLL (at 0x10000000). The operating system first attempts to load a program at its specified or default base address. If sufficient space is not available there, the system relocates the program. To prevent relocation, use the /FIXED option.

Specify the preferred base address in the text box (or in the address argument on the command line). The linker rounds the specified number up to the nearest multiple of 64K.

Another way to specify the base address is by using a filename, preceded by an at sign (@), and a key into the file. The filename is a text file that contains the locations and sizes of all DLLs your program uses. The linker looks for filename in either the specified path or, if no path is specified, in directories named in the LIB environment variable. Each line in filename represents one DLL and has the following syntax:

key address size ;comment

The key is a string of alphanumeric characters and is not case sensitive. It is usually the name of a DLL but it need not be. The key is followed by a base address in C-notation hexadecimal or decimal and a maximum size. All three arguments are separated by spaces or tabs. The linker issues a warning if the specified size is less than the virtual address space required by the program. Indicate a comment by a semicolon (;). Comments can be on the same or a separate line. The linker ignores all text from the semicolon to the end of the line. The following example shows part of such a file:

  main   0x00010000   0x08000000   ; for PROJECT.EXE
  one    0x28000000   0x00100000   ; for DLLONE.DLL
  two    0x28100000   0x00300000   ; for DLLTWO.DLL

If the file that contains these lines is called DLLS.TXT, the following example command applies this information.

  link dlltwo.obj  /dll  /base:dlls.txt,two

You can reduce paging and improve performance of your program by assigning base addresses so that DLLs do not overlap in the address space.

An alternate way to set the base address is with the BASE argument in a NAME or LIBRARY module-definition statement. The /BASE and /DLL options together are equivalent to the LIBRARY statement. For information on module-definition statements, see Module-Definition Files.


/COMMENT

Syntax:

/COMMENT:["] comment ["]

Inserts a comment string into the header of an executable file or DLL, after the array of section headers. The type of operating system determines whether the string is loaded into memory. This comment string, unlike the comment specified with DESCRIPTION in a .DEF file, is not inserted into the data section. Comments are useful for embedding copyright and version information.

To specify a comment that contains spaces or tabs, enclose it in double quotation marks ("). LINK removes the quotation marks before inserting the string. If more than one /COMMENT option is specified, LINK concatenates the strings and places a null byte at the end of each string.


/DEBUG

Syntax:

/DEBUG

Creates debugging information for the executable file or DLL.

The linker puts the debugging information into a program database (PDB). It updates the program database during subsequent builds of the program. For details about PDBs, see /PDB.

An executable file or DLL created for debugging contains the name and path of the corresponding PDB. Visual Fortran reads the embedded name and uses the PDB when you debug the program. The linker uses the base name of the program and the extension .PDB to name the PDB, and embeds the path where it was created. To override this default, use /PDB:filename.

The object files must contain debugging information. Use the compiler's /Zi (Program Database), /Zd (Line Numbers Only), or /Z7 (C7 Compatible) option. If an object (whether specified explicitly or supplied from a library) was compiled with Program Database, its debugging information is stored in a PDB for the object file, and the name and location of the .PDB file is embedded in the object. The linker looks for the object's PDB first in the absolute path written in the object file and then in the directory that contains the object file. You cannot specify a PDB's filename or location to the linker.

If you have turned off Use Program Database (or specified /PDB:NONE on the command line), or if you have chosen either /DEBUGTYPE:COFF or /DEBUGTYPE:BOTH, the linker does not create a PDB but instead puts the debugging information into the executable file or DLL.

The /DEBUG option changes the default for the /OPT option from REF to NOREF.


/DEBUGTYPE

Syntax:

/DEBUGTYPE:{CV|COFF|BOTH}

This option generates debugging information in one of three ways, Microsoft format (CV), COFF format, or both:

  • /DEBUGTYPE:CV

    Visual Fortran requires new-style Microsoft Symbolic Debugging Information in order to read a program for debugging. To select this option in the Microsoft visual development environment, choose the Link tab of the Project Settings dialog box. In the Debug category, select the Microsoft Format button, which is only available if you have checked the Generate Debug Info box.

  • /DEBUGTYPE:COFF

    This option generates COFF-style debugging information. Some debuggers require Common Object File Format (COFF) debugging information.

    When you set this option, the linker does not create a PDB; in addition, incremental linking is disabled.

    To select this option in the visual development environment, choose the Link tab of the Project Settings dialog box. In the Debug category, select the COFF Format button, which is only available if you have checked the Generate Debug Info box.

  • /DEBUGTYPE:BOTH

    This option generates both COFF debugging information and old-style Microsoft debugging information.

    When you set this option, the linker does not create a PDB; in addition, incremental linking is disabled. The linker must call the CVPACK.EXE tool to process the old-style Microsoft debugging information. CVPACK must be in the same directory as LINK or in a directory in the PATH environment variable.

    In the visual development environment, specify this option with the Both Formats button, which is only available if you have selected Generate Debug Info.

If you do not specify /DEBUG, /DEBUGTYPE is ignored. If you specify /DEBUG but not /DEBUGTYPE, the default type is /DEBUGTYPE:CV.


/DEF

Syntax:

/DEF:filename

Passes a module-definition (.DEF) file to the linker. Only one .DEF file can be specified to LINK. For details about .DEF files, see Module-Definition Files.

When a .DEF file is used in a build, whether the main output file is an executable file or a DLL, LINK creates an import library (.LIB) and an exports file (.EXP). These files are created regardless of whether the main output file contains exports.

Do not specify this option in the visual development environment; this option is for use only on the command line. To specify a .DEF file, add it to the project along with other files.


/DEFAULTLIB

Syntax:

/DEFAULTLIB:libraries...

Adds one or more libraries to the list of libraries that LINK searches when resolving references. A library specified with /DEFAULTLIB is searched after libraries specified on the command line and before default libraries named in object files. To specify multiple libraries, type a comma (,) between library names.

Ignore All Default Libraries (/NODEFAULTLIB) overrides /DEFAULTLIB:library. Ignore Libraries (/NODEFAULTLIB:library) overrides /DEFAULTLIB:library when the same library name is specified in both.


/DELAY

Syntax:

/DELAY:{unload|nobind}

Controls delayed loading of DDLs:

  • /DELAY:unload tells the delay-load helper function to support explicit unloading of the DLL by resetting the IAT to its original form, invalidating IAT pointers and causing them to be overwritten.

  • /DELAY:nobind tells the linker not to include a bindable IAT in the final image. The resulting image cannot be statically bound. (Images with bindable IATs may be statically bound prior to execution.)

To specify DLLs to delay load, use the /DELAYLOAD option.


/DELAYLOAD

Syntax:

/DELAYLOAD:dllname

Causes delayed loading of DLLs. The dllname specifies a DLL to delay load. You can use this option as many times as necessary to specify as many DLLs as you choose. You must link your program with Delayimp.lib or implement your own delay-load helper function.


/DLL

Syntax:

/DLL

Builds a DLL as the main output file. A DLL usually contains exports that can be used by another program. There are three methods for specifying exports, listed in recommended order of use:

  • cDEC$ ATTRIBUTES DLLEXPORT in the source code
  • An /EXPORT specification in a LINK command
  • An EXPORTS statement in a module definition (.DEF) file

A program can use more than one method.

An alternate way to build a DLL is with the LIBRARY module-definition statement. The /BASE and /DLL options together are equivalent to the LIBRARY statement.

In the visual development environment, you can set this option by choosing Dynamic-Link Library under Project Type in the New Project dialog box.


/DRIVER

Syntax:

/DRIVER[:UPONLY]

Use this option to build a Windows NT 4 or Windows 2000 kernel mode driver. The linker will perform some special optimizations if this option is selected. The UPONLY keyword causes the linker to add the IMAGE_FILE_UP_SYSTEM_ONLY bit to the characteristics in the output header to specify that it is a uniprocessor (UP) driver. The operating system will refuse to load a UP driver on a multiprocessor (MP) system.


/ENTRY

Syntax:

/ENTRY:function

This option sets the starting address for an executable file or DLL. Specify a function name that is defined with cDEC$ ATTRIBUTES STDCALL. The parameters and return value must be defined as documented in the Win32 API for WinMain (for an .EXE) or DllEntryPoint (for a DLL). It is recommended that you let the linker set the entry point.

By default, the starting address is a function name from the run-time library. The linker selects it according to the attributes of the program, as shown in the following table.

Function Name | Default for
mainCRTStartup | An application using /SUBSYSTEM:CONSOLE; calls main
WinMainCRTStartup | An application using /SUBSYSTEM:WINDOWS; calls WinMain, which must be defined with the cDEC$ ATTRIBUTES STDCALL attribute
_DllMainCRTStartup | A DLL; calls DllMain (which must be defined with the STDCALL attribute) if it exists

If the /DLL or /SUBSYSTEM option is not specified, the linker selects a subsystem and entry point depending on whether main or WinMain is defined.

The functions main, WinMain, and DllMain are the three forms of the user-defined entry point.


/EXETYPE

Syntax:

/EXETYPE:DYNAMIC

Used when building a virtual device driver (VxD). A VxD is linked using the /VXD option.

Specify DYNAMIC to create a dynamically-loaded VxD.


/EXPORT

Syntax:

/EXPORT:entryname[=internalname][, @ordinal [, NONAME]] [, DATA]

Lets you export a function from your program to allow other programs to call the function. You can also export data. Exports are usually defined in a DLL.

The entryname is the name of the function or data item as it is to be used by the calling program. You can optionally specify the internalname as the function known in the defining program; by default, internalname is the same as entryname. The ordinal specifies an index into the exports table in the range 1 - 65535; if you do not specify ordinal, LINK assigns one. The NONAME keyword exports the function only as an ordinal, without an entryname.

The DATA keyword specifies that the exported item is a data item. The data item in the client program must be declared using DLLIMPORT. (The CONSTANT keyword is supported for compatibility but is not recommended.)

There are three methods for exporting a definition, listed in recommended order of use:

  • cDEC$ ATTRIBUTES DLLEXPORT in the source code
  • An /EXPORT specification in a LINK command
  • An EXPORTS statement in a module definition (.DEF) file

All three methods can be used in the same program. When LINK builds a program that contains exports, it also creates an import library, unless an .EXP file is used in the build.

LINK uses decorated forms of identifiers. A "decorated name" is an internal representation of a procedure name or variable name that contains information about where it is declared; for procedures, the information includes how it is called. Decorated names are mainly of interest in mixed-language programming, when calling Fortran routines from other languages.

The compiler decorates an identifier when it creates the object file. If entryname or internalname is specified to the linker in its undecorated form as it appears in the source code, LINK attempts to match the name. If it cannot find a unique match, LINK issues an error.

Use the DUMPBIN tool described in Examining Files with DUMPBIN to get the decorated form of an identifier when you need to specify it to the linker. Do not specify the decorated form of identifiers declared with the C or STDCALL attributes. For more information on when and how to use decorated names, see Adjusting Naming Conventions in Mixed-Language Programming.


/FIXED

Syntax:

/FIXED

This option tells the operating system to load the program only at its preferred base address. If the preferred base address is unavailable, the operating system does not load the file. For more information on base address, see /BASE.

When you specify /FIXED, LINK does not generate a relocation section in the program. At run-time, if the operating system cannot load the program at that address, it issues an error and does not load the program.

Some Win32 operating systems, especially those that coexist with MS-DOS, frequently must relocate a program. A program created with /FIXED will not run on Win32s® operating systems.

Note: Do not use /FIXED when building device drivers.


/FORCE

Syntax:

/FORCE:[ {MULTIPLE|UNRESOLVED} ]

Tells the linker to create a valid executable file or DLL even if a symbol is referenced but not defined or is multiply defined.

The /FORCE option can take an optional argument:

  • Use /FORCE:MULTIPLE to create an output file whether or not LINK finds more than one definition for a symbol.
  • Use /FORCE:UNRESOLVED to create an output file whether or not LINK finds an undefined symbol.

A file created with this option may not run as expected. The linker will not link incrementally with the /FORCE option.

You can select this option in the visual development environment by checking the Force File Output box in the Customize category of the Link tab in the Project Settings dialog box.


/HEAP

Syntax:

/HEAP:reserve[,commit]

Sets the size of the heap in bytes.

The reserve argument specifies the total heap allocation in virtual memory. The default heap size is 1MB. The linker rounds up the specified value to the nearest 4 bytes.

The optional commit argument is subject to interpretation by the operating system. In Windows NT 4 and Windows 2000, it specifies the amount of physical memory to allocate at a time. Committed virtual memory causes space to be reserved in the paging file. A higher commit value saves time when the application needs more heap space but increases the memory requirements and possibly startup time.

Specify the reserve and commit values in decimal or C-language notation. (Use the digits 1 - 9 for decimal values, precede octal values with zero (0), and precede hexadecimal values with zero and x (0x or 0X).


/IMPLIB

Syntax:

/IMPLIB:filename

Overrides the default name for the import library that LINK creates when it builds a program that contains exports. The default name is formed from the base name of the main output file and the extension .LIB. A program contains exports if one or more of the following is true:

  • cDEC$ ATTRIBUTES DLLEXPORT in the source code
  • An /EXPORT specification in a LINK command
  • An EXPORTS statement in a module definition (.DEF) file

LINK ignores the /IMPLIB option when an import library is not being created. If no exports are specified, LINK does not create an import library. If an export (.EXP) file is used in the build, LINK assumes an import library already exists and does not create one. For information on import libraries and export files, see Import Libraries and Export Files in Using Visual Fortran Tools.


/IMPORT

Syntax:

/IMPORT

This option is specific to MACOS and does not apply to Visual Fortran.


/INCLUDE

Syntax:

/INCLUDE:symbol

Tells the linker to add a specified symbol to the symbol table.

Specify a symbol name in the text box. To specify multiple symbols, specify /INCLUDE:symbol once for each symbol.

The linker resolves symbol by adding the object that contains the symbol definition to the program. This is useful for including a library object that otherwise would not be linked to the program.

Specifying a symbol in the /INCLUDE option overrides the removal of that symbol by /OPT:REF.

To select this option in the visual development environment, choose the Force Symbol References text box in the Input category of the Link tab of the Project Settings dialog box.


/INCREMENTAL

Syntax:

/INCREMENTAL:{YES|NO}

Controls how the linker handles incremental linking. By default, the linker runs in incremental mode (for exceptions, see the /[no]traceback compiler option).

To prevent incremental linking, clear the Link Incrementally check box in the Customize category (or specify /INCREMENTAL:NO on the command line).

To link incrementally, set the Link Incrementally check box (or specify /INCREMENTAL:YES on the command line). When you specify this option, the linker issues a warning if it cannot link incrementally and then links the program nonincrementally. Certain options and situations override /INCREMENTAL:YES.

Most programs can be linked incrementally. However, some changes are too great, and some options are incompatible with incremental linking. LINK performs a full link if any of the following options are specified:

  • Link Incrementally is turned off (/INCREMENTAL:NO)
  • COFF Format (/DEBUGTYPE:COFF)
  • Both Formats (/DEBUGTYPE:BOTH)
  • /OPT:REF is selected.
  • /OPT:ICF is selected.
  • /ORDER is selected.
  • Use Program Database is not selected (/PDB:NONE) when Generate Debug Info (/DEBUG) is selected.

Additionally, LINK performs a full link if any of the following occur:

  • The incremental status (.ILK) file is missing. (LINK creates a new .ILK file in preparation for subsequent incremental linking.)
  • There is no write permission for the .ILK file. (LINK ignores the .ILK file and links nonincrementally.)
  • The .EXE or .DLL output file is missing.
  • The timestamp of the .ILK, .EXE, or .DLL is changed.
  • A LINK option is changed. Most LINK options, when changed between builds, cause a full link.
  • An object (.OBJ) file is added or omitted.
  • An object that was compiled with the /Yu /Z7 option is changed.

To select this option in the visual development environment, select the Link Incrementally check box in the Customize category of the Link tab in the Project Settings dialog box.


/LARGEADDRESSAWARE

Syntax:

/LARGEADDRESSAWARE

Informs the linker that the application can handle addresses larger than 2 gigabytes.


/LIBPATH

Syntax:

/LIBPATH:dir

Overrides the environment library path. The linker will first search in the path specified by this option, and then search in the path specified in the LIB environment variable. You can specify only one directory for each /LIBPATH option you enter. If you want to specify more than one directory, you must specify multiple /LIBPATH options. The linker will then search the specified directories in order.


/LINK50COMPAT

Syntax:

/LINK50COMPAT

Generates import libraries in the old (Visual C++ version 5.0) format for backward compatibility.


/MACHINE

Syntax:

/MACHINE:{IX86|IA64}

Specifies the target platform for the program (for Visual Fortran, specify either IX86 or IA64).

Usually, you do not need to specify the /MACHINE option. LINK infers the machine type from the .OBJ files. However, in some circumstances LINK cannot determine the machine type and issues a linker tools error LNK1113. If such an error occurs, specify /MACHINE.


/MAP

Syntax:

/MAP[:filename]

This option tells the linker to generate a mapfile. You can optionally specify a map file name to override the default.

The linker names the mapfile with the base name of the program and the extension .MAP. To override the default name, use the filename argument.

A map file is a text file that contains the following information about the program being linked:

  • The module name, which is the base name of the file
  • The timestamp from the program file header (not from the file system)
  • A list of groups in the program, with each group's start address (as section:offset), length, group name, and class
  • A list of public symbols, with each address (as section:offset), symbol name, flat address, and object file where the symbol is defined
  • The entry point (as section:offset)
  • A list of fixups

To select this in the visual development environment, select the Generate Mapfile check box in the Debug category of the Link tab in the Project Settings dialog box.


/MAPINFO

Syntax:

/MAPINFO:{EXPORTS|FIXUPS|LINES}

Informs the linker to include the specified information in a map file, which is created if you specify the /MAP option:

  • EXPORTS tells the linker to include exported functions.
  • FIXUPS tells the linker to include base-relocation information in the mapfile if relocation information exists in the image. Base relocations will be present in the image if you link with /FIXED:NO.
  • LINES includes line-number information.


/MERGE

Syntax:

/MERGE:from=to

Combines the first section (from) with the second section (to), naming the resulting section to. If the second section does not exist, LINK renames the section from as to.

The /MERGE option is useful for creating virtual device drivers (VxDs) and overriding the compiler-generated section names.


/NODEFAULTLIB

Syntax:

/NODEFAULTLIB[:library]

Tells the linker to remove all default libraries from the list of libraries it searches when resolving external references. If you specify library, the linker only ignores the libraries you have named. To specify multiple libraries, type a comma (,) between the library names.

The linker resolves references to external definitions by searching first in libraries specified on the command line, then in default libraries specified with the /DEFAULTLIB option, then in default libraries named in object files.

Ignore All Default Libraries (/NODEFAULTLIB) overrides /DEFAULTLIB:library. Ignore Libraries (/NODEFAULTLIB:library) overrides /DEFAULTLIB:library when the same library name is specified in both.

To select this in the visual development environment, select the Ignore Libraries or Ignore All Default Libraries check box in the Input category of the Link tab in the Project Settings dialog box.


/NOENTRY

Syntax:

/NOENTRY

This option is required for creating a resource-only DLL.

Use this option to prevent LINK from linking a reference to _main into the DLL.


/NOLOGO

Syntax:

/NOLOGO

The /nologo option prevents display of the copyright message and version number. This option also suppresses echoing of command files.

For the command line and in the visual development environment for a debug configuration, the default is /logo (displays copyright message, version number, and echoing of command files). In the visual development environment for a release configuration, the default is /nologo.

By default, information displayed by /logo is sent by the linker to the Output window. On the command line, it is sent to standard output and can be redirected to a file.

To select this option in the visual development environment, select the Suppress Startup Banner check box in the Customize category of the Link tab in the Project Settings dialog box.


/OPT

Syntax:

/OPT:{REF|NOREF}

Controls the optimizations LINK performs during a build. Optimizations generally decrease the image size and increase the program speed, at a cost of increased link time.

By default, LINK removes unreferenced packaged functions (COMDATs). This optimization is called transitive COMDAT elimination. To override this default and keep unused packaged functions in the program, specify /OPT:NOREF. You can use the /INCLUDE option to override the removal of a specific symbol. It is not possible to create packaged functions with the Visual Fortran compiler. This description is included for mixed-language applications with languages such as Visual C++ that support packaged functions (with the /Gy compiler option).

If you specify the /DEBUG option, the default for /OPT changes from REF to NOREF and all functions are preserved in the image. To override this default and optimize a debugging build, specify /OPT:REF. The /OPT:REF option disables incremental linking.


/ORDER

Syntax:

/ORDER:@filename

Lets you perform optimization by telling LINK to place certain packaged functions into the image in a predetermined order. It is not possible to make packaged functions with the Visual Fortran compiler. This description is included for mixed-language applications with languages such as Visual C++ that support packaged functions (with the /Gy compiler option).

LINK places packaged functions in the specified order within each section in the image.

Specify the order in filename, which is a text file that lists the packaged functions in the order you want to link them. Each line in filename contains the name of one packaged function. Function names are case sensitive. A comment is specified by a semicolon (;) and can be on the same or a separate line. LINK ignores all text from the semicolon to the end of the line.

LINK uses decorated forms of identifiers. A decorated name is an internal representation of a procedure name or variable name that contains information about where it is declared; for procedures, the information includes how it is called. Decorated names are mainly of interest in mixed-language programming, when calling Fortran routines from other languages.

The compiler decorates an identifier when it creates the object file. If the name of the packaged function is specified to the linker in its undecorated form as it appears in the source code, LINK attempts to match the name. If it cannot find a unique match, LINK issues an error.

Use the DUMPBIN tool to get the decorated form of an identifier when you need to specify it to the linker. Do not specify the decorated form of identifiers declared with cDEC$ ATTRIBUTES C or STDCALL. For more information on when and how to use decorated names, see Adjusting Naming Conventions in Mixed-Language Programming.

If more than one /ORDER specification is used, the last one specified takes effect.

Ordering allows you to optimize your program's paging behavior through swap tuning. Group a function with the functions it calls. You can also group frequently called functions together. These techniques increase the probability that a called function is in memory when it is needed and will not have to be paged from disk.

This option disables incremental linking.


/OUT

Syntax:

/OUT:filename

Overrides the default name and location of the image file that LINK creates. By default, LINK forms the filename using the base name of the first file specified and the appropriate extension (.EXE or .DLL).

The /OUT option controls the default base name for a mapfile or import library. For details, see the descriptions of /MAP and /IMPLIB.


/PDB

Syntax:

/PDB[:filename]

Controls how the linker produces debugging information. The optional filenameargument overrides the default filename for the program database. The default filename for the PDB has the base name of the program and the extension .PDB.

By default when you specify /DEBUG, the linker creates a program database (PDB), which holds debugging information. If you have not specified /DEBUG, the linker ignores /PDB.

If you specify /PDB:NONE, the linker does not create a PDB, but instead puts old-style debugging information into the executable file or DLL. The linker then calls the CVPACK.EXE tool, which must be in the same directory as LINK.EXE or in a directory in the PATH environment variable.

Debugging information in a program database must be in Microsoft Format (/DEBUGTYPE:CV). If you choose either COFF Format (/DEBUGTYPE:COFF) or Both Formats (/DEBUGTYPE:BOTH), no PDB is created.

Incremental linking is suppressed if you specify /PDB:NONE.

You can select this option in the visual development environment by selecting the Use Program Database check box in the Customize category of the Link tab in the Project Settings dialog box.


/PDBTYPE

Syntax:

/PDBTYPE:{CON[SOLIDATE]|SEPT[YPES]}

Controls which Program Database (PDB) stores the debug type information.

On the command line, the /PDBTYPE option can take one of the following arguments:

  • Use /PDBTYPE:CON[SOLIDATE] to tell the linker to place the debug type information in a single .PDB file. This option is the default. This option cannot be used if /PDB:NONE is specified.
  • Use /PDBTYPE:SEPT[YPES] to tell the linker to leave the debug type information distributed in the source (compiler) .PDB files. In the Project Settings dialog box, select Separate Types in the Debug category of the Link tab to specify this linker option.

If SEPT[YPES] is specified, linking can be significantly faster. The advantages are:

  • The debugger startup time may be slightly faster.
  • Less hard disk space is needed to store data.

The disadvantage is more files are needed for the debugger to find the debug information when debugging.

Use this option when you plan to debug privately. Do not use this option when the debug build is to be used by multiple users.


/PROFILE

Syntax:

/PROFILE

Creates an output file that can be used with the profiler. This option is found only in the General category on the Link tab.

A profiler-ready program has a map file. If it contains debugging information, the information must be stored in the output file instead of a program database file (.PDB file) and must be in Microsoft old-style format.

In the visual development environment, setting Enable Profiling enables the Generate Mapfile option in the General and Debug categories. If you set the Generate Debug option, be sure to choose Microsoft Format in the Debug category.

On the command line, /PROFILE has the same effect as setting the /MAP option; if the /DEBUG option is specified, then /PROFILE also implies the options /DEBUGTYPE:CV and /PDB:NONE. In either case, /PROFILE implies /INCREMENTAL:NO.

You can select this option in the visual development environment by selecting the Enable Profiling check box in the General category of the Link tab in the Project Settings dialog box.


/RELEASE

Syntax:

/RELEASE

Sets the checksum in the header of an executable file.

The operating system requires the checksum for certain files such as device drivers. To ensure compatibility with future operating systems, set the checksum for release versions of your programs.

This option is set by default when you specify the /SUBSYSTEM:NATIVE option.


/SECTION

Syntax:

/SECTION:name,[E][C][I][R][W][S][D][K][L][P][X]

Changes the properties of a section, overriding the properties set when the .OBJ file for the section was compiled.

A section in a portable executable (PE) file is roughly equivalent to a segment or the resources in an NE file. Sections contain either code or data. Unlike segments, sections are blocks of contiguous memory with no size constraints. Some sections contain code or data that your program declared and uses directly, while other data sections are created for you by the linker and librarian, and contain information vital to the operating system.

Specify a colon (:) and a section name. The name is case sensitive.

Specify one or more properties for the section. The property characters, listed below, are not case sensitive. You must specify all properties that you want the section to have; an omitted property character causes that property bit to be turned off. The meanings of the property characters are shown below.

Character | Property | Meaning
E | Execute | Allows code to be executed
C | Conforming | Marks the section as conforming
I | IOPL | Marks the section as IOPL
R | Read | Allows read operations on data
W | Write | Allows write operations on data
S | Shared | Shares the section among all processes that load the image
D | Discardable | Marks the section as discardable
K | Cacheable | Marks the section as not cacheable
L | Preload | VxD only; marks the section as preload
P | Pageable | Marks the section as not pageable
X | Memory-resident | VxD only; marks the section as memory-resident

A section that does not have E, R, or W set is probably invalid.


/STACK

Syntax:

/STACK:reserve[,commit]

Sets the size of the stack in bytes.

The reserve argument specifies the total stack allocation in virtual memory. The default stack size is 1MB. The linker rounds up the specified value to the nearest 4 bytes.

The optional commit argument is subject to interpretation by the operating system. In Windows NT 4 and Windows 2000, it specifies the amount of physical memory to allocate at a time. Committed virtual memory causes space to be reserved in the paging file. A higher commit value saves time when the application needs more stack space but increases the memory requirements and possibly startup time.

Specify the reserve and commit values in decimal or C-language notation. (Use the digits 1-9 for decimal values, precede octal values with zero (0), and precede hexadecimal values with zero and x (0x or 0X).

An alternate way to set the stack is with the STACKSIZE statement in a .DEF file. STACKSIZE overrides Stack Allocations (/STACK) if you specify both. You can change the stack after the executable file is built by using the EDITBIN.EXE tool. For more information, see Editing Files with EDITBIN.

To set these options in the visual development environment, type values in the Reserve and Commit boxes in the Output category of the Link tab in the Project Settings dialog box.


/STUB

Syntax:

/STUB:filename

Attaches an MS-DOS stub program to a Win32 program.

A stub program is invoked if the file is executed in MS-DOS. Usually, it displays an appropriate message; however, any valid MS-DOS application can be a stub program.

Specify a filename for the stub program after a colon (:). The linker checks filename to be sure that it is a valid MS-DOS executable file and issues an error if the file is not valid. The program must be an .EXE file; a .COM file is invalid for a stub program.

If you do not specify /STUB, the linker attaches a default stub program that generates the following message:

This program cannot be run in MS-DOS mode.

You can select this option in the visual development environment by typing the stub file name in the MS-DOS Stub File Name box in the Input category of the Link tab of the Project Settings dialog box.


/SUBSYSTEM

Syntax:

/SUBSYSTEM:{CONSOLE|WINDOWS|NATIVE|POSIX|WINDOWSCE}[,major [.minor]]

Tells the operating system how to run the executable file. The subsystem is specified as follows:

  • The CONSOLE subsystem is used for Win32 character-mode applications. Console applications are given a console by the operating system. If main or wmain is defined, CONSOLE is the default.
  • The WINDOWS subsystem is appropriate for an application that does not require a console. It creates its own windows for interaction with the user. If WinMain or wWinMain is defined, WINDOWS is the default.
  • The NATIVE subsystem is used for device drivers.
  • The POSIX subsystem creates an application that runs with the POSIX subsystem in Windows NT 4 or Windows 2000.
  • The WINDOWSCE subsystem is not used by Visual Fortran.

The optional major and minor version numbers specify the minimum required version of the subsystem. The arguments are decimal numbers in the range 0 - 65535. The default is version 3.10 for CONSOLE and WINDOWS and 1.0 for NATIVE.

The choice of subsystem affects the default starting address for the program. For more information, see the /ENTRY option.


/SWAPRUN

Syntax:

/SWAPRUN:{NET|CD}

Tells the operating system to first copy the linker output to a swap file, and then run the image from there. This is a Windows NT 4 or Windows 2000 feature.

If NET is specified, the operating system will first copy the binary image from the network to a swap file and load it from there. This option is useful for running applications over the network. When CD is specified, the operating system will copy the image on a removable disk to a page file and then load it.


/VERBOSE

Syntax:

/VERBOSE[:LIB]

The linker sends information about the progress of the linking session to the Output window. If specified on the command line, the information is sent to standard output and can be redirected to a file.

The displayed information includes the library search process and lists each library and object name (with full path), the symbol being resolved from the library, and the list of objects that reference the symbol.

Adding :LIB to the /VERBOSE option restricts progress messages to those indicating the libraries searched.

You can select this option in the Microsoft visual development environment by filling in the Print Progress Messages box in the Customize category of the Link tab of the Project Settings dialog box.


/VERSION

Syntax:

/VERSION:major [.minor ]

Tells the linker to put a version number in the header of the executable file or DLL.

The major and minor arguments are decimal numbers in the range 0 - 65535. The default is version 0.0.

An alternate way to insert a version number is with the VERSION module-definition statement.

You can select this option in the Microsoft visual development environment by typing version information in the Major and Minor boxes in the Output category of the Link tab of the Project Settings dialog box.


/VXD

Syntax:

/VXD

Creates a virtual device driver (VxD). When this option is specified, the default file name extension changes to .VXD. For details on VxDs, see the Microsoft Windows NT Device Driver Kit.

A .VXD file is not in Common Object File Format, and it cannot be used with DUMPBIN or EDITBIN. It does not contain debugging information. However, you can create a map file when you link a .VXD file.

A .VXD file cannot be incrementally linked.

For related information, see /EXETYPE.


/WARN

Syntax:

/WARN[:level]

Allows you to determine the output of LINK warnings. Specify the level as one of the following:

level | Meaning
0 | Suppress all warnings.
1 | Displays most warnings. Overrides a /WARN:level specified earlier on the LINK command line or in the LINK environment variable. Default if /WARN:level is not used.
2 | Displays additional warnings. Default if /WARN is specified without level.


/WS

Syntax:

/WS:AGGRESSIVE

Adds the WS_AGGRESSIVE property to your application's image. The Windows NT 4 or Windows 2000 loader will recognize this property and aggressively trim the working set of the process when it is not active. Using this option is similar to adding the following call throughout your application:

  SetProcessWorkingSetSize(hThisProcess, -1, -1)

/WS:AGGRESSIVE can be used for applications that must have a low impact on the system's memory pool.

If the speed of your application is important, do not use /WS:AGGRESSIVE without testing the resulting performance implications. Ideal candidates are processes that tend to operate in the background, such as services and screen savers.


Module-Definition Files

A module-definition (.DEF) file is a text file that contains statements that define an executable file or DLL. (These should not be confused with module program units, described in Program Units and Procedures.) The following sections describe the statements in a .DEF file and Rules for Module-Definition Statements discusses rules for DEF files.

Because LINK provides equivalent command-line options for most module-definition statements, a typical program for Win32 does not usually require a .DEF file. In contrast, 16-bit programs for Windows almost always must be linked using a .DEF file.

You can use one or more of the following statements in a .DEF file:

  • DESCRIPTION
  • EXPORTS
  • LIBRARY
  • NAME
  • STACKSIZE
  • VERSION

The section describing each module-definition statement gives its command-line equivalent.


Rules for Module-Definition Statements

The following syntax rules apply to all statements in a .DEF file. Other rules that apply to specific statements are described with each statement.

  • Statements and attribute keywords are not case sensitive. User-specified identifiers are case sensitive.

  • Use one or more spaces, tabs, or newline characters to separate a statement keyword from its arguments and to separate statements from each other. A colon (:) or equal sign (=) that designates an argument is surrounded by zero or more spaces, tabs, or newline characters.

  • A NAME or LIBRARY statement, if used, must precede all other statements.

  • Most statements appear only once in the .DEF file and accept one specification of arguments. The arguments follow the statement keyword on the same or subsequent line(s). If the statement is repeated with different arguments later in the file, the latter statement overrides the former.

  • The EXPORTS statement can appear more than once in the .DEF file. Each statement can take multiple specifications, which must be separated by one or more spaces, tabs, or newline characters. The statement keyword must appear once before the first specification and can be repeated before each additional specification.

  • Comments in the .DEF file are designated by a semicolon (;) at the beginning of each comment line. A comment cannot share a line with a statement, but it can appear between specifications in a multiline statement. (EXPORTS is a multiline statement.)

  • Numeric arguments are specified in decimal or in C-language notation.

  • If a string argument matches a reserved word, it must be enclosed in double quotation (" ) marks.

Many statements have an equivalent LINK command-line option. See the Linker Options and Related Information for additional details.


DESCRIPTION

Syntax:

DESCRIPTION "text"

This statement writes a string into an .rdata section. Enclose the specified text in single or double quotation marks (' or "). To use a literal quotation mark (either single or double) in the string, enclose the string with the other type of mark.

This feature differs from the comment specified with the /COMMENT linker option.


EXPORTS

Syntax:

EXPORTS

This statement makes one or more definitions available as exports to other programs.

EXPORTS marks the beginning of a list of export definitions. Each definition must be on a separate line. The EXPORTS keyword can be on the same line as the first definition or on a preceding line. The .DEF file can contain one or more EXPORTS statements.

The syntax for an export definition is:

entryname[=internalname] [@ordinal [ NONAME]] [DATA]

For information on the entryname, internalname, ordinal, NONAME, and DATA arguments, see the /EXPORT option.

There are three methods for exporting a definition, listed in recommended order of use:

  • cDEC$ ATTRIBUTES DLLEXPORT in the source code
  • An /EXPORT specification in a LINK command
  • An EXPORTS statement in a .DEF file

All three methods can be used in the same program. When LINK builds a program that contains exports, it also creates an import library, unless the build uses an .EXP file.


LIBRARY

Syntax:

LIBRARY [library] [BASE=address]

This statement tells LINK to create a DLL. LINK creates an import library at the same time, unless you use an .EXP file in the build.

The library argument specifies the internal name of the DLL. (Use the Output File Name (/OUT) option to specify the DLL's output name.)

The BASE=address argument sets the base address that the operating system uses to load the DLL. This argument overrides the default DLL location of 0x10000000. See the description of the Base Address (/BASE) option for details about base addresses.

You can also use the /DLL linker option to specify a DLL build, and the /BASE option to set the base address.


NAME

Syntax:

NAME [application] [BASE=address]

This statement specifies a name for the main output file. An equivalent way to specify an output filename is with the /OUT option, and an equivalent way to set the base address is with the /BASE option. If both are specified, /OUT overrides NAME. See the Base Address (/BASE) and Output File Name (/OUT) options for details about output filenames and base addresses.


STACKSIZE

Syntax:

STACKSIZE reserve [,commit]

This statement sets the size of the stack in bytes. An equivalent way to set the stack is with the /STACK option. See the /STACK option for details about the reserve and commit arguments.


VERSION

Syntax:

VERSION major [.minor]

This statement tells LINK to put a number in the header of the executable file or DLL. The major and minor arguments are decimal numbers in the range 0 - 65535. The default is version 0.0.

An equivalent way to specify a version number is with the Version Information (/VERSION) option.


Linker Reserved Words

The following table lists words reserved by the linker. You can use these names as arguments in module-definition statements only if you enclose the name in double quotation marks (").

Linker Reserved Words

APPLOADER | INITINSTANCE | PRELOAD
BASE | IOPL | PROTMODE
CODE | LIBRARY | PURE
CONFORMING | LOADONCALL | READONLY
DATA | LONGNAMES | READWRITE
DESCRIPTION | MOVABLE | REALMODE
DEV386 | MOVEABLE | RESIDENT
DISCARDABLE | MULTIPLE | RESIDENTNAME
DYNAMIC | NAME | SEGMENTS
EXECUTE-ONLY | NEWFILES | SHARED
EXECUTEONLY | NODATA | SINGLE
EXECUTEREAD | NOIOPL | STACKSIZE
EXETYPE | NONAME | STUB
EXPORTS | NONCONFORMING | VERSION
FIXED | NONDISCARDABLE | WINDOWAPI
FUNCTIONS | NONE | WINDOWCOMPAT
HEAPSIZE | NONSHARED | WINDOWS
IMPORTS | NOTWINDOWCOMPAT |
IMPURE | OBJECTS |
INCLUDE | OLD |


Microsoft Fortran PowerStation Command-Line Compatibility

This section provides compatibility information for FL32 command-line users of Microsoft Fortran PowerStation Version 4. It includes the following topics:

  • Using the DF or FL32 Command Line
  • Equivalent Visual Fortran Compiler Options


Using the DF or FL32 Command Line

You can use either the DF or FL32 commands to compile (and link) your application. The main difference between the DF and FL32 commands is the defaults set for certain command-line options:

  • FL32 requests no optimization (/Od). See /[no]optimize.
  • FL32 requests checking of arguments passed to and results from the math library (/math_library:check or /Od). See /[no]math_library.
  • FL32 provides minimal debug information (/debug:minimal or /Zd). See /[no]debug.
  • FL32 requests full Microsoft Fortran PowerStation compatibility (/fpscomp:all). See /[no]fpscomp.
  • FL32 disallows alternative PARAMETER syntax (/noaltparam). See /[no]altparam.
  • FL32 requests record length units for unformatted files to be in bytes (/assume:byterecl). See /assume.
  • FL32 requests warnings for mismatched arguments (/warn:argument_checking). See /[no]warn.
  • FL32 compiles each source unit individually and retains intermediate files that would otherwise be deleted (/keep). This prevents interprocedure optimizations at higher optimization levels. See /keep.
  • FL32 does not display an informational message related to compiling multiple files individually. See /warn:fileopts.
  • FL32 requests no inlining (/inline:none). See /[no]inline.
  • FL32 places module files in the same directory as the object files. See /module:path.

The DF and FL32 commands both:

  • Recognize the same set of command-line options. For example, the following commands are supported:
      DF   /Odx test2.for
  FL32 /Odx test2.for

    Both DF and FL32 command lines allow most Microsoft Fortran PowerStation style options (such as /Ox) and all Visual Fortran options (such as /optimize:4). For a detailed list of equivalent Microsoft Fortran PowerStation style compiler options and Visual Fortran compiler options, see Equivalent Visual Fortran Compiler Options.

  • Activate the same compiler, the Compaq Fortran compiler.

    For new programs and most existing applications, use the Compaq Fortran compiler (default). The Compaq Fortran compiler and language used by Visual Fortran provides a superset of the Fortran 95 standard with extensions for compatibility with previous versions of Compaq Fortran (DIGITAL Fortran, DEC Fortran), VAX FORTRAN, and Microsoft Fortran PowerStation Version 4.

  • Pass options specified after /LINK to the LINK command.

    The LINK command options after /link are passed directly to the Linker. These options are described in Linker Options.

  • Allow the use of indirect command files.

    For example, assume the file text.txt contains the following:

     /pdbfile:testout.pdb /exe:testout.exe /debug:full /optimize:0 test.f90 rest.f90

    Either of the following (DF or FL32) commands executes the contents of file text.txt as an indirect command file to create a debugging version of the executable program and its associated PDB file:

      DF   @test.txt

  FL32 @test.txt

To request Microsoft Fortran PowerStation V4 compatibility, specify the /[no]fpscomp option.

For information about using the DF command, see Using the Compiler and Linker from the Command Line.


Equivalent Visual Fortran Compiler Options

The following table lists the Microsoft Fortran PowerStation style options and their Visual Fortran equivalents. The Microsoft Fortran PowerStation options (such as /FAc) are case-sensitive; other Visual Fortran options (such as /asmfile) are not case-sensitive.

This table also lists some compiler options that were not supported by Microsoft Fortran PowerStation, but are supported by Visual C++.

Fortran PowerStation Option (and Category) | Visual Fortran Command-Line Option
Listing Options
/FA | Assembly listing. Specify /noasmattributes with /asmfile[:file] or /FA.
/FAc | Assembly listing with machine code. Specify /asmattributes:machine with /asmfile[:file] or /FAc.
/FAs | Assembly listing with source code. Specify /asmattributes:source with /asmfile[:file] or /FAs.
/FAcs | Assembly listing with machine instructions and source code. Specify /asmattributes:all with /asmfile[:file] or /FAcs.
/Fa[file] | Assembly listing to file file. Specify /asmfile[:file] with /noasmattributes or specify /Fa[file].
/Fc[file] | Assembly listing with source and machine code to file file. Specify /asmfile[:file] with /asmattributes:all or specify /Fc[file].
/Fl[file] | Assembly listing with machine instructions to file file. Specify /asmfile[:file] with /asmattributes:machine or specify /Fl[file].
/Fs[file] | Source listing with compiled code. Specify /list[:file] with /show:map or specify /Fs[file].
Code Generation Options
/FR[file] | Generates extended Source Browser information. Specify /browser[:file] or /FR[file].
/G4 /G5 | Generates code for specific ia32 chip architectures. Specify /tune:keyword.
/Ob2 | Automatic inlining of code, use with /Ox. Specify /inline:speed or /Ob2.
/Od | No code optimization (default for FL32 command). Specify /optimize:0 with /math_library:check, or specify /Od.
/Op | Improved floating-point consistency. Specify /fltconsistency or /Op. Applies to ia32 systems only.
/Ox | Full optimization with no error checking. Specify /optimize:4 with /math_library:fast and /assume:nodummy_aliases, or specify /Ox.
/Oxp | Speed optimization and denoted inlining; error checking. Specify /optimize:4 with /assume:nodummy_aliases and (on ia32 systems) /math_library:check with /fltconsistency, or specify /Oxp.
/Zp[n] | Packs structures on n-byte boundary (n is 1, 2, or 4). Specify /alignment[:keyword] or /Zp[n]. If you specify /Zp (omit n), structures are packed at 8-byte boundaries.
Language Extension Options
/4Lnn | Line length for Fortran 90 fixed-form source (nn is 72, 80, or 132). Specify /extend_source[:nn] or /4Lnn.
/4Yb or /4Nb | Enable/disable extended error checking. Specify /check[:keyword], /4Yb, or /4Nb.
/4Yd or /4Nd | Warnings about undeclared variables. Specify /warn: [no]declarations, /4Yd or /4Nd.
/W0 | Suppress warnings. Specify /nowarn or /W0.
/W1 | Show warnings (default). Specify /warn:general or /W1.
/WX | Interpret all warnings as errors. Specify /warn:(general,errors) or /WX.
Language Standard, Source Form, and Data Options
/4Ya or /4Na | Makes all variables AUTOMATIC. Specify /[no]automatic, /[no]static, /4Ya, or /4Na.
/4Yaltparam /4Naltparam | Use the alternate syntax for PARAMETER statements. Specify /[no]altparam, /4Yaltparam, or /4Naltparam.
/4Yf or /4Nf | Use free-form source format. Specify /[no]free, /[no]fixed, /4Yf, or /4Nf.
/4I2 | Change default KIND for INTEGER and LOGICAL declarations. Specify /integer_size:nn (nn is 16 for KIND=2) or /4I2.
/4R8 | Change default KIND for REAL declarations. Specify /real_size:nn (nn is 32 for KIND=4) or /4R8.
/4Ys or /4Ns | Strict Fortran 90 syntax. Specify /stand:f90, /warn:stderrors, /4Ys, or /4Ns.
Compiler Directive Options
/Dsymbol[=int] | Define preprocessor symbol. Specify /define:symbol[=int] or Dsymbol[=int].
/4ccstring | Treat lines with d or D in column 1 as comments. Specify /d_lines or /4ccd or /4ccD (partial support).
Build Control Options
/4Yportlib or /4Nportlib | Specify /4Yportlib or /4Nportlib.
/Fd[file] | Controls creation of compiler PDB files. Specify /[no]pdbfile[:file] or /Fd[file].
/Fe[file] | Specifies file name of executable or DLL file. Specify /exe:file, /dll:file, or /Fe[file].
/Fm[file] | Controls creation of link map file. Specify /map[:file] or /Fm[file].
/Fo[file] | Controls creation of object file. Specify /object[:file] or /Fo[file].
/GNa | Keep external names as is and treat source code identifiers as case sensitive. Specify /names:as_is or /GNa.
/GNl | Make external names lowercase and ignore the case of source code identifiers. Specify /names:lowercase or /GNl.
/GNu | Make external names uppercase and ignore the case of source code identifiers. Specify /names:uppercase or /GNu.
/Ipath | Control search path for module or include files. Specify /[no]include[:path] or /Ipath.
/LD | Create dynamic-link library. Specify /dll or /LD.
/MD | Link against multithreaded DLL libraries. Specify /libs:dll with /threads or /MD.
/MDd | Link against multithreaded DLL libraries. Specify /libs:dll with /threads and /dbglibs or specify /MDd.
/MDs | Link against single threaded DLL libraries. Specify /libs:dll or /MDs.
/MG | Link against libraries for windows applications. Specify /winapp or /MG.
/ML | Link against single threaded static libraries. Specify /libs:static or /ML.
/MLd | Link against single threaded static libraries. Specify /libs:static with /dbglibs or /MLd.
/MT | Link against multithreaded static libraries. Specify /libs:static with /threads or /MT.
/MTd | Link against multithreaded static libraries. Specify /libs:static with /threads and /dbglibs or specify /MTd.
/MW | Link against QuickWin multidoc libraries. Specify /libs:qwin or /MW.
/MWs | Link against QuickWin single doc libraries. Specify /libs:qwins or /MWs.
/Tffile | Request that file be treated as a Fortran source file. Specify /source:filename or /Tffile.
/V"string" | Place string in object file. Specify /bintext:string or /V"string".
/Z7 | Request full debug information in object file. Specify /debug:full with /nopdbfile or /Z7.
/Zd | Request minimal debug information. Specify /debug:minimal with /pdbfile or /Zd.
/Zi | Request full debug information and create PDB file. Specify /debug:full with /pdbfile or /Zi.
/Zla | Do not insert any library names in object file. Specify /nolibdir or /Zla.
/Zl | Do not insert default library names in object file. Specify /libdir:noautomatic or /Zl.
/Zs | Perform syntax check only (no object). Specify /syntax_only or /Zs.
/Zt | Requests traceback information (run-time program counter to source file line correlation). Specify /traceback or /Zt.
/link [option] | Begin specifying linker options. Specify /link [option].
Command-Line Specific Options
/?, /help | Display command help. Specify /? or /help.
/nologo | Prevent display of copyright information. Specify /nologo.


Debugging Fortran Programs

Although you can use the command line to develop your programs, Visual Fortran programs are typically debugged in the Microsoft visual development environment integrated debugger.

This chapter discusses how to use the integrated debugger to debug Visual Fortran programs. The following topics are discussed:

  • Preparing Your Program for Debugging

  • Debugging the Squares Example Program

  • Using Breakpoints in the Debugger

  • Viewing Fortran Data Types in the Debugger

  • Using the Array Viewer in the Debugger

  • Locating Run-Time Errors in the Debugger


Preparing Your Program for Debugging

This section describes preparing your program for debugging:

  • When developing your application with the Microsoft visual development environment
  • When developing your application with the command-line environment

To prepare your program for debugging when using the visual development environment:

  1. Start the visual development environment (click Developer Studio in the Compaq Visual Fortran program folder).

  2. Open the appropriate Workspace (File menu, either Open Workspaces or Recent Workspaces).

  3. Click the FileView pane.

  4. To edit the source file to be debugged, double-click on the file name.

  5. Click the Project name. The screen might appear as follows (the ClassView tab only appears if Visual C++ is also installed):

    visual development environment after opening a workspace and fortran source file

  6. In the Build menu, click Set Active Configuration and select the debug configuration.

  7. To check your project settings for compiling and linking, in the Project menu, click Settings, then click the Fortran tab. Similarly, to check the debug options set for your program (such as program arguments or working directory), click the Debug tab in the Project Settings dialog box.

  8. To compile your program:
    • Click (select) the source file to be compiled
    • In the Build menu, click Compile filename

  9. Eliminate any compiler diagnostic messages in the text editor and recompile if needed.

  10. To build your application, in the Build menu, click Build file.EXE.

  11. Set breakpoints in the source file and debug the program, as described in Debugging the Squares Example Program.

To prepare your program for debugging when using the command line (DF command):

  1. Correct any compilation and linker errors.
  2. In a command window (such as the Fortran command window available from the Visual Fortran program folder), compile and link the program with full debug information and no optimization:
     DF /debug:full /nooptimize file.f90
  3. Start the visual development environment.
  4. In the File menu, click the Open Workspace item. Specify the file name of the executable (.EXE) file to be debugged.
  5. In the File menu, click Open. Specify the name of the source file (such as .F90 or .FOR) that corresponds to the file being debugged. The text editor window appears. Your screen might appear as follows:

    opening a fortran source file
  6. Set breakpoints in the source file and debug the program, as described in Debugging the Squares Example Program.

To add Source Browser Information to your debug configuration, see Source Browser Information for a Configuration.


Debugging the Squares Example Program

The following program (SQUARES) uses the Fortran Console project type. The SQUARES program reads formatted data from the file datafile.dat and displays the calculated results. With the source code shown below, it does not generate the expected results:

    PROGRAM SQUARES
       INTEGER INARR(10), OUTARR(10), I, K
 ! Read the input array from the data file.
       OPEN(UNIT=8, FILE='datafile.dat', STATUS='OLD')
       READ(8,*,END=5) N, (INARR(I), I=1,N)
   5   CLOSE (UNIT=8)

 ! Square all nonzero elements and store in OUTARR.
       K = 0
       DO I = 1, N
     IF (INARR(I) .NE. 0) THEN
 ! Is the error in this DO loop?
        OUTARR(K) = INARR(I)**2
     ENDIF
       END DO

 ! Print the squared output values.  Then stop.
       PRINT 20, N
   20  FORMAT (' Total number of elements read is',I4)
       PRINT 30, K
   30  FORMAT (' Number of nonzero elements is',I4)
       DO, I=1,K
         PRINT 40, I, OUTARR(K)
   40    FORMAT(' Element', I4, ' has value',I6)
       END DO
   END PROGRAM SQUARES

The formatted file datafile.dat currently contains one record that includes the following:

  • An INTEGER count of the number of array elements, value 4
  • The values for each of the four INTEGER array elements

To view the values of this formatted data file in the Microsoft visual development environment, use the Open item in the File menu.

When executed without array bounds checking (set by the /check:nobounds option), the output appears as follows:

When the program was executed with array bounds checking on, the output appears as follows:

You can either build this program from the command line or within the visual development environment (see Preparing Your Program for Debugging). This example assumes a project workspace already exists.

To debug this program:

  1. From the Compaq Visual Fortran program folder, click Developer Studio to start the visual development environment.
  2. In the File menu, click Open Workspace.
  3. Click the FileView pane in the Workspace window. If the Workspace window is not displayed, click Workspace in the View menu.
  4. Edit the file squares.f90: double-click its file name in the FileView pane. The screen appears as follows:

    visual development environment, after opening project workspace

    The following toolbars are shown:

    • Build toolbar
    • Standard toolbar
    • Fortran toolbar

    To change the displayed toolbars, select Customize in the Tools menu and click the Toolbars tab. You can move toolbars by dragging the anchor (double vertical line on the left of the toolbar).

  5. Click the first executable line to set the cursor position. In this case, click the beginning of the OPEN statement line:
       OPEN(UNIT=8, FILE='datafile.dat', STATUS='OLD')
  6. Click the Set/Remove Breakpoint (open hand symbol) button in the Build toolbar:

    set initial the breakpoint, build toolbar

    The red circle in the left margin of the text editor/debugger window shows where a breakpoint is set.

  7. This example assumes you have previously built your application (see Preparing Your Program for Debugging).

    In the Build menu, click the Start Debug, Go item:

    starting the debugger, build menu

  8. The debugger is now active. The current position is marked by a yellow arrow at the first executable line (the initial breakpoint):

    debugger positioned at the first breakpoint

    The Debug menu appears on the visual development environment title bar in place of the Build menu. If not displayed previously, the Debug toolbar appears.

    If needed, you can set another breakpoint, position the cursor at the line where you want to add or remove a breakpoint and do either of the following:

    • In the Build toolbar, click the Set/Remove Breakpoint button.
    • In the Edit menu, click Breakpoints. A dialog box allows you to set or clear breakpoints, evaluate expressions, and perform other functions.

    Step through the lines of source code. You can do this with the Debug menu item Step Over (as shown) or the Step Over button on the Debug toolbar:

    debug menu, step over item

  9. Repeat the Step Over action and follow program execution into the DO loop. Repeat the Step Over action until you are at the end of the program. Position the cursor over the variable K to view its value (called Data Tips):

    viewing the value of variable k

    The error seems related to the value of variable K!

  10. In the text editor, add the line K = K + 1 as follows:
     ! Square all nonzero elements and store in OUTARR.
       K = 0
       DO I = 1, N
         IF (INARR(I) .NE. 0) THEN
         K = K + 1       ! add this line
         OUTARR(K) = INARR(I)**2
         ENDIF
       END DO
  11. You have modified the source, so you need to rebuild the application:
    • In the Debug menu, click Stop Debugging
    • In the Build menu, click Build Squares.exe
    • In the Build menu, click Execute Squares.exe or click the exclamation point (!) on the Build toolbar.

    The output screen appears as follows:

    displayed output after fixing the program

  12. Although the program generates better results, you can examine the values of both the input array INARR (read from the file) and the output array OUTARR that the program calculates. In the text editor window, the previously set breakpoint remains set.

    In the Build menu, click the Start Debug, Go item.

  13. To view the values of certain variables as the program executes, we need to display the Variables or the Watch window. In the View menu, click the Debug Windows, Variables window item:

    display the debug variables window: view menu, debug windows, variables

  14. In the Variables window, click the Locals tab to display the values of your local variables:

    display the locals tab in the variables window

    You can view the values of the local variables by using the Locals tab, including the arrays (click the plus sign).

    The Variables window displays a Context menu (after the word Context:). The Context menu can help you debug exceptions.

    The Locals tab does not let you display module variables or other non-local variables. To display non-local variables, display the Watch window:

    view menu, debug windows, watch: displaying the watch window

  15. Although this example does not use module variables or non-local variables, you can drag a variable name into the Watch window so the variable can be displayed. The Watch window allows you to display expressions.

    In the text editor window, select the variable name INARR (without its subscript syntax), drag it, and drop it into the Watch window:

    select inarr in text window. drag and drop to watch window

  16. Also drag the OUTARR array name to the Watch window. Click the Plus sign (+) to the left of the OUTARR variable's name to display the values of its array elements.
  17. Execute lines of the program by using the Step Over button on the Debug toolbar. As the program executes, you can view the values of scalar variables with the data tips feature and view the values of arrays (or other variables) in the Watch window.

    When the program completes execution, the screen appears as follows:

    watch window at completion of corrected program

If a Disassembly window (shows disassembled code with source-code symbols) unintentionally appears, click the Step Out button on the debugger toolbar (or select the Step Out item in the Debug menu) as needed to dismiss the Disassembly window.

If you have the Visual Fortran Professional or Enterprise Edition, you can use the Array Viewer to display and graph multidimensional array element values.

For more information:

  • On using breakpoints, see Using Breakpoints in the Debugger.
  • On viewing different types of Fortran data, see Viewing Fortran Data Types in the Debugger.
  • On displaying array values in the Array Viewer, see Using the Array Viewer in the Debugger.
  • On locating errors in your program, see Locating Run-Time Errors in the Debugger.
  • On additional debugger capabilities, see the Debugger section of the Visual C++ Users Guide.


Using Breakpoints in the Debugger

The Developer Studio debugger lets you set breakpoints at certain locations, when certain conditions are met at a certain location, or when a variable changes its value. This section discusses the following topics:

  • Viewing and Using Location Breakpoints
  • Setting Location Condition Breakpoints
  • Using Data Breakpoints (Current Scope)
  • Setting Advanced Data Breakpoints

Viewing and Using Location Breakpoints

To view the breakpoints currently set:

  1. In the Edit menu, click Breakpoints.
  2. Scroll up or down in the Breakpoints list to view the breakpoints. Enabled breakpoints have a check mark in the check box and disabled breakpoints have an empty check box. The Edit Breakpoints dialog box displays all types of breakpoints (not just location breakpoints).

Alternatively, for smaller programs you can view location breakpoints set in the text editor window. Enabled location breakpoints are identified as a red circle in the left margin (see Debugging the Squares Example Program). Disabled location breakpoints are identified as a hollow circle in the left margin. You can also remove a breakpoint.

To set a location breakpoint:

  1. After you open the project workspace, open the source file within which you will set a location breakpoint in the text editor (double-click the file name in the FileView pane).
  2. In a text editor window (or in the Call Stack or Disassembly window), click the line at which you want to enable a location breakpoint.
  3. Do one of the following:
    • Click the Insert/Remove Breakpoint button (open hand symbol) button in the Build toolbar or press the F9 key. When you set a breakpoint, it is enabled by default.
    • Right click on that line, and select Insert/Remove Breakpoint from the pop-up menu.
    • In the Edit menu, select Breakpoints. In the Location tab, click the arrow to the right of the Break At field. Click the displayed line number. Click OK.

To disable or enable a location breakpoint:

  1. In a text editor window (or in the Call Stack or Disassembly window), click the line containing the location breakpoint you want to disable.
  2. Do one of the following:
    • Right click on that line, and select Disable Breakpoint or Enable Breakpoint from the pop-up menu.
    • In the Edit menu, select Breakpoints. Click on the check box for that breakpoint so it is unchecked (disabled) or checked (enabled). Click OK.

To remove a location breakpoint:

  1. In a text editor window (or in the Call Stack or Disassembly window), click the line containing the location breakpoint you want to remove.
  2. Do one of the following:
    • Click the Insert/Remove Breakpoint button (open hand symbol) button in the Build toolbar or press the F9 key. If the breakpoint was originally disabled, click the Insert/Remove Breakpoint button or press F9 again to remove it.
    • Right click on that line, and select Remove Breakpoint from the pop-up menu.
    • In the Edit menu, select Breakpoints. In the Location tab, click (select) the breakpoint to be removed and click the Remove button. Click OK.

To view the source code where a location breakpoint is set:

  1. In the Edit menu, select Breakpoints.
  2. In the Breakpoints list, click (select) a location breakpoint.
  3. Click the Edit Code button (upper right corner).

    This action takes you to the source code for a breakpoint set at a line number or function (or subroutine) name. In the case of function (or subroutine) names, the debugger must be running for this to work.

To remove all breakpoints:

  1. In the Edit menu, select Breakpoints. Click on the Remove All button. Click OK.

Setting Location Condition Breakpoints

Like a location breakpoint, a location condition breakpoint occurs only at a certain location. Instead of the break always occurring when the program executes at that location, a location condition breakpoint occurs when the program executes at that location and the specified condition is met (such as when the value of an array element is greater than 1). The following procedure applies to source code within the current scope.

Unlike location breakpoints, location condition breakpoints must be set only using the Edit Breakpoints dialog box:

To set a location condition breakpoint:

  1. In a text editor window (or in the Call Stack or Disassembly window), click the line at which you want to enable a location condition breakpoint.
  2. Do the following:
    • In the Edit menu, select Breakpoints.
    • In the Location tab, click the arrow to the right of the Break At field.
    • Click the displayed line number.
    • Click the Condition button to display the Condition Breakpoint dialog box.
    • Type the desired condition, such as:
      A(1) .gt. 0
    • Click OK to dismiss the Condition Breakpoint dialog.
    • Click OK

To disable, enable, and remove a location condition breakpoint, follow the general procedures for a location breakpoint. Under certain conditions, the debugger may disable the location condition breakpoint. In this case, you should either try to enable it or remove and set it again.

When the program is run and if the specified condition occurs at the chosen location, a message box similar to the following appears:

Message box after condition met

Using Data Breakpoints (Current Scope)

A data breakpoint displays a message box when the value of a variable changes or when a specified condition is met. Unlike a location condition breakpoint, data breakpoints are not associated with a specific source location. The following procedure applies to debugging the current routine (current scope).

To set a data breakpoint:
  1. In the Edit menu, select Breakpoints.
  2. Click the Data tab.
  3. Either type the variable name alone if you want a data breakpoint to occur whenever its value changes or type the desired condition, such as:
    A(1) .eq. 0
  4. Click OK to dismiss the Breakpoint dialog.

To disable, enable, or remove a data breakpoint, do one of the following:

  1. In the Edit menu, select Breakpoints.
  2. To disable or enable the data breakpoint, use the check box to the left of the data breakpoint (check indicates enabled).
  3. To remove a data breakpoint, click (select) the data breakpoint and click the Remove button.

Under certain conditions, the debugger may disable the data breakpoint. In this case, you should either try to enable it or remove and set it again.

Setting Advanced Data Breakpoints

You can request that your program stop execution when a specific variable is set to a specific logical expression (data breakpoint or watchpoint). To properly instruct the debugger to watch for a change of a certain data value (variable), you should specify the routine name (scope) within which the data value condition will be watched. When the data value condition for the variable occurs within the specified scope, a message box window is displayed informing you that the condition has been met.

To set a data breakpoint for a specific local variable:

  1. In the Edit menu, select Breakpoints.
  2. Click the Data tab
  3. Enter the logical expression to be evaluated, such as K .GT. 2
  4. Unless the data value being watched is in the main program code, specify the scope of the data breakpoint as follows:
    • Click the right arrow (to the right of the expression) to display the Advanced pop-up menu:

      Setting a data breakpoint for a specific routine

    • Click Advanced and specify the routine (function) name within which the data expression will be watched.
    • Click OK
  5. Start the debugger (Build menu). Consider displaying the source file associated with the data expression being watched.
  6. If you have previously set an initial breakpoint for the program, in the Debug menu, click Go. Execution stops at the initial breakpoint.
  7. In the Debug menu, click Go. Execution continues until the specified data value expression is met. A message box similar to the following appears when the specified data expression is met:

    Message box after stop at watchpoint

  8. You can now view the source line just executed, examine current variable values, execute the next instruction, and so on to help you better understand that part of your program. If the error is related to an I/O statement, also see Viewing the Call Stack and Context Menu.

Some limitations with the current implementation:

  • Setting data breakpoints on array elements is not fully supported.
  • Under certain conditions, before you run the program again, you may need remove the original data breakpoint and set the data breakpoint again.


Viewing Fortran Data Types in the Debugger

The following general suggestions apply to different types of Fortran data:

  • For scalar (nonarray) data, use the data tips (leave pointer on a variable name) feature or use the Local Variables window.
  • For single-dimension array data, derived-type data, record structure data, and COMPLEX data, use the Local Variables window or the Watch window.
  • For multidimension array data, use the Local Variables window, the Watch window, or (Professional and Enterprise Editions) the Array Viewer.
  • For common blocks in a DLL, move (drag) the name of the common block to the Watch window. You will be able to view the common block fields like any other structure.

For information on using Data Tips, the Local Variables window, or a Watch window, see Debugging the Squares Example Program.

For information on using the Array Viewer in the debugger, see Using the Array Viewer in the Debugger.

The following sections apply to using the Watch window:

  • Specifying Array Sections
  • Specifying Module Variables
  • Specifying Format Specifiers

To display the Watch window:

  1. In the View menu, point at (or click) Debug Windows
  2. In the submenu, click Watch

Specifying Array Sections

You can specify array sections in a watch window. For example, consider an array declared as:

  integer foo(10)

You can specify the following statement in a watch window to see the 2nd, 5th, and 8th elements:

  foo(2:10:3)

When working with character arrays, this syntax may be combined with a substring specification. Consider the following array declaration:

  character*8 chr_arr(10)

You can specify the following statement in a watch window to display the substring made up of character 3 through 8 of array elements 2 through 5:

  chr_arr(2:5)(3:8)

This support is available for arrays of any type, including array pointers, assumed-shape, allocatable, and assumed-size arrays.

Any valid integer expression can be used when specifying lower bound, upper bound, or stride. If the lower bound is omitted, the array lower bound is used. If the upper bound is omitted, the array upper bound is used. For example, consider the following declaration:

  integer foo(10)

To display:

  • Elements 1 through 8, specify foo(:8)
  • Elements 5 through 10, specify foo(5:)
  • All 10 elements, specify foo(:)

Specifying Module Variables

To view a module variable in the Watch window, specify the module name, followed by "::", followed by the variable name.

For example, to watch variable "bar" of module "foo", specify the following expression:

  foo::bar

Specifying Format Specifiers

You can use format specifiers in Watch windows to display variables in different data formats.

For example, given a REAL variable 'foo' in a program, it is now possible to see 'foo' in different floating point notation (by typing "foo,f" "foo,g" or "foo,e" in a Watch window) or as an integer (""foo,i" or "foo,d"), a hexadecimal value ("foo,x"), an an octal value ("foo,o"), and so on.

You can change the display format of variables in the Watch window using the formatting symbols in the following table:

Symbol | Format | Value | Displays
d,i | signed decimal integer | 0xF000F065 | -268373915
o | unsigned octal integer | 0xF065 | 0170145
x,X | Hexadecimal integer | 61541 (decimal) | #0000F065
f | signed floating-point | 3./2. | 1.5000000
e | signed scientific notation | 3./2. | 0.1500000E+01
g | signed floating-point or signed scientific notation, whichever is shorter | 3./2. | 1.500000
c | Single character | 0x0065 | 'e'
s | String | 0x0012fde8 | "Hello world"

To use a formatting symbol, type the variable name, followed by a comma and the appropriate symbol. For example, if var has a value of 0x0065, and you want to see the value in character form, type var,c in the Name column on the tab of the Watch window. When you press ENTER, the character-format value appears:

  var,c = 'e'

You can use the formatting symbols shown in the following table to format the contents of memory locations:

Symbol | Format | Displays
ma | 64 ASCII characters | 0x0012ffac .4...0...".0W&.......1W&.0.:W..1...."..1.JO&.1.2.."..1...0y....1
m | 16 bytes in hexadecimal, followed by 16 ASCII characters | 0x0012ffac B3 34 CB 00 84 30 94 80 FF 22 8A 30 57 26 00 00 .4...0...".0W&..
mb | 16 bytes in hexadecimal, followed by 16 ASCII characters | 0x0012ffac B3 34 CB 00 84 30 94 80 FF 22 8A 30 57 26 00 00 .4...0...".0W&..
mw | 8 words | 0x0012ffac 34B3 00CB 3084 8094 22FF 308A 2657 0000
md | 4 doublewords | 0x0012ffac 00CB34B3 80943084 308A22FF 00002657

With the memory location formatting symbols, you can type any value or expression that evaluates to a location.

A formatting character can follow an expression also:

  rep+1,x
  alps[0],mb
  xloc,g
  count,d
Note: You can apply formatting symbols to structures, arrays, pointers, and objects as unexpanded variables only. If you expand the variable, the specified formatting affects all members. You cannot apply formatting symbols to individual members.


Using the Array Viewer in the Debugger

If you have the Professional or Enterprise Edition, you can use the Array Viewer in the debugger. Consider the following example program:

 PROGRAM ARRAY
   INTEGER I1, I2
   REAL VAL(5,5), X

   VAL = 0.0
   X = 1.0
   DO I1 = 1,5
     DO I2 = 1,5
        X = X*1.2
        VAL(I1,I2) = X
     END DO
   END DO

   PRINT *,VAL
 END PROGRAM ARRAY

To use the Array Viewer in the debugger:

  1. Start the debugger (see Debugging the Squares Example Program)
  2. Step through the parts of the program that generate the values of the array you want to view, perhaps after stopping program execution at a certain breakpoint.
  3. Select (click) the name of the array you want to view in the Array Viewer. For example:

    selecting an array

  4. In the Debug menu, click Fortran Array Viewer or click the Array Viewer button in the Fortran toolbar:

    fortran toolbar, with pointer on view fortran arrays button

    To display the Fortran toolbar:

    1. In the Tools menu, select Customize.
    2. Click the Toolbars tab.
    3. Set the Fortran toolbar check box.

    The Array Viewer as well as a Fortran Arrays window appears:

    array viewer and fortran arrays window

    In the upper part (data window), Array Viewer displays the values of the array elements for VAL.

    In the lower part (graph window), the view shown for array VAL is a two-dimensional view. You can also display other types of views, such as a height plot (in the View menu, click Height Plot).

    Initially, the Fortran Arrays window shows the current array being displayed and its status.

  5. After your program changes the data in the Array being viewed, you can:
    • Refresh the current Array Viewer data and graph by double-clicking the array name in the Fortran Array window.
    • Create another instance of Array Viewer with an updated view of the data by clicking the Fortran Arrays button in the Fortran toolbar. The second instance may contain different value limits on the graph.

  6. The Fortran Arrays window allows you to:

    To Do This: In the Fortran Arrays Window, Do This:
    Display a different array in the existing Array Viewer | Click the Name column and type an array name
    Display a different array in a new instance of the Array Viewer | Click in the last row of the Name column, type the array name, and press Enter (Return). A new instance of Array Viewer appears for the specified array.
    Update the displayed array's values | Double-click the line for the array
    Discontinue using the Array Viewer (removes the name from the Fortran Arrays window) | Either stop the debugger (Debug menu, Stop Debugging item) or repeatedly select the array name and click the Delete key.
    Create a detached instance of Array Viewer (not associated with the debugger) | Click on an array in the Name column and press the Escape (Esc) key. This removes the array name from the Fortran Arrays window and creates a detached instance of the Array Viewer that remains after the debugging session ends.

For more information on using the Array Viewer:

  • When using the Array Viewer, in the Help menu, click Help Topics.
  • Read the Array Visualizer HTML Help documentation.


Locating Run-Time Errors in the Debugger

For many types of errors, using the Debugger can help you isolate the cause of errors. This section discusses the following topics:

  • Effect of Certain Compiler Options
  • Debugging an Exception
  • Viewing the Call Stack and Using the Context Menu

Effect of Certain Compiler Options

Be aware that your program must use compiler options that allow the debugger to catch the appropriate error conditions:

  • The /check:keyword options generate extra code to catch certain conditions at run-time. For example, if you do not specify Array and Substring Bounds checking (/check:bounds), the debugger will not catch and stop at array or character string bounds errors.
  • If you specify the /fpe:3 compiler option, certain floating-point exceptions will not be caught, since this setting allows IEEE exceptional values and program continuation. In contrast, specifying /fpe:0 stops execution when an exceptional value (such as a NaN) is generated or when attempting to use a denormalized number, which usually allows you to localize the cause of the error.

In most cases, your program will automatically stop at the point where the exception occurs, allowing you to view the source code and values of variables. If the error is related to an I/O statement, see Viewing the Call Stack and Using the Context Menu.

Debugging an Exception

You can request that the program always stop when a certain type of exception occurs. Certain exceptions are caught by default by the Visual Fortran run-time library, so your program stops in the run-time library code. In most cases, you want the program to instead stop in your program's source code.

To change how an exception is handled in the debugger:

  1. Start the debugger and stop execution at the initial breakpoint.
  2. In the Debug menu, click Exceptions
  3. View the displayed exceptions.
  4. Select each type of exception to be changed and change it from "Stop if not handled" to "Stop Always"
  5. Continue program execution by clicking Go in the Debug menu.
  6. When the exception occurs, you can now view the source line being executed, examine current variable values, execute the next instruction, and so on to help you better understand that part of your program. If the error is related to an I/O statement, also see Viewing the Call Stack and Using the Context Menu.
  7. After you locate the error and correct the program, consider whether you want to reset the appropriate type of exception to "Stop if not handled" before you debug the program again.

For machine exceptions, you can use the just-in-time debugging feature to debug your programs as they run outside of the visual development environment, if both of the following items have been set:

  • In the Tools menu Options item, the Debug tab has the checkbox for Just-In Time debugging set.
  • The FOR_IGNORE_EXCEPTIONS environment variable is set to TRUE.

Viewing the Call Stack and Using the Context Menu

If you want to view where in the hierarchy of routines your program in currently executing, such as after your program stops at the point where an exception occurs, you can view the Call Stack window and Context menu in the debugger:

  1. Start the debugger and stop at a breakpoint
  2. In the View menu, click Debug Windows
  3. In the submenu, click Call Stack

A severe unhandled I/O programming error (such as an End-of-File condition) can occur while the program is executing in the debugger. When this occurs, the Fortran run-time system will raise a debug event automatically to stop program execution, allowing display of the Call Stack Display.

When the severe unhandled I/O error occurs in the debugger:

  • An information box is displayed that contains:
      User breakpoint called from code at 0xnnnnnnn
  • A window appears with your cursor in NTDLL disassembly code

Click OK to dismiss the information box.

Scanning down the Call Stack display, there will be a few frames from NTDLL and the Fortran run-time system displayed, and then the actual Fortran routine with the I/O statement that caused the error. In the Context menu, select the Fortran routine to display the Fortran code. The green arrow points to the I/O statement that caused the error.

You can view the Context menu (after Context:) to help locate the source code line that executed the I/O statement. The Context menu appears in the top of the Variables window (see Debugging the Squares Example Program). Use the Context menu to select the viewing context for the routine (use the arrow at the right to display selections).

This action all occurs after the error message and traceback information has been displayed. The error message and traceback information is available in the program output window. To view the program output window, either iconize (minimize) the visual development environment or click the icon for the output window in the task bar. You should not need the stack dump because you have the Call Stack window in the visual development environment, but the error message with the file name might be useful to see.

For more information:

  • On locating exceptions and the compiler options needed, see Locating Run-Time Errors
  • On using traceback information, see Using Traceback Information


Performance: Making Programs Run Faster

This chapter discusses the following topics related to improving run-time performance of Visual Fortran programs:

  • Software Environment and Efficient Compilation
    Important software environment suggestions that apply to nearly all applications, including using the most recent version of the compiler, related performance tools, and efficient ways to compile using the DF command or the visual development environment
  • Analyze Program Performance
    Analyzing program performance, including using profiling tools
  • Data Alignment Considerations
    Guidelines related to avoiding unaligned data
  • Use Arrays Efficiently
    Guidelines for efficient array use
  • Improve Overall I/O Performance
    Guidelines related to improving overall I/O performance
  • Additional Source Code Guidelines for Run-Time Efficiency
    Additional performance guidelines related to source code
  • Optimization Levels: the /optimize:num Option
    Understanding the compiler /optimize:num optimization level options and the types of optimizations performed
  • Other Options Related to Optimization
    Understanding other compiler optimization options (besides the /optimize:num options)
  • Compiler Directives Related to Performance
    Discuss the source directives (cDEC$ prefix) related to performance that can be used in place of compiler options or to provide more control of certain optimizations


Software Environment and Efficient Compilation

Before you attempt to analyze and improve program performance, you should:

  • Obtain and install the latest version of Visual Fortran, along with performance products that can improve application performance.
  • Use the DF command and its options in a manner that lets the Visual Fortran compiler perform as many optimizations as possible to improve run-time performance.
  • Use certain performance capabilities provided by the operating system.

For more information:

  • Install the Latest Version of Visual Fortran and Performance Products
  • Compile With Appropriate Options and Multiple Source Files


Install the Latest Version of Visual Fortran and Performance Products

To ensure that your software development environment can significantly improve the run-time performance of your applications, obtain and install the following optional software products:

  • The latest version of Visual Fortran

    New releases of the Visual Fortran compiler and its associated run-time libraries may provide new features that improve run-time performance.

    For information on more recent Visual Fortran releases and other information about Visual Fortran, access the Compaq Fortran web page.

    If you have the appropriate technical support contract, you can also contact the Compaq technical support center for information on new releases (see "Visual Fortran Technical Support" in Compaq Visual Fortran Installing and Getting Started).

  • Performance profiling tools

    The visual development environment profiling tools allow function and line profiling. For more information on profiling, see Analyze Program Performance.

  • System-wide performance products

    Other products are not specific to a particular programming language or application, but can improve system-wide performance, such as minimizing disk device I/O and handling capacity planning.

    When running large programs, such as those accessing large arrays, adequate process limits and virtual memory (paging file) space as well as proper system tuning are especially important.


Compile With Appropriate Options and Multiple Source Files

During the earlier stages of program development (such as for the debug configuration in the visual development environment), you can use compilation with minimal optimization. For example:

  DF /compile_only /optimize:1  sub2.f90
  DF /compile_only /optimize:1  sub3.f90
  DF /exe:main.exe /debug /optimize:0  main.f90 sub2.obj sub3.obj

During the later stages of program development (such as for the release configuration), you should:

  • Avoid using incremental linking.
  • Specify multiple source files together and use an optimization level of at least /optimize:4 on the DF command line to allow more interprocedural optimizations to occur. For instance, the following command compiles all three source files together using the default level of optimization (/optimize:4):
      DF /exe:main.exe main.f90  sub2.f90  sub3.f90
  • When using the visual development environment, consider reducing the number of top-level source files by copying your application to a separate project. The separate project should use only one (or a few) top-level Fortran source files that contain INCLUDE statements for the other source files. Or, you can build your application from the command line, which allows many source files to be compiled together with a single command. For information on creating (exporting) makefile for command-line use, see Files in a Project; for information about using NMAKE, see Building Projects with NMAKE.

Compiling multiple source files together lets the compiler examine more code for possible optimizations, which results in:

  • Inlining more procedures
  • More complete data flow analysis
  • Reducing the number of external references to be resolved during linking

When compiling all source files together is not feasible (such as for very large programs), consider compiling related source files together using multiple DF commands rather than compiling source files individually.

If you use the /compile_only option to prevent linking, also use the /object:file option so that multiple sources files are compiled into a single object file, allowing more optimizations to occur.

Visual Fortran performs certain optimizations unless you specify the appropriate DF command-line options or corresponding visual development environment options in the Optimization category of the Fortran tab (see Categories of Compiler Options). Additional optimizations can be enabled or disabled using DF command options or in the visual development environment Project Settings dialog box Fortran tab.

The following table shows DF options that can directly improve run-time performance on both ia32 and ia64 systems. Most of these options do not affect the accuracy of the results, while others improve run-time performance but can change some numeric results.

Options Related to Run-Time Performance

Option Names | Description | For More Information
/align: keyword | Controls whether padding bytes are added between data items within common blocks, derived-type data, and Compaq Fortran record structures to make the data items naturally aligned. | See Data Alignment Considerations.
/architecture: keyword | Requests code generation for a specific chip generation. On ia32 systems, certain ia32 chip generations use new instructions that provide improved performance for certain applications, but those instructions are not supported by older ia32 chips. | See /architecture
/fast | Sets the following performance-related options: /alignment:(dcommons, records, sequence), /architecture:host /assume:noaccuracy_sensitive /math_library:fast (which changes the default of /check:[no]power), and /tune:host | See description of each option
/assume:noaccuracy_sensitive | Allows the compiler to reorder code based on algebraic identities to improve performance, enabling certain optimizations. The numeric results can be slightly different from the default (accuracy_sensitive) because of the way intermediate results are rounded. This slight difference in numeric results is acceptable to most programs. | See Arithmetic Reordering Optimizations
/assume:buffered_io | Allows records that are otherwise written (flushed) to disk as each record is written (default) to be accumulated in the buffer and written as a unit. Using buffered writes usually makes disk I/O more efficient by writing larger blocks of data to the disk less often. | See Efficient Use of Record Buffers and Disk I/O
/inline:all | Inlines every call that can possibly be inlined while generating correct code. Certain recursive routines are not inlined to prevent infinite loops. | See Controlling the Inlining of Procedures
/inline:speed | Inlines procedures that will improve run-time performance with a likely significant increase in program size. | See Controlling the Inlining of Procedures
/inline:size | Inlines procedures that will improve run-time performance without a significant increase in program size. This type of inlining occurs with optimization level /optimize:4 or /optimize:5. | See Controlling the Inlining of Procedures
/math_library:fast | On ia32 systems, requests that arguments to the math library routines are not checked to improve performance. | See /math_library
/optimize:level | Controls the optimization level and thus the types of optimizations performed. The default optimization level is /optimize:4 (except in the visual development environment for a debug configuration), unless you specify /debug, which changes the default to /optimize:0 (no optimizations). Use /optimize:5 to activate loop transformation optimizations and (on ia64 systems) the software pipelining optimizations. | See Optimization Levels: the /optimize Option
/pipeline (ia64 only) | Activates the software pipelining optimization (a subset of /optimize:5) on ia64 systems. | See /[no]pipeline (ia64 only)
/transform_loops | Activates a group of loop transformation optimizations (a subset of /optimize:5). | See /[no]transform_loops
/tune:keyword | Specifies the target processor generation (chip) architecture on which the program will be run, allowing the optimizer to make decisions about instruction tuning optimizations needed to create the most efficient code. Keywords allow specifying one particular processor generation type, multiple processor generation types, or the processor generation type currently in use during compilation. Regardless of the setting of /tune keyword, the generated code compiled on ia32 systems will run correctly on all implementations of the ia32 architecture. | See Requesting Optimized Code for a Specific Processor Generation
/unroll:num | Specifies the number of times a loop is unrolled (num) when specified with optimization level /optimize:3 or higher. If you omit /unroll: num, the optimizer determines how many times loops are unrolled. Primarily on ia32 systems, increasing the default unroll limit may improve run-time performance for certain applications. | See Loop Unrolling

The following table lists options that can slow program performance on ia32 and ia64 systems. Some applications that require floating-point exception handling might need to use a different /fpe:n option. Other applications might need to use the /assume:dummy_aliases or /vms options for compatibility reasons. Other options listed in the table are primarily for troubleshooting or debugging purposes.

Options that Slow Run-Time Performance

Option Names | Description | For More Information
/assume:dummy_aliases | Forces the compiler to assume that dummy (formal) arguments to procedures share memory locations with other dummy arguments or with variables shared through use association, host association, or common block use. These program semantics slow performance, so you should specify /assume: dummy_aliases only for the called subprograms that depend on such aliases. The use of dummy aliases violates the FORTRAN 77 and Fortran 90 standards but occurs in some older programs. | See Dummy Aliasing Assumption
/compile_only | If you use /compile_only when compiling multiple source files, also specify /object:file to compile many source files together into one object file. Separate compilations prevent certain interprocedural optimizations, the same as using multiple DF commands or using /compile_only without the /object:file option. | See Compile With Appropriate Options and Multiple Source Files
/check:bounds | Generates extra code for array bounds checking at run time. | See /check
/check:overflow | Generates extra code to check integer calculations for arithmetic overflow at run time. Once the program is debugged, you may want to omit this option to reduce executable program size and slightly improve run-time performance. | See /check
/fpe:n values | On ia32 systems, /fpe:3 provides the best performance. Using /fpe:0 slows program execution. On ia64 systems, using /fpe:0 provides the best performance. Using /fpe:3 slows program execution. | See /fpe
/debug:full, /debug, or equivalent | Generates extra symbol table information in the object file. Specifying /debug also reduces the default level of optimization to /optimize:0. | See /debug
/inline: none /inline: manual | Prevents the inlining of all procedures (except statement functions). | See Controlling the Inlining of Procedures
/optimize:0, /optimize:1, /optimize:2, or /optimize:3 | Reduces the optimization level (and types of optimizations). Use during the early stages of program development or when you will use the debugger. | See /[no]optimize and Optimization Levels: the /optimize Option
/vms | Controls certain VMS-related run-time defaults, including alignment. If you specify the /vms option, you may need to also specify the /align:records option to obtain optimal run-time performance. | See /[no]vms

For more information:

  • On compiling multiple files, see Compiling and Linking for Optimization.


Analyze Program Performance

This section describes how you can analyze program performance using timings and profiling tools.

Along with profiling, you can consider generating a listing file with annotations of optimizations, by specifying the /list and /annotations:keyword options (Listing category in the Project Settings dialog box).

Before you analyze program performance, make sure any errors you might have encountered during the early stages of program development have been corrected. Only profile code that is stable and has been debugged.

The following topics are covered:

  • Timing Your Application
  • Profiling and Performance Tools


Timing Your Application

The following considerations apply to timing your application:

  • Run program timings when other users are not active. Your timing results can be affected by one or more CPU-intensive processes also running while doing your timings.
  • Try to run the program under the same conditions each time to provide the most accurate results, especially when comparing execution times of a previous version of the same program. Use the same system (processor model, amount of memory, version of the operating system, and so on) if possible.
  • If you do need to change systems, you should measure the time using the same version of the program on both systems, so you know each system's effect on your timings.
  • For programs that run for less than a few seconds, run several timings to ensure that the results are not misleading. Certain overhead functions like loading DLLs might influence short timings considerably.
  • If your program displays a lot of text, consider redirecting the output from the program. Redirecting output from the program will change the times reported because of reduced screen I/O.

Methods of Timing Your Application

To perform application timings, use a version of the TIME command in a .BAT file (or the function timing profiling option). You might consider modifying the program to call routines within the program to measure execution time (possibly using conditionally compiled lines). For example:

  • Compaq Fortran intrinsic procedures, such as CPU_TIME, SYSTEM_CLOCK, DATE_AND_TIME, and TIME.
  • Library routines, such as ETIME or TIME.

Visual Fortran programs created in a Windows 98, Windows Me, or Windows 95 development environment can be run and analyzed on Windows NT 4 or Windows 2000 systems. Whenever possible, perform detailed performance analysis on a system that closely resembles the system(s) that will used for actual application use.

Sample Command Procedure that Uses TIME and Performance Monitor

The following example shows a .BAT command procedure that uses the TIME command and the Performance Monitor (perfmon) tool available on Windows NT 4 and Windows 2000 systems. The kill command that stops the perfmon tool is included on the Windows NT Resource kit; if the kill tool is not available on your system, manually end the perfmon task by using the task manager.

This .BAT procedure assumes that the program to be timed is myprog.exe.

Before using this batch file, start the performance monitor to setup logging of the statistics that you are interested in:

  1. At the DOS prompt type: Perfmon
  2. In the View menu, select Log
  3. In the Edit menu, select Add to Log and select some statistics
  4. In the Options menu, select Log. In the dialog box:
    • Name the log file. The following .BAT procedure assumes that you have named the logfile myprog.log.
    • Consider adjusting the Log Interval.
    • As the last step, be sure to select "Start Log".
  5. In the File menu, select Save Workspace to save the setup information. The following .BAT procedure assumes you have saved the workspace as my_perfmon_setup.pmw.

The command procedure follows:

  echo off
  rem  Sample batch file to record performance statistics for later analysis.
  rem  This .bat file assumes that you have the utility "kill" available, which
  rem  is distributed with the NT resource kit.

  rem Delete previous logs, then start up the Performance Monitor.
  rem We use start so that control returns instantly to this batch file.
  del myprog.log
  start perfmon my_perfmon_setup.pmw

  rem print the time we started
  time <nul | findstr current

  rem start the program we are interested in, this time using
  rem cmd /c so that the batch file waits for the program to finish.
  echo on
  cmd /c myprog.exe
  echo off

  rem print the time we stopped
  time <nul | findstr current

  rem all done logging statistics
  kill perfmon
  rem if kill is not available, end the perfmon task manually

After the run, analyze your data by using Performance Monitor:

  1. If it is not currently running, start Performance Monitor.
  2. In the View menu, select Chart.
  3. In the Options menu, select Data From and specify the name of the logfile.
  4. In the Edit menu, select Add To Chart to display the counters.

For more information:

  • About the optimizations that improve application performance without source code modification, see Compile With Appropriate Options and Multiple Source Files.
  • About profiling your application, see Profiling and Performance Tools.


Profiling and Performance Tools

To generate profiling information, you use the compiler, linker, and the profiler from either the visual development environment or the command line.

Select those parts of your application that make the most sense to profile. For example, routines that perform user interaction may not be worth profiling. Consider profiling routines that perform a series of complex calculations or call multiple user-written subprograms.

Profiling identifies areas of code where significant program execution time is spent. It can also show areas of code that are not executed. Visual Fortran programs created in a Windows ia32 development environment can be run and analyzed on a Windows NT 4, Windows 2000, Windows 98, Windows Me, or Windows 95 system. Whenever possible, perform detailed performance analysis on a system that closely resembles the system(s) that will be used to run the actual application.

For detailed information about profiling from the command line, see Profiling Code from the Command Line.

There are two main types of profiling: function profiling and line profiling.

Function Profiling

Function profiling helps you locate areas of inefficient code. It can show:

  • The time spent in functions and the number of times a function was called (function timing).
  • Only the number of times a function was called (function counting).
  • A list of functions executed or not executed (function coverage).
  • Information about the stack when each function is called (function attribution).

Function profiling does not require debug information (it obtains addresses from a .MAP file). Since function profiling (except function attribution) uses the stack, routines that modify the stack cannot be profiled. Exclude object files for routines that modify the stack.

To perform function profiling:

  1. In the Project menu, select Settings.
  2. Click the Link tab.
  3. In the General category, click the Enable profiling checkbox (this turns off incremental linking).
  4. In the General category, click the Generate mapfile checkbox.
  5. Click OK to accept the current project settings.
  6. Build your application.
  7. After building your application, profile your project.

Line Profiling

Line profiling collects more information than function profiling. It shows how many times a line is executed and whether certain lines are not executed. Line profiling requires debug information.

To perform line profiling:

  1. In the Project menu, select Settings.
  2. Click the Link tab.
  3. In the General category, click the Enable profiling checkbox (this turns off incremental linking).
  4. In the General category, click the Generate debug information checkbox.
  5. Click on the Fortran tab.
  6. In the category drop-down list, select Debug.
  7. In the Debugging level drop-down list, select Full.
  8. In the Debugging level drop-down list, click the Use Program Database for Debug Information checkbox.
  9. Click OK to accept the current project settings.
  10. Build your application
  11. After building your application, profile your project.

Performance Tools

Tools that you can use to analyze performance include:

  • Process Viewer (Pview) lets you view process and thread characteristics.
  • Spy++ provides a graphical view of system use.
  • On Windows NT or Windows 2000 systems, the Windows Performance Monitor can help identify performance bottlenecks.
  • Other performance tools are available in the Microsoft Win32 SDK (see the online Platform SDK Tools Guide, Tuning section in HTML Help Viewer).

You can also purchase separate products to perform performance analysis and profiling.

Efficient Source Code

Once you have determined those sections of code where most of the program execution time is spent, examine these sections for coding efficiency. Suggested guidelines for improving source code efficiency are provided in the following sections:

  • Data Alignment Considerations
  • Use Arrays Efficiently
  • Improve Overall I/O Performance
  • Additional Source Code Guidelines for Run-Time Efficiency

For information about timing your application and for an example command procedure that uses the Windows NT Performance Monitor, see Timing Your Application.


Data Alignment Considerations

For optimal performance with most cases, make sure your data is aligned naturally. If you must use 1- or 2-byte integer or logical data, in some cases specifying 4- or 8-byte alignment provides better performance (see Ordering Data Declarations to Avoid Unaligned Data).

A natural boundary is a memory address that is a multiple of the data item's size (data type sizes are described in Data Representation ). For example, a REAL (KIND=8) data item aligned on natural boundaries has an address that is a multiple of 8. An array is aligned on natural boundaries if all of its elements are so aligned.

All data items whose starting address is on a natural boundary are naturally aligned. Data not aligned on a natural boundary is called unaligned data.

Although the Visual Fortran compiler naturally aligns individual data items when it can, certain Compaq Fortran statements (such as EQUIVALENCE) can cause data items to become unaligned (see Causes of Unaligned Data and Ensuring Natural Alignment).

Although you can use the DF command /align: keyword options to ensure naturally aligned data, you should check and consider reordering data declarations of data items within common blocks and structures. Within each common block, derived type, or record structure, carefully specify the order and sizes of data declarations to ensure naturally aligned data. Start with the largest size numeric items first, followed by smaller size numeric items, and then nonnumeric (character) data.

The following sections discuss data alignment considerations in more detail:

  • Causes of Unaligned Data and Ensuring Natural Alignment
  • Checking for Inefficient Unaligned Data
  • Ordering Data Declarations to Avoid Unaligned Data
  • Options Controlling Alignment


Causes of Unaligned Data and Ensuring Natural Alignment

Common blocks (COMMON statement), derived-type data, and Compaq Fortran record structures (RECORD statement) usually contain multiple items within the context of the larger structure.

The following declarations can force data to be unaligned:

  • Common blocks (COMMON statement)

    The order of variables in the COMMON statement determines their storage order.

    Unless you are sure that the data items in the common block will be naturally aligned, specify either the /align:commons or /align:dcommons option, depending on the largest data size used.

    For examples and more information, see Arranging Data in Common Blocks.

  • Derived-type (user-defined) data

    Derived-type data members are declared after a TYPE statement.

    If your data includes derived-type data structures, unless you are sure that the data items in derived-type data structures will be naturally aligned, use the /align:records option (default).

    If you omit the SEQUENCE statement, the /align:records option ensures all data items are naturally aligned.

    If you specify the SEQUENCE statement, the /align:records option is prevented from adding necessary padding to avoid unaligned data (data items are packed) unless you also specify the /align:sequence option. When you use SEQUENCE, you should specify a data declaration order such that all data items are naturally aligned or specify /align:sequence.

    For an example and more information, see Arranging Data Items in Derived-Type Data.

  • Compaq Fortran record structures (RECORD and STRUCTURE statements)

    Compaq Fortran record structures usually contain multiple data items. The order of variables in the STRUCTURE statement determines their storage order. The RECORD statement names the record structure.

    If your data includes Compaq Fortran record structures, you should use the /align:records option (default), unless you are sure that the data items in derived-type data and Compaq Fortran record structures will be naturally aligned.

    For examples and more information, see Arranging Data Items in Compaq Fortran Record Structures.

  • Equivalenced data

    EQUIVALENCE statements can force unaligned data or cause data to span natural boundaries.

To avoid unaligned data in a common block, derived-type data, or record structures, use one or both of the following:

  • For new programs or for programs where the source code declarations can be modified easily, plan the order of data declarations with care. For example, you should order variables in a COMMON statement such that numeric data is arranged from largest to smallest, followed by any character data (see the data declaration rules in Ordering Data Declarations to Avoid Unaligned Data). Consider using explicit-length declarations, such as INTEGER(KIND=8) instead of INTEGER, which uses default kind. This prevents command-line options like /real_size and /integer_size from changing the length of INTEGER, LOGICAL, REAL, and COMPLEX declarations, which may change alignment.
  • For existing programs where source code changes are not easily done or for array elements containing derived-type or record structures, you can use command line options to request that the compiler align numeric data by adding padding spaces where needed.

Other possible causes of unaligned data include unaligned actual arguments and arrays that contain a derived-type structure or Compaq Fortran record structure.

When actual arguments from outside the program unit are not naturally aligned, unaligned data access will occur. Compaq Fortran assumes all passed arguments are naturally aligned and has no information at compile time about data that will be introduced by actual arguments during program execution.

For arrays where each array element contains a derived-type structure or Compaq Fortran record structure, the size of the array elements may cause some elements (but not the first) to start on an unaligned boundary.

Even if the data items are naturally aligned within a derived-type structure without the SEQUENCE statement or a record structures, the size of an array element might require use of /align options to supply needed padding to avoid some array elements being unaligned.

If you specify /align:norecords, no padding bytes are added between array elements. If array elements each contain a derived-type structure with the SEQUENCE statement, array elements are packed without padding bytes regardless of the DF command options specified. In this case, some elements will be unaligned.

When /align:records option is in effect, the number of padding bytes added by the compiler for each array element is dependent on the size of the largest data item within the structure. The compiler determines the size of the array elements as an exact multiple of the largest data item in the derived-type structure without the SEQUENCE statement or a record structure. The compiler then adds the appropriate number of padding bytes.

For instance, if a structure contains an 8-byte floating-point number followed by a 3-byte character variable, each element contains five bytes of padding (16 is an exact multiple of 8). However, if the structure contains one 4-byte floating-point number, one 4-byte integer, followed by a 3-byte character variable, each element would contain one byte of padding (12 is an exact multiple of 4).

For more information:

On the /align options, see Options Controlling Alignment.


Checking for Inefficient Unaligned Data

During compilation, the Visual Fortran compiler naturally aligns as much data as possible. Exceptions that can result in unaligned data are described in Causes of Unaligned Data and Ensuring Natural Alignment.

Because unaligned data can slow run-time performance, it is worthwhile to:

  • Double-check data declarations within common block, derived-type data, or record structures to ensure all data items are naturally aligned (see the data declaration rules in Ordering Data Declarations to Avoid Unaligned Data). Using modules to contain data declarations can ensure consistent alignment and use of such data.
  • Avoid the EQUIVALENCE statement or use it in a manner that cannot cause unaligned data or data spanning natural boundaries.
  • Ensure that passed arguments from outside the program unit are naturally aligned.
  • Check that the size of array elements containing at least one derived-type data or record structure cause array elements to start on aligned boundaries (see Causes of Unaligned Data and Ensuring Natural Alignment).

During compilation, warning messages are issued for any data items that are known to be unaligned (unless you specify the /warn:noalignments option).


Ordering Data Declarations to Avoid Unaligned Data

For new programs or when the source declarations of an existing program can be easily modified, plan the order of your data declarations carefully to ensure the data items in a common block, derived-type data, record structure, or data items made equivalent by an EQUIVALENCE statement will be naturally aligned.

Use the following rules to prevent unaligned data:

  • Always define the largest size numeric data items first.
  • If your data includes a mixture of character and numeric data, place the numeric data first.
  • Add small data items of the correct size (or padding) before otherwise unaligned data to ensure natural alignment for the data that follows.

When declaring data, consider using explicit length declarations, such as specifying a KIND parameter. For example, specify INTEGER(KIND=4) (or INTEGER(4)) rather than INTEGER. If you do use a default length (such as INTEGER, LOGICAL, COMPLEX, and REAL), be aware that the compiler options /integer_size:num and /real_size:num can change the size of an individual field's data declaration size and thus can alter the data alignment of a carefully-planned order of data declarations.

Using the suggested data declaration guidelines minimizes the need to use the /align options to add padding bytes to ensure naturally aligned data. In cases where the /align options are still needed, using the suggested data declaration guidelines can minimize the number of padding bytes added by the compiler:

  • Arranging Data Items in Common Blocks
  • Arranging Data Items in Derived-Type Data
  • Arranging Data Items in Compaq Fortran Record Structures


Arranging Data Items in Common Blocks

The order of data items in a COMMON statement determine the order in which the data items are stored. Consider the following declaration of a common block named X:

  LOGICAL (KIND=2) FLAG
  INTEGER          IARRY_I(3)
  CHARACTER(LEN=5) NAME_CH
  COMMON /X/ FLAG, IARRY_I(3), NAME_CH

As shown in the following figure, if you omit the alignment compiler options, the common block will contain unaligned data items beginning at the first array element of IARRY_I.

Common Block with Unaligned Data

As shown in the following figure, if you compile the program units that use the common block with the /align:commons options, data items will be naturally aligned.

Common Block with Naturally Aligned Data

Because the common block X contains data items whose size is 32 bits or smaller, specify /align:commons. If the common block contains data items whose size might be larger than 32 bits (such as REAL (KIND=8) data), use /align:dcommons.

If you can easily modify the source files that use the common block data, define the numeric variables in the COMMON statement in descending order of size and place the character variable last to provide more portability and ensure natural alignment without padding or the DF command options /align:commons or /align:dcommons:

  LOGICAL (KIND=2) FLAG
  INTEGER          IARRY_I(3)
  CHARACTER(LEN=5) NAME_CH
  COMMON /X/ IARRY_I(3), FLAG, NAME_CH

As shown in the following figure, if you arrange the order of variables from largest to smallest size and place character data last, the data items will be naturally aligned.

Common Block with Naturally Aligned Reordered Data

When modifying or creating all source files that use common block data, consider placing the common block data declarations in a module so the declarations are consistent. If the common block is not needed for compatibility (such as file storage or Compaq Fortran 77 use), you can place the data declarations in a module without using a common block.


Arranging Data Items in Derived-Type Data

Like common blocks, derived-type data may contain multiple data items (members).

Data item components within derived-type data will be naturally aligned on up to 64-bit boundaries, with certain exceptions related to the use of the SEQUENCE statement and DF options.

Compaq Visual Fortran stores a derived data type as a linear sequence of values, as follows:

  • If you specify the SEQUENCE statement, the first data item is in the first storage location and the last data item is in the last storage location. The data items appear in the order in which they are declared. If you omit the /align:sequence option, data declarations must be carefully specified to naturally align data.
  • If you omit the SEQUENCE statement, Compaq Fortran adds the padding bytes needed to naturally align data item components, unless you specify the /align:norecords option.

Consider the following declaration of array CATALOG_SPRING of derived-type PART_DT:

  MODULE DATA_DEFS
    TYPE PART_DT
      INTEGER           IDENTIFIER
      REAL              WEIGHT
      CHARACTER(LEN=15) DESCRIPTION
    END TYPE PART_DT
    TYPE (PART_DT) CATALOG_SPRING(30)
    .
    .
    .
  END MODULE DATA_DEFS

As shown in the following figure, the largest numeric data items are defined first and the character data type is defined last. There are no padding characters between data items and all items are naturally aligned. The trailing padding byte is needed because CATALOG_SPRING is an array; it is inserted by the compiler when the /align:records option is in effect.

Derived-Type Naturally Aligned Data (in CATALOG_SPRING())


Arranging Data Items in Compaq Fortran Record Structures

Record structures are a Compaq language extension to the FORTRAN 77, Fortran 90, and Fortran 95 Standards. Record structures use the RECORD statement and optionally the STRUCTURE statement, which are also Compaq Fortran language extensions. The order of data items in a STRUCTURE statement determine the order in which the data items are stored.

Compaq Fortran stores a record in memory as a linear sequence of values, with the record's first element in the first storage location and its last element in the last storage location. Unless you specify /align:norecords, padding bytes are added if needed to ensure data fields are naturally aligned.

The following example contains a structure declaration, a RECORD statement, and diagrams of the resulting records as they are stored in memory:

  STRUCTURE /STRA/
    CHARACTER*1 CHR
    INTEGER*4 INT
  END STRUCTURE
    .
    .
    .
  RECORD /STRA/ REC

The following figure shows the memory diagram of record REC for naturally aligned records.

Memory Diagram of REC for Naturally Aligned Records


Options Controlling Alignment

The following options control whether the Visual Fortran compiler adds padding (when needed) to naturally align multiple data items in common blocks, derived-type data, and Compaq Fortran record structures:

  • The /align:commons option

    Requests that data in common blocks be aligned on up to 4-byte boundaries, by adding padding bytes as needed. Unless you specify /fast, the default is /align:nocommons or arbitrary byte alignment of common block data. In this case, unaligned data can occur unless the order of data items specified in the COMMON statement places the largest numeric data item first, followed by the next largest numeric data (and so on), followed by any character data.

  • The /align:dcommons option

    Requests that data in common blocks be aligned on up to 8-byte boundaries, by adding padding bytes as needed. Unless you specify /fast, the default is /align:nocommons or arbitrary byte alignment of data items in a common data.

    Specify the /align:dcommons option for applications that use common blocks, unless your application has no unaligned data or, if the application might have unaligned data, all data items are four bytes or larger. For applications that use common blocks where all data items are four bytes or smaller, you can specify /align:commons instead of /align:dcommons.

  • The /align:norecords option

    Requests that multiple data items in derived-type data and record structures (a Compaq Fortran extension) be aligned arbitrarily on byte boundaries instead of being naturally aligned. The default is /align:records.

  • The /align:records option

    Requests that multiple data items in record structures and derived-type data without the SEQUENCE statement be naturally aligned, by adding padding bytes as needed. The default is /align:records.

  • The /align:sequence option

    Controls alignment of derived types with the SEQUENCE statement. Specifying the /align:sequence option means that derived types with the SEQUENCE statement obey whatever alignment rules are currently in use. Consequently, since /align:records is a default value, then /align:sequence alone on the command line will cause the fields in these derived types to be naturally aligned. Specifying /fast implies /align:sequence.

  • The /align:nosequence option

    Controls alignment of derived types with the SEQUENCE statement. The default /align:nosequence option means that derived types with the SEQUENCE statement are packed regardless of any other alignment rules.

The default behavior is that multiple data items in derived-type data and record structures will be naturally aligned; data items in common blocks will not be naturally aligned (/align:records) with /align:nocommons. In derived-type data, using the SEQUENCE statement without specifying /align:sequence prevents /align:records from adding needed padding bytes to naturally align data items.


Use Arrays Efficiently

The way arrays are accessed and passed as arguments can have a significant impact on run-time performance, especially when using large arrays. This section discusses the following topics:

  • Accessing Arrays Efficiently
  • Passing Array Arguments Efficiently


Accessing Arrays Efficiently

Many of the array access efficiency techniques described in this section are applied automatically by the Visual Fortran loop transformation optimizations (set at /optimization:5).

Several aspects of array access can improve run-time performance:

  • The fastest array access occurs when contiguous access to the whole array or most of an array occurs. Perform one or a few array operations that access all of the array or major parts of an array rather than numerous operations on scattered array elements.

    Rather than use explicit loops for array access, use elemental array operations, such as the following line that increments all elements of array variable A:

      A = A + 1.

    When reading or writing an array, use the array name and not a DO loop or an implied DO-loop that specifies each element number. Fortran 90 array syntax allows you to reference a whole array by using its name in an expression. For example:

      REAL ::  A(100,100)
  A = 0.0
  A = A + 1.           ! Increment all elements of A by 1
  .
  .
  .
  WRITE (8) A          ! Fast whole array use

    Similarly, you can use derived-type array structure components, such as:

      TYPE X
    INTEGER A(5)
  END TYPE X
  .
  .
  .
  TYPE (X) Z
  WRITE (8) Z%A     ! Fast array structure component use
  • Make sure multidimensional arrays are referenced using proper array syntax and are traversed in the "natural" ascending order column major for Fortran. With column-major order, the leftmost subscript varies most rapidly with a stride of one. Whole array access uses column-major order.

    Avoid row-major order, as is done by C, where the rightmost subscript varies most rapidly.

    For example, consider the nested DO loops that access a two-dimension array with the J loop as the innermost loop:

      INTEGER  X(3,5), Y(3,5), I, J
  Y = 0
  DO I=1,3                  ! I outer loop varies slowest
    DO J=1,5                ! J inner loop varies fastest
      X (I,J) = Y(I,J) + 1  ! Inefficient row-major storage order
    END DO                  ! (rightmost subscript varies fastest)
  END DO
  .
  .
  .
  END PROGRAM

    Because J varies the fastest and is the second array subscript in the expression X (I,J), the array is accessed in row-major order.

    To make the array accessed in natural column-major order, examine the array algorithm and data being modified.

    Using arrays X and Y, the array can be accessed in natural column-major order by changing the nesting order of the DO loops so the innermost loop variable corresponds to the leftmost array dimension:

      INTEGER  X(3,5), Y(3,5), I, J
  Y = 0

  DO J=1,5                  ! J outer loop varies slowest
    DO I=1,3                ! I inner loop varies fastest
      X (I,J) = Y(I,J) + 1  ! Efficient column-major storage order
    END DO                  ! (leftmost subscript varies fastest)
  END DO
   .
   .
   .
  END PROGRAM

    Fortran whole array access (X= Y + 1) uses efficient column major order. However, if the application requires that J vary the fastest or if you cannot modify the loop order without changing the results, consider modifying the application program to use a rearranged order of array dimensions. Program modifications include rearranging the order of:

    • Dimensions in the declaration of the arrays X(5,3) and Y(5,3)
    • The assignment of X(J,I) and Y(J,I) within the DO loops
    • All other references to arrays X and Y

    In this case, the original DO loop nesting is used where J is the innermost loop:

      INTEGER  X(5,3), Y(5,3), I, J
  Y = 0
  DO I=1,3                  ! I outer loop varies slowest
    DO J=1,5                ! J inner loop varies fastest
      X (J,I) = Y(J,I) + 1  ! Efficient column-major storage order
    END DO                  ! (leftmost subscript varies fastest)
  END DO
  .
  .
  .
  END PROGRAM

    Code written to access multidimensional arrays in row-major order (like C) or random order can often make inefficient use of the CPU memory cache. For more information on using natural storage order during record I/O operations, see Write Array Data in the Natural Storage Order.

  • Use the available Fortran 95/90 array intrinsic procedures rather than creating your own.

    Whenever possible, use Fortran 95/90 array intrinsic procedures instead of creating your own routines to accomplish the same task. Fortran 95/90 array intrinsic procedures are designed for efficient use with the various Visual Fortran run-time components.

    Using the standard-conforming array intrinsics can also make your program more portable.

  • With multidimensional arrays where access to array elements will be noncontiguous, avoid left-most array dimensions that are a power of two (such as 256, 512). At higher levels of optimization (/optimize=3 or higher), the compiler pads certain power-of-two array sizes to minimize possible inefficient use of the cache.

    Because the cache sizes are a power of two, array dimensions that are also a power of two may make inefficient use of cache when array access is noncontiguous.

    One work-around is to increase the dimension to allow some unused elements, making the leftmost dimension larger than actually needed. For example, increasing the leftmost dimension of A from 512 to 520 would make better use of cache:

       REAL A (512,100)
   DO I = 2,511
     DO J = 2,99
       A(I,J)=(A(I+1,J-1) + A(I-1, J+1)) * 0.5
     END DO
   END DO

    In this code, array A has a leftmost dimension of 512, a power of two. The innermost loop accesses the rightmost dimension (row major), causing inefficient access. Increasing the leftmost dimension of A to 520 (REAL A (520,100)) allows the loop to provide better performance, but at the expense of some unused elements.

    Because loop index variables I and J are used in the calculation, changing the nesting order of the DO loops changes the results.

  • To minimize data storage and memory cache misses with arrays, use 32-bit data rather than 64-bit data, unless you require the greater range and precision of double precision floating-point numbers or the numeric range of 8-byte integers.

For more information:

On arrays and their data declaration statements, see Arrays.


Passing Array Arguments Efficiently

In Fortran 95/90, there are two general types of array arguments:

  • Explicit-shape arrays were used with FORTRAN 77. These arrays have a fixed rank and extent that is known at compile time. Other dummy argument (receiving) arrays that are not deferred-shape (such as assumed-size arrays) can be grouped with explicit-shape array arguments in the following discussion.
  • Deferred-shape arrays were introduced with Fortran 90. Types of deferred-shape arrays include array pointers and allocatable arrays. Assumed-shape array arguments generally follow the rules about passing deferred-shape array arguments.

When passing arrays as arguments, either the starting (base) address of the array or the address of an array descriptor is passed:

  • When using explicit-shape (or assumed-size) arrays to receive an array, the starting address of the array is passed.
  • When using deferred-shape or assumed-shape arrays to receive an array, the address of the array descriptor is passed (the compiler creates the array descriptor).

Passing an assumed-shape array or array pointer to an explicit-shape array can slow run-time performance, since the compiler needs to create an array temporary for the entire array. The array temporary is created because the passed array may not be contiguous and the receiving (explicit-shape) array requires a contiguous array. When an array temporary is created, the size of the passed array determines whether the impact on slowing run-time performance is slight or severe.

The following table summarizes what happens with the various combinations of array types. The amount of run-time performance inefficiency depends on the size of the array.

 | Output Argument Array Types
Input Argument Array Types | Explicit-Shape Arrays | Deferred-Shape and Assumed-Shape Arrays
Explicit-Shape Arrays | Very efficient. Does not use an array temporary. Does not pass an array descriptor. Interface block optional. | Efficient. Only allowed for assumed-shape arrays (not deferred-shape arrays). Does not use an array temporary. Passes an array descriptor. Requires an interface block.
Deferred-Shape and Assumed-Shape Arrays | When passing an allocatable array, very efficient. Does not use an array temporary. Does not pass an array descriptor. Interface block optional. When not passing an allocatable array, not efficient. Instead use allocatable arrays whenever possible. Uses an array temporary. Does not pass an array descriptor. Interface block optional. | Efficient. Requires an assumed-shape or array pointer as dummy argument. Does not use an array temporary. Passes an array descriptor. Requires an interface block.


Improve Overall I/O Performance

Improving overall I/O performance can minimize both device I/O and actual CPU time. The techniques listed in this section can greatly improve performance in many applications.

A bottleneck limits the maximum speed of execution by being the slowest process in an executing program. In some programs, I/O is the bottleneck that prevents an improvement in run-time performance. The key to relieving I/O bottlenecks is to reduce the actual amount of CPU and I/O device time involved in I/O. Bottlenecks may be caused by one or more of the following:

  • A dramatic reduction in CPU time without a corresponding improvement in I/O time results in an I/O bottleneck.
  • By such coding practices as:
    • Unnecessary formatting of data and other CPU-intensive processing
    • Unnecessary transfers of intermediate results
    • Inefficient transfers of small amounts of data
    • Application requirements

Improved coding practices can minimize actual device I/O, as well as the actual CPU time.

You can also consider solutions to system-wide problems like minimizing device I/O delays.

The following sections discuss I/O performance considerations in more detail:

  • Use Unformatted Files Instead of Formatted Files
  • Write Whole Arrays or Strings
  • Write Array Data in the Natural Storage Order
  • Use Memory for Intermediate Results
  • Enable Implied-DO Loop Collapsing
  • Use of Variable Format Expressions
  • Efficient Use of Record Buffers and Disk I/O
  • Specify RECL
  • Use the Optimal Record Type


Use Unformatted Files Instead of Formatted Files

Use unformatted files whenever possible. Unformatted I/O of numeric data is more efficient and more precise than formatted I/O. Native unformatted data does not need to be modified when transferred and will take up less space on an external file.

Conversely, when writing data to formatted files, formatted data must be converted to character strings for output, less data can transfer in a single operation, and formatted data may lose precision if read back into binary form.

To write the array A(25,25) in the following statements, S1 is more efficient than S2:

  S1         WRITE (7) A

  S2         WRITE (7,100) A
       100   FORMAT (25(' ',25F5.21))

Although formatted data files are more easily ported to other systems, Visual Fortran can convert unformatted data in several formats (see Converting Unformatted Numeric Data).


Write Whole Arrays or Strings

The general guidelines about array use discussed in Use Arrays Efficiently also apply to reading or writing an array with an I/O statement.

To eliminate unnecessary overhead, write whole arrays or strings at one time rather than individual elements at multiple times. Each item in an I/O list generates its own calling sequence. This processing overhead becomes most significant in implied-DO loops. When accessing whole arrays, use the array name (Fortran 95/90 array syntax) instead of using implied-DO loops.


Write Array Data in the Natural Storage Order

Use the natural ascending storage order whenever possible. This is column-major order, with the leftmost subscript varying fastest and striding by 1 (see Use Arrays Efficiently). If a program must read or write data in any other order, efficient block moves are inhibited.

If the whole array is not being written, natural storage order is the best order possible.

If you must use an unnatural storage order, in certain cases it might be more efficient to transfer the data to memory and reorder the data before performing the I/O operation.


Use Memory for Intermediate Results

Performance can improve by storing intermediate results in memory rather than storing them in a file on a peripheral device. One situation that may not benefit from using intermediate storage is when there is a disproportionately large amount of data in relation to physical memory on your system. Excessive page faults can dramatically impede virtual memory performance.


Enable Implied-DO Loop Collapsing

DO loop collapsing reduces a major overhead in I/O processing. Normally, each element in an I/O list generates a separate call to the Compaq Fortran RTL. The processing overhead of these calls can be most significant in implied-DO loops.

Compaq Fortran reduces the number of calls in implied-DO loops by replacing up to seven nested implied-DO loops with a single call to an optimized run-time library I/O routine. The routine can transmit many I/O elements at once.

Loop collapsing can occur in formatted and unformatted I/O, but only if certain conditions are met:

  • The control variable must be an integer. The control variable cannot be a dummy argument or contained in an EQUIVALENCE or VOLATILE statement. Compaq Fortran must be able to determine that the control variable does not change unexpectedly at run time.
  • The format must not contain a variable format expression.

For more information:

  • See the VOLATILE attribute and statement.
  • On loop optimizations, see Optimization Levels: the /optimize:num Option.


Use of Variable Format Expressions

Variable format expressions (a Compaq Fortran extension) is a numeric expression enclosed in angle brackets (< >) that can be used in a FORMAT statement. Variable format expressions (VFEs) are almost as flexible as run-time formatting, but they are more efficient because the compiler can eliminate run-time parsing of the I/O format. Only a small amount of processing and the actual data transfer are required during run time.

On the other hand, run-time formatting can impair performance significantly. For example, in the following statements, S1 is more efficient than S2 because the formatting is done once at compile time, not at run time:

  S1        WRITE (6,400) (A(I), I=1,N)
      400   FORMAT (1X, <N> F5.2)
                         .
                         .
                         .
  S2        WRITE (CHFMT,500) '(1X,',N,'F5.2)'
      500   FORMAT (A,I3,A)
            WRITE (6,FMT=CHFMT) (A(I), I=1,N)


Efficient Use of Record Buffers and Disk I/O

Records being read or written are transferred between the user's program buffers and one or more disk block I/O buffers, which are established when the file is opened by the Compaq Fortran run-time system. Unless very large records are being read or written, multiple logical records can reside in the disk block I/O buffer when it is written to disk or read from disk, minimizing physical disk I/O.

You can specify the size of the disk block I/O buffer by using the OPEN Statement BLOCKSIZE specifier. If you omit the BLOCKSIZE specifier in the OPEN statement, it is set for optimal I/O use with the type of device the file resides on.

The default for BUFFERCOUNT is 1. Any experiments to improve I/O performance should increase the BUFFERCOUNT value and not the BLOCKSIZE value, to increase the amount of data read by each disk I/O.

If the OPEN statement includes the BUFFERCOUNT and BLOCKSIZE specifiers, their product is the size in bytes of the internal buffer. If these are not specified, the default size is 1024 bytes if /fpscomp:general (or /fpscomp:all) was specified and 8192 bytes if it was omitted. This internal buffer will grow to hold the largest single record but will never shrink.

For disk writes, the OPEN statement BUFFERED specifier, the /assume:buffered_io option, or the FORT_BUFFERED run-time environment variable lets you control whether records written are written (flushed) to disk as each record is written (default) or accumulated in the buffer.

Unless you set the FORT_BUFFERED environment variable to TRUE, the default is BUFFERED='NO' and /assume:nobuffered_io for all I/O, in which case, the Fortran run-time system empties its internal buffer for each WRITE (or similar record output statement).

If you specify BUFFERED='YES', specify /assume:buffered_io, or at run-time set the FORT_BUFFERED environment variable to TRUE, for disk devices the internal buffer will be filled, possibly by many record output statements (WRITE), before it is written to disk.

The OPEN statement BUFFERED specifier takes precedence over the /assume:[no]buffered_io option. If neither are set (default), the FORT_BUFFERED environment variable is tested at run-time.

The OPEN statement BUFFERED specifier applies to a specific logical unit. In contrast, the /assume:[no]buffered_io option and the FORT_BUFFERED environment variable apply to all Fortran units.

Using buffered writes usually makes disk I/O more efficient by writing larger blocks of data to the disk less often. However, a system failure when using buffered writes can cause records to be lost, since they might not yet have been written to disk (such records would have written to disk with the default unbuffered writes).


Specify RECL

The sum of the record length (RECL specifier in an OPEN statement) and its overhead is a multiple or divisor of the blocksize, which is device specific. For example, if the BLOCKSIZE is 8192 then RECL might be 24576 (a multiple of 3) or 1024 (a divisor of 8).

The RECL value should fill blocks as close to capacity as possible (but not over capacity). Such values allow efficient moves, with each operation moving as much data as possible; the least amount of space in the block is wasted. Avoid using values larger than the block capacity, because they create very inefficient moves for the excess data only slightly filling a block (allocating extra memory for the buffer and writing partial blocks are inefficient).

The RECL value unit for formatted files is always 1-byte units. For unformatted files, the RECL unit is 4-byte units, unless you specify the /assume:byterecl option to request 1-byte units.

When porting unformatted data files from non-Compaq systems, see Converting Unformatted Numeric Data.


Use the Optimal Record Type

Unless a certain record type is needed for portability reasons, choose the most efficient type, as follows:

  • For sequential files of a consistent record size, the fixed-length record type gives the best performance.
  • For sequential unformatted files when records are not fixed in size, the variable-length record type gives the best performance, particularly for BACKSPACE operations.
  • For sequential formatted files when records are not fixed in size, the Stream_LF record type gives the best performance.

For more information:

  • On OPEN statement specifiers and defaults, see OPEN Statement and OPEN.
  • On Visual Fortran data files, see Devices and Files.


Additional Source Code Guidelines for Run-Time Efficiency

In addition to data alignment and the efficient use of arrays and I/O, other source coding guidelines can be implemented to improve run-time performance.

The amount of improvement in run-time performance is related to the number of times a statement is executed. For example, improving an arithmetic expression executed within a loop many times has the potential to improve performance, more than improving a similar expression executed once outside a loop.

Suggested guidelines for improving source code efficiency are provided in the following sections:

  • Avoid Small Integer and Small Logical Data Items (ia64 only)
  • Avoid Mixed Data Type Arithmetic Expressions
  • Use Efficient Data Types
  • Avoid Using Slow Arithmetic Operators
  • Avoid EQUIVALENCE Statement Use
  • Use Statement Functions and Internal Subprograms
  • Code DO Loops for Efficiency


Avoid Small Integer and Small Logical Data Items (ia64 only)

To minimize data storage and memory cache misses with arrays, use 32-bit data rather than 64-bit data, unless you require the greater range and precision of double precision floating-point numbers or the numeric range of 8-byte integers.

On ia64 systems, avoid using integer or logical data less than 32 bits (KIND=4). Accessing a 16-bit (KIND=2) or 8-bit (KIND=1) data type can result in a sequence of machine instructions to access the data, rather than a single, efficient machine instruction for a 32-bit data item.


Avoid Mixed Data Type Arithmetic Expressions

Avoid mixing integer and floating-point (REAL) data in the same computation. Expressing all numbers in a floating-point arithmetic expression (assignment statement) as floating-point values eliminates the need to convert data between fixed and floating-point formats. Expressing all numbers in an integer arithmetic expression as integer values also achieves this. This improves run-time performance.

For example, assuming that I and J are both INTEGER variables, expressing a constant number (2.) as an integer value (2) eliminates the need to convert the data:

Original Code: | INTEGER I, J I= J / 2.
Efficient Code: | INTEGER I, J I= J / 2

For applications with numerous floating-point operations, consider using the /assume: accuracy_sensitive option (see Arithmetic Reordering Optimizations) if a small difference in the result is acceptable.

You can use different sizes of the same general data type in an expression with minimal or no effect on run-time performance. For example, using REAL, DOUBLE PRECISION, and COMPLEX floating-point numbers in the same floating-point arithmetic expression has minimal or no effect on run-time performance.


Use Efficient Data Types

In cases where more than one data type can be used for a variable, consider selecting the data types based on the following hierarchy, listed from most to least efficient:

  • On ia32 systems:
    • Integer of four bytes, expressed as INTEGER(4) or INTEGER*4
    • Single-precision real, expressed explicitly as REAL, REAL(KIND=4), or REAL*4
    • Double-precision real, expressed explicitly as DOUBLE PRECISION, REAL(KIND=8), or REAL*8
    • Integer of eight bytes, expressed as INTEGER(8) or INTEGER*8
  • On ia64 systems:
    • Integer of four or eight bytes (also see Avoid Small Integer and Small Logical Data Items (ia64 only))
    • Single-precision real, expressed explicitly as REAL, REAL(KIND=4), or REAL*4
    • Double-precision real, expressed explicitly as DOUBLE PRECISION, REAL(KIND=8), or REAL*8

However, keep in mind that in an arithmetic expression, you should avoid mixing integer and floating-point (REAL) data (see Avoid Mixed Data Type Arithmetic Expressions).


Avoid Using Slow Arithmetic Operators

Before you modify source code to avoid slow arithmetic operators, be aware that optimizations convert many slow arithmetic operators to faster arithmetic operators. For example, the compiler optimizes the expression H=J**2 to be H=J*J.

Consider also whether replacing a slow arithmetic operator with a faster arithmetic operator will change the accuracy of the results or impact the maintainability (readability) of the source code.

Replacing slow arithmetic operators with faster ones should be reserved for critical code areas. The following hierarchy lists the Compaq Fortran arithmetic operators, from fastest to slowest:

  • Addition (+), subtraction (-), and floating-point multiplication (*)
  • Integer multiplication (*)
  • Division (/)
  • Exponentiation (**)


Avoid EQUIVALENCE Statement Use

Avoid using EQUIVALENCE statements; they can:

  • Force unaligned data or cause data to span natural boundaries.
  • Prevent certain optimizations, including:
    • Global data analysis under certain conditions (see Global Optimizations)
    • Implied-DO loop collapsing when the control variable is contained in an EQUIVALENCE statement


Use Statement Functions and Internal Subprograms

Whenever the Visual Fortran compiler has access to the use and definition of a subprogram during compilation, it may choose to inline the subprogram. Using statement functions and internal subprograms maximizes the number of subprogram references that will be inlined, especially when multiple source files are compiled together at optimization level /optimize:4 or /optimize:5 (or an appropriate /inline keyword was specified).

For more information, see Compile With Appropriate Options and Multiple Source Files.


Code DO Loops for Efficiency

Minimize the arithmetic operations and other operations in a DO loop whenever possible. Moving unnecessary operations outside the loop will improve performance (for example, when the intermediate nonvarying values within the loop are not needed).

For more information:

  • On loop optimizations, see Loop Transformations, and Controlling Loop Unrolling, and Software Pipelining (ia64 only).
  • On the DO statement, see DO in the A-Z Summary in the Language Reference


Optimization Levels: the /optimize Option

Visual Fortran performs many optimizations by default. You do not have to recode your program to use them. However, understanding how optimizations work helps you remove any inhibitors to their successful function.

If an operation can be performed, eliminated, or simplified at compile time, Visual Fortran does so, rather than have it done at run time. The time required to compile the program usually increases as more optimizations occur.

The program will likely execute faster when compiled at /optimize:4, but will require more compilation time than if you compile the program at a lower level of optimization.

The size of object files varies with the optimizations requested. Factors that can increase object file size include an increase of loop unrolling or procedure inlining.

The following table lists the levels of Visual Fortran optimization with different /optimize:num options (for example, /optimize:0 specifies no selectable optimizations); some optimizations always occur. All levels of optimizations available on the architecture can be specified using /optimize:5. On ia32 systems, /optimize:5 includes loop transformations; on ia64 systems, /optimize:5 includes loop transformations and software pipelining.

Levels of Optimization with Different /optimize:num Options

Optimization Type | /optimize:0 | /optimize:1 | /optimize:2 | /optimize:3 | /optimize:4 | /optimize:5
Software pipelining |  |  |  |  |  | x (ia64 only)
Loop transformation |  |  |  |  |  | x
Automatic inlining |  |  |  |  | x | x
Additional global optimizations |  |  |  | x | x | x
Global optimizations |  |  | x | x | x | x
Local (minimal) optimizations |  | x | x | x | x | x

The default for the command line and in the visual development environment for a release configuration is /optimize:4. In the visual development environment for a debug configuration, the default is /optimize:0. However, when /debug is specified, the default is /optimize:0 (no optimizations).

In the table, the following terms are used to describe the levels of optimization (described in detail in the following sections:

  • Local (minimal) optimizations (/optimize:1) or higher occur within the source program unit and include recognition of common subexpressions and the expansion of multiplication and division.
  • Global optimizations (/optimize:2) or higher include such optimizations as data-flow analysis, code motion, strength reduction, split-lifetime analysis, and instruction scheduling.
  • Additional global optimizations (/optimize:3) or higher improve speed at the cost of extra code size. These optimizations include loop unrolling, code replication to eliminate branches, and padding certain power-of-two array sizes for more efficient cache use.
  • Automatic inlining (/optimize:4) or higher applies interprocedure analysis and inline expansion of small procedures, usually by using heuristics that limit extra code size.
  • Loop transformation and software pipelining (/optimize:5), include a group of loop transformation optimizations and, on ia64 systems, also include the software pipelining optimization. The loop transformation optimizations apply to array references within loops and can apply to multiple nested loops. Loop transformation optimizations can improve the performance of the memory system.

    On ia64 systems, software pipelining applies instruction scheduling to certain innermost loops, allowing instructions within a loop to "wrap around" and execute in a different iteration of the loop. This can reduce the impact of long-latency operations, resulting in faster loop execution. Software pipelining also enables the prefetching of data to reduce the impact of cache misses.

The following sections discuss I/O performance considerations in more detail:

  • Optimizations Performed at All Optimization Levels
  • Local (Minimal) Optimizations
  • Global Optimizations
  • Additional Global Optimizations
  • Automatic Inlining
  • Loop Transformation and Software Pipelining


Optimizations Performed at All Optimization Levels

The following optimizations occur at any optimization level (/optimize:0 through /optimize:5):

  • Space optimizations

    Space optimizations decrease the size of the object or executing program by eliminating unnecessary use of memory, thereby improving speed of execution and system throughput. Visual Fortran space optimizations are as follows:

    • Constant Pooling

      Only one copy of a given constant value is ever allocated memory space. If that constant value is used in several places in the program, all references point to that value.

    • Dead Code Elimination

      If operations will never execute or if data items will never be used, Visual Fortran eliminates them. Dead code includes unreachable code and code that becomes unused as a result of other optimizations, such as value propagation.

  • Inlining arithmetic statement functions and intrinsic procedures

    Regardless of the optimization level, Visual Fortran inserts arithmetic statement functions directly into a program instead of calling them as functions. This permits other optimizations of the inlined code and eliminates several operations, such as calls and returns or stores and fetches of the actual arguments. For example:

      SUM(A,B) = A+B
     .
     .
     .
  Y = 3.14
  X = SUM(Y,3.0)   ! With value propagation, becomes: X = 6.14

    Many intrinsic procedures are automatically inlined.

    Inlining of other subprograms, such as contained subprograms, occurs at optimization level /optimize:4 or /optimize:5 (or when you specify appropriate /inline keywords at /optimize:1 or higher).

  • Implied-DO loop collapsing

    DO loop collapsing reduces a major overhead in I/O processing. Normally, each element in an I/O list generates a separate call to the Visual Fortran RTL. The processing overhead of these calls can be most significant in implied-DO loops.

    If Visual Fortran can determine that the format will not change during program execution, it replaces the series of calls in up to seven nested implied-DO loops with a single call to an optimized RTL routine (see Enable Implied-Do Loop Collapsing). The optimized RTL routine can transfer many elements in one operation.

    Visual Fortran collapses implied-DO loops in formatted and unformatted I/O operations, but it is more important with unformatted I/O, where the cost of transmitting the elements is a higher fraction of the total cost.

  • Array temporary elimination and FORALL statements

    Certain array store operations are optimized. For example, to minimize the creation of array temporaries, Visual Fortran can detect when no overlap occurs between the two sides of an array assignment. This type of optimization occurs for some assignment statements in FORALL constructs.

    Certain array operations are also candidates for loop unrolling optimizations (see Loop Unrolling).


Local (Minimal) Optimizations

To enable local optimizations, use /optimize:1 or a higher optimization level /optimize:2, /optimize:3, /optimize:4, or /optimize:5.

To prevent local optimizations, specify the /optimize:0 option.

The following sections discuss the local optimizations:

  • Common Subexpression Elimination
  • Integer Multiplication and Division Expansion
  • Compile-Time Operations
  • Value Propagation
  • Dead Store Elimination
  • Register Usage
  • Mixed Real/Complex Operations


Common Subexpression Elimination

If the same subexpressions appear in more than one computation and the values do not change between computations, Visual Fortran computes the result once and replaces the subexpressions with the result itself:

  DIMENSION A(25,25), B(25,25)
  A(I,J) = B(I,J)

Without optimization, these statements can be coded as follows:

  t1 = ((J-1)*25+(I-1))*4
  t2 = ((J-1)*25+(I-1))*4
  A(t1) = B(t2)

Variables t1 and t2 represent equivalent expressions. Visual Fortran eliminates this redundancy by producing the following:

  t = ((J-1)*25+(I-1))*4
  A(t) = B(t)


Integer Multiplication and Division Expansion

Expansion of multiplication and division refers to bit shifts that allow faster multiplication and division while producing the same result. For example, the integer expression (I*17) can be calculated as I with a 4-bit shift plus the original value of I. This can be expressed using the Compaq Fortran ISHFT intrinsic function:

  J1 = I*17
  J2 = ISHFT(I,4) + I     ! equivalent expression for I*17

The optimizer uses machine code that, like the ISHFT intrinsic function, shifts bits to expand multiplication and division by literals.


Compile-Time Operations

Visual Fortran does as many operations as possible at compile time rather than having them done at run time.

Constant Operations

Visual Fortran can perform many operations on constants (including PARAMETER constants):

  • Constants preceded by a unary minus sign are negated.
  • Expressions involving +, -, *, or / operators are evaluated; for example:
      PARAMETER (NN=27)
  I = 2*NN+J           ! Becomes: I = 54 + J

    Evaluation of some constant functions and operators is performed at compile time. This includes certain functions of constants, concatenation of string constants, and logical and relational operations involving constants.

  • Lower-ranked constants are converted to the data type of the higher-ranked operand:
      REAL X, Y
  X = 10 * Y          ! Becomes: X = 10.0 * Y
  • Array address calculations involving constant subscripts are simplified at compile time whenever possible:
      INTEGER I(10,10)
  I(1,2) = I(4,5)     ! Compiled as a direct load and store

Algebraic Reassociation Optimizations

Visual Fortran delays operations to see whether they have no effect or can be transformed to have no effect. If they have no effect, these operations are removed. A typical example involves unary minus and .NOT. operations:

  X = -Y * -Z           ! Becomes: Y * Z


Value Propagation

Visual Fortran tracks the values assigned to variables and constants, including those from DATA statements, and traces them to every place they are used. Visual Fortran uses the value itself when it is more efficient to do so.

When compiling subprograms, Visual Fortran analyzes the program to ensure that propagation is safe if the subroutine is called more than once.

Value propagation frequently leads to more value propagation. Visual Fortran can eliminate run-time operations, comparisons and branches, and whole statements.

In the following example, constants are propagated, eliminating multiple operations from run time:

Original Code Optimized Code
    PI = 3.14
    .
    .
    .
    PIOVER2 = PI/2
    .
    .
    .
    I = 100
    .
    .
    .
    IF (I.GT.1) GOTO 10
10  A(I) = 3.0*Q

    .
    .
    .
    PIOVER2 = 1.57
    .
    .
    .
    I = 100
    .
    .
    .

10  A(100) = 3.0*Q


Dead Store Elimination

If a variable is assigned but never used, Visual Fortran eliminates the entire assignment statement:

  X = Y*Z
    .
    .
    .      !If X is not used in between,  X=Y*Z is eliminated.

  X = A(I,J)* PI

Some programs used for performance analysis often contain such unnecessary operations. When you try to measure the performance of such programs compiled with Visual Fortran, these programs may show unrealistically good performance results. Realistic results are possible only with program units using their results in output statements.


Register Usage

A large program usually has more data that would benefit from being held in registers than there are registers to hold the data. In such cases, Visual Fortran typically tries to use the registers according to the following descending priority list:

  1. For temporary operation results, including array indexes
  2. For variables
  3. For addresses of arrays (base address)
  4. All other usages

Visual Fortran uses heuristic algorithms and a modest amount of computation to attempt to determine an effective usage for the registers.

Holding Variables in Registers

Because operations using registers are much faster than using memory, Visual Fortran generates code that uses the integer and floating-point registers instead of memory locations. Knowing when Visual Fortran uses registers may be helpful when doing certain forms of debugging.

Visual Fortran uses registers to hold the values of variables whenever the Fortran language does not require them to be held in memory, such as holding the values of temporary results of subexpressions, even if /optimize:0 (no optimization) was specified.

Visual Fortran may hold the same variable in different registers at different points in the program:

  V = 3.0*Q
    .
    .
    .
  X = SIN(Y)*V
    .
    .
    .
  V = PI*X
    .
    .
    .
  Y = COS(Y)*V

Visual Fortran may choose one register to hold the first use of V and another register to hold the second. Both registers can be used for other purposes at points in between. There may be times when the value of the variable does not exist anywhere in the registers. If the value of V is never needed in memory, it might not ever be assigned.

Visual Fortran uses registers to hold the values of I, J, and K (so long as there are no other optimization effects, such as loops involving the variables):

  A(I) = B(J) + C(K)

More typically, an expression uses the same index variable:

  A(K) = B(K) + C(K)

In this case, K is loaded into only one register, which is used to index all three arrays at the same time.


Mixed Real/Complex Operations

In mixed REAL/COMPLEX operations, Visual Fortran avoids the conversion and performs a simplified operation on:

  • Add (+), subtract (-), and multiply (*) operations if either operand is REAL
  • Divide (/) operations if the divisor is REAL

For example, if variable R is REAL and A and B are COMPLEX, no conversion occurs with the following:

  COMPLEX A, B
    .
    .
    .
  B = A + R


Global Optimizations

To enable global optimizations, use /optimize:2 or a higher optimization level. Using /optimize:2 or higher also enables local optimizations (/optimize:1).

Global optimizations include:

  • Data-flow analysis
  • Split lifetime analysis
  • Strength reduction (replaces a CPU-intensive calculation with one that uses fewer CPU cycles)
  • Code motion (also called code hoisting)
  • Instruction scheduling

Data-flow and split lifetime analysis (global data analysis) traces the values of variables and whole arrays as they are created and used in different parts of a program unit. During this analysis, Visual Fortran assumes that any pair of array references to a given array might access the same memory location, unless constant subscripts are used in both cases.

To eliminate unnecessary recomputations of invariant expressions in loops, Visual Fortran hoists them out of the loops so they execute only once.

Global data analysis includes which data items are selected for analysis. Some data items are analyzed as a group and some are analyzed individually. Visual Fortran limits or may disqualify data items that participate in the following constructs, generally because it cannot fully trace their values.

Data items in the following declarations can make global optimizations less effective:

  • VOLATILE declarations

    VOLATILE declarations are needed to use certain run-time features of the operating system. Declare a variable as VOLATILE if the variable can be accessed using rules in addition to those provided by the Fortran 95/90 language. Examples include:

    • COMMON data items or entire common blocks that can change value by means other than direct assignment or during a routine call. For such applications, you must declare the variable or the COMMON block to which it belongs as volatile.
    • An address not saved by the %LOC built-in function.
    • Variables read or written by a signal handler, including those in a common block or module.

    As requested by the VOLATILE statement, Visual Fortran disqualifies any volatile variables from global data analysis.

  • Subroutine calls or external function references

    Visual Fortran cannot trace data flow in a called routine that is not part of the program unit being compiled, unless the same DF command compiled multiple program units (see Compile With Appropriate Options and Multiple Source Files). Arguments passed to a called routine that are used again in a calling program are assumed to be modified, unless the proper INTENT is specified in an interface block (the compiler must assume they are referenced by the called routine).

  • Common blocks

    Visual Fortran limits optimizations on data items in common blocks. If common block data items are referenced inside called routines, their values might be altered. In the following example, variable I might be altered by FOO, so Visual Fortran cannot predict its value in subsequent references.

      COMMON /X/ I

  DO J=1,N
     I = J
     CALL FOO
     A(I) = I
  ENDDO
  • Variables in Fortran 90 modules

    Visual Fortran limits optimizations on variables in Fortran 90 modules. Like common blocks, if the variables in Fortran 90 modules are referenced inside called routines, their values might be altered.

  • Variables referenced by a %LOC built-in function or variables with the TARGET attribute

    Visual Fortran limits optimizations on variables indirectly referenced by a %LOC function or on variables with the TARGET attribute, because the called routine may dereference a pointer to such a variable.

  • Equivalence groups

    An equivalence group is formed explicitly with the EQUIVALENCE statement or implicitly by the COMMON statement. A program section is a particular common block or local data area for a particular routine. Visual Fortran combines equivalence groups within the same program section and in the same program unit.

    The equivalence groups in separate program sections are analyzed separately, but the data items within each group are not, so some optimizations are limited to the data within each group.


Additional Global Optimizations

To enable additional global optimizations, use /optimize:3 or a higher optimization level. Using /optimize:3 or higher also enables local optimizations (/optimize:1) and global optimizations (/optimize:2).

Additional global optimizations improve speed at the cost of longer compile times and possibly extra code size. These optimizations include:

  • Loop unrolling, including instruction scheduling (see Loop Unrolling)
  • Code replication to eliminate branches (see Code Replication to Eliminate Branches)
  • Padding the size of certain power-of-two arrays to allow more efficient cache use (see Use Arrays Efficiently)


Loop Unrolling

At optimization level /optimize:3 or above, Visual Fortran attempts to unroll certain innermost loops, minimizing the number of branches and grouping more instructions together to allow efficient overlapped instruction execution (instruction pipelining). The best candidates for loop unrolling are innermost loops with limited control flow.

As more loops are unrolled, the average size of basic blocks increases. Loop unrolling generates multiple copies of the code for the loop body (loop code iterations) in a manner that allows efficient instruction pipelining.

The loop body is replicated some number of times, substituting index expressions. An initialization loop might be created to align the first reference with the main series of loops. A remainder loop might be created for leftover work.

The number of times a loop is unrolled can be determined either by the optimizer or by using the /unroll option, which can specify the limit for loop unrolling. Unless the user specifies a value, the optimizer optimizer will choose an unroll amount that minimizes the overhead of prefetching while also limiting code size expansion.

Array operations are often represented as a nested series of loops when expanded into instructions. The innermost loop for the array operation is the best candidate for loop unrolling (like DO loops). For example, the following array operation (once optimized) is represented by nested loops, where the innermost loop is a candidate for loop unrolling:

  A(1:100,2:30) = B(1:100,1:29) * 2.0


Code Replication to Eliminate Branches

In addition to loop unrolling and other optimizations, the number of branches are reduced by replicating code that will eliminate branches. Code replication decreases the number of basic blocks (a stream of instructions entered only at the beginning and exited only at the end) and increases instruction-scheduling opportunities.

Code replication normally occurs when a branch is at the end of a flow of control, such as a routine with multiple, short exit sequences. The code at the exit sequence gets replicated at the various places where a branch to it might occur.

For example, consider the following unoptimized routine and its optimized equivalent that uses code replication, where R0 (EAX on ia32 systems) is register 0:

Unoptimized Instructions Optimized (Replicated) Instructions
      .
      .
      .
      branch to exit1
      .
      .
      .
      branch to exit1
      .
      .
      .
exit1: move 1 into R0
       return

      .
      .
      .
      move 1 into R0
      return
      .
      .
      .
      move 1 into R0
      return
      .
      .
      .
      move 1 into R0
      return

Similarly, code replication can also occur within a loop that contains a small amount of shared code at the bottom of a loop and a case-type dispatch within the loop. The loop-end test-and-branch code might be replicated at the end of each case to create efficient instruction pipelining within the code for each case.


Automatic Inlining

To enable optimizations that perform automatic inlining, use /optimize:4 (or /optimize:5). Using /optimize:4 also enables local optimizations (/optimize:1), global optimizations (/optimize:2), and additional global optimizations (/optimize:3).

To request inlining at lower optimization levels (/optimize:1, /optimize:2, or /optimize:3), use the /inline option.

The default is /optimize:4 (unless /debug is specified), except in the visual development environment for a debug configuration.


Interprocedure Analysis

Compiling multiple source files at optimization level /optimize:4 or higher lets the compiler examine more code for possible optimizations, including multiple program units. This results in:

  • Inlining more procedures
  • More complete global data analysis
  • Reducing the number of external references to be resolved during linking

As more procedures are inlined, the size of the executable program and compile times may increase, but execution time should decrease.


Inlining Procedures

Inlining refers to replacing a subprogram reference (such as a CALL statement or function invocation) with the replicated code of the subprogram. As more procedures are inlined, global optimizations often become more effective.

The optimizer inlines small procedures, limiting inlining candidates based on such criteria as:

  • Estimated size of code
  • Number of call sites
  • Use of constant arguments

You can specify:

  • One of the /optimize options to control the optimization level. For example, specifying /optimize:4 or /optimize:5 enables interprocedure optimizations.

    Different /optimize options set different /inline:keyword options. For example, /optimize:4 sets /inline:speed.

  • One of the /inline options to directly control the inlining of procedures (see Controlling the Inlining of Procedures). For example, /inline:speed inlines more procedures than /inline:size. Certain /inline keywords require /optimize:1 or higher.


Loop Transformation and Software Pipelining

A group of optimizations known as loop transformation optimizations and software pipelining with its associated additional software dependence analysis are enabled by using the /optimize:5 option. In certain cases, this improves run-time performance.

The loop transformation optimizations apply to array references within loops and can apply to multiple nested loops. These optimizations can improve the performance of the memory system.

On ia64 systems, software pipelining applies instruction scheduling to certain innermost loops, allowing instructions within a loop to "wrap around" and execute in a different iteration of the loop. This can reduce the impact of long-latency operations, resulting in faster loop execution.

Software pipelining also enables the prefetching of data to reduce the impact of cache misses.

For more information:

  • On loop transformations, see Loop Transformations.
  • On software pipelining, see Software Pipelining (ia64 only).


Loop Transformations

The loop transformation optimizations are enabled by using the /transform_loops option or the /optimize:5 option. Loop transformation attempts to improve performance by rewriting loops to make better use of the memory system. By rewriting loops, the loop transformation optimizations can increase the number of instructions executed, which can degrade the run-time performance of some programs.

To request loop transformation optimizations without software pipelining, do one of the following:

  • Specify /optimize:5 with /nopipeline.
  • Specify /transform_loops with /optimize:4, /optimize:3, or /optimize:2. This optimization is not performed at optimization levels below /optimize:2.

The loop transformation optimizations apply to array references within loops. These optimizations can improve the performance of the memory system and usually apply to multiple nested loops. The loops chosen for loop transformation optimizations are always counted loops. Counted loops are those loops that use a variable to count iterations in a manner that the number of iterations can be determined before entering the loop. For example, most DO loops are counted loops.

Conditions that typically prevent the loop transformation optimizations from occurring include subprogram references that are not inlined (such as an external function call), complicated exit conditions, and uncounted loops.

The types of optimizations associated with /transform_loops include the following:

  • Loop blocking

    Can minimize memory system use with multidimensional array elements by completing as many operations as possible on array elements currently in the cache. Also known as loop tiling.

  • Loop distribution

    Moves instructions from one loop into separate, new loops. This can reduce the amount of memory used during one loop so that the remaining memory may fit in the cache. It can also create improved opportunities for loop blocking.

  • Loop fusion

    Combines instructions from two or more adjacent loops that use some of the same memory locations into a single loop. This can avoid the need to load those memory locations into the cache multiple times and improves opportunities for instruction scheduling.

  • Loop interchange

    Changes the nesting order of some or all loops. This can minimize the stride of array element access during loop execution and reduce the number of memory accesses needed. Also known as loop permutation.

  • Scalar replacement

    Replaces the use of an array element with a scalar variable under certain conditions.

  • Outer loop unrolling

    Unrolls the outer loop inside the inner loop under certain conditions to minimize the number of instructions and memory accesses needed. This also improves opportunities for instruction scheduling and scalar replacement.

For more information:

On the interaction of compiler options and timing programs compiled with the loop transformation optimizations, see /[no]transform_loops.


Software Pipelining (ia64 only)

Software pipelining and additional software dependence analysis are enabled by using the /pipeline option or by the /optimize:5 option. Software pipelining in certain cases improves run-time performance.

The software pipelining optimization applies instruction scheduling to certain innermost loops, allowing instructions within a loop to "wrap around" and execute in a different iteration of the loop. This can reduce the impact of long-latency operations, resulting in faster loop execution.

Loop unrolling (enabled at /optimize:3 or above) cannot schedule across iterations of a loop. Because software pipelining can schedule across loop iterations, it can perform more efficient scheduling to eliminate instruction stalls within loops.

For instance, if software dependence analysis of data flow reveals that certain calculations can be done before or after that iteration of the loop, software pipelining reschedules those instructions ahead of or behind that loop iteration, at places where their execution can prevent instruction stalls or otherwise improve performance.

Software pipelining also enables the prefetching of data to reduce the impact of cache misses.

Software pipelining can be more effective when you combine /pipeline (or /optimize:5) with the appropriate /tune keyword for the target processor generation (see Requesting Optimized Code for a Specific Processor Generation).

To specify software pipelining without loop transformation optimizations, do one of the following:

  • Specify /optimize:5 with /notransform_loops.

  • Specify /pipeline with /optimize:4, /optimize:3, or /optimize:2. This optimization is not performed at optimization levels below /optimize:2.

For this version of Visual Fortran, loops chosen for software pipelining:

  • Are always innermost loops (those executed the most).

  • Do not contain branches or procedure calls.

  • Do not use COMPLEX floating-point data.

By modifying the unrolled loop and inserting instructions as needed before and/or after the unrolled loop, software pipelining generally improves run-time performance, except where the loops contain a large number of instructions with many existing overlapped operations. In this case, software pipelining may not have enough registers available to effectively improve execution performance. Run-time performance using /optimize:5 (or /pipeline) may not improve performance, as compared to using /optimize:4.

For programs that contain loops that exhaust available registers, longer execution times may result with /optimize:5 or /pipeline. In cases where performance does not improve, consider compiling with the /unroll:1 option along with /optimize:5 or /pipeline, to possibly improve the effects of software pipelining.

For more information:

  • On the interaction of command-line options and timing programs compiled with software pipelining, see /[no]pipeline.


Other Options Related to Optimization

In addition to the /optimize options (discussed in Optimization Levels: the /optimize Option), several other compiler options can prevent or facilitate improved optimizations, as discussed in the following sections:

  • Options Set by the /fast Option
  • Controlling Loop Unrolling
  • Controlling the Inlining of Procedures
  • Arithmetic Reordering Optimizations
  • Dummy Aliasing Assumption
  • Requesting Optimized Code for a Specific Processor Generation
  • Requesting Code Generation for a Specific Processor Generation
  • Loop Transformation
  • Software Pipelining (ia64 only)


Options Set by the /fast Option

Specifying the /fast option sets the following options:

  • /align:(dcommons,records,sequence) (see Data Alignment Considerations)
  • /assume:noaccuracy_sensitive (see Arithmetic Reordering Optimizations)
  • /architecture:host (see Requesting Code Generation for a Specific Processor Generation)
  • /math_library:fast (see /math_library)
  • /tune:host (see Requesting Optimized Code for a Specific Processor Generation)


Controlling Loop Unrolling

You can specify the number of times loops are unrolled by using the /unroll option. You can control the number of times a specific loop is unrolled by using the cDEC$ UNROLL Directive to Control Loop Unrolling.

Although unrolling loops usually improves run-time performance, the size of the executable program may increase.

On ia64 systems, the /unroll: num option can also influence the run-time results of software pipelining optimizations performed when you specify /optimize:5 or /pipeline.

For more information:

On loop unrolling, see Loop Unrolling.


Controlling the Inlining of Procedures

To specify the types of procedures to be inlined, use the /inline options. Also, compile multiple source files together and specify an adequate optimization level, such as /optimize:4.

If you omit /noinline and the /inline options, the optimization level /optimize option used determines the types of procedures that are inlined.

The /inline options are as follows:

  • /inline:none (same as /noinline)

    Inlines statement functions but not other procedures. This type of inlining occurs if you specify /optimize:0 or /optimize:1 and omit /inline options.

  • /inline:manual

    Inlines statement functions but not other procedures. This type of inlining occurs if you specify /optimize:2 or /optimize:3 and omit /inline options.

  • /inline:size

    In addition to inlining statement functions, inlines any procedures that the Visual Fortran optimizer expects will improve run-time performance with no likely significant increase in program size.

  • /inline:speed

    In addition to inlining statement functions, inlines any procedures that the Visual Fortran optimizer expects will improve run-time performance with a likely significant increase in program size. This type of inlining occurs if you specify /optimize:4 or /optimize:5 and omit /inline options.

  • /inline:all

    Inlines every call that can possibly be inlined while generating correct code, including the following:

    • Statement functions (always inlined)
    • Any procedures that Visual Fortran expects will improve run-time performance with a likely significant increase in program size.
    • Any other procedures that can possibly be inlined and generate correct code. Certain recursive routines are not inlined to prevent infinite expansion.

For information on the inlining of other procedures (inlined at optimization level /optimize:4 or higher), see Inlining Procedures.

Maximizing the types of procedures that are inlined usually improves run-time performance, but compile-time memory usage and the size of the executable program may increase.

To determine whether using /inline:all benefits your particular program, time program execution for the same program compiled with and without /inline:all.


Arithmetic Reordering Optimizations

If you use the /assume:noaccuracy_sensitive option, Compaq Visual Fortran may reorder code (based on algebraic identities) to improve performance. For example, the following expressions are mathematically equivalent but may not compute the same value using finite precision arithmetic:

  X = (A + B) + C

  X = A + (B + C)

The results can be slightly different from the default /assume:accuracy_sensitive because of the way intermediate results are rounded. However, the /assume:noaccuracy_sensitive results are not categorically less accurate than those gained by the default. In fact, dot-product summations using /assume:noaccuracy_sensitive can produce more accurate results than those using /assume:accuracy_sensitive.

The effect of /assume:noaccuracy_sensitive is important when Compaq Fortran hoists divide operations out of a loop. If /assume:noaccuracy_sensitive is in effect, the unoptimized loop becomes the optimized loop:

Unoptimized Code Optimized Code
  DO I=1,N
  .
  .
  .
  B(I)= A(I)/V
  END DO

   T= 1/V
   DO I=1,N
   .
   .
   .
   B(I)= A(I)*T
   END DO

The transformation in the optimized loop increases performance significantly, and loses little or no accuracy. However, it does have the potential for raising overflow or underflow arithmetic exceptions.


Dummy Aliasing Assumption

Some programs compiled with Visual Fortran (or Compaq Fortran and Compaq Fortran 77 on other platforms) may have results that differ from the results of other Fortran compilers. Such programs may be aliasing dummy arguments to each other or to a variable in a common block or shared through use association, and at least one variable access is a store.

This program behavior is prohibited in programs conforming to the Fortran 90 standard, but not by Visual Fortran. Other versions of Fortran allow dummy aliases and check for them to ensure correct results. However, Visual Fortran assumes that no dummy aliasing will occur, and it can ignore potential data dependencies from this source in favor of faster execution.

The Visual Fortran default is safe for programs conforming to the Fortran 90 standard. It will improve performance of these programs because the standard prohibits such programs from passing overlapped variables or arrays as actual arguments if either is assigned in the execution of the program unit.

The /assume:dummy_aliases option allows dummy aliasing. It ensures correct results by assuming the exact order of the references to dummy and common variables is required. Program units taking advantage of this behavior can produce inaccurate results if compiled with /assume:nodummy_aliases.

The following example is taken from the DAXPY routine in the FORTRAN 77 version of the Basic Linear Algebra Subroutines (BLAS).

Using the /assume:dummy_aliases Option

      SUBROUTINE DAXPY(N,DA,DX,INCX,DY,INCY)

C     Constant times a vector plus a vector.
C     uses unrolled loops for increments equal to 1.

      DOUBLE PRECISION DX(1), DY(1), DA
      INTEGER I,INCX,INCY,IX,IY,M,MP1,N
C
      IF (N.LE.0) RETURN
      IF (DA.EQ.0.0) RETURN
      IF (INCX.EQ.1.AND.INCY.EQ.1) GOTO 20

C     Code for unequal increments or equal increments
C     not equal to 1.
      .
      .
      .
      RETURN
C     Code for both increments equal to 1.
C     Clean-up loop

20    M = MOD(N,4)
      IF (M.EQ.0) GOTO 40
      DO I=1,M
          DY(I) = DY(I) + DA*DX(I)
      END DO

      IF (N.LT.4) RETURN
40    MP1 = M + 1
      DO I = MP1, N, 4
          DY(I) = DY(I) + DA*DX(I)
          DY(I + 1) = DY(I + 1) + DA*DX(I + 1)
          DY(I + 2) = DY(I + 2) + DA*DX(I + 2)
          DY(I + 3) = DY(I + 3) + DA*DX(I + 3)
      END DO

      RETURN
      END SUBROUTINE

The second DO loop contains assignments to DY. If DY is overlapped with DA, any of the assignments to DY might give DA a new value, and this overlap would affect the results. If this overlap is desired, then DA must be fetched from memory each time it is referenced. The repetitious fetching of DA degrades performance.

Linking Routines with Opposite Settings

You can link routines compiled with the /assume:dummy_aliases option to routines compiled with /assume:nodummy_aliases. For example, if only one routine is called with dummy aliases, you can use /assume:dummy_aliases when compiling that routine, and compile all the other routines with /assume:nodummy_aliases to gain the performance value of that option.

Programs calling DAXPY with DA overlapping DY do not conform to the FORTRAN 77 and Fortran 90 standards. However, they are accommodated if /assume:dummy_aliases was used to compile the DAXPY routine.


Requesting Optimized Code for a Specific Processor Generation

You can specify the types of optimized code to be generated by using the /tune option. Tuning for a specific implementation can improve run-time performance; it is also possible that code tuned for a specific target may run slower on another target.

On ia32 systems, regardless of the specified keyword for /tune, the generated code will run correctly on all implementations of the ia32 architecture. Specifying the correct keyword for /tune for the target ia32 processor generation type usually slightly improves run-time performance.

The /tune keywords are described in /tune.

The combination of the specified keyword for /tune and the type of processor generation used has no effect on producing the expected correct program results. To request a specific set of instructions for an ia32 architecture generation, see the /architecture option.


Requesting Code Generation for a Specific Processor Generation

The /architecture (/arch) option determines the type of code that will be generated for this program. On an ia32 system, you can specify whether the code to be generated can be run:

  • On Pentium 4 processor systems only, by generating code using the base set of Pentium instructions plus MMX, SSE, and SSE2 instruction extensions.
  • On AMD Athlon processor systems only, by generating code using the base set of Pentium instructions plus MMX, SSE, 3DNow, and Enhanced 3DNow instruction extensions.
  • On AMD K6_2, AMD K6_III, and AMD Athlon processor systems only, by generating code using the base set of Pentium instructions plus MMX, SSE, and 3DNow instruction extensions.
  • On Intel Pentium III and Pentium 4 processor systems, and AMD K6_2, AMD K6_III, and AMD Athlon processor systems only, by generating code using the base set of Pentium instructions plus MMX and SSE instruction extensions.
  • On Intel Pentium Pro, Pentium II, and higher Intel processor systems, and AMD K6 and higher AMD processor systems only, by generating code using the base set of Pentium instructions plus MMX instruction extensions.
  • On Pentium (586) and higher Intel and AMD systems only, by generating code using the base set of Pentium instructions.
  • On all ia32 Intel and AMD systems, by generating code using a generic blend of instructions that runs with moderate efficiency on all Intel and AMD systems.

You can also request that the type of generated code be determined by the host system being used to compile the application.

For an ia64 system, request either the type of host system being used for compilation or request generic blend of instructions.

The /arch:keyword option uses the same keywords as the /tune:keyword option.

For more information:

  • See /architecture.


Compiler Directives Related to Performance

Certain compiler source directives (cDEC$ prefix) can be used in place of some performance-related compiler options and provide more control of certain optimizations, as discussed in the following sections:

  • Using the cDEC$ OPTIONS Directive
  • Using the cDEC$ UNROLL Directive to Control Loop Unrolling
  • Using the cDEC$ IVDEP Directive to Control Certain Loop Optimizations


Using the cDEC$ OPTIONS Directive

The c DEC$ OPTIONS directive allows source code control of the alignment of fields in record structures and data items in common blocks. The fields and data items can be naturally aligned (for performance reasons) or they can be packed together on arbitrary byte boundaries.

Using this directive is an alternative to the compiler option /[no]alignment, which affects the alignment of all fields in record structures and data items in common blocks in the current program unit.

For more information:

  • See the OPTIONS Directive.


Using the cDEC$ UNROLL Directive to Control Loop Unrolling

The c DEC$ UNROLL directive allows you to specify the number of times certain counted DO loops will be unrolled. Place the c DEC$ UNROLL directive before the DO loop you want to control the unrolling of.

Using this directive for a specific loop overrides the value specified by the compiler option /unroll for that loop. The value specified by /unroll affects how many times all loops not controlled by their respective c DEC$ UNROLL directives are unrolled.

For more information:

  • See the UNROLL Directive.


Using the cDEC$ IVDEP Directive to Control Certain Loop Optimizations

The c DEC$ IVDEP directive allows you to help control certain optimizations related to dependence analysis in a DO loop. Place the c DEC$ IVDEP directive before the DO loop you want to help control the optimizations for. Not all DO loops should use this directive.

The c DEC$ IVDEP directive tells the optimizer to begin dependence analysis by assuming all dependences occur in the same forward direction as their appearance in the normal scalar execution order. This contrasts with normal compiler behavior, which is for the dependence analysis to make no initial assumptions about the direction of a dependence.

For more information:

  • See the IVDEP Directive.


Using QuickWin

This chapter introduces the major categories of QuickWin library routines. It gives an overview of QuickWin features and their use in creating and displaying graphics, and customizing your QuickWin applications with custom menus and mouse routines. Drawing Graphics Elements, and Using Fonts from the Graphics Library cover graphics and fonts in more detail.

The Visual Fortran QuickWin run-time library helps you turn graphics programs into simple Windows applications. Though the full capability of Windows is not available through QuickWin, QuickWin is simpler to learn and to use. QuickWin applications do support pixel-based graphics, real-coordinate graphics, text windows, character fonts, user-defined menus, mouse events, and editing (select/copy/paste) of text, graphics, or both.

In Visual Fortran, graphics programs must be either Fortran QuickWin, Fortran Standard Graphics, Fortran Windows, or use OpenGL routines. Fortran Standard Graphics Applications are a subset of QuickWin that support only one window.

You can choose the Fortran QuickWin or Standard Graphics application type from the drop-down list of available project types when you create a new project in the visual development environment. Or you can use the /libs:qwin compiler option for Fortran QuickWin or the /libs:qwins compiler option for Fortran Standard Graphics.

Note that Fortran QuickWin and Standard Graphics applications cannot be DLLs, and QuickWin and Standard Graphics cannot be linked with run-time routines that are in DLLs. This means that the /libs:qwin option and the /libs:dll with /threads options cannot be used together.

You can access the QuickWin routines library from Visual Fortran as well as other languages that support the Fortran calling conventions. The graphics package supports all video modes supported by Windows 2000, Windows NT 4, Windows Me, Windows 98, and Windows 95.

A program using the QuickWin routines must explicitly access the QuickWin graphics library routines with the statement USE DFLIB (see USE Statement Needed for Fortran QuickWin Applications).

This section includes the following topics:

  • Capabilities of QuickWin
  • Comparing QuickWin with Windows-Based Applications
  • Using Win32 with QuickWin
  • Types of QuickWin Programs
  • The QuickWin User Interface
  • USE Statement Needed for Fortran QuickWin Applications
  • Creating QuickWin Windows
  • Using Graphics and Character-Font Routines
  • Defining Graphics Characteristics
  • Displaying Graphics Output
  • Working with Screen Images
  • Enhancing QuickWin Applications
  • Customizing QuickWin Applications
  • QuickWin Programming Precautions
  • Simulating Nonblocking I/O


Capabilities of QuickWin

You can use the QuickWin library to do the following:

  • Compile console programs into simple applications for Windows.
  • Minimize and maximize QuickWin applications like any Windows-based application.
  • Call graphics routines.
  • Load and save bitmaps.
  • Select, copy and paste text, graphics, or a mix of both.
  • Detect and respond to mouse clicks.
  • Display graphics output.
  • Alter the default application menus or add programmable menus.
  • Create custom icons.
  • Open multiple child windows.


Comparing QuickWin with Windows-Based Applications

QuickWin does not provide the total capability of Windows. Although you can call many Win32 APIs (Application Programming Interface) from QuickWin and console programs, many other Win32 APIs (such as GDI functions) should be called only from a full Windows application. You need to use Windows-based applications, not QuickWin, if any of the following applies:

  • Your application has an OLE (Object Linking and Embedding) container.
  • You want direct access to GDI (Graphical Data Interface) functions.
  • You want to add your own customized Help information to QuickWin Help.
  • You want to create something other than a standard SDI (Single Document Interface) or MDI (Multiple Document Interface) application. (For example, if you want your application to have a dialog such as Windows' Calculator in the client area.)
  • You want to use a modeless dialog box rather than a modal dialog box.


Using Win32 with QuickWin

You can convert the unit numbers of QuickWin windows to Win32 handles with the GETHWNDQQ QuickWin function. You should not use Windows GDI to draw on QuickWin windows because QuickWin keeps a window buffer and the altered window would be destroyed on redraw. You can use Windows subclassing to intercept graphics messages bound for QuickWin before QuickWin receives them.

See the sample program POKER in the Visual Fortran Samples ...\DF98\SAMPLES\QUICKWIN\POKER folder for a demonstration of this technique.


Types of QuickWin Programs

You can creates a Fortran Standard Graphics application or a Fortran QuickWin application, depending on the project type you choose. Fortran Standard Graphics (QuickWin single document) applications support only one window and do not support programmable menus. Fortran QuickWin applications support multiple windows and user-defined menus. Any Fortran program, whether it contains graphics or not, can be compiled as a QuickWin application. You can use the Microsoft visual development environment to create, debug, and execute Fortran Standard Graphics programs and Fortran QuickWin programs.

To build a Fortran QuickWin application in the visual development environment, select Fortran Standard Graphics or Quickwin Application from the list of available project types displayed when you create a new project. In the dialog box, specify a Fortran Quickwin multiple-window project.

To build a Fortran Standard Graphics application in the visual development environment, select Fortran Standard Graphics or Quickwin Application from the list of available project types. In the dialog box, specify a Fortran Standard Graphics single-window project.

To build a Fortran QuickWin application from the command line, use the /libs:qwin option. For example:

  DF /libs=qwin qw_app.f90

To build a Fortran Standard Graphics application from the command line, use the /libs:qwins option. For example:

  DF /libs=qwins stdg_app.f90

For information about building projects in the visual development environment, see Building Programs and Libraries.

Some of the QuickWin project Visual Fortran Samples are in folders in ...DF98\SAMPLES\QUICKWIN.

The following sections discuss the two types of QuickWin applications:

  • Fortran Standard Graphics Application
  • Fortran QuickWin Application


Fortran Standard Graphics Applications

A Fortran standard graphics application has a single maximized application window covering the entire screen area, whose appearance resembles a MS-DOS screen without scrolls bars or menus. The Esc key can be used to exit a program that does otherwise terminate. When the Esc key is pressed, the frame window appears with a border, title bar, scroll bars, and a menu item in the upper-left corner that allows you to close the application.

Programmable menus and multiple child windows cannot be created in this mode.

The following figure shows a typical Fortran Standard Graphics application, which resembles an MS-DOS application running in a window.

MTRX.F90 Compiled as a Fortran Standard Graphics Application


Fortran QuickWin Graphics Applications

The following shows a typical Fortran QuickWin application. The frame window has a border, title bar, scroll bars, and default menu bar. You can modify, add, or delete the default menu items, respond to mouse events, and create multiple child windows within the frame window using QuickWin enhanced features. Routines to create enhanced features are listed in Enhancing QuickWin Applications. Using these routines to customize your QuickWin application is described in Customizing QuickWin Applications.

MTRX.FOR Compiled as a QuickWin Application

Some of the Fortran QuickWin applications provided as Samples include PLATFORM and POLYDRAW (see the respective folders in ...\DF98\SAMPLES\ADVANCED\WIN32).


The QuickWin User Interface

All QuickWin applications create an application or frame window; child windows are optional. Fortran Standard Graphics applications and Fortran QuickWin applications have these general characteristics:

  • Window contents can be copied as bitmaps or text to the Clipboard for printing or pasting to other applications. In Fortran QuickWin applications, any portion of the window can be selected and copied.
  • Vertical and horizontal scroll bars appear automatically, if needed.
  • The base name of the application's .EXE file appears in the window's title bar.
  • Closing the application window terminates the program.

In addition, the Fortran QuickWin application has a status bar and menu bar. The status bar at the bottom of the window reports the current status of the window program (for example, running or input pending).

Default QuickWin Menus shows the default QuickWin menus.


Default QuickWin Menus

The default MDI (Multiple Document Interface) menu bar has six menus: File, Edit, View, State, Window, and Help.

File Menu

Edit Menu

For instructions on using the Edit options within QuickWin see Editing Text and Graphics from the QuickWin Edit Menu.

View Menu

The resulting graphics might appear somewhat distorted whenever the logical graphics screen is enlarged or reduced with the Size to Fit and Full Screen commands. While in Full Screen or Size To Fit mode, cursors are not scaled.

State Menu

Window Menu

Help Menu

For instructions on replacing the About default information within the Help menu with your own text message, see Defining an About Box.

For instructions on how to create custom QuickWin menus, see Customizing QuickWin Applications.


USE Statement Needed for Fortran QuickWin Applications

A program using the Fortran QuickWin or Standard Graphics features must explicitly access the QuickWin graphics library routines with the statement USE DFLIB.

Any program using the QuickWin features must include the statement USE DFLIB to access the QuickWin graphics library. The DFLIB.MOD module file contains subroutine and function declarations in INTERFACE statements, derived-type declarations, and symbolic constant declarations for each QuickWin routine.

Because INTERFACE statements must appear before the body of a program, the USE DFLIB statement must appear before the body of a program unit. This usually means putting USE DFLIB before any other statement (such as IMPLICIT NONE or INTEGER).

Depending on the type of routines used by your application, other USE statements that include other Visual Fortran modules may be needed in addition to USE DFLIB. The description of each Visual Fortran routine in the Language Reference (see A to Z Reference) indicates the module that needs to be included for external routines (such as USE DFLIB, USE DFPORT).


Creating QuickWin Windows

The QuickWin library contains many routines to create and control your QuickWin windows. These routines are discussed in the following topics:

  • Accessing Window Properties
  • Creating Child Windows
  • Giving a Window Focus and Setting the Active Window
  • Keeping Child Windows Open
  • Controlling Size and Position of Windows


Accessing Window Properties

SETWINDOWCONFIG and GETWINDOWCONFIG set and get the current virtual window properties. Virtual window properties set by SETWINDOWCONFIG contain the maximum amount of text and graphics for that unit. The SETWSIZEQQ routine sets the properties of the visible window, which is generally smaller than a virtual window.

If the size of the virtual window (SETWINDOWCONFIG) is larger than the size of the visible window (SETWSIZEQQ), scroll bars are automatically provided to allow all the text and graphics in a virtual window to be displayed.

These virtual window properties are stored in the windowconfig derived type defined in DFLIB.MOD, which contains the following parameters:

  TYPE windowconfig
     INTEGER(2) numxpixels            ! Number of pixels on x-axis.
     INTEGER(2) numypixels            ! Number of pixels on y-axis.
     INTEGER(2) numtextcols           ! Number of text columns available.
     INTEGER(2) numtextrows           ! Number of scrollable text lines available.
     INTEGER(2) numcolors             ! Number of color indexes.
     INTEGER(4) fontsize              ! Size of default font. Set to
                                      ! QWIN$EXTENDFONT when using multibyte
                                      ! characters, in which case
                                      ! extendfontsize sets the font size.
     CHARACTER(80) title              ! Window title, where title is a C string.
     INTEGER(2) bitsperpixel          ! Number of bits per pixel. This value
                                      ! is calculated by the system and is an
                                      ! output-only parameter.
                                      ! The next three parameters support multibyte
                                      ! character sets (such as Japanese)
     CHARACTER(32) extendfontname     ! Any non-proportionally spaced font
                                      ! available on the system.
     INTEGER(4) extendfontsize        ! Takes same values as fontsize, but
                                      ! used for multiple-byte character sets
                                      ! when fontsize set to QWIN$EXTENDFONT.
     INTEGER(4) extendfontattributes  ! Font attributes such as bold and
                                      ! italic for multibyte character sets.
  END TYPE windowconfig

If you use SETWINDOWCONFIG to set the variables in windowconfig to -1, the highest resolution will be set for your system, given the other fields you specify, if any. You can set the actual size of the window by specifying parameters that influence the window size -- the number of x and y pixels, the number of rows and columns, and the font size. If you do not call SETWINDOWCONFIG, the window defaults to the best possible resolution and a font size of 8 by 16. The number of colors depends on the video driver used.

The font size, x pixels, y pixels, and columns and rows are related and cannot all be set arbitrarily. The following example specifies the number of x and y pixels and the font size and accepts the system calculation for the best number of rows and columns for the window:

     USE DFLIB
     TYPE (windowconfig) wc
     LOGICAL status
  ! Set the x & y pixels to 800X600 and font size to 8x12.
     wc%numxpixels  = 800                ! pixels on x-axis, window width
     wc%numypixels  = 600                ! pixels on y-axis, window height
     wc%numtextcols = -1                 ! -1 requests system default/calculation
     wc%numtextrows = -1
     wc%numcolors   = -1
     wc%title       = " "C
     wc%fontsize    = #0008000C          ! Request 8x12 pixel fonts
     status         = SETWINDOWCONFIG(wc)

In this example:

  • The variables wc%numxpixels and wc%numypixels specify the size of the window, in this case 800 by 600 pixels. Within this window size, you can choose to specify either the font size (wc%fontsize) or the number of text columns (wc%numtextcols) and rows (wc%numtextrows).

    This example specifies the window size and font size, and lets the system calculate the number of text columns and rows.

    If you choose to specify the number of text columns and rows, you can let the system calculate (specify -1) either the font size or the window size.

  • The variable wc%fontsize is given as hexadecimal constant of #0008000C, which is interpreted in two parts:
    • The left side of 0008 (8) specifies the width of the font, in pixels.
    • The right side of 000C (12 in decimal) specifies the height of the font, in pixels.

  • The variable wc%numtextrows is -1 and wc%numtextcols is -1, which allows the system to calculate the best available number of text columns and text rows to be used, as follows:
    • The number of text columns is calculated as wc%numypixels (800) divided by the width of the font 8 (decimal) or 100.
    • The number of text rows is calculated as wc%numxpixels (600) divided by the width of the font, 12 (decimal) or 50.

The requested font size is matched to the nearest available font size. If the matched size differs from the requested size, the matched size is used to determine the number of columns and rows.

If scroll bars are needed (virtual window size exceeds the visible window size), because of the size required by horizontal and vertical scroll bars for a window, you may need to set the number of lines and columns to a value 1 or 2 greater than the number of rows and columns needed to display the application's information.

If the requested configuration cannot be set, SETWINDOWCONFIG returns .FALSE. and calculates parameter values that will work and best fit the requested configuration. Another call to SETWINDOWCONFIG establishes these values:

   IF(.NOT.status) status = SETWINDOWCONFIG(wc)

For an example, see the QuickWin Sample Cleanwin.

For information on setting the graphics mode with SETWINDOWCONFIG, see Setting the Graphics Mode.

Routines such as SETWINDOWCONFIG work on the window that is currently in focus. You can have multiple windows open as your application requires, but you need to decide which one gains focus. There is a single frame window and one or more child windows. A window is in focus right after it is opened, after I/O to it, and when FOCUSQQ is used. Clicking the mouse when the cursor is in a window will also bring the window into focus.

For example, to set the characteristics for the window associated with unit 10, either gain focus with either an OPEN, a subsequent READ or WRITE statement to unit 10, or FOCUSQQ. For example, use OPEN:

   open(unit=10, file='user')
   result = setwindowconfig(wc)

After you open unit 10, focus can be regained by a READ or WRITE statement to that unit. For example:

   write(10,*) "Hello, this is unit 10"

Or you can use FOCUSQQ:

   result = focusqq(10)
   result = setwindowconfig(wc)

For more information about when a window gains focus, see Giving a Window Focus and Setting the Active Window.


Creating Child Windows

The FILE='USER' option in the OPEN statement opens a child window. The child window defaults to a scrollable text window, 30 rows by 80 columns. You can open up to 40 child windows.

Running a QuickWin application displays the frame window, but not the child window. You must call SETWINDOWCONFIG or execute an I/O statement or a graphics statement to display the child window. The window receives output by its unit number, as in:

  OPEN (UNIT= 12, FILE= 'USER', TITLE= 'Product Matrix')
  WRITE (12, *) 'Enter matrix type: '

Child windows opened with FILE='USER' must be opened as sequential-access formatted files (the default). Other file specifications (direct-access, binary, or unformatted) result in run-time errors.

The following example creates three child windows. A frame window is automatically created. Text is written to each so the child windows are visible:

  program testch
   use dflib
   open(11,file="user")
   write(11,*) "Hello 11"
   open(12,file="user")
   write(12,*) "Hello 12"
   open(13,file="user")
   write(13,*) "Hello 13"
   write(13,*) "Windows 11, 12, and 13 can be read and written with normal"
   write(13,*) "Fortran I/O statements. The size of each window on the screen"
   write(13,*) "can be modified by SETWSIZEQQ. The size of the virtual window"
   write(13,*) "(i.e., a data buffer) can be modified by SETWINDOWCONFIG."
   read(13,*)
  end

When this program is run, the output appears as follows:

example of child windows


Giving a Window Focus and Setting the Active Window

When a window is made active, it receives graphics output (from ARC, LINETO, and OUTGTEXT, for example) but is not brought to the foreground and thus does not have the focus. When a window acquires focus, either by a mouse click, I/O to it, or by a FOCUSQQ call, it also becomes the active window. When a window gains focus, the window that previously had focus will lose focus.

If a window needs to be brought to the foreground, it must be given focus. The window that has the focus is always on top, and all other windows have their title bars grayed out. A window can have the focus and yet not be active and not have graphics output directed to it. Graphical output is independent of focus.

Under most circumstances, focus and active should apply to the same window. This is the default behavior of QuickWin and a programmer must consciously override this default.

Certain QuickWin routines (such as GETCHARQQ, PASSDIRKEYSQQ, and SETWINDOWCONFIG) that do not take a unit number as an input argument usually effect the active window whether or not it is in focus.

If another window is made active but is not in focus, these routines effect the window active at the time of the routine call. This may appear unusual to the user since a GETCHARQQ under these circumstances will expect input from a grayed, background window. The user would then have to click on that window before input could be typed to it.

To use these routines (that effect the active window), either do I/O to the unit number of the window you wish to put in focus (and also make active), or call FOCUSQQ (with a unit number specified). If only one window is open then that window is the one effected. If several windows are opened, then the last one opened is the one effected since that window will get focus and active as a side effect of being opened.

The OPEN (IOFOCUS) parameter also can determine whether a window receives the focus when a I/O statement is executed on that unit. For example:

  OPEN (UNIT = 10, FILE = 'USER', IOFOCUS = .TRUE.)

With an explicit OPEN with FILE='USER', IOFOCUS defaults to .TRUE. For child windows opened implicitly (no OPEN statement before the READ WRITE, or PRINT) as unit 0, 5, or 6, IOFOCUS defaults to .FALSE..

If IOFOCUS=.TRUE., the child window receives focus prior to each READ, WRITE, or PRINT. Calls to OUTTEXT or graphics functions (for example, OUTGTEXT, LINETO, and ELLIPSE) do not cause the focus to shift. If you use IOFOCUS with any unit other than a QuickWin child window, a run-time error occurs.

The focus shifts to a window when it is given the focus with FOCUSQQ, when it is selected by a mouse click, or when an I/O operation other than a graphics operation is performed on it, unless the window was opened with IOFOCUS=.FALSE.. INQFOCUSQQ determines which unit has the focus. For example:

    USE DFLIB
    INTEGER(4) status, focusunit
    OPEN(UNIT = 10, FILE = 'USER', TITLE = 'Child Window 1')
    OPEN(UNIT = 11, FILE = 'USER', TITLE = 'Child Window 2')
 ! Give focus to Child Window 2 by writing to it:
    WRITE (11, *) 'Giving focus to Child 2.'
 ! Give focus to Child Window 1 with the FOCUSQQ function:
    status = FOCUSQQ(10)
     ...
 ! Find out the unit number of the child window that currently has focus:
    status = INQFOCUSQQ(focusunit)

SETACTIVEQQ makes a child window active without bringing it to the foreground. GETACTIVEQQ returns the unit number of the currently active child window. GETHWNDQQ converts the unit number into a Windows handle for functions that require it.


Keeping Child Windows Open

A child window remains open as long as its unit is open. The STATUS parameter in the CLOSE statement determines whether the child window remains open after the unit has been closed. If you set STATUS='KEEP', the associated window remains open but no further input or output is permitted. Also, the Close command is added to the child window's menu and the word Closed is appended to the window title. The default is STATUS='DELETE', which closes the window.

A window that remains open when you use STATUS='KEEP' counts as one of the 40 child windows available for the QuickWin application.


Controlling Size and Position of Windows

SETWSIZEQQ and GETWSIZEQQ set and get the size and position of the visible representation of a window. The positions and dimensions of visible child windows are expressed in units of character height and width. The position and dimensions of the frame window are expressed in screen pixels. The position and dimensions are returned in the derived type qwinfo defined in DFLIB.MOD as follows:

  TYPE QWINFO
     INTEGER(2) TYPE     ! Type of action performed by SETWSIZEQQ.
     INTEGER(2) X        ! x-coordinate for upper left corner.
     INTEGER(2) Y        ! y-coordinate for upper left corner.
     INTEGER(2) H        ! Window height.
     INTEGER(2) W        ! Window width.
  END TYPE QWINFO

The options for the qwinfo type are listed under SETWSIZEQQ in the Language Reference.

GETWSIZEQQ returns the position and the current or maximum window size of the current frame or child window. To access information about a child window, specify the unit number associated with it. Unit numbers 0, 5, and 6 refer to the default startup window if you have not explicitly opened them with the OPEN statement. To access information about the frame window, specify the unit number as the symbolic constant QWIN$FRAMEWINDOW. For example:

   USE DFLIB
   INTEGER(4) status
   TYPE (QWINFO) winfo
   OPEN (4, FILE='USER')
    ...
 ! Get current size of child window associated with unit 4.
   status = GETWSIZEQQ(4, QWIN$SIZECURR, winfo)
   WRITE (*,*) "Child window size is ", winfo.H, " by ", winfo.W
 ! Get maximum size of frame window.
   status = GETWSIZEQQ(QWIN$FRAMEWINDOW, QWIN$SIZEMAX, winfo)
   WRITE (*,*) "Max frame window size is ", winfo.H, " by ", winfo.W

SETWSIZEQQ is used to set the visible window position and size. For example:

   USE DFLIB
   INTEGER(4) status
   TYPE (QWINFO) winfo
   OPEN (4, FILE='USER')
   winfo.H    = 30
   winfo.W    = 80
   winfo.TYPE = QWIN$SET
   status     = SETWSIZEQQ(4, winfo)


Using Graphics and Character-Font Routines

Graphics routines are functions and subroutines that draw lines, rectangles, ellipses, and similar elements on the screen. Font routines create text in a variety of sizes and styles. The QuickWin graphics library provides routines that:

  • Change the window's dimensions.
  • Set coordinates.
  • Set color palettes.
  • Set line styles, fill masks, and other figure attributes.
  • Draw graphics elements.
  • Display text in several character styles.
  • Display text in fonts compatible with Microsoft Windows.
  • Store and retrieve screen images.


Defining Graphics Characteristics

The following topics discuss groups of routines that define the way text and graphics are displayed:

  • Selecting Display Options
  • Setting Graphics Coordinates
  • Using Color
  • Setting Figure Properties


Selecting Display Options

The QuickWin run-time library provides a number of routines that you can use to define text and graphics displays. These routines determine the graphics environment characteristics and control the cursor.

SETWINDOWCONFIG is the routine you use to configure window properties. You can use DISPLAYCURSOR to control whether the cursor will be displayed. The cursor becomes invisible after a call to SETWINDOWCONFIG. To display the cursor you must explicitly turn on cursor visibility with DISPLAYCURSOR($GCURSORON).

SETGTEXTROTATION sets the current orientation for font text output, and GETGTEXTROTATION returns the current setting. The current orientation is used in calls to OUTGTEXT.

For more information on these routines, see the Language Reference.


Setting Graphics Coordinates

The coordinate-setting routines control where graphics can appear on the screen. Visual Fortran graphics routines recognize the following sets of coordinates:

  • Fixed physical coordinates, which are determined by the hardware and the video mode used
  • Viewport coordinates, which you can define in the application
  • Window coordinates, which you can define to simplify scaling of floating-point data values

Unless you change it, the viewport-coordinate system is identical to the physical-coordinate system. The physical origin (0, 0) is always in the upper-left corner of the display.

For QuickWin, display means a child window's client area, not the actual monitor screen (unless you go to Full Screen mode). The x-axis extends in the positive direction left to right, while the y-axis extends in the positive direction top to bottom. The default viewport has the dimensions of the selected mode. In a QuickWin application, you can draw outside of the child window's current client area. If you then make the child window bigger, you will see what was previously outside the frame.

You can also use coordinate routines to convert between physical-, viewport-, and window-coordinate systems. (For more detailed information on coordinate systems, see Drawing Graphics Elements.)

You can set the pixel dimensions of the x- and y-axes with SETWINDOWCONFIG. You can access these values through the wc%numxpixels and wc%numypixels values returned by GETWINDOWCONFIG. Similarly, GETWINDOWCONFIG also returns the range of colors available in the current mode through the wc%numcolors value.

You can also define the graphics area with SETCLIPRGN and SETVIEWPORT. Both of these functions define a subset of the available window area for graphics output. SETCLIPRGN does not change the viewport coordinates, but merely masks part of the screen. SETVIEWPORT resets the viewport bounds to the limits you give it and sets the origin to the upper-left corner of this region.

The origin of the viewport-coordinate system can be moved to a new position relative to the physical origin with SETVIEWORG. Regardless of the viewport coordinates, however, you can always locate the current graphics output position with GETCURRENTPOSITION and GETCURRENTPOSITION_W. (For more detailed information on viewports and clipping regions, see Drawing Graphics Elements.)

Using the window-coordinate system, you can easily scale any set of data to fit on the screen. You define any range of coordinates (such as 0 to 5000) that works well for your data as the range for the window-coordinate axes. By telling the program that you want the window-coordinate system to fit in a particular area on the screen (map to a particular set of viewport coordinates), you can scale a chart or drawing to any size you want. SETWINDOW defines a window-coordinate system bounded by the specified values. See the Visual Fortran Sample SINE.F90 in the ...\DF98\SAMPLES\TUTORIAL folder for an example of this technique.

GETPHYSCOORD converts viewport coordinates to physical coordinates, and GETVIEWCOORD translates from physical coordinates to viewport coordinates. Similarly, GETVIEWCOORD_W converts window coordinates to viewport coordinates, and GETWINDOWCOORD converts viewport coordinates to window coordinates.

For more information:

  • On these routines, see their descriptions in the Language Reference.


Using Color

If you have a VGA machine, you are restricted to displaying at most 256 colors at a time. These 256 colors are held in a palette. You can choose the palette colors from a range of 262,144 colors (256K), but only 256 at a time. The palette routines REMAPPALETTERGB and REMAPALLPALETTERGB assign Red-Green-Blue (RGB) colors to palette indexes.

Functions and subroutines that use color indexes create graphic outputs that depend on the mapping between palette indexes and RGB colors. REMAPPALETTERGB remaps one color index to an RGB color, and REMAPALLPALETTERGB remaps the entire palette, up to 236 colors, (20 colors are reserved by the system). You cannot remap the palette on machines capable of displaying 20 colors or fewer.

SVGA and true color video adapters are capable of displaying 262,144 (256K) colors and 16.7 million colors respectively. If you use a palette, you are restricted to the colors available in the palette.

To access the entire set of available colors, not just the 256 or fewer colors in the palette, you should use functions that specify a color value directly. These functions end in RGB and use Red-Green-Blue color values, not indexes to a palette. For example, SETCOLORRGB, SETTEXTCOLORRGB, and SETPIXELRGB specify a direct color value, while SETCOLOR, SETTEXTCOLOR, and SETPIXEL each specify a palette color index. If you are displaying more than 256 colors simultaneously, you need to use the RGB direct color value functions exclusively.

To set the physical display properties of your monitor, open the Control Panel and click the Display icon.

QuickWin only supports a 256-color pallette, regardless of the number of colors set for the monitor.

For more information on setting colors, see Adding Color in Drawing Graphics Elements.


Setting Figure Properties

The output routines that draw arcs, ellipses, and other primitive figures do not specify color or line-style information. Instead, they rely on properties set independently by other routines.

GETCOLORRGB (or GETCOLOR) and SETCOLORRGB (or SETCOLOR) obtain or set the current color value (or color index), which FLOODFILLRGB (or FLOODFILL), OUTGTEXT, and the shape-drawing routines all use. Similarly, GETBKCOLORRGB (or GETBKCOLOR) and SETBKCOLORRGB (or SETBKCOLOR) retrieve or set the current background color.

GETFILLMASK and SETFILLMASK return or set the current fill mask. The mask is an 8-by-8-bit array with each bit representing a pixel. If a bit is 0, the pixel in memory is left untouched: the mask is transparent to that pixel. If a bit is 1, the pixel is assigned the current color value. The array acts as a template that repeats over the entire fill area. It "masks" the background with a pattern of pixels drawn in the current color, creating a large number of fill patterns. These routines are particularly useful for shading.

GETWRITEMODE and SETWRITEMODE return or set the current logical write mode used when drawing lines. The logical write mode, which can be set to $GAND, $GOR, $GPRESET, $GPSET, or $GXOR, determines the interaction between the new drawing and the existing screen and current graphics color. The logical write mode affects the LINETO, RECTANGLE, and POLYGON routines.

GETLINESTYLE and SETLINESTYLE retrieve and set the current line style. The line style is determined by a 16-bit-long mask that determines which of the five available styles is chosen. You can use these two routines to create a wide variety of dashed lines that affect the LINETO, RECTANGLE, and POLYGON routines.

For more information:

  • On these routines, see their description in the Language Reference.


Displaying Graphics Output

The run-time graphics library routines can draw geometric features, display text, display font-based characters, and transfer images between memory and the screen. These capabilities are discussed in the following topics:

  • Drawing Graphics
  • Displaying Character-Based Text
  • Displaying Font-Based Characters


Drawing Graphics

If you want anything other than the default line style (solid), mask (no mask), background color (black), or foreground color (white), you must call the appropriate routine before calling the drawing routine. Subsequent output routines employ the same attributes until you change them or open a new child window.

The following is a list of routines that ask about the current graphics settings, set new graphics settings, and draw graphics:

Routine | Description
ARC, ARC_W | Draws an arc
CLEARSCREEN | Clears the screen, viewport, or text window
ELLIPSE, ELLIPSE_W | Draws an ellipse or circle
FLOODFILL, FLOODFILL_W | Fills an enclosed area of the screen with the current color index using the current fill mask
FLOODFILLRGB, FLOODFILLRGB_W | Fills an enclosed area of the screen with the current RGB color using the current fill mask
GETARCINFO | Determines the endpoints of the most recently drawn arc or pie
GETCURRENTPOSITION, GETCURRENTPOSITION_W | Returns the coordinates of the current graphics-output position
GETPIXEL, GETPIXEL_W | Returns a pixel's color index
GETPIXELRGB, GETPIXELRGB_W | Returns a pixel's Red-Green-Blue color value
GETPIXELS | Gets the color indices of multiple pixels
GETPIXELSRGB | Gets the Red-Green-Blue color values of multiple pixels
GRSTATUS | Returns the status (success or failure) of the most recently called graphics routine
INTEGERTORGB | Convert a true color value into its red, green, and blue components
LINETO, LINETO_W | Draws a line from the current graphics-output position to a specified point
LINETOAR, LINETOAREX | Draws lines from arrays at x,y coordinate points
MOVETO, MOVETO_W | Moves the current graphics-output position to a specified point
PIE, PIE_W | Draws a pie-slice-shaped figure
POLYGON, POLYGON_W | Draws a polygon
RECTANGLE, RECTANGLE_W | Draws a rectangle
RGBTOINTEGER | Convert a trio of red, green, and blue values to a true color value for use with RGB functions and subroutines
SETPIXEL, SETPIXEL_W | Sets a pixel at a specified location to a color index
SETPIXELRGB, SETPIXELRGB_W | Sets a pixel at a specified location to a Red-Green-Blue color value
SETPIXELS | Set the color indices of multiple pixels
SETPIXELSRGB | Set the Red-Green-Blue color value of multiple pixels

Most of these routines have multiple forms. Routine names that end with _W use the window-coordinate system and REAL(8) argument values. Routines without this suffix use the viewport-coordinate system and INTEGER(2) argument values.

Curved figures, such as arcs and ellipses, are centered within a bounding rectangle, which is specified by the upper-left and lower-right corners of the rectangle. The center of the rectangle becomes the center for the figure, and the rectangle's borders determine the size of the figure. In the following figure, the points (x1, y1) and (x2, y2) define the bounding rectangle.

Bounding Rectangle

For more information:

  • On these routines, see their descriptions in the Language Reference.


Displaying Character-Based Text

The routines in the following table ask about screen attributes that affect text display, prepare the screen for text and send text to the screen. To print text in specialized fonts, see Displaying Font-Based Characters and Using Fonts from the Graphics Library.

In addition to these general text routines, you can customize the text in your menus with MODIFYMENUSTRINGQQ. You can also customize any other string that QuickWin produces, including status bar messages, the state message (for example, "Paused" or "Running"), and dialog box messages, with SETMESSAGEQQ. Use of these customization routines is described in Customizing QuickWin Applications.

The following routines recognize text-window boundaries:

Routine | Description
CLEARSCREEN | Clears the screen, viewport, or text window
DISPLAYCURSOR | Sets the cursor on or off
GETBKCOLOR | Returns the current background color index
GETBKCOLORRGB | Returns the current background Red-Green-Blue color value
GETTEXTCOLOR | Returns the current text color index
GETTEXTCOLORRGB | Returns the current text Red-Green-Blue color value
GETTEXTPOSITION | Returns the current text-output position
GETTEXTWINDOW | Returns the boundaries of the current text window
OUTTEXT | Sends text to the screen at the current position
SCROLLTEXTWINDOW | Scrolls the contents of a text window
SETBKCOLOR | Sets the current background color index
SETBKCOLORRGB | Sets the current background Red-Green-Blue color value
SETTEXTCOLOR | Sets the current text color to a new color index
SETTEXTCOLORRGB | Sets the current text color to a new Red-Green-Blue color value
SETTEXTPOSITION | Changes the current text position
SETTEXTWINDOW | Sets the current text-display window
WRAPON | Turns line wrapping on or off

These routines do not provide text-formatting capabilities. If you want to print integer or floating-point values, you must convert the values into a string (using an internal WRITE statement) before calling these routines. The text routines specify all screen positions in character-row and column coordinates.

SETTEXTWINDOW is the text equivalent of the SETVIEWPORT graphics routine, except that it restricts only the display area for text printed with OUTTEXT, PRINT, and WRITE. GETTEXTWINDOW returns the boundaries of the current text window set by SETTEXTWINDOW. SCROLLTEXTWINDOW scrolls the contents of a text window. OUTTEXT, PRINT, and WRITE display text strings written to the current text window.

Warning: The WRITE statement sends its carriage return (CR) and line feed (LF) to the screen at the beginning of the first I/O statement following the WRITE statement. This can cause unpredictable text positioning if you mix the graphics routines SETTEXTPOSITION and OUTTEXT with the WRITE statement. To minimize this effect, use the backslash ( \ ) or dollar sign ( $ ) format descriptor (to suppress CR-LF) in the associated FORMAT statement.

For more information:

  • On these routines, see their descriptions in the Language Reference.
  • On allocating a console to display text in a QuickWin application, see Using the Console.


Displaying Font-Based Characters

Because the Visual Fortran Graphics Library provides a variety of fonts, you must indicate which font to use when displaying font-based characters. After you select a font, you can make inquiries about the width of a string printed in that font or about font characteristics.

The following functions control the display of font-based characters:

Routine | Description
GETFONTINFO | Returns the current font characteristics
GETGTEXTEXTENT | Determines the width of specified text in the current font
GETGTEXTROTATION | Gets the current orientation for font text output in 0.1º increments
INITIALIZEFONTS | Initializes the font library
OUTGTEXT | Sends text in the current font to the screen at the current graphics output position
SETFONT | Finds a single font that matches a specified set of characteristics and makes it the current font used by OUTGTEXT
SETGTEXTROTATION | Sets the current orientation for font text output in 0.1º increments

Characters may be drawn ("mapped") in one of two ways: as bitmapped letters (a "picture" of the letter) or as TrueType characters. See Using Fonts from the Graphics Library, for detailed explanations and examples of how to use the font routines from the QuickWin Library.

For more information on these routines, see the Language Reference.


Working With Screen Images

The routines described in the following sections offer the following ways to store and retrieve images:

  • Transfer images between memory buffers and the screen

    Transferring images from buffers is a quick and flexible way to move things around the screen. Memory images can interact with the current screen image; for example, you can perform a logical AND of a memory image and the current screen or superimpose a negative of the memory image on the screen.

  • Transfer images between the screen and Windows bitmap files

    Transferring images from files gives access to images created by other programs, and saves graphs and images for later use. However, images loaded from bitmap files overwrite the portion of the screen they are pasted into and retain the attributes they were created with, such as the color palette, rather than accepting current attributes.

  • Transfer images between the screen and the Clipboard from the QuickWin Edit menu

    Editing screen images from the QuickWin Edit menu is a quick and easy way to move and modify images interactively on the screen, retaining the current screen attributes, and also provides temporary storage (the Clipboard) for transferring images among applications.

These routines allow you to cut, paste, and move images around the screen.


Transferring Images in Memory

The GETIMAGE and PUTIMAGE routines transfer images between memory and the screen and give you options that control the way the image and screen interact. When you hold an image in memory, the application allocates a memory buffer for the image. The IMAGESIZE routines calculate the size of the buffer needed to store a given image.

Routines that end with _W use window coordinates; the other functions use viewport coordinates.

Routine | Description
GETIMAGE, GETIMAGE_W | Stores a screen image in memory
IMAGESIZE, IMAGESIZE_W | Returns image size in bytes
PUTIMAGE, PUTIMAGE_W | Retrieves an image from memory and displays it

For more information:

  • On these routines, see their descriptions in the Language Reference.


Loading and Saving Images to Files

The LOADIMAGE and SAVEIMAGE routines transfer images between the screen and Windows bitmap files:

Routine | Description
LOADIMAGE, LOADIMAGE_W | Reads a Windows bitmap file (.BMP) from disk and displays it as specified coordinates
SAVEIMAGE, SAVEIMAGE_W | Captures a screen image from the specified portion of the screen and saves it as a Windows bitmap file

You can use a Windows format bitmap file created with a graphics program as a backdrop for graphics that you draw with the Visual Fortran graphics functions and subroutines.

For more information:

  • On these routines, see their descriptions in the Language Reference.


Editing Text and Graphics from the QuickWin Edit Menu

From the QuickWin Edit menu you can choose the Select Text, Select Graphics, or Select All options. You can then outline your selection with the mouse or the keyboard arrow keys. When you use the Select Text option, your selection is highlighted. When you use the Select Graphics or Select All option, your selection is marked with a box whose dimensions you control.

Once you have selected a portion of the screen, you can copy it onto the Clipboard by using the Edit/Copy option or by using the Ctrl+INS key combination. If the screen area you have selected contains only text, it is copied onto the Clipboard as text. If the selected screen area contains graphics, or a mix of text and graphics, it is copied onto the Clipboard as a bitmap.

The Edit menu's Paste option will only paste text. Bitmaps can be pasted into other Windows applications from the Clipboard (with the Ctrl+V or Shift+INS key combinations).

Remember the following when selecting portions of the screen:

  • If you have chosen the Select All option from the Edit menu, the whole screen is selected and you cannot then select a portion of the screen.
  • Text selections are not bounded by the current text window set with SETTEXTWINDOW.
  • When text is copied to the Clipboard, trailing blanks in a line are removed.
  • Text that is written to a window can be overdrawn by graphics. In this case, the text is still present in the screen text buffer, though not visible on the screen. When you select a portion of the screen to copy, you can select text that is actually present but not visible, and that text will be copied onto the Clipboard.
  • When you chose Select Text or Select Graphics from the Edit menu, the application is paused, a caret (^) appears at the top left corner of the currently active window, all user-defined callbacks are disabled, and the window title changes to "Mark Text - windownam "or "Mark Graphics - windowname", where windowname is the name of the currently active window.

    As soon as you begin selection (by pressing an arrow key or a mouse button), the Window title changes to "Select Text - windowname" or "Select Graphics - windowname" and selection begins at that point. If you do not want selection to begin in the upper-left corner, your first action when "Mark Text" or "Mark Graphics" appears in the title is to use the mouse to place the cursor at the position where selection is to be begin.


Enhancing QuickWin Applications

In addition to the basic QuickWin features, you can optionally customize and enhance your QuickWin applications with the features described in the following table. The use of these features to create customized menus, respond to mouse events, and add custom icons is described in the section Customizing QuickWin Applications.

Category | QuickWin Function | Description
Initial settings | INITIALSETTINGS | Controls initial menu settings and/or initial frame window
Display/add box | MESSAGEBOXQQ | Displays a message box
 | ABOUTBOXQQ | Adds an About Box with customized text
Menu items | CLICKMENUQQ | Simulates the effect of clicking or selecting a menu item
 | APPENDMENUQQ | Appends a menu item
 | DELETEMENUQQ | Deletes a menu item
 | INSERTMENUQQ | Inserts a menu item
 | MODIFYMENUFLAGSQQ | Modifies a menu item's state
 | MODIFYMENUROUTINEQQ | Modifies a menu item's callback routine
 | MODIFYMENUSTRINGQQ | Changes a menu item's text string
 | SETWINDOWMENUQQ | Sets the menu to which a list of current child window names are appended
Directional keys | PASSDIRKEYSQQ | Enables (or disables) use of the arrow directional keys and page keys as input (see the Sample DIRKEYS.F90 in the ...\DF98\SAMPLES\ADVANCED\DIRKEYS folder)
QuickWin messages | SETMESSAGEQQ | Changes any QuickWin message, including status bar messages, state messages and dialog box messages
Mouse actions | REGISTERMOUSEEVENT | Registers the application defined routines to be called on mouse events
 | UNREGISTERMOUSEEVENT | Removes the routine registered by REGISTERMOUSEEVENT
 | WAITONMOUSEEVENT | Blocks return until a mouse event occurs


Customizing QuickWin Applications

The QuickWin library is a set of routines you can use to create graphics programs or simple applications for Windows. For a general overview of QuickWin and a description of how to create and size child windows, see the beginning of this section. For information on how to compile and link QuickWin applications, see Building Programs and Libraries.

The following topics describe how to customize and fine-tune your QuickWin applications:

  • Program Control of Menus
  • Changing Status Bar and State Messages
  • Displaying Message Boxes
  • Defining an About Box
  • Using Custom Icons
  • Using a Mouse


Program Control of Menus

You do not have to use the default QuickWin menus. You can eliminate and alter menus, menu item lists, menu titles or item titles. The QuickWin functions that control menus are described in the following sections:

  • Controlling the Initial Menu and Frame Window
  • Deleting, Inserting, and Appending Menu Items
  • Modifying Menu Items
  • Creating a Menu List of Available Child Windows
  • Simulating Menu Selections

Controlling the Initial Menu and Frame Window

You can change the initial appearance of an application's default frame window and menus by defining an INITIALSETTINGS function. If no user-defined INITIALSETTINGS function is supplied, QuickWin calls a predefined (default) INITIALSETTINGS routine that provides a default frame window and menu.

Your application does not call INITIALSETTINGS. If you supply the function in your project, QuickWin calls it automatically.

If you supply it, INITIALSETTINGS can call QuickWin functions that set the initial menus and the size and position of the frame window. Besides the menu functions, SETWSIZEQQ can be called from your INITIALSETTINGS function to adjust the frame window size and position before the window is first drawn.

The following is a sample of INITIALSETTINGS:

   LOGICAL(4) FUNCTION INITIALSETTINGS( )
     USE DFLIB
     LOGICAL(4) result
     TYPE (qwinfo) qwi
 ! Set window frame size.
     qwi%x = 0
     qwi%y = 0
     qwi%w = 400
     qwi%h = 400
     qwi%type = QWIN$SET
     i = SetWSizeQQ( QWIN$FRAMEWINDOW, qwi )
 ! Create first menu called Games.
     result = APPENDMENUQQ(1, $MENUENABLED, '&Games'C, NUL )
 ! Add item called TicTacToe.
     result = APPENDMENUQQ(1, $MENUENABLED, '&TicTacToe'C, WINPRINT)
 ! Draw a separator bar.
     result = APPENDMENUQQ(1, $MENUSEPARATOR, ''C, NUL )
 ! Add item called Exit.
     result = APPENDMENUQQ(1, $MENUENABLED, 'E&xit'C, WINEXIT )
 ! Add second menu called Help.
     result = APPENDMENUQQ(2, $MENUENABLED, '&Help'C, NUL )
     result = APPENDMENUQQ(2, $MENUENABLED, '&QuickWin Help'C, WININDEX)
     INITIALSETTINGS= .true.
  END FUNCTION INITIALSETTINGS

QuickWin executes your INITIALSETTINGS function during initialization, before creating the frame window. When your function is done, control returns to QuickWin and it does the remaining initialization. The control then passes to the Visual Fortran application.

You only need to include the code for an INITIALSETTINGS function in your project. If it is part of your project, you do not need to call your INITIALSETTINGS function.

The INITIALSETTINGS function can specify the position and size of the frame window and the contents of the menus. Because the INITIALSETTINGS function is executed before creating the frame window, it must not call any routines that require that frame window initialization be complete. For example, routines that refer to the child window in focus (such as SETWINDOWCINFIG) or a specific child window unit number (such as OPEN) should not be called from the INITIALSETTINGS function.

Your INITIALSETTINGS function should return .TRUE. if it succeeds, and .FALSE. otherwise. The QuickWin default function returns a value of .TRUE. only.

Note that default menus are created after INITIALSETTINGS has been called, and only if you do not create your own menus. Therefore, using DELETEMENUQQ, INSERTMENUQQ, APPENDMENUQQ, and the other menu configuration QuickWin functions while in INITIALSETTINGS affects your custom menus, not the default QuickWin menus.

Deleting, Inserting, and Appending Menu Items

Menus are defined from left to right, starting with 1 at the far left. Menu items are defined from top to bottom, starting with 0 at the top (the menu title itself). Within INITIALSETTINGS, if you supply it, you can delete, insert, and append menu items in custom menus. Outside INITIALSETTINGS, you can alter the default QuickWin menus as well as custom menus at any point in your application. (Default QuickWin menus are not created until after INITIALSETTINGS has run and only if you do not create custom menus.)

To delete a menu item, specify the menu number and item number in DELETEMENUQQ. To delete an entire menu, delete item 0 of that menu. For example:

  USE DFLIB
  LOGICAL status
  status = DELETEMENUQQ(1, 2) ! Delete the second menu item from
                              ! menu 1 (the default FILE menu).
  status = DELETEMENUQQ(5, 0) ! Delete menu 5 (the default Windows
                              ! menu).

INSERTMENUQQ inserts a menu item or menu and registers its callback routine. QuickWin supplies several standard callback routines such as WINEXIT to terminate a program, WININDEX to list QuickWin Help, and WINCOPY which copies the contents of the current window to the Clipboard. A list of available callbacks is given in the Language Reference for INSERTMENUQQ and APPENDMENUQQ.

Often, you will supply your own callback routines to perform a particular action when a user selects something from one of your menus.

In general, you should not assign the same callback routine to more than one menu item because a menu item's state might not be properly updated when you change it (put a check mark next to it, gray it out, or disable, or enable it). You cannot insert a menu item or menu beyond the existing number; for example, inserting item 7 when 5 and 6 have not been defined yet. To insert an entire menu, specify menu item 0. The new menu can take any position among or immediately after existing menus.

If you specify a menu position occupied by an existing menu, the existing menu and any menus to the right of the one you add are shifted right and their menu numbers are incremented.

For example, the following code inserts a fifth menu item called Position into menu 5 (the default Windows menu):

  USE DFLIB
  LOGICAL(4) status
  status = INSERTMENUQQ (5, 5, $MENUCHECKED, 'Position'C, WINPRINT)

The next code example inserts a new menu called My List into menu position 3. The menu currently in position 3 and any menus to the right (the default menus View, State, Windows, and Help) are shifted right one position:

  USE DFLIB
  LOGICAL(4) status
  status = INSERTMENUQQ(3,0, $MENUENABLED, 'My List'C, WINSTATE)

You can append a menu item with APPENDMENUQQ. The item is added to the bottom of the menu list. If there is no item yet for the menu, your appended item is treated as the top-level menu item, and the string you assign to it appears on the menu bar.

The QuickWin menu routines like INSERTMENUQQ and APPENDMENUQQ let you to create a single level of menu items beneath a menu name. You cannot create submenus with the QuickWin project type.

The following code uses APPENDMENUQQ to append the menu item called Cascade Windows to the first menu (the default File menu):

   USE DFLIB
   LOGICAL(4) status
   status = APPENDMENUQQ(1, $MENUCHECKED, 'Cascade Windows'C,   &
  & WINCASCADE)

The $MENUCHECKED flag in the example puts a check mark next to the menu item. To remove the check mark, you can set the flag to $MENUUNCHECKED in the MODIFYMENUFLAGSQQ function. Some predefined routines (such as WINSTATUS) take care of updating their own check marks. However, if the routine is registered to more than one menu item, the check marks might not be properly updated. See APPENDMENUQQ or INSERTMENUQQ in the Language Reference for the list of callback routines and other flags.

Modifying Menu Items

MODIFYMENUSTRINGQQ can modify the string identifier of a menu item, MODIFYMENUROUTINEQQ can modify the callback routine called when the item is selected, and MODIFYMENUFLAGSQQ can modify a menu item's state (such as enabled, grayed out, checked, and so on).

The following example code uses MODIFYMENUSTRINGQQ to modify the menu string for the fourth item in the first menu (the File menu by default) to Tile Windows, it uses MODIFYMENUROUTINEQQ to change the callback routine called if the item is selected to WINTILE, and uses MODIFYMENUFLAGSQQ to put a check mark next to the menu item:

  status = MODIFYMENUSTRINGQQ( 1, 4, 'Tile Windows'C)
  status = MODIFYMENUROUTINEQQ( 1, 4, WINTILE)
  status = MODIFYMENUFLAGSQQ( 1, 4, $MENUCHECKED)

Creating a Menu List of Available Child Windows

By default, the Windows menu contains a list of all open child windows in your QuickWin applications. SETWINDOWMENUQQ changes the menu which lists the currently open child windows to the menu you specify. The list of child window names is appended to the end of the menu you choose and deleted from any other menu that previously contained it. For example:

   USE DFLIB
   LOGICAL(4) status
   ...
 ! Append list of open child windows to menu 1 (the default File menu)
   status = SETWINDOWMENUQQ(1)

Simulating Menu Selections

CLICKMENUQQ simulates the effect of clicking or selecting a menu command from the Window menu. The QuickWin application behaves as though the user had clicked or selected the command. The following code fragment simulates the effect of selecting the Tile item from the Window menu:

  USE DFLIB
  INTEGER(4) status
  status = CLICKMENUQQ(QWIN$TILE)

Items from the Window menu can be specified in CLICKMENUQQ. Other predefined routines such as WINFULLSCREEN and WINSIZETOFIT (see the callback subroutine names listed in APPENDMENUQQ) can be invoked by calling CLICKMENUQQ with an argument containing the LOC intrinsic function before the callback routine name. For example, the following program calls WINSIZETOFIT:

! Some of the callback subroutine names listed in APPENDMENUQQ may not
! work or be useful in this context, but they will be "called".
! Run the program and note how the scroll bars disappear
      use dflib
      integer*4 result
      character*1 ch
      print *,'type a character'
      read(*,*) ch
      result = clickmenuqq(loc(WINSIZETOFIT))
      print *,'type a character'
      read(*,*) ch
      end


Changing Status Bar and State Messages

Any string QuickWin produces can be changed by calling SETMESSAGEQQ with the appropriate message ID. Unlike other QuickWin message functions, SETMESSAGEQQ uses regular Fortran strings, not null-terminated C strings. For example, to change the PAUSED state message to I am waiting:

  USE DFLIB
  CALL SETMESSAGEQQ('I am waiting', QWIN$MSG_PAUSED)

This function is useful for localizing your QuickWin applications for countries with different native languages. A list of message IDs is given in SETMESSAGEQQ in the Language Reference.


Displaying Message Boxes

MESSAGEBOXQQ causes your program to display a message box. You can specify the message the box displays and the caption that appears in the title bar. Both strings must be null-terminated C strings. You can also specify the type of message box. Box types are symbolic constants defined in DFLIB.MOD, and can be combined by means of the IOR intrinsic function or the .OR. operator. The available box types are listed under MESSAGEBOXQQ in the Language Reference. For example:

   USE DFLIB
   INTEGER(4) response
   response = MESSAGEBOXQQ('Retry or Cancel?'C, 'Smith Chart   &
  & Simulator'C, MB$RETRYCANCELQWIN .OR. MB$DEFBUTTON2)


Defining an About Box

The ABOUTBOXQQ function specifies the message displayed in the message box that appears when the user selects the About command from a QuickWin application's Help menu. (If your program does not call ABOUTBOXQQ, the QuickWin run-time library supplies a default string.) The message string must be a null-terminated C string. For example:

  USE DFLIB
  INTEGER(4) status
  status = ABOUTBOXQQ ('Sound Speed Profile Tables Version 1.0'C)


Using Custom Icons

The QuickWin run-time library provides default icons that appear when the user minimizes the application's frame window or its child windows. You can add custom-made icons to your executable files, and Windows will display them instead of the default icons.

To add a custom child window icon to your QuickWin program:

  1. Select Resource from the Insert menu in the visual development environment. Select Icon from the list that appears. The screen will become an icon drawing tool.

  2. Draw the icon. (For more information about using the Graphics Editor in the visual development environment, see "Resource Editors, Graphics Editor" in the Visual C++ User's Guide.)

    – or –

    If your icon already exists (for example, as a bitmap) and you want to import it, not draw it, select Resource from the Insert menu, then select Import from the buttons in the Resource dialog. You will be prompted for the file containing your icon.

  3. Name the icon. The frame window's icon must have the name "frameicon," and the child window's icon must have the name "childicon." These names must be entered as strings into the Icon Properties dialog box.

    To display the Icon Properties dialog box, double-click in the icon editor area outside the icon's grid or press ALT+ENTER.

    In the ID field on the General tab of Icon Properties dialog box, type over the default icon name with "frameicon" or "childicon." You must add the quotation marks to the text you type in order to make the name be interpreted as a string.

    Your icon will be saved in a file with the extension .ICO.

  4. Create a script file to hold your icons. Select File/Save As. You will be prompted for the name of the script file that will contain your icons. Name the script file. It must end with the extension .RC; for example, myicons.rc. Using this method, the icons and their string values will be automatically saved in the script file. (Alternatively, you can create a script file with any editor and add the icon names and their string values by hand.)

  5. Add the script file to the project that contains your QuickWin application. Select Build and the script file will be built into the application's executable. (The compiled script file will have the extension .RES.)

When you run your application, the icon you created will take the place of the default child or frame icon. Your custom icon appears in the upper-left corner of the window frame. When you minimize the window, the icon appears on the left of the minimized window bar.


Using a Mouse

Your applications can detect and respond to mouse events, such as left mouse button down, right mouse button down, or double-click. Mouse events can be used as an alternative to keyboard input or for manipulating what is shown on the screen.

QuickWin provides two types of mouse functions:

  1. Event-based functions, which call an application-defined callback routine when a mouse click occurs
  2. Blocking (sequential) functions, which provide blocking functions that halt an application until mouse input is made

The mouse is an asynchronous device, so the user can click the mouse anytime while the application is running (mouse input does not have to be synchronized to anything). When a mouse-click occurs, Windows sends a message to the application, which takes the appropriate action. Mouse support in applications is most often event-based, that is, a mouse-click occurs and the application does something.

However, an application can use blocking functions to wait for a mouse-click. This allows an application to execute in a particular sequential order and yet provide mouse support. QuickWin performs default processing based on mouse events.

To change the shape of the mouse cursor, use the SETMOUSECURSOR routine.

Event-Based Functions

The QuickWin function REGISTERMOUSEEVENT registers the routine to be called when a particular mouse event occurs (left mouse button, right mouse button, double-click, and so on). You define what events you want it to handle and the routines to be called if those events occur. UNREGISTERMOUSEEVENT unregisters the routines so that QuickWin doesn't call them but uses default handling for the particular event.

By default, QuickWin typically ignores events except when mouse-clicks occur on menus or dialog controls. Note that no events are received on a minimized window. A window must be restored or maximized in order for mouse events to happen within it.

For example:

  USE DFLIB
  INTEGER(4) result
  OPEN (4, FILE= 'USER')
  ...
  result = REGISTERMOUSEEVENT (4, MOUSE$LBUTTONDBLCLK, CALCULATE)

This registers the routine CALCULATE, to be called when the user double-clicks the left mouse button while the mouse cursor is in the child window opened as unit 4. The symbolic constants available to identify mouse events are:

Mouse Event 1 | Description
MOUSE$LBUTTONDOWN | Left mouse button down
MOUSE$LBUTTONUP | Left mouse button up
MOUSE$LBUTTONDBLCLK | Left mouse button double-click
MOUSE$RBUTTONDOWN | Right mouse button down
MOUSE$RBUTTONUP | Right mouse button up
MOUSE$RBUTTONDBLCLK | Right mouse button double-click
MOUSE$MOVE | Mouse moved

1 For every BUTTONDOWN and BUTTONDBLCLK event there is an associated BUTTONUP event. When the user double-clicks, four events happen: BUTTONDOWN and BUTTONUP for the first click, and BUTTONDBLCLK and BUTTONUP for the second click. The difference between getting BUTTONDBLCLK and BUTTONDOWN for the second click depends on whether the second click occurs in the double-click interval, set in the system's CONTROL PANEL/MOUSE.

To unregister the routine in the preceding example, use the following code:

  result = UNREGISTERMOUSEEVENT (4, MOUSE$LBUTTONDBLCLK)

If REGISTERMOUSEEVENT is called again without unregistering a previous call, it overrides the first call. A new callback routine is then called on the specified event.

The callback routine you create to be called when a mouse event occurs should have the following prototype:

  INTERFACE
    SUBROUTINE MouseCallBackRoutine (unit, mouseevent, keystate, &
     & MouseXpos,MouseYpos)
       INTEGER unit
       INTEGER mouseevent
       INTEGER keystate
       INTEGER MouseXpos
       INTEGER MouseYpos
    END SUBROUTINE
  END INTERFACE

The unit parameter is the unit number associated with the child window where events are to be detected, and the mouseevent parameter is one of those listed in the preceding table. The MouseXpos and the MouseYpos parameters specify the x and y positions of the mouse during the event. The keystate parameter indicates the state of the shift and control keys at the time of the mouse event, and can be any ORed combination of the following constants:

Keystate Parameter | Description
MOUSE$KS_LBUTTON | Left mouse button down during event
MOUSE$KS_RBUTTON | Right mouse button down during event
MOUSE$KS_SHIFT | Shift key held down during event
MOUSE$KS_CONTROL | Control key held down during event

QuickWin callback routines for mouse events should do a minimum of processing and then return. While processing a callback, the program will appear to be non-responsive because messages are not being serviced, so it is important to return quickly. If more processing time is needed in a callback, another thread should be started to perform this work; threads can be created by calling the Win32 API CreateThread. (For more information on creating and using threads, see Creating Multithread Applications.) If a callback routine does not start a new thread, the callback will not be re-entered until it is done processing.

Note: In event-based functions, there is no buffering of events. Therefore, issues such as multithreading and synchronizing access to shared resources must be addressed. To avoid multithreading problems, use blocking functions rather than event-based functions. Blocking functions work well in applications that proceed sequentially. Applications where there is little sequential flow and the user jumps around the application are probably better implemented as event-based functions.

Blocking (Sequential) Functions

The QuickWin blocking function WAITONMOUSEEVENT blocks execution until a specific mouse input is received. This function is similar to INCHARQQ, except that it waits for a mouse event instead of a keystroke.

For example:

   USE DFLIB
   INTEGER(4) mouseevent, keystate, x, y, result
   ...
   mouseevent = MOUSE$RBUTTONDOWN .OR. MOUSE$LBUTTONDOWN
   result = WAITONMOUSEEVENT (mouseevent, keystate, x , y) ! Wait
 ! until right or left mouse button clicked, then check the keystate
 ! with the following:
   if ((MOUSE$KS_SHIFT .AND. keystate) == MOUSE$KS_SHIFT) then      &
  & write (*,*) 'Shift key was down'
   if ((MOUSE$KS_CONTROL .AND. keystate) == MOUSE$KS_CONTROL) then  &
  & write (*,*) 'Ctrl key was down'

Your application passes a mouse event parameter, which can be any ORed combination of mouse events, to WAITONMOUSEEVENT. The function then waits and blocks execution until one of the specified events occurs. It returns the state of the Shift and Ctrl keys at the time of the event in the parameter keystate, and returns the position of the mouse when the event occurred in the parameters x and y.

A mouse event must happen in the window that had focus when WAITONMOUSEEVENT was initially called. Mouse events in other windows will not end the wait. Mouse events in other windows cause callbacks to be called for the other windows, if callbacks were previously registered for those windows.

Default QuickWin Processing

QuickWin performs some actions based on mouse events. It uses mouse events to return from the FullScreen mode and to select text and/or graphics to copy to the Clipboard. Servicing the mouse event functions takes precedence over return from FullScreen mode. Servicing mouse event functions does not take precedence over Cut/Paste selection modes. Once selection mode is over, processing of mouse event functions resumes.


QuickWin Programming Precautions

Two features of QuickWin programming need to applied thoughtfully to avoid non-responsive programs that halt an application while waiting for a process to execute or input to be entered in a child window. The two features are described in the topics:

  • Blocking Procedures
  • Callback Routines


Blocking Procedures

Procedures that wait for an event before allowing the program to proceed, such as READ or WAITONMOUSEEVENT, both of which wait for user input, are called blocking procedures because they block execution of the program until the awaited event occurs. QuickWin child processes can contain multiple callback routines; for example, a different routine to be called for each menu selection and each kind of mouse-click (left button, right button, double-click, and so on).

Problems can arise when a process and its callback routine, or two callback routines within the same process, both contain blocking procedures. This is because each QuickWin child process supports a primary and secondary thread.

As a result of selecting a menu item, a menu procedure may call a blocking procedure, while the main thread of the process has also called a blocking procedure. For example, say you have created a file menu, which contains an option to LOAD a file. Selecting the LOAD menu option calls a blocking function that prompts for a filename and waits for the user to enter the name. However, a blocking call such as WAITONMOUSEEVENT can be pending in the main process thread when the user selects the LOAD menu option, so two blocking functions are initiated.

When QuickWin has two blocking calls pending, it displays a message in the status bar that corresponds to the blocking call first encountered. If there are further callbacks with other blocking procedures in the two threads, the status bar may not correspond to the actual input pending, execution can appear to be taking place in one thread when it is really blocked in another, and the application can be confusing and misleading to the user.

To avoid this confusion, you should try not to use blocking procedures in your callback routines. QuickWin will not accept more than one READ or INCHARQQ request through user callbacks from the same child window at one time. If one READ or INCHARQQ request is pending, subsequent READ or INCHARQQ requests will be ignored and -1 will be returned to the caller.

If you have a child window that in some user scenario might call multiple callback routines containing READ or INCHARQQ requests, you need to check the return value to make sure the request has been successful, and if not, take appropriate action, for example, request again.

This protective QuickWin behavior does not guard against multiple blocking calls through mouse selection of menu input options. As a general rule, using blocking procedures in callback routines is not advised, since the results can lead to program flow that is unexpected and difficult to interpret.


Callback Routines

All callback routines run in a separate thread from the main program. So, all multithread issues are in full force. In particular, sharing data, drawing to windows, and doing I/O must be properly coordinated and controlled. The Visual Fortran Sample POKER.F90 (in the ...\DF98\SAMPLES\QUICKWIN\POKER folder) is a good example of how to control access to shared resources.

QuickWin callback routines, both for menu callbacks and mouse callbacks, should do a minimum of processing and then return. While processing a callback, the program will appear to be non-responsive because messages are not being serviced. This is why it is important to return quickly.

If more processing time is needed in a callback, another thread should be started to perform this work; threads can be created by calling the Win32 API CreateThread. (For more information on creating and using threads, see Creating Multithread Applications.) If a callback routine does not start a new thread, the callback will not be reentered until it is done processing.


Simulating Nonblocking I/O

QuickWin does not accept unsolicited input. You get beeps if you type into an active window if no READ or GETCHARQQ has been done. Because of this, it is necessary to do a READ or GETCHARQQ in order for a character to be accepted. But this type of blocking I/O puts the program to sleep until a character has been typed.

In Fortran Console applications, PEEKCHARQQ can be used to see if a character has already been typed. However, PEEKCHARQQ does not work under Fortran QuickWin applications, since QuickWin has no console buffer to accept unsolicited input. Because of this limitation, PEEKCHARQQ cannot be used as it is with Fortran Console applications to see whether a character has already been typed.

One way to simulate PEEKCHARQQ with QuickWin applications is to add an additional thread:

  • One thread does a READ or GETCHARQQ and is blocked until a character typed.
  • The other thread (the main program) is in a loop doing useful work and checking in the loop to see if the other thread has received input.

For more information, see the Visual Fortran Samples PEEKAPP and PEEKAPP3 in the ...\DF98\SAMPLES\QUICKWIN folder.


Creating Fortran DLLs

A dynamic-link library (DLL) contains one or more subprogram procedures (functions or subroutines) that are compiled, linked, and stored separately from the applications using them. Because the functions or subroutines are separate from the applications using them, they can be shared or replaced easily.

Like a static library, a DLL is an executable file. Unlike a static library where routines are included in the base executable image during linking, the routines in a DLL are loaded when an application that references that DLL is loaded (run time). A DLL can also be used as a place to share data across processes.

The advantages of DLLs include:

  • You can change the functions in a DLL without recompiling or relinking the applications that use them, as long as the functions' arguments and return types do not change.

    This allows you to upgrade your applications easily. For example, a display driver DLL can be modified to support a display that was not available when your application was created.

  • When general functions are placed in DLLs, the applications that share the DLLs can have very small executables.
  • Multiple applications can access the same DLL.

    This reduces the overall amount of memory needed in the system, which results in fewer memory swaps to disk and improves performance.

  • Common blocks or module data placed in a DLL can be shared across multiple processes.

To build a DLL in the visual development environment, specify the Fortran Dynamic-Link Library project type. On the command line, specify the /dll option.

You cannot make a QuickWin application into a DLL (see Using QuickWin) and QuickWin applications cannot be used with Fortran run-time routines in a DLL.

This section describes the following aspects of creating Fortran DLLs:

  • Coding Requirements for Sharing Procedures in DLLs
  • Coding Requirements for Sharing Data in DLLs
  • Building and Using Dynamic-Link Libraries


Coding Requirements for DLLs

Coding Requirements for Sharing Procedures in DLLs

A dynamic-link library (DLL) contains one or more subprograms that are compiled, linked and stored separately from the applications using them.

Coding requirements include using the cDEC$ ATTRIBUTES DLLIMPORT and DLLEXPORT compiler directives. Variables and routines declared in the main program and in the DLL are not visible to each other unless you use DLLIMPORT and DLLEXPORT.

This section discusses aspects of sharing subprogram procedures (functions and subroutines) in a Fortran DLL.

To export and import each DLL subprogram:

  1. Within your Fortran DLL, export each subprogram that will be used outside the DLL. Add a c DEC$ ATTRIBUTES DLLEXPORT directive to declare that a function, subroutine, or data is being exported outside the DLL. For example:
      SUBROUTINE ARRAYTEST(arr)
  !DEC$ ATTRIBUTES DLLEXPORT :: ARRAYTEST
     REAL(4) arr(3, 7)
     INTEGER i, j
     DO i = 1, 3
        DO j = 1, 7
           arr (i, j) = 11.0 * i + j
        END DO
     END DO
  END SUBROUTINE
  2. Within your Fortran application, import each DLL subprogram. Add a c DEC$ ATTRIBUTES DLLIMPORT directive to declare that a function, subroutine, or data is being imported from outside the current image. For example:
      INTERFACE
     SUBROUTINE ARRAYTEST (rarray)
     !DEC$ ATTRIBUTES DLLIMPORT :: ARRAYTEST
        REAL rarray(3, 7)
     END SUBROUTINE ARRAYTEST
  END INTERFACE

    The DLLEXPORT and DLLIMPORT options (for the cDEC$ ATTRIBUTES directive) define a DLL's interface.

    The DLLEXPORT property declares that functions or data are being exported to other images or DLLs, usually eliminating the need for a Linker module definition (.DEF) file to export symbols for the functions or subroutines declared with DLLEXPORT. When you declare a function, subroutine, or data with the DLLEXPORT property, it must be defined in the same module of the same program.

    A program that uses symbols defined in another image (such as a DLL) must import them. The DLL user needs to link with the import LIB file from the other image and use the DLLIMPORT property inside the application that imports the symbol. The DLLIMPORT option is used in a declaration, not a definition, because you do not define the symbol you are importing.

  3. Build the DLL and then build the main program, as described in Building and Using Dynamic-Link Libraries.

Fortran and C applications can call Fortran and C DLLs provided the calling conventions are consistent (see Programming with Mixed Languages, especially Visual Fortran/Visual C++ Mixed-Language Programs).

Visual Basic applications can also call Fortran functions and subroutines in the form of DLLs (see Programming with Mixed Languages, especially Calling Visual Fortran from Visual Basic).

For more information:

  • About building DLLs, see Building and Using Dynamic-Link Libraries.
  • On sharing either common block or module data in a DLL, see Coding Requirements for Sharing Data in DLLs.
  • About importing and exporting subprograms using a Sample program, see the Visual Fortran Sample TLS in folder ...\Df98\Samples\Advanced\Win32.


Coding Requirements for Sharing Data in DLLs

A dynamic-link library (DLL) is an executable file that can be used as a place to share data across processes.

Coding requirements include using the cDEC$ ATTRIBUTES DLLIMPORT and DLLEXPORT compiler directives. Variables and routines declared in the program and in the DLL are not visible to each another unless you use DLLIMPORT and DLLEXPORT.

When sharing data among multiple threads or processes, do the following:

  • Declare the order, size, and data types of shared data consistently in the DLL and in all procedures importing the DLL exported data.
  • If more than one thread or process can write to the common block simultaneously, use the appropriate features of the Windows operating system to control access to the shared data. Such features on Windows NT 4 and Windows 2000 systems include critical sections (for single process, multiple thread synchronization) and mutex objects (for multi-process synchronization).

This section discusses:

  • Exporting and Importing Common Block Data
  • Exporting and Importing Data Objects in Modules

Exporting and Importing Common Block Data

Data and code in a dynamic-link library is loaded into the same address space as the data and code of the program that calls it. However, variables and routines declared in the program and in the DLL are not visible to one another unless you use the c DEC$ ATTRIBUTES DLLIMPORT and DLLEXPORT compiler directives. These directives enable the compiler and linker to map to the correct portions of the address space so that the data and routines can be shared, allowing use of common block data across multiple images.

You can use DLLEXPORT to declare that a common block in a DLL is being exported to a program or another DLL. Similarly, you can use DLLIMPORT within a calling routine to tell the compiler that a common block is being imported from the DLL that defines it.

To export and import common block data:

  1. Create a common block in the subprogram that will be built into a Fortran DLL. Export that common block with a c DEC$ ATTRIBUTES DLLEXPORT directive, followed by the COMMON statement, associated data declarations, and any procedure declarations to be exported. For example:
     !DEC$ ATTRIBUTES DLLEXPORT :: /X/
     COMMON /X/ C, B, A
     REAL C, B, A
     END
     ...

    If the Fortran DLL procedure contains only a common block declaration, you can use the BLOCK DATA statement:

         BLOCK DATA T
 !DEC$ ATTRIBUTES DLLEXPORT :: /X/
     COMMON /X/ C, B, A
     REAL C, B, A
     END

    The Fortran procedure to be linked into a DLL can contain a procedure, such as the following:

        SUBROUTINE SETA(I)
 !DEC$ ATTRIBUTES DLLEXPORT :: SETA, /X/
      COMMON /X/ C, B, A
      REAL C, B, A
      INTEGER I
      A = A + 1.
      I = I + 1
      WRITE (6,*) 'In SETA subroutine, values of A and I:' , A, I
      RETURN
    END SUBROUTINE
  2. Refer to the common block in the main image with a c DEC$ ATTRIBUTES DLLIMPORT directive, followed by the local data declarations and any procedure declarations defined in the exported DLL. For example:
        PROGRAM COMMONX
 !DEC$ ATTRIBUTES DLLIMPORT:: SETA,  /X/
       COMMON /X/ C, B, A
       REAL C, B, A, Q
       EQUIVALENCE (A,Q)

     A = 0.
     I = 0
     WRITE (6,*) 'In Main program before calling SETA...'
     WRITE (6,*) 'values of A and I:' , A, I

     CALL SETA(I)
     WRITE (6,*) 'In Main program after calling SETA...'
     WRITE (6,*) 'values of A and I:' , Q, I

     A = A + 1.
     I = I + 1
     WRITE (6,*) 'In Main program after incrementing values'
  END PROGRAM COMMONX
  3. Build the DLL and then build the main program, as described in Building and Using Dynamic-Link Libraries.

Exporting and Importing Data Objects in Modules

You can give data objects in a module the DLLEXPORT property, in which case the object is exported from a DLL.

When a module is used in other program units, through the USE statement, any objects in the module with the DLLEXPORT property are treated in the program using the module as if they were declared with the DLLIMPORT property. So, a main program that uses a module contained in a DLL has the correct import attributes for all objects exported from the DLL.

You can also give some objects in a module the DLLIMPORT property. Only procedure declarations in INTERFACE blocks and objects declared EXTERNAL or with cDEC$ ATTRIBUTES EXTERN can have the DLLIMPORT property. In this case, the objects are imported by any program unit using the module.

If you use a module that is part of a DLL and you use an object from that module that does not have the DLLEXPORT or DLLIMPORT property, the results are undefined.

For more information:

  • On building a DLL, see Building and Using Dynamic-Link Libraries.
  • On multithread programming, see Creating Multithread Applications.


Building and Using Dynamic-Link Libraries

A dynamic-link library is a collection of source and object code in the same manner as a static library. The differences between the two libraries are:

  • The DLL requires an interface specification.
  • The DLL is associated with a main project during execution, not during linking.

For more information, see:

  • Building Dynamic-Link Libraries
  • The DLL Build Output
  • Checking the DLL Symbol Export Table
  • Building Executables that Use DLLs
  • DLL Sample Programs


Building Dynamic-Link Libraries

When you first create a DLL, you follow the general steps described in Defining Your Project. Select Fortran Dynamic-Link Library as the project type when you create a new project in the Microsoft visual development environment.

To debug a DLL, you must use a main program that calls the library routines (or references the data). From the Project Settings menu, choose the Debug tab. A dialog box is available for you to specify the executable for a debug session.

To build the DLL from the Microsoft visual development environment:

  1. A Fortran DLL project is created like any other project, but you must specify Fortran Dynamic-Link Library as the project type (see Defining Your Project).
  2. Add files to your Fortran DLL project (see Defining Your Project). Include the DLL Fortran source that exports procedures or data as a file in your project.
  3. If your DLL exports data, for both the DLL and any image that references the DLL's exported data, consistently specify the project settings options in the Fortran Data category. In the Fortran Data compiler option category, specify the appropriate values for Common Element Alignment (common block data) and Structure Element Alignment (structures in a module). This sets the /alignment option, which specifies whether padding is needed to ensure that exported data items are naturally aligned.

    For example, in the case of a common block containing four-byte variables, in the Project Setting dialog box you might specify:

    • Open the appropriate workspace
    • From the Project menu, click Settings
    • Click the Fortran tab
    • Select the Fortran Data category
    • In the Common Element Alignment box, specify 4.
  4. If you need to specify linker options, use the Linker tab of the Project Settings dialog box.
  5. Build your Fortran DLL project.

    The Microsoft visual development environment automatically selects the correct linker instructions for loading the proper run-time library routines (located in a DLL themselves). Your DLL is created as a multithread-enabled library. An import library (.LIB) is created for use when you link images that reference the DLL.

To build the DLL from the command line:

  1. If you build a DLL from the command line or use an exported makefile, you must specify the /dll option. For example, if the Fortran DLL source code is in the file f90arr.f90, use the following command line:

  DF /dll f90arr.f90

    This command creates:

    • A DLL named f90arr.dll.
    • An import library, f90arr.lib, that you must link with applications that call your DLL.

    If you also specify /exe:file or /link /out:file, you name a .DLL rather than an .EXE file (the default file extension becomes projectname.DLL instead of projectname.EXE)

    The /dll option selects as the default the DLL run-time libraries to support multithreaded operation.

  2. If your DLL will export data, the procedures must be compiled and linked consistently. Consistently use the same /alignment option for the DLL export procedure and the application that references (imports) it. The goal is to specify padding to ensure that exported data items are naturally aligned, including common block data items and structure element alignment (structures in a module).
  3. If you need to specify linker options, place them after the /link option on the DF command line.
  4. Build the application.

    For example, if your DLL exports a common block containing four-byte variables, you might use the following command line (specify the /dll option):

      DF /align:commons /dll dllfile.for

    The /dll option automatically selects the correct linker instructions for loading the proper run-time library routines (located in a DLL themselves). Your DLL is created as a multithread-enabled library.

For more information, see:

  • The DLL Build Output
  • Checking the DLL Symbol Export Table
  • Building Executables that Use DLLs
  • DLL Sample Programs


The DLL Build Output

When a DLL is built, two library files are created:

  • An import library (.LIB), which the linker uses to associate a main program with the DLL.
  • The .DLL file containing the library's executable code.

Both files have the same basename as the library project by default.

Your library routines are contained in the file projectname.DLL located in the default directory for your project, unless you specified another name and location. Your import library file is projectname.LIB, located in the default directory for your project.


Checking the DLL Symbol Export Table

To make sure that everything that you want to be visible shows up in the export table, look at the export information of an existing DLL file by using QuickView in the Windows Explorer File menu or the following DUMPBIN command:

  DUMPBIN /exports file.dll


Building Executables that Use DLLs

When you build the executable that imports the procedures or data defined in the DLL, you must link using the import library, check certain project settings or command-line options, copy the import library so the Linker can locate it, and then build the executable.

To use the DLL from another image:

  1. Add the import .LIB file with its path and library name to the other image.

    In the visual development environment, add the .LIB import library file to your project. In the Project menu, click Add to project, then Files.

    On the command line, specify the .LIB file on the command line.

    The import .LIB file contains information that your program needs to work with the DLL.

  2. If your DLL exports data, consistently use the same project settings options in the Fortran Data category /alignment option as was used to create the DLL. In the Fortran Data compiler option category, specify the appropriate values for Common Element Alignment (common block data) and Structure Element Alignment (structures in a module). This sets the /alignment option, which specifies whether padding is needed to ensure that imported data items are naturally aligned.
  3. In the Project Settings dialog box (Fortran tab), make sure the type of libraries specified is consistent with that specified for the Fortran DLL.
  4. If you need to specify linker options:
    • In the visual development environment, specify linker options in the Linker tab of the Project Settings dialog box.
    • On the DF command line, place linker options after the /link option.
  5. Copy the DLL into your path.

    For an application to access your DLL, it must be located in a directory on the search path or in the same directory as the main project. If you have more than one program accessing your DLL, you can keep it in a convenient directory identified in the environment path. If you have several DLLs, you can place them all in the same directory to avoid adding numerous directories to the path specification.

    When changing your path specification on a Windows Me, Windows 98, or Windows 95 system, you must restart the operating system for the change to take effect. On a Windows NT 4 or Windows 2000 system, you should log out and back in after modifying the system path.

  6. Build the image that references the DLL.

    When using the visual development environment:

    • Make sure you have added the import library (created when you built the DLL file) to the project by (click the FileView tab).
    • Like building other projects in the visual development environment, use the Build menu items to create the executable (see Defining Your Project).

    When using the command line:

    • Specify the import library at the end of the command line.
    • If your DLL exports data that will be used by the application being built, specify the same /alignment options that were used to build the DLL.
    • If you are building a main application, omit the /dll option.
    • When building a Fortran DLL that references another DLL, specify the /dll option.

    For example, to build the main application from the command line that references 4-byte items in a common block defined in dllfile.dll:

      DF /align:commons mainapp.f90 dllfile.lib


DLL Sample Programs

Visual Fortran provides Sample programs are installed in ...\Df98\SAMPLES\ when you request the Samples with a custom installation. You can copy the Samples folders from the ...\DF\SAMPLES\ folder on the Visual Fortran CD-ROM to your hard disk.

For an example of a DLL, see the Samples folder ...\DF98\SAMPLES\ADVANCED\WIN32\TLS, which creates a DLL as a subproject. The subproject DLL is used in a second project.

Other Samples that use DLLs are folders in ...\DF98\SAMPLES\DLL\. For example:

  • The files associated with Sample DLLEXP2 are in the folder ...\DF98\SAMPLES\DLL\DLLEXP2\. DLLEXP2 demonstrates how COMMON variables defined in a DLL can be shared between multiple programs. To build DLLEXP2, use the makefile.
  • The Sample Loadexp1 shows how to dynamically load a DLL by using the LoadLibrary and GetProcAddress Win32 routines. The folder ...\DF98\SAMPLES\DLL\Loadexp1\ contains the source files and a project workspace file.

For a description of the Samples, see Visual Fortran Samples.


Creating Windows Applications

With Visual Fortran, you can build Fortran applications that are also fully-featured Windows applications. You can create full Windows applications that use the familiar Windows interface, complete with tool bars, pull-down menus, dialog boxes, and other features. You can include data entry and mouse control, and interaction with programs written in other languages or commercial programs such as Microsoft Excel.

With full Windows programming you can:

  • Deliver Fortran applications with a Windows Graphical User Interface (GUI). GUI applications typically use at least the Graphic Device Interface (GDI) and USER32 Win32 routines.
  • Access all available Windows GDI calls with your Fortran applications. GDI functions use a 32-bit coordinate system, allowing coordinates in the +/-2 GB range, and performs skewing, reflection, rotation and shearing.

Only the Fortran Windows project type provides access to the full set of Win32 routines needed to create GUI applications. Windows projects are much more complex than other kinds of Visual Fortran projects. Before attempting to use the full capabilities of Windows programming, you should be comfortable with writing C applications and should familiarize yourself with the Win32 Software Development Kit (SDK).

To build your application as a Fortran Windows application in the visual development environment, choose Fortran Windows Application from the list of Project types when you open a new project.

When using the command line, specify the /winapp option to search the commonly used link libraries.

Fortran Windows applications must use the DFWIN module or subset of DFWIN (see Calling Win32 Routines).

The following Fortran Windows application topics are discussed:

  • Calling Win32 Routines
  • Coding Requirements for Fortran Windows Applications
  • Using Menus and Dialogs in SDI and MDI Fortran Windows Applications
  • Sample Fortran Windows Applications
  • Getting Help with Windows Programming


Calling Win32 Routines

This section describes general information about calling Win32 routines from Visual Fortran applications. It describes the following topics:

  • A Comparison of Visual Fortran and Win32 Routines
  • Including the Visual Fortran Interface Definitions for Win32 Routines
  • Calling Win32 Routines Using the Visual Fortran Interface Definitions
  • Special Naming Convention for Certain QuickWin and Win32 Graphics Routines
  • Understanding Data Types Differences
  • Examples Programs and Samples
  • Additional Resources

A Comparison of Visual Fortran and Win32 Routines

Visual Fortran provides Fortran 95/90 language elements (such as intrinsic procedures and statements) that conform to the Fortran 95 standard. Visual Fortran also provides language elements that are language extensions, including library routines.

The library routines provided by Visual Fortran:

  • Are intended to be called from the Fortran language. For example, character arguments are assumed to be Fortran character variables, not null-terminated C strings.
  • May have QQ appended at the end of their names to differentiate them from equivalent Win32 operating system routines.
  • Are described in the Visual Fortran Language Reference online documentation, in the A to Z Reference. The routine description lists the appropriate USE statement needed to include the interface definitions, such as USE DFLIB.
  • Call appropriate Windows system (Win32) routines provided with the operating system.
  • Are specific to Windows systems (one exception: most of the Visual Fortran Portability Library routines exist on most U*X systems).

In contrast, the Win32 Application Programming Interface (API) routines provided by the Windows operating system:

  • Are intended to be called from the C language. For example, character arguments are assumed to be null-terminated C strings.

    However, Visual Fortran provides interface block definitions that simplify calling Win32 routines from Visual Fortran (such as allowing you to specify Fortran data arguments as being passed by reference). To obtain these interface definitions, add the USE DFWIN line to your program (explained below).

  • Often have multiple words appended together in their names, such as GetSystemTime.
  • Are described in the Platform SDK online documentation. To look up a specific routine, use the Index or Search tabs in HTML Help viewer. The calling format is listed near the top of the page, followed by a description of the routine's arguments. The QuickInfo at the bottom of the Win32 routine documentation page lists the import library needed.
  • Are also specific to Windows operating systems.

There are many groups of Win32 routines (see the Platform SDK and other resources). Win32 routines provide sophisticated window management, memory management, graphics support, threading, security, and networking.

You can access many Win32 routines from any Fortran application, including Fortran Console and Fortran QuickWin applications. Only the Fortran Windows application project type provides access to the full set of Win32 routines needed to create GUI applications.

Fortran Console applications are text-only applications. Fortran QuickWin applications allow you to build Windows style applications easily, but access only a small subset of the available Win32 API features. (Fortran QuickWin applications also allow you to use graphics.) For differences between Fortran QuickWin and Fortran Windows applications, see Comparing QuickWin with Windows-Based Applications.

Including the Visual Fortran Interface Definitions for Win32 Routines

Visual Fortran provides interface definitions for both the Visual Fortran library routines and nearly all of the Win32 API routines in the standard include directory:

  ...\DF98\INCLUDE\

To include the Win32 interface definitions, do one of the following:

  1. Add the statement USE DFWIN to include all Win32 API routine definitions.

    The USE DFWIN statement makes all parameters and interfaces for most Windows routines available to your Visual Fortran program. Any program or subprogram that uses the Windows features can include the statement USE DFWIN, which is needed in each subprogram that makes graphics calls.

    Add the USE statement before any declaration statements (such as IMPLICIT NONE or INTEGER) or any other modules containing declaration statements.

  2. You can limit the type of parameters and interfaces for Windows applications to make compilation times faster. To do this, include only the subsets of the Win32 API needed in multiple USE statements (see the file ...\DF98\INCLUDE\DFWIN.F90).

    To locate the specific libraries for the routines being called, view the QuickInfo at the bottom of the routine page in the Platform SDK documentation, which lists the import library name. For example, to call only GetSystemTime, you need the interface definitions provided in kernel32.mod (binary form). To do this, add the following USE statement:

     USE KERNEL32

    If you want to further minimize compile time, add the ONLY keyword to the USE statement. For example:

     USE KERNEL32, only: GetSystemTime, GetLastError

Calling Win32 Routines Using the Visual Fortran Interface Definitions

To call the appropriate Win32 routine after including the Visual Fortran interface definitions, follow these guidelines:

  1. Examine the documentation for the appropriate routine in the Platform SDK (for example GetSystemTime) to obtain the following information:
    • The number and order of arguments. You will need to declare and initialize each argument variable using the correct data type. In the case of the GetSystemTime routine, a structure (derived type) is passed by reference.

      If character arguments are present, add a null character as a terminator to the character variable before calling the Win32 routine.

    • Whether the routine returns a result (a function) or not (subroutine). For example, the GetSystemTime routine calling format starts with VOID, so this routine should be called as a subroutine with a CALL statement.

  2. If you are not sure about the data type of arguments or its function return value, you can examine the interface definitions in the appropriate .F90 file in ...\DF98\INCLUDE\. For example, to view the interface definition for GetSystemTime:
    1. In a text editor (such as Notepad), open the file kernel32.f90 from ...\DF98\INCLUDE\.
    2. Search (or Find) the routine name (such as GetSystemTime)
    3. View the interface definition and copy-and-paste parts of it into your source file text editor window.

  3. If one of the arguments is a structure, you should look up the definition in DFWINTY.F90 in ...\DF98\INCLUDE\. For example, to view the data type definition for the T_SYSTEMTIME type used in GetSystemTime:
    1. In a text editor (such as Notepad), open the file DFWINTY.F90 from ...\DF98\INCLUDE\.
    2. Search (or Find) the data type name (such as T_SYSTEMTIME).
    3. View the data type definition and copy-and-paste parts of it into your source file text editor window. Note the defined field names for later use.
    4. Define a variable name to use the derived-type definition in your program, such as:
      TYPE (T_SYSTEMTIME) MYTIME
    5. Use the variable definition to call the Win32 routine. For example, the completed program follows:
       !  Getsystime.f90 file, shows how to call a Win32 routine
 !
 ! Since the only routine called is GetSystemTime, only include
 ! interface definitions from kernel32.mod instead of all modules
 ! included by dfwin.f90. Type definitions are defined in DFWINTY,
 ! which is used within KERNEL32.

  PROGRAM Getsystime

   USE KERNEL32

   TYPE (T_SYSTEMTIME) MYTIME

   CALL GetSystemTime(MYTIME)

   WRITE (*,*) 'Current UTC time hour and minute:', Mytime.wHour, Mytime.Wminute

  END PROGRAM

      You might create a new Fortran Console (or QuickWin) application project, add the code shown above as a source file, build it, and view the result.

Special Naming Convention for Certain QuickWin and Win32 Graphics Routines

Most QuickWin routines have a QQ appended to their name ito differentiate them from equivalent Win32 operating system routines. However, a small group of QuickWin graphics routines have the same name as the Win32 routines, causing a potential naming conflict if your program unit includes both USE DFLIBS (which includes QuickWin routine interface definitions) and USE DFWIN (which includes Win32 API routine interface definitions).

The QuickWin routines perform the same functions as the SDK routines but take a unit number, or use the unit in focus at the time of call, instead of taking a device context (DC) as one of their arguments.

To handle this situation, a special MSFWIN$ prefix is used for the Win32 routines. These prefixed names must be used even if you only specify USE DFWIN.

For example, Rectangle is a QuickWin routine, not a Win32 SDK routine, and you must use the name MSFWIN$Rectangle to refer to the SDK routine:

QuickWin Routine | Win32 API Routine
ARC | MSFWIN$Arc
ELLIPSE | MSFWIN$Ellipse
FLOODFILL | MSFWIN$FloodFill
GETBKCOLOR | MSFWIN$GetBkColor
GETPIXEL | MSFWIN$GetPixel
GETTEXTCOLOR | MSFWIN$GetTextColor
LINETO | MSFWIN$LineTo
PIE | MSFWIN$Pie
POLYGON | MSFWIN$Polygon
RECTANGLE | MSFWIN$Rectangle
1 | MSFWIN$SelectPalette
SETBKCOLOR | MSFWIN$SetBkColor
SETPIXEL | MSFWIN$SetPixel
SETTEXTCOLOR | MSFWIN$SetTextColor

1 There is no longer a QuickWin routine named SELECTPALLETE.

Understanding Data Type Differences

The files referenced by the DFWIN module are a Fortran version (a subset) of the Win32 WINDOWS.H header file. The correspondence of data types is given in the following table:

Win32 Data Type | Equivalent Fortran Data Type
BOOL, BOOLEAN | LOGICAL(4)
BYTE | BYTE
CHAR, CCHAR, UCHAR | CHARACTER
COLORREF | INTEGER(4)
DWORD, INT, LONG, ULONG | INTEGER(4)
SHORT, USHORT, WORD | INTEGER(2)
FLOAT | REAL(4)
All Handles | INTEGER(4)
All Pointers (LP*, P*) | INTEGER(4) (Integer Pointers)

Other notes about equivalent data types for arguments:

  • If an argument is described in the Platform SDK documentation as a pointer, then the corresponding Fortran interface definition of that argument would have the REFERENCE property (see the cDEC$ ATTRIBUTES directive). Older interface definitions use the Compaq Fortran pointer data type and pass the address of the argument.
  • Pointer arguments are currently 32-bit (4 bytes) in length. A future version of the Windows operating system will support 64-bit (8-byte) pointer arguments.
  • Be aware that Fortran character variables need to be null-terminated. This code shows the extension of using the null-terminator for the string in the Fortran DATA statement (see C Strings):
       DATA forstring /'This is a null-terminated string.'C/

    You can also use the CHAR intrinsic:

      character(LEN=32) forstring
  forstring= "Courier New" // CHAR(0)

The structures in WINDOWS.H have been converted to derived types in DFWINTY. Unions in structures are converted to union/maps within the derived type. Names of components are unchanged. Bit fields are converted to Fortran's INTEGER(4). Functions accessing bit fields are contained in the DFWIN.F90 module with names of the form:

   StructureName$BitfieldName

These bit field functions take an integer argument and return an integer. All bit fields are unsigned integers. The following shows the WINDOWS.H definition. It is followed by an example program where Win32 structures are represented as Fortran derived types.

WINDOWS.H Definition

typedef struct _LDT_ENTRY {
  WORD LimitLow;
  WORD BaseLow;
  union {
     struct {
        BYTE BaseMid;
        BYTE Flags1;
        BYTE Flags2;
        BYTE BaseHi;
     } Bytes;

     struct {
        DWORD BaseMid : 8;
        DWORD Type : 5;
        DWORD Opl : 2;
        DWORD Pres : 1;
        DWORD LimitHi : 4;
        DWORD Sys : 1;
        DWORD Reserved_0 : 1;
        DWORD Default_Big : 1;
        DWORD Granularity : 1;
        DWORD BaseHi : 8;
     } Bits;
  } HighWord;
 } LDT_ENTRY, *PLDT_ENTRY;

Note that _LDT_ENTRY and PLDT_ENTRY do not exist in the Fortran definition. Also note that Bits.xxx is not the same as the C version. In the Fortran case, the bit field functions must be used. For example, the C variable yyy.HighWord.Bits.BaseHi is represented in Fortran by LDT_ENTRY$BaseHi(ldtentry%HighWord%bits).

The following Fortran example shows the use of the corresponding Fortran data definitions and the use of a bit extraction utility routine:

Program Test
    type T_LDT_ENTRY$HIGHWORD_BYTES
       sequence
       BYTE  BaseMid
       BYTE  Flags1
       BYTE  Flags2
       BYTE  BaseHi
    end type T_LDT_ENTRY$HIGHWORD_BYTES

    type  T_LDT_ENTRY$HIGHWORD
       sequence
       union
          map
             type (T_LDT_ENTRY$HIGHWORD_BYTES)  Bytes
          end map
          map
             integer(4)  Bits
          end map
       end union
    end type T_LDT_ENTRY$HIGHWORD

    type T_LDT_ENTRY
       sequence
       integer(2) LimitLow
       integer(2) BaseLow
       type (T_LDT_ENTRY$HIGHWORD)  HighWord
    end type T_LDT_ENTRY

type(T_LDT_ENTRY) ldtentry

integer(4) thebits

external LDT_ENTRY$BaseHi
integer(4) LDT_ENTRY$BaseHi

ldtentry%HighWord%bits = #ABFFFFFF

thebits = LDT_ENTRY$BaseHi(ldtentry%HighWord%bits)
write(*,'(Z)') thebits
end program Test

integer(4) function LDT_ENTRY$BaseHi (Bits)
integer(4)   Bits
   LDT_ENTRY$BaseHi = IAND(ISHFT(bits,-24),#FF)
end function LDT_ENTRY$BaseHi

In addition to using the TYPE statement, you can use the STRUCTURE statement as shown by the following example. If you have embedded data types, the data type definitions are easier to read. Also, selecting the components is more natural. For example:

  program struct
 STRUCTURE /T_LDT_ENTRY/
    integer(2) LimitLow
    integer(2) BaseLow
    UNION
       MAP
         STRUCTURE /f_Bytes/ Bytes
            BYTE  BaseMid
            BYTE  Flags1
            BYTE  Flags2
            BYTE  BaseHi
         END STRUCTURE
       END MAP

       MAP
         STRUCTURE /f_Bits/ Bits
             INTEGER(4) Bits
         END STRUCTURE
       END MAP
    END UNION
 END STRUCTURE

 type(T_LDT_ENTRY) ldtentry

 ldtentry%Bits%Bits = #7f6f5f4f
 write(*,'(8Z)') ldtentry%Bits%Bits
 write(*,'(8Z)') ldtentry%Bytes%BaseMid

 end program

The expected program output follows:

 7F6F5F4F
  4F

You can create a data object defined by a STRUCTURE statement in two ways, by using one of the following:

  • type(T_LDT_ENTRY) ldtentry
  • RECORD /T_LDT_ENTRY/ ldtentry

The example program shows how to access a field in a structured data object, for example:

 I4=ldtentry%Bits%Bits

Examples Programs and Samples

Visual Fortran provides many Sample programs that show Fortran Windows applications that call Win32 routines, such as the following:

  • Fortran Console applications in the folder ...\Df98\Misc, such as Console and Forprint.
  • Fortran QuickWin applications in the folder ...\Df98\QuickWin, such as Conapp, Cleanwin, and Testscrl.
  • Fortran Windows applications the folder ...\Df98\Advanced\Win32, such as Generic and Bounce.

Additional Resources

For more information about Win32 API routines and Windows programming, see the following:

  • Platform SDK online HTML Help title
  • Microsoft Win32 Developer's Reference Library by David Iseminger (Microsoft Press)
  • Programming Windows by Charles Petzold (Microsoft Press)
  • Windows NT Win32 API SuperBible by Richard Simon (Waite Group Press)
  • Win32 Programming by Brent Rector and Joseph Newcomer (Addison-Wesley)
  • Win32 System Programming by Johnson Hart (Addison-Wesley)

Visual Fortran provides an online bookstore that lists suggested titles:

  1. Open the Visual Fortran home page (http://www.compaq.com/fortran)
  2. Click Bookstore in the left margin
  3. Click the link to the Compaq Fortran Online Bookstore
  4. Click the link for the appropriate area of interest, such as Win32
  5. View the descriptions of the appropriate books


Coding Requirements for Fortran Windows Applications

This section contains the following topics:

  • General Coding Requirements: WinMain Function and USE Statements
  • Code Generation Options Using the Fortran Windows Application Wizard
  • Single Document Interface (SDI) or Multiple Document Interface (MDI) Applications
  • Dialog-Based Applications

General Coding Requirements: WinMain Function and USE Statements

Coding requirements for Fortran Windows applications include (in the following order):

  1. WinMain function declaration and interface

    The WinMain function declaration and interface are required for Windows Graphical User Interface (GUI) applications (typically use at least the GDI and USER32 Win32 routines). An interface block for the function declaration can be provided. On ia32 systems, the following function must be defined by the user:

          INTEGER(4) function WinMain ( hInstance, hPrevInstance, &
     &         lpszCmdLine, nCmdShow )
!DEC$ ATTRIBUTES STDCALL, ALIAS:'_WinMain@16' :: WinMain
         INTEGER(4), INTENT(IN) :: hInstance, hPrevInstance
         INTEGER(4), INTENT(IN) :: lpszCmdLine
         INTEGER(4), INTENT(IN) :: nCmdShow

    In a program that includes a WinMain function, no program unit can be identified as the main program with the PROGRAM statement.

  2. The statement USE DFWIN or other appropriate USE statements

    The USE DFWIN statement makes all parameters and interfaces for nearly all Windows public routines available to your Visual Fortran program. Any program or subprogram that uses the Windows features must include the statement USE DFWIN, which must appear in each subprogram that makes graphics calls, before any declaration statements (such as IMPLICIT NONE or INTEGER) or any other modules containing declaration statements.

    If you want to limit the type of parameters and interfaces for Windows applications or if unresolved references occur when linking your Fortran Windows application, see Calling Win32 Routines.

  3. Data declarations for the WinMain function arguments.

  4. Application-dependent code (other USE statements, variable declarations, and then executable code).

For example, the first lines of the Visual Fortran Sample named Generic uses the following free-form source code and conditional ia32 and ia64 code:

 integer function WinMain( hInstance, hPrevInstance, lpszCmdLine, nCmdShow )
 !DEC$ IF DEFINED(_M_IX86)
 !DEC$ ATTRIBUTES STDCALL, ALIAS : '_WinMain@16' :: WinMain
 !DEC$ ELSE
 !DEC$ ATTRIBUTES STDCALL, ALIAS : 'WinMain' :: WinMain
 !DEC$ ENDIF
 use dfwin

 integer hInstance
 integer hPrevInstance
 integer nCmdShow
 integer lpszCmdLine
 .
 .
 .

This Sample uses the IF Directive Construct and a predefined preprocessor symbol _M_IX86 to generate portable conditional code. For a description of predefined preprocessor symbols (such as _M_IX86 and _M_IA64), see the /define compiler option.

DFWIN.F90 includes a Fortran version (a subset) of the Win32 WINDOWS.H header file (see Calling Win32 Routines).

Code Generation Options Using the Fortran Windows Application Wizard

When you create a project with the Fortran Windows Application project type, the Fortran Windows Application Wizard (AppWizard) appears, allowing you to select whether the new project being created will have source code, type of tutorial source code, and specify other options:

appwizard for fortran windows projects

If selected, you can specify whether the source file will contain template-like source statements typically used by one of the Fortran Windows applications subtypes:

  • Single document interface (SDI) or multiple document interface (MDI) applications
  • Dialog-based applications

If your application (SDI, MDI, or dialog-based) will use ActiveX controls in a dialog box, if you check the box labeled "This project will use ActiveX controls," the Fortran Windows AppWizard will add additional template code for supporting ActiveX controls in your dialog boxes.

To select project options that request that the project be linked against dynamic-link libraries (instead of static libraries), click the check box labeled "This project will be linking against one or more Fortran DLL Import libraries."

Single Document Interface (SDI) or Multiple Document Interface (MDI) Applications

Creating these applications requires advanced programming expertise and knowledge of the Win32 routines API. Such applications call certain library routines and requires the statement USE DFWIN and usually USE DFLIB. SDI applications display a single window, whereas MDI application can display multiple windows (a main frame window with one or more child windows that appear within the frame window).

For example, select the MDI option from the Fortran AppWizard screen. After you build and run the application (without changing the source files), the following screen might appear after you create two child window by clicking New from the File menu twice:

fortran appwizard mdi sample

If you selected the SDI option from the Fortran AppWizard screen and built and ran the application, you could not create child windows within the main window.

For more information:

  • On using menus and dialogs from SDI and MDI Fortran Windows applications, see Using Menus and Dialogs in SDI and MDI Fortran Windows Applications
  • About SDI and MDI Samples that use the Fortran Windows project type, see Sample Fortran Windows Applications.

Dialog-Based Applications

Dialog applications use a dialog box for the application's main window. Creating these applications requires some knowledge of the Win32 routines API, but considerably less than for a SDI or MDI application. These applications call certain Visual Fortran library routines and requires the statements USE DFWIN and USE DFLOGM. Dialog-based applications usually do not have menus.

For example, select the Dialog-based applications from the Fortran AppWizard screen. After you build and run the application (without changing the source files), the following dialog box appears:

fortran appwizard dialog-based sample

For more information:

  • On using dialogs, see Using Dialogs.
  • About dialog Samples that use the Fortran Windows project type, see Sample Fortran Windows Applications.


Using Menus and Dialogs in SDI and MDI Fortran Windows Applications

This section describes the following topics:

  • Creating the Menu
  • Using the Menu
  • Handling Menu Messages
  • Using Dialogs in an SDI or MDI Application

Creating the Menu

When you create a new SDI or MDI application using the Fortran Windows AppWizard, a default menu bar is created for you. The default menu bar contains many of the menu entries that are common to Windows applications. You can modify the default menu, or create a new menu, by using the Menu Editor, which is one of the Developer Studio Resource Editors.

To create a new menu resource (menu bar):

  1. Click Resource from the Insert menu
  2. Select Menu as the resource type

The menu bar consists of multiple menu names, where each menu name contains one or more items. You can use the Menu Editor to create submenus (select the pop-up property).

To edit an existing menu:

  1. Select the ResourceView
  2. Expand the Menu item in the list of resource types
  3. Double click on the menu mame

For more information about the menu resource editor, see the Visual C++ User's Guide section on Resource Editors.

Using the Menu

To use a menu bar in your Fortran application, you must load the menu resource and use it when creating the main window of the application. Code to do this is created automatically by the Fortran Windows AppWizard. The code that loads the menu resource is:

 ghMenu = LoadMenu(hInstance, LOC(lpszMenuName))

The returned menu handle is then used in the call to CreatWindowEx:

 ghwndMain = CreateWindowEx( 0, lpszClassName,         &
                                lpszAppName,               &
                                INT(WS_OVERLAPPEDWINDOW),  &
                                CW_USEDEFAULT,             &
                                0,                         &
                                CW_USEDEFAULT,             &
                                0,                         &
                                NULL,                      &
                                ghMenu,                    &
                                hInstance,                 &
                                NULL                       &
                              )

Handling Menu Messages

Windows sends a WM_COMMAND message to the main window when the user selects an item from the menu. The wParam parameter to the WM_COMMAND message contains:

  • The low-order word specifies the identifier of the menu item
  • The high-order word specifies either 0 if the message is from a menu item, or 1 if the message is the result of an accelerator key. It is usually not important to distinguish between these two cases, but you must be careful to compare against only the low-order word as in the example below.

For example, the following code from the main window procedure generated by the Fortran Windows AppWizard handles the WM_COMMAND messages from the File menu Exit item and the Help menu About item:

 ! WM_COMMAND: user command
    case (WM_COMMAND)
     select case ( IAND(wParam, 16#ffff ) )

        case (IDM_EXIT)
            ret = SendMessage( hWnd, WM_CLOSE, 0, 0 )
             MainWndProc = 0
             return

         case (IDM_ABOUT)
             lpszName = "AboutDlg"C
             ret = DialogBoxParam(ghInstance,LOC(lpszName),hWnd,&
               LOC(AboutDlgProc), 0)
             MainWndProc = 0
             return

     ...

For advanced techniques with using menus, refer to the online Platform SDK section on User Interface Services, for subsections: Windows User Interface, Resources, Menus.

Using Dialogs in an SDI or MDI Application

An Fortran Windows SDI or MDI application that uses dialogs has the choice of using:

  • The Visual Fortran Dialog routines
  • The native Win32 APIs for creating dialog boxes

For any particular dialog box, you should use either the Visual Fortran Dialog routines or the native Win32 dialog box APIs. For example, if you create a dialog box using Win32 APIs, you cannot use the Visual Fortran dialog routines to work with that dialog box.

You should Note, for example, that the code generated by the Fortran Windows AppWizard uses the native Win32 APIs to display the About dialog box.

For more information:

  • On using the Visual Fortran Dialog routines, see Using Dialogs
  • On using the Win32 APIs, see the online Platform SDK section on User Interface Services, for subsections: Windows User Interface, Windowing, Dialog Boxes.


Sample Fortran Windows Applications

The Visual Fortran Samples ...\DF98\SAMPLES\ADVANCED folder contains many Fortran Windows applications that demonstrate Windows functionality or a particular Win32 function. Each sample application is in separate folder.

Users unfamiliar with full Windows applications should start by looking at:

  • Sample SDI and MDI Fortran Windows Samples in ...\DF98\SAMPLES\ADVANCED\WIN32, such as Generic, Platform, or Polydraw.
  • Sample dialog Fortran Windows Samples in ...\DF98\SAMPLES\DIALOG, such as THERM or MMPLAYER. For more information about coding reqirements for dialog boxes and using the Dialog Resource editor, see Using Dialogs.


Getting Help with Windows Programming

In HTML Help Viewer, you can access the title "Platform SDK Documentation."

The full Win32 API set is documented in the Win32 Application Programming Interface for Windows NT Programmer's Reference, available from Microsoft Press® and also distributed as part of the online Platform Software Development Kit (sdk).

Other titles related to Windows programming and calling Win32 APIs are listed in Additional Resources (in Calling Win32 Routines), which describes the Visual Fortran Online Bookstore.


Portability and Design Considerations

Before you can start to write new programs or port existing ones to Visual Fortran, you must decide what to build and how to build it. This section covers the following topics:

  • Portability considerations
  • Choosing Your Development Environment with Visual Fortran
  • Selecting a Program Type that you can build
  • Structuring Your Program
  • Special Design Considerations
  • Using the Special Features of Microsoft Windows with your programs


Portability

This section presents topics to help you understand how language standards, operating system differences, and computing hardware influence your use of Visual Fortran and the portability of your programs.

Your program is portable if you can implement it on one hardware-software platform and then move it to additional systems with a minimum of changes to the source code. Correct results on the first system should be correct on the additional systems. The number of changes you might have to make when moving your program varies significantly. You might have no changes at all (strictly portable), or so many (non-portable customization) that it is more efficient to design or implement a new program. Most programs in their lifetime will need to be ported from one system to another, and this section can help you write code that makes this easy.

For information on special library routines to help port your program from one system to another, see Portability Library.

For more information:

  • Standard Fortran Language
  • Operating System
  • Storage and Representation of Data


Standard Fortran Language

A language standard specifies the form and establishes the interpretation of programs expressed in the language. Its primary purpose is to promote, among vendors and users, portability of programs across a variety of systems.

The vendor-user community has adopted four major Fortran language standards. ANSI (American National Standards Institute) and ISO (International Standards Organization) are the primary organizations that develop and publish the standards.

The major Fortran language standards are:

  • FORTRAN IV

    American National Standard Programming Language FORTRAN, ANSI X3.9-1966. This was the first attempt to standardize the languages called FORTRAN by many vendors.

  • FORTRAN 77

    American National Standard Programming Language FORTRAN, ANSI X3.9-1978. This standard added new features based on vendor extensions to FORTRAN IV and addressed problems associated with large-scale projects, such as improved control structures.

  • Fortran 90

    American National Standard Programming Language Fortran, ANSI X3.198-1992 and International Standards Organization, ISO/IEC 1539: 1991, Information technology -- Programming languages -- Fortran. This standard emphasizes modernization of the language by introducing new developments. For information about differences between Fortran 90 and FORTRAN 77, see Features of Fortran 90 or the printed Compaq Fortran Language Reference Manual.

  • Fortran 95

    American National Standard Programming Language Fortran and International Standards Organization, ISO/IEC 1539-1: 1997(E), Information technology -- Programming languages -- Fortran. This recent standard introduces certain language elements and corrections into Fortran 90. Fortran 95 includes Fortran 90 and most features of FORTRAN 77. For information about differences between Fortran 95 and Fortran 90, see Features of Fortran 95 or the printed Compaq Fortran Language Reference Manual.

Although a language standard seeks to define the form and the interpretation uniquely, a standard might not cover all areas of interpretation. It might also include some ambiguities. You need to carefully craft your program in these cases so that you get the answers that you want when producing a portable program.

For more information:

  • Standard vs. Extensions
  • Compiler Optimizations


Standard vs. Extensions

Use standard features to achieve the greatest degree of portability for your Visual Fortran programs. You can design a robust implementation to improve the portability of your program, or you can choose to use extensions to the standard to increase the readability, functionality, and efficiency of your programs. You can ensure your program enforces the Fortran standard by using the /stand:f90 or /stand:f95 compiler option to flag extensions.

Not all extensions will cause problems in porting to other platforms. Many extensions are supported on a wide range of platforms, and if a system you are porting a program to supports an extension, there is no reason to avoid using it. There is no guarantee, however, that the same feature on another system will be implemented in the same way as it is in Visual Fortran. Only the Fortran standard is guaranteed to coexist uniformly on all platforms.

Compaq Fortran supports many language extensions on multiple platforms, including Compaq Alpha systems. For information on compatibility with Compaq Fortran on Alpha systems, see Compatibility with Compaq Fortran on Other Platforms. Also, the printed Compaq Fortran Language Reference Manual identifies whether each language element is supported on other Compaq Fortran platforms.

It is a good programming practice to declare any external procedures either in an EXTERNAL statement or in a procedure interface block, for the following reasons:

  • The Fortran 90 standard added many new intrinsic procedures to the language. Programs that conformed to the FORTRAN 77 standard may include nonintrinsic functions or subroutines having the same name as new Fortran 90 procedures.
  • Some processors include nonstandard intrinsic procedures that might conflict with procedure names in your program.

If you do not explicitly declare the external procedures and the name duplicates an intrinsic procedure, the processor calls the intrinsic procedure, not your external routine. For more information on how the Fortran compiler resolves name definitions, see Resolving Procedure References.


Compiler Optimizations

Many Fortran compilers perform code-generation optimizations to increase the speed of execution or to decrease the required amount of memory for the generated code. Although the behaviors of both the optimized and nonoptimized programs fall within the language standard specification, different behaviors can occur in areas not covered by the language standard. Compiler optimization especially can influence floating-point numeric results.

The Visual Fortran compiler can perform optimizations to increase execution speed and to improve floating-point numerical consistency. For a summary of optimization levels, see Optimization Levels and Other Options Related to Optimization.

Floating-point consistency refers to obtaining results consistent with the IEEE binary floating-point standards (see the /fltconsistency option).

Unless you properly design your code, you might encounter numerical difficulties when you optimize for fastest execution. The /nofltconsistency option uses the floating-point registers, which have a higher precision than stored variables, whenever possible. This tends to produce results that are inconsistent with the precision of stored variables. The /fltconsistency option (also set by /Oxp) can improve the consistency of generated code by rounding results of statement evaluations to the precision of the standard data types, but it does produce slower execution times.


Operating System

The operating system envelops your program and influences it both externally and internally. To achieve portability, you need to minimize the amount of operating-system-specific information required by your program. The Fortran language standards do not specify this information.

Operating-system-specific information consists of nonintrinsic extensions to the language, compiler and linker options, and possibly the graphical user interface of Windows. Input and output operations use devices that may be system-specific, and may involve a file system with system-specific record and file structures.

The operating system also governs resource management and error handling. You can depend on default resource management and error handling mechanisms or provide mechanisms of your own. For information on special library routines to help port your program from one system to another, see Portability Library.

The minimal interaction with the operating system is for input/output operations and usually consists of knowing the standard units preconnected for input and output. You can use default file units with the asterisk (*) unit specifier.

To increase the portability of your programs across operating systems, consider the following:

  • Do not assume the use of a particular type of file system.
  • Do not embed filenames or paths in the body of your program. Define them as constants at the beginning of the program or read them from input data.
  • Do not assume a particular type of standard I/O device or the "size" of that device (number of rows and columns).
  • Do not assume display attributes for the standard I/O device. Some environments do not support attributes such as color, underlined text, blinking text, highlighted text, inverse text, protected text, or dim text.


Storage and Representation of Data

The Fortran language standard specifies little about the storage of data types. This loose specification of storage for data types results from a great diversity of computing hardware. This diversity poses problems in representing data and especially in transporting stored data among a multitude of systems. The size (as measured by the number of bits) of a storage unit (a word, usually several bytes) varies from machine to machine. In addition, the ordering of bits within bytes and bytes within words varies from one machine to another. Furthermore, binary representations of negative integers and floating-point representations of real and complex numbers take several different forms.

If you are careful, you can avoid most of the problems involving data storage. The simplest and most reliable means of transferring data between dissimilar systems is in character and not binary form. Simple programming practices ensure that your data as well as your program is portable.

For more information:

  • Size of Basic Types
  • Bit, Byte, and Word Characteristics
  • Transportability of Data


Size of Basic Types

The intrinsic data types are INTEGER, REAL, LOGICAL, COMPLEX, and CHARACTER, whose sizes are shown in the following table.

Data Types and Storage Sizes

Types | Number of Bytes
INTEGER(1), LOGICAL(1), CHARACTER | 1
INTEGER(2), LOGICAL(2) | 2
INTEGER, LOGICAL, REAL | Depending on default integer size (set by the /integer_size compiler option or equivalent directive) , INTEGER and LOGICAL can have 2, 4, or 8 bytes; default allocation is 4 bytes. Depending on default real size (set by the /real_size compiler option or equivalent directive), REAL can have 4 or 8 bytes; default allocation is 4 bytes.
INTEGER(4), REAL(4), LOGICAL(4) | 4
INTEGER(8), LOGICAL(8) | 8
COMPLEX | Depending on default real, COMPLEX can have 8 or 16 bytes; default allocation is 8 bytes.
DOUBLE PRECISION, REAL(8), COMPLEX(4) | 8
DOUBLE COMPLEX, COMPLEX(8) | 16
CHARACTER(n) | n
Structures | Size of derived type (can be affected by the PACK directive)
RECORD | Size of record structure (can be affected by the PACK directive)


Bit, Byte, and Word Characteristics

In a 32-bit word environment such as that of Visual Fortran, it might seem as though there should be no problems with data storage, since all data types are consecutive subcomponents (bytes) of a word or are consecutive, multiple words. However, when transporting binary data among disparate systems -- either by intermediate storage medium (disk, tape) or by direct connection (serial port, network) -- problems arise from different definitions of serial bit and serial byte order. For simplicity, the following discussion considers only byte order within a word, since that is the usual case of difficulty. (For more information, refer to "On Holy Wars and a Plea for Peace" by Danny Cohen, IEEE Computer, vol. 14, pp. 48-54, 1981.)

For more information:

  • Big End or Little End Ordering
  • Binary Representations
  • Declaring Data Types


Big End or Little End Ordering

Computer memory is a linear sequence of bits organized into a hierarchical structure of bytes and words. One system is the "Big End," where bits and bytes are numbered starting at the most significant bit (MSB, "left," or high end). Another system is the "Little End," where bits and bytes start at the least significant bit (LSB, "right, " or low end). The following figure illustrates the difference between the two conventions for the case of addressing bytes within words.

Byte Order Within Words: (a) Big End, (b) Little End

Data types stored as subcomponents (bytes stored in words) end up in different locations within corresponding words of the two conventions. The following figure illustrates the difference between the representation of several data types in the two conventions. Letters represent 8-bit character data, while numbers represent the 8-bit partial contribution to 32-bit integer data.

Character and Integer Data in Words: (a) Big End, (b) Little End

If you serially transfer bytes now from the Big End words to the Little End words (BE byte 0 to LE byte 0, BE byte 1 to LE byte 1, ...), the left half of the figure shows how the data ends up in the Little End words. Note that data of size one byte (characters in this case) is ordered correctly, but that integer data no longer correctly represents the original binary values. The right half of the figure shows that you need to swap bytes around the middle of the word to reconstitute the correct 32-bit integer values. After swapping bytes, the two preceding figures are identical.

Data Sent from Big to Little: (a) After Transfer, (b) After Byte Swaps

You can generalize the previous example to include floating-point data types and to include multiple-word data types. The following table summarizes the ordering nature of several common processors.

Ordering Nature of Processors

Processor | Byte Order | Bit Order
Intel 80486, Pentium Series | Little | Little
Compaq Alpha and VAX | Little | Little
Motorola® 680XX | Big | Little
IBM Mainframes | Big | Big

The important result is that portable, serial transport of 8-bit character data between most systems is possible with little or no knowledge about the ordering nature of each system.

For more information on big and little endian data and Visual Fortran unformatted data conversion capabilities, see Converting Unformatted Numeric Data.


Binary Representations

The discussion in Big End or Little End Ordering stresses 8-bit character data because you might encounter hardware that uses a different representation of binary data. The Visual Fortran system uses the two's-complement representation of negative binary integers. You might encounter a system that uses a signed magnitude representation, a one's complement representation, or a biased (excess) representation. Additionally, the bit representation of binary floating-point numbers is not unique.

If you transport binary data to or from a different system, you need to know the respective representations to convert the binary data appropriately.


Declaring Data Types

Use default data types unless you anticipate memory problems, or if your data is sensitive to overflow limits. If data precision errors or numeric overflow could affect your program, specify type and kind parameters for the intrinsic types as well as for declared data objects. Default data types are portable and are usually aligned by the compiler to achieve good memory access speed. Using some of the nondefault data types on certain machines may slow down memory access.


Transportability of Data

You can achieve the highest transportability of your data by formatting it as 8-bit character data. Use a standard character set such as the ASCII standard for encoding your character data. Although this practice is less efficient than using binary data, it will save you from shuffling and converting your data.

If you are transporting your data by means of a record-structured medium, it is best to use the Fortran sequential formatted (as character data) form. You can also use the direct formatted form, but you need to know the record length of your data. Remember also that some systems use a carriage return-linefeed pair as an end-of-record indicator, while other systems use linefeed only. If you use either the direct unformatted or the sequential unformatted form, there might be system-dependent values embedded within your data that complicate its transport.

Implementing a strictly portable solution requires a careful effort. Maximizing portability may also mean making compromises to the efficiency and functionality of your solution. If portability is not your highest priority, you can use some of the techniques that appear in later sections to ease your task of customizing a solution.

For more information on big and little endian data and unformatted data conversion, see Converting Unformatted Numeric Data.


Choosing Your Development Environment

With Visual Fortran, you can build programs either from a command-line window (which allows you to enter text commands directly into a command prompt) or from the Microsoft visual development environment.

For information on using the Microsoft visual development environment, see Building Programs and Libraries. For information on using the command-line environment, see Using the Compiler and Linker from the Command Line.

The visual development environment offers a number of ways to simplify the task of compiling and linking programs. For example, a dialog box presents compiler and linker options in logical groupings, with descriptive names and simple mouse or keyboard selection methods. (If you need assistance using this or any other dialog box, choose the Help button in the dialog box.)

The visual development environment also provides a default text editor, which is integrated with Help, the debugger, and error tracking features. The default visual development environment text editor can be customized for keyboard compatibility with certain editors (in the Tools menu, select Customize and click the Compatibility tab) and you can customize keyboard bindings (in the Tools menu, select Customize and click the Keyboard tab). You can also use your favorite ASCII text editor outside the visual development environment. If you do, however, you may not be able to use the integrated Help, debugger, and error tracking features.

Because software development is an iterative process, it is important to be able to move quickly and efficiently to various locations in your source code. If you use the visual development environment to compile and link your programs, you can call up both the description of the error message and the relevant source code directly from the error messages in the output window.

You also use the visual development environment text editor to view and control execution of your program with the integrated source level debugger. Finally, when you use the project browser to locate routines, data elements, and references to them, the visual development environment uses its editor to go directly to the source code.

When you build programs from the console, you are in complete control of the build tools. If you choose to, you can customize how your program is built by your selection of compiler and linker options. Compiler and linker options are described in Compiler and Linker Options.

Even if you choose to edit and build your program from the command line, you can still use the visual development environment debugger and browser after your program has compiled and linked cleanly (see Preparing Your Program for Debugging). Finally, you can run the profiler to produce a text report of your program's execution statistics either from the command-line console or from the visual development environment.


Selecting a Program Type

When you create a new project, you need to select the appropriate Fortran project type. You can build four basic kinds of executable programs:

  • Fortran Console applications
  • Fortran Standard graphics applications
  • Fortran QuickWin graphics applications
  • Fortran Windows applications

You can also create a Fortran COM server project or a library project that contains subprograms (functions or subroutines) called from your main application:

  • Static libraries
  • Dynamic-Link Libraries (DLLs)

Code that works in one application may not work in others. For example, graphics calls are not appropriate in a Fortran console application.

Fortran console applications are the most portable to other systems because they are text-only and do not support graphics.

With Fortran standard graphics (QuickWin single document) applications, you can add graphics to your text without the additional overhead of menus and other interface features of typical programs for Windows. Fortran QuickWin (QuickWin multiple document) graphics applications provide a simple way to use some features of Windows in a Visual Fortran program with graphics.

Fortran Windows applications give users full access to the Win32 Application Programming Interface (API), giving you a larger set of functions than QuickWin offers. With Windows applications, you can access low-level system services directly, or access higher level system services such as OpenGL.

None of the graphics functions in Visual Fortran, except for those in the OpenGL library, are directly portable to operating systems offered by other vendors. A graphical interface does, however, offer certain advantages to the application designer and to the person who will use the program. The choice of what kind of program to build is a trade-off between performance, portability, ease of coding, and ease of use. The advantages and disadvantages of each type of application are summarized in the following sections.

All four kinds of main applications can be maximized, minimized, resized, and moved around the screen when displayed in a window. If the drawing area of a window in your application is larger than the window in which it is displayed, scroll bars are automatically added to the bottom and right edges of the window.

You can write any of the applications with one section of the program beginning execution before another has completed. These threads of execution run either concurrently on a computer with one processor or simultaneously on a computer with multiple processors. (See Creating Multithread Applications.)

For more information on the Visual Fortran application project types, see Types of Projects.


Structuring Your Program

There are several ways to organize your projects and the applications that you build with Visual Fortran. This section introduces several of these options and offers suggestions for when you might want to use them.

For more information:

  • Creating Fortran Executables
  • Advantages of Modules
  • Advantages of Internal Procedures
  • Storing Object Code in Static Libraries
  • Storing Routines in Dynamic-Link Libraries


Creating Fortran Executables

The simplest way to build an application is to compile all of your Visual Fortran source files (.FOR) and then link the resulting object files (.OBJ) into a single executable file (.EXE). You can build single-file executables either with the visual development environment or by using the DF (or FL32) command from the console command line.

The executable file you build with this method contains all of the code needed to execute the program, including the run-time library. Because the program resides in a single file, it is easy to copy or install. However, the project contains all of the source and object files for the routines that you used to build the application. If you need to use some of these routines in other projects, you must link all of them again.


Advantages of Modules

One way to reduce potential confusion when you use the same source code in several projects is to organize the routines into modules. There are two main uses for modules in Visual Fortran:

  • Internal encapsulation – A single complex program can be made up of many modules. Each module can be a self-contained entity, incorporating all the procedures and data required for one of your program's tasks. When a task is encapsulated, it is easy to share the code between two different projects.

    In this case, all the modules should be included in the main project directory. If many projects all share the same module, the module should reside in only one directory. All projects that use it should specify the /I compiler option to indicate the location of the module.

  • External modules – If you use a module provided from an outside source, you need only the .MOD file at compile time, and the .OBJ file at link time. Use the /[no]include[path] (or /Ipath) command line option (or the INCLUDE environment variable) to specify the location of these files, which will probably not be the same as your project directory.

During the building of a project, the compiler scans the project files for dependencies. If you specify the /[no]include[path] (or /Ipath) command line option or the INCLUDE environment variable, the compiler is able to find the external modules.

Store precompiled module files, with the extension .MOD, in a directory included in the path. When the compiler sees the USE statement in a program, it finds the module based on the name given in the USE statement, so there is no need to maintain several copies of the same source or object code.

Modules are excellent ways to organize programs. You can set up separate modules for:

  • Commonly used routines
  • Data definitions specific to certain operating systems
  • System-dependent language extensions


Advantages of Internal Procedures

Functions or subroutines that are used in only one program can be organized as internal procedures, following the CONTAINS statement of a program or module.

Internal procedures have the advantage of host association, that is, variables declared and used in the main program are also available to any internal procedure it may contain. For more information on procedures and host association, see Program Units and Procedures.

Internal procedures, like modules, provide a means of encapsulation. Where modules can be used to store routines commonly used by many programs, internal procedures separate functions and subroutines whose use is limited or temporary.


Storing Object Code in Static Libraries

Another way to organize source code used by several projects is to build a static library (.LIB) containing the object files for the reused procedures. You can create a static library:

  • From the visual development environment, build a Fortran Static Library project type.
  • From the command line, use the LIB command.

After you have created a static library, you can use it to build any of the other types of Visual Fortran projects.

For more information:

  • About static libraries, see Fortran Static Library Projects


Storing Routines in Dynamic-Link Libraries

Another method of organizing the code in your application involves storing the executable code for certain routines in a separate file called a Dynamic-Link Library (DLL) and building your applications so that they call these routines from the DLL.

When routines in a DLL are called, the routines are loaded into memory at run-time as they are needed. This is most useful when several applications use a common group of routines. By storing these common routines in a DLL, you reduce the size of each application that calls the DLL. In addition, you can update the routines in the DLL without having to rebuild any of the applications that call the DLL.

For more information on compiler and linker options and how to build a project, see Fortran Dynamic-Link Library Projects.


Special Design Considerations

You can write your code any way you want if you plan to run it on a single computer, use only one variation of one programming language, and never hand your code to anyone else. If any of these assumptions changes, there are several other issues to consider when you design your program.

For more information:

  • Porting Fortran Source Between Systems
  • Mixed-Language Issues
  • Porting Data Between Systems


Porting Fortran Source Code Between Systems

In general, Visual Fortran is a portable language. One of the main advantages of the language is the availability of large and well-tested libraries of Fortran code. You also might have existing code addressing your problem that you want to reuse. Math and scientific code libraries from most vendors should port to Visual Fortran with virtually no problems.

You might also want to use Visual Fortran as a development platform for code that can later be ported to another Compaq Fortran system, such as mainframe-class Alpha systems running the Compaq Tru64 UNIX, Linux, or Compaq OpenVMS operating system.

Whether you are bringing code from another system or planning to export it to another system, you will need to do the following:

  • Isolate system-dependent code into separate modules. Maintain distinct modules with similar functionality for each separate platform.
  • In your main program, use only language extensions that will compile on both platforms, putting system-dependent code into modules.
  • Place language extension subsets into modules.
  • If you use Microsoft compiler directives, replace the older $directive format with the !DEC$ directive format, because this will be ignored by other systems.
  • Specify data precision, for integers and logicals as well as for floating-point numbers when the size matters. If you do not explicitly specify KIND for variables, this could be the source of problems if one system uses a default of (KIND=2) for integers, while your program assumes (KIND=4).
  • Conversely, if the size of a variable is not significant, avoid specifying data precision. Code that does specify precision will run slower on systems that do not use the same default integer and real sizes.
  • Avoid using algorithms that exhibit floating-point instability. For information on handling floating-point numbers, see The Floating-Point Environment.
  • Specify equivalent floating-point precision on each platform.
  • Specify the appropriate attributes when defining routines and data that will be interacting with code written in Microsoft Visual C/C++ or assembly language.

For more information:

  • On porting code between systems, see Portability.
  • On compatibility with Compaq Fortran on Alpha platforms, see Compatibility with Compaq Fortran on Other Platforms

Choosing a Language Extension Subset

The Visual Fortran compiler supports extensions used on a variety of platforms, plus some that are specific to Visual Fortran. Because there are Fortran compilers for many different computers, you might need to move your source code from one to another. If the trip is one-way and it is permanent, you can simply change the code to work on the second platform. But if you need to make sure you can move the code where ever it is needed, you must be aware of the extensions to Fortran that are supported on each platform.

You can use some of the Visual Fortran compiler options to help you write portable code. For example, by specifying ANSI/ISO syntax adherence (/stand option) in the Project Settings (Fortran tab) dialog box or on the command line, you can have the compiler enforce Fortran 90 or 95 syntax. Code that compiles cleanly with this option set is very likely to compile cleanly on any other computer with a Fortran compiler that obeys strict Fortran syntax.

If you choose to use platform-specific extensions, you need to note whether there are any differences in how those extensions are implemented on each computer, and use only those features that are identical on both. (For more information, see Portability.) The default is to compile with the full set of extensions available.

Because Visual Fortran compiler directives look like standard Fortran comments (such as !DEC$ directive), programs that use directives can compile on other systems. They will, however, lose their function as compiler directives.

Floating-Point Issues

Floating-point answers can differ from system to system, because different systems have different precisions and treat rounding errors in different ways.

One programming practice that can be a serious source of floating-point instability is performing an IF test (either obvious or implied) that takes some action if and only if a floating-point number exactly equals a particular value. If your program contains code like this, rewrite the code to a version that is stable in the presence of rounding error. For more details, see The Floating-Point Environment.

Another source of floating-point instability is the use of mathematical algorithms that tend to diminish precision. Incorrect answers can result when the code is moved to a system with less precision. For more information, see The Floating-Point Environment.

One way of making all REAL variables on one system DOUBLE PRECISION on another is to use modules to declare explicit data types for each system. Specify a different KIND parameter in each module. Another way is to add an include file that declares explicit data types on each system in all source files.


Mixed-Language Issues

You can combine object modules generated by Visual Fortran with object files from compilers for 32-bit Windows that compile other languages (such as Microsoft Visual C++, or Microsoft MASM), so long as the compilers use the COFF object module format used by Microsoft.

You need to respect certain calling, naming, and argument-passing conventions when combining object modules from different languages. These conventions are discussed in Programming with Mixed Languages.


Porting Data Between Systems

The easiest way to port data to or from the Visual Fortran environment is as a formatted, sequential, 8-bit ASCII character file that can be read using Fortran formatted input statements; if you do this, you should have no trouble.

If you try to transfer unformatted binary data between systems, you need to be aware of the different orders (low-order byte first or high-order byte first) in which different systems store bytes within words. If you need to transfer unformatted binary data, review:

  • Portability
  • Compatibility with Compaq Fortran on Other Platforms
  • Converting Unformatted Numeric Data

You can avoid these problems by using a formatted ASCII file.


Using the Special Features of Microsoft Windows

One of the greatest advantages to building applications for Windows is the power and security provided by the operating system. By simply recompiling your old source code and building a (text-only) Fortran Console application, you can run your program in a protected address space where it cannot damage other applications, hang the processor, or cause the computer to crash.

If you choose to take advantage of the power of Windows operating systems, your programs can run more efficiently on single-processor computers. Window NT 4 and Windows 2000 also support multi-processor computers.

For more information:

  • Built-in Benefits of Windows
  • Single or Multithread Program Execution
  • Dialog Boxes
  • QuickWin and Windows Programs


Built-in Benefits of Windows

Windows executes your application in a secure environment that includes the support services your application needs to execute efficiently and with a minimum of problems. This environment is a flat virtual address space that can be as large as 2 gigabytes, providing you have enough available disk space. While executing, your program is protected by Windows from damaging other applications and from being damaged by other applications.

The operating system uses preemptive multitasking to control how much processor time each application uses. Instead of waiting for an application to voluntarily yield control of the computer back to the operating system, Windows allocates a period of processor time to the application and regains control when that period has expired. This prevents a program with an infinite loop from hanging the computer. If your program hangs, you can easily and safely stop it by using the Windows task manager. (For information about using this or any other feature of Windows, see the manuals that came with the operating system.)

Because you can use one application while another continues to execute, you can make better use of your own time. For example, you can use the visual development environment to edit the source for one project while another project is building, or use Microsoft Excel to prepare a graph for data that your program is busy producing. And if your computer has multiple processors and you are using Windows NT 4 or Windows 2000, the computation-intensive program producing your data might be executing on an otherwise idle processor, making it less likely that your other work will slow it down.


Single or Multithread Program Execution

You can take further advantage of preemptive multitasking by designing your program so that portions of it, called threads, can be executed in parallel. For example, one thread can perform a lengthy input/output operation while another thread processes data. All of the threads in your application share the same virtual address space.

Windows 9x, Windows 2000, and Windows NT 4 operating systems support multithreading. On a Windows NT 4 or Windows 2000 system with multiple processors sharing memory, threads can execute in parallel (symmetric multiprocessing).

Multithreaded code must be written so that the threads do not interfere with each other and overwrite each other's data, as described in Creating Multithread Applications.


Dialog Boxes

Visual Fortran gives you an easy way to create simple dialog boxes that can be used for data entry and application control. Dialogs are a user-friendly way to get and process input. As your application executes, you can make a dialog box appear on the screen and the user can click on a button or scroll bar to enter data or choose what happens next. You can add dialog boxes to any Fortran application, including Fortran Windows, Fortran QuickWin, and Fortran Console applications.

You design your dialog with the Resource Editor, and drive them with a combination of the dialog routines, such as DLGSET, and your own subroutines. A complete discussion of how to design and use dialog boxes is given in Using Dialogs.


QuickWin and Windows Programs

One decision you must make when designing a program is how it will be used. If the person using your program must interact with it, the method of interaction can be important. For example, anytime the user must supply data, that data must be validated or it could cause errors. One way to minimize data errors is to change how the data is provided. In this example, if the data is one of several values that are known when the program is executed, the user can select a menu item instead of typing on the keyboard.

When you design programs to be interactive, you use a different structure than if you design them to be run in unattended batches. Interactive applications behave more like state machines than numerical algorithms, because they perform the actions you request when you request them. You may also find that once you can change what your program is doing while it runs, you will be more likely to experiment with it.

The QuickWin library lets you build simple Windows applications. Because QuickWin is a wrapper around a subset of the Windows API, there are limitations to what you can do, but it can fulfill the requirement of most users. If you need additional capabilities, you can call the Windows API directly rather than using QuickWin to build your program. (For more information, see Using QuickWin). You can also build a graphic user interface in either Microsoft Visual C++ or Visual Basic® that calls your Fortran code.


Using Dialogs

Dialogs are a user-friendly way to solicit application control. As your application executes, you can make a dialog box appear on the screen and the user can click on a dialog box control to enter data or choose what happens next.

With the dialog routines provided with Visual Fortran, you can add dialog boxes to your application. These routines define dialog boxes and their controls (scroll bars, buttons, and so on), and call your subroutines to respond to user selections.

There are two types of dialog boxes:

  • Modal dialog boxes, which you can use with any Fortran project type, including Fortran Windows, Fortran QuickWin (multiple doc.), Fortran Standard Graphics (QuickWin single doc.), Fortran Console, Fortran DLL, and Fortran Static library project types.
  • Modeless dialog boxes, which are typically used with the Fortran Windows project type.

When your program displays a modal dialog box (any project type), the user must explicitly enter data and close the dialog box before your application resumes execution.

When your program displays a modeless dialog box, your application continues executing. Unlike a modal dialog box, the user can switch between the modeless dialog box and the other windows in the application.

There are two steps to make a dialog:

  1. Specify the appearance of the dialog box and the names and properties of the controls it contains.
  2. Write an application that activates those controls by recognizing and responding to user selections.

This section covers the following topics:

  • Using the Resource Editor to Design a Dialog
  • Writing a Dialog Application
  • Dialog Routines
  • Dialog Controls
  • Using Dialog Controls
  • Using ActiveX Controls


Using the Resource Editor to Design a Dialog

You design the appearance of the dialog box, choose and name the dialog controls within it, and set other control properties with the Dialog Editor.

The Dialog Editor is one of the Resource Editors provided by the visual development environment (Developer Studio). Developer Studio contains other resource editors for editing icons, bitmaps, menus, and so on. For information on the other resource editors, see "Resource Editors" section in the Visual C++ User's Guide .

A program's resources are defined in a resource file (typically with a .rc extension). A Developer Studio project typically contains a single resource file. The contents of the resource file are displayed in the ResourceView. The resource file can be created by one of the following:

  • When you create a project and use one of the Fortran AppWizards (for example, when using the Fortran Windows Application AppWizard).
  • When you save the resources that you define using one of the Resource Editors.

If you create the resource file from the resource editors, be sure to add the resource file to your project. After you do this, the resources will be displayed in the ResourceView. It is possible to include additional resource files in a project (see Including Resources Using Multiple Resource Files).

This section describes the steps needed to design a dialog box, and uses as an example a dialog box that converts temperatures between Celsius and Fahrenheit. The code in the example is explained as you read through this chapter.

In this section, we include the dialog box in a Fortran Console project. You can use the completed Visual Fortran sample in the ...\Samples\Dialog\Temp directory or you can create your own application.

To create a Fortran Console application:

  • From the File menu, click New...
  • Click the Project tab
  • From the list of project types, select Fortran Console Application
  • Enter TEMP as the name for the project, verify where the project will be created, and click OK
  • In the Fortran Console Application - Step 1 of 1 dialog box, choose A simple project and click Finish
  • Click OK after reading the displayed summary information. The project workspace is opened, displaying the FileView pane.
  • In the FileView pane, click the plus sign (+) next to the project name to display the categories of source files.

To open the dialog resource editor:

  1. From the Insert menu, choose Resource.
  2. From the list of possible resources, choose Dialog.
  3. Click the New button. The dialog editor (one of the resource editors) appears on the screen as shown below.

Dialog Editor Sample 1

initial screen, dialog editor

A blank dialog box appears at the left and a toolbar of available controls appears on the right. If the Controls toolbar does not appear:

  1. Click Customize in the Tools menu
  2. Click the Toolbars tab
  3. Select (check) Controls

If you place the cursor over a control on the toolbar, the name of the control appears. The Controls toolbar items that are supported by Visual Fortran follow:

Button | Check box
Combo box (such as a drop-down list box) | Group box
Edit box | List box
Picture | Progress bar
Radio button | Scroll bar, horizontal
Scroll bar, vertical | Slider
Spin control | Static text
Tab control |

You can also add ActiveX controls to your dialog box (see Using ActiveX Controls).

To add controls to the dialog box:

  1. Point at one of the available controls on the Control toolbar, hold down the left mouse button and drag the control to the dialog box.
  2. Place the dialog control where you want it to be on the dialog box and release the mouse button. You can delete controls by selecting them with the mouse, then pressing the Delete (or DEL) key.

The following figure shows the dialog box after adding two Static text lines (currently say Static), two Edit boxes (currently say Edit), a Horizontal Scroll bar, and a Group box. The Group box is the outlined rectangular area in the dialog box that encloses the other related controls.

The OK and CANCEL buttons were added for you by the Resource Editor. You can delete (select the control and press DEL key), move (drag the control), resize (drag one of the anchor points), rename the OK and CANCEL buttons or any of the controls that you add.

Dialog Editor Sample 2

dialog box after adding controls

To specify the names and properties of the added controls:

  1. Double-click one of the controls in your dialog box with the left mouse button. A Properties box appears showing the default name and properties for that control.

    The following figure shows the Properties box for the Horizontal Scroll bar with the default values.

    Dialog Editor Sample 3

    screen after double-clicking on the horizontal scroll bar

  2. Change the control name by typing over the default name (IDC_SCROLLBAR1 in the following figure).
  3. Check or uncheck the available options to change the control's properties. (The Visible option in the following figure is checked by default.)
  4. Click the left mouse button in the upper-right corner of the window Properties box to save the control's properties and to close the box.

    Repeat the same process for each control and for the dialog box itself.

To use the controls from within a program, you need symbolic names for each of them. In this example, the Horizontal Scroll bar symbolic name is changed in the Properties box to IDC_SCROLLBAR_TEMPERATURE. This is how the control will be referred to in your program; for example, when you get the slide position:

 INTEGER slide_position
 retlog = DLGGET (dlg, IDC_SCROLLBAR_TEMPERATURE,            &
                 slide_position, DLG_POSITION)

The controls are renamed as follows:

  • The top Edit box is named IDC_EDIT_CELSIUS. The Static text next to it is named IDC_TEXT_CELSIUS and set to the left-aligned text "Celsius".
  • The lower Edit box is named IDC_EDIT_FAHRENHEIT, and the Static text next to it is named IDC_TEXT_FAHRENHEIT and set to the left-aligned text "Fahrenheit".
  • The Group box is named IDC_BOX_TEMPERATURE, and its caption is set to Temperature.
  • The dialog itself is named IDD_TEMP and its caption is set to Temperature Conversion.
  • All other control properties are left at the default values.

The resulting dialog box is shown in the following figure:

Dialog Editor Sample 4

completed dialog box

To save the dialog box as a resource file:

  1. From the File menu, choose Save As.

  2. Enter a resource filename for your file.

    In this example, the resource file is given the name TEMP.RC. The visual development environment saves the resource file and creates an include file with the name RESOURCE.FD. Typically, only one resource file is used with each Visual Fortran project (see Including Resources Using Multiple Resource Files).

  3. Add the TEMP.RC file to your project:
    1. In the Project menu, select Add to Project and click Files... from the submenu.
    2. The Insert Files into Project dialog box appears. Use this dialog box to select the TEMP.RC file to be added to the project.

To open an existing dialog box in the resource editor:

  1. From the File menu, open the project workspace.
  2. Click the ResourceView tab.
  3. Click the plus sign (+) next to project-name Resources.
  4. Click the plus sign (+) next to Dialog.
  5. Double-click the appropriate dialog name, such as IDD_DIALOG1.
  6. Use the Resource Editor to add a new control or modify an existing control. To modify an existing control, use the Tab key to select the appropriate control. Double-click the selected control to view or modify its properties.

At this point the appearance of the dialog box is finished and the controls are named, but the box cannot function on its own. An application must be created to run it.

Not all the controls on the Resource Editor Controls toolbar are supported by Visual Fortran dialog routines. The supported dialog controls are:

  • Button
  • Check box
  • Combo box (such as a drop-down list box)
  • Edit box
  • Group box
  • List box
  • Picture
  • Progress bar
  • Radio button
  • Scroll bar (Horizontal and Vertical)
  • Slider
  • Spin control
  • Static text
  • Tab control

You can also add ActiveX controls to your dialog box. For information, see Using ActiveX Controls.

For further information on resources and control properties, see:

  • Setting Control Properties
  • Including Resources Using Multiple Resource Files
  • The Include (.FD) File

For information on creating an application for your dialog box, see Writing a Dialog Application.

For more information about using the Resource Dialog editor, see Using Resource Editors in the Visual C++ User's Guide (for Visual Fortran), located in the HTML Help folder Developer Studio 98.


Setting Control Properties

Help is available within the Resource Editor to explain the options for each of the dialog controls. Click the question mark in the upper-left area of the Dialog Properties box to display Resource Editor help.

Some of the controls have multiple Properties sets. Click the mouse on the name of the Properties set you want to view or modify.

In addition to changing the properties of its individual controls, you can change the properties of the dialog box itself. To change the dialog box properties, double-click the left mouse button (or right-click and select Properties from the pop-up menu) in any clear area in the box. The Properties box opens for the dialog.

To specify where your dialog appears on the screen do one of the following:

  • In General tab of the Properties box, you can change the x and y values. These specify the pixel position of the dialog box's upper-left corner, relative to its parent window. For a modal or a popup modeless dialog box, the parent window is the screen. For example, specifying the X position as 40 and Y position as 40 would place a modal dialog box in the upper-left corner of the screen.

  • In the More Styles tab, you can specify the Center checkbox to display the dialog box in the center of its parent window or specify the Center Mouse checkbox to place the dialog centered at the current mouse pointer position.

You can change the size of the dialog box by holding down the left mouse button as you drag the right or lower perimeter of the box. If you have sized your dialog window to be larger than the edit window, use the scroll bars to move the view region.

You can edit the appearance of the dialog box later. To start the Resource Editor and display the selected dialog box:

  1. From the File menu, open the project workspace.
  2. Click the ResourceView tab.
  3. Click the plus sign (+) next to project-name Resources.
  4. Click the plus sign (+) next to Dialog.
  5. Double-click the appropriate dialog name, such as IDD_DIALOG1.
  6. Use the Resource Editor to modify an existing control or add a new one.


Including Resources Using Multiple Resource Files

Normally it is easy and convenient to work with the default arrangement of all resources in one resource script (.rc) file. However, you can add resources in other files to your current project at compile time by listing them in the compile-time directives box in the Resource Includes dialog box.

There are several reasons to place resources in a file other than the main .rc file:

  • To include resources that have already been developed and tested and do not need further modification.
  • To include resources that are being used by several different projects, or that are part of a source code version-control system, and thus must exist in a central location where modifications will affect all projects.
  • To include resources that are in a custom format.
  • To include statements in your resource file that execute conditionally at compile time using compiler directives, such as #ifdef and #else. For example, your project may have a group of resources that are bracketed by #ifdef _DEBUG ... #endif and are thus included only if the constant _DEBUG is defined at compile time.
  • To include statements in your resource file that modify resource-file syntax by using the #define directive to implement simple macros.

If you have sections in your existing .rc files that meet any of these conditions, you should place the sections in one or more separate .rc files and include them in your project using the Resource Includes dialog box.

To include resource files that will be added to your project at compile time:

  1. Place the resources in a resource script file with a unique filename. (Do not use projectname.rc, since this is the default filename used for the main resource script file.)
  2. From the View menu, choose Resource Includes.
  3. In the Compile-time directives box, use the #include compiler directive to include the new resource file in the main resource file in the development environment. The resources in files included in this way are made a part of your executable file at compile time. They are not directly available for editing or modification when you are working on your project's main .rc file. You need to open included .rc files separately.
  4. Click OK.


The Include (.FD) File

Each control in a dialog box has a unique integer identifier. When the Resource Editor creates the include file (.FD), it assigns the PARAMETER attribute to each control and to the dialog box itself, so they become named constants. It also assigns each control and the dialog box an integer value. You can read the list of names and values in your dialog boxes include file (for example, RESOURCE.FD). To view and modify the named constants, click Resource Symbols in the View menu.

When your application uses a control, it can refer to the control or dialog box by its name (for example, IDC_SCROLLBAR_TEMPERATURE or IDD_TEMP), or by its integer value. If you want to rename a control or make some other change to your dialog box, you should make the change through the Resource Editor in the visual development environment. Do not use a text editor to alter your .FD include file because the dialog resource will not be able to access the changes.


Writing a Dialog Application

When creating a dialog box with the Resource Editor, you specify the types of controls that are to be included in the box. You then must provide procedures to make the dialog box active. These procedures use both dialog routines and your subroutines to control your program's response to the user's dialog box input.

You give your application access to your dialog resource by adding the .RC file to your project, giving your application access to the dialog include file, and associating the dialog properties in these files with the dialog type (see Initializing and Activating the Dialog Box).

Your application must include the statement USE DFLOGM to access the dialog routines, and it must include the .FD file the Resource Editor created for your dialog. For example:

  PROGRAM TEMPERATURE
  USE DFLOGM
  IMPLICIT NONE
  INCLUDE 'RESOURCE.FD'
   .
   . ! Call dialog routines, such as DlgInit, DlgModal, and DlgUninit
   .
  END PROGRAM TEMPERATURE

The following sections describe how to code a dialog application:

  • Initializing and Activating the Dialog Box
  • Callback Routines
  • Using a Modeless Dialog Box
  • Using Fortran AppWizards to Help Add Modal Dialog Box Coding
  • Using Fortran AppWizards to Help Add Modeless Dialog Box Coding
  • Using Dialog Controls in a DLL


Initializing and Activating the Dialog Box

Each dialog box has an associated variable of the derived type dialog. The dialog derived type is defined in the DFLOGM.F90 module; you access it with USE DFLOGM. When you write your dialog application, refer to your dialog box as a variable of type dialog. For example:

  USE DFLOGM
  INCLUDE 'RESOURCE.FD'
  TYPE (dialog) dlg
  LOGICAL return
  return = DLGINIT( IDD_TEMP, dlg )

This code associates the dialog type with the dialog (IDD_TEMP in this example) defined in your resource and include files (TEMP.RC and RESOURCE.FD in this example).

You give your application access to your dialog resource by adding the .RC file to your project. You give your application access to the dialog include file by including the .FD file in each subprogram. You associate the dialog properties in these files with the dialog type by calling DLGINIT with your dialog name.

An application that controls a dialog box should perform the following actions:

  1. Call DLGINIT or DLGINITWITHRESOURCEHANDLE to initialize the dialog type and associate your dialog and its properties with the type.
  2. Initialize the controls with the dialog set routines, such as DLGSET.
  3. Set the callback routines to be executed when a user manipulates a control in the dialog box with DLGSETSUB.
  4. Depending on whether you want a modal or modeless dialog type:
    • To use a modal dialog, run the dialog with DLGMODAL.
    • To use a modeless dialog, call DLGMODELESS and use DLGISDLGMESSAGE in your message loop.
  5. Retrieve control information with the dialog get functions, such as DLGGET.
  6. Free resources from the dialog with DLGUNINIT.

As an example of activating a dialog box and controls, the following code initializes the temperature dialog box and controls created in the TEMP project example. It also sets the callback routine as UpdateTemp, displays the dialog box, and releases the dialog resources when done:

  SUBROUTINE DoDialog( )
  USE DFLOGM
  IMPLICIT NONE
  INCLUDE 'RESOURCE.FD'

  INTEGER retint
  LOGICAL retlog
  TYPE (dialog) dlg
  EXTERNAL UpdateTemp
! Initialize.
  IF ( .not. DlgInit( idd_temp, dlg ) ) THEN
    WRITE (*,*) "Error: dialog not found"
  ELSE
! Set up temperature controls.
    retlog = DlgSet( dlg, IDC_SCROLLBAR_TEMPERATURE, 200, DLG_RANGEMAX)
    retlog = DlgSet( dlg, IDC_EDIT_CELSIUS, "100" )
    CALL UpdateTemp( dlg, IDC_EDIT_CELSIUS, DLG_CHANGE)
    retlog = DlgSetSub( dlg, IDC_EDIT_CELSIUS, UpdateTemp )
    retlog = DlgSetSub( dlg, IDC_EDIT_FAHRENHEIT, UpdateTemp )
    retlog = DlgSetSub( dlg, IDC_SCROLLBAR_TEMPERATURE, UpdateTemp )
! Activate the modal dialog.
    retint = DlgModal( dlg )
! Release dialog resources.
    CALL DlgUninit( dlg )
  END IF
  END SUBROUTINE DoDialog

The dialog routines, such as DLGSET and DLGSETSUB, refer to the dialog controls by the names you assigned to them in the Properties box while creating the dialog box in the Resource Editor. For example:

  retlog = DlgSet( dlg, IDC_SCROLLBAR_TEMPERATURE, 200, DLG_RANGEMAX)

In this statement, the dialog function DLGSET assigns the control named IDC_SCROLLBAR_TEMPERATURE a value of 200. The index DLG_RANGEMAX specifies that this value is a scroll bar maximum range. Consider the following:

  retlog = DlgSet( dlg, IDC_EDIT_CELSIUS, "100" )
  CALL UpdateTemp( dlg, IDC_EDIT_CELSIUS, DLG_CHANGE)

The preceding statements set the dialog's top Edit box, named IDC_EDIT_CELSIUS in the Resource Editor, to an initial value of 100, and calls the routine UpdateTemp to inform the application that the value has changed. Consider the following:

  retlog = DlgSetSub( dlg, IDC_EDIT_CELSIUS, UpdateTemp )
  retlog = DlgSetSub( dlg, IDC_EDIT_FAHRENHEIT, UpdateTemp )
  retlog = DlgSetSub( dlg, IDC_SCROLLBAR_TEMPERATURE,UpdateTemp )

The preceding statements associate the callback routine UpdateTemp with the three controls. This results in the UpdateTemp routine being called whenever the value of any of the three controls changes.

Routines are assigned to the controls with the function DLGSETSUB. Its first argument is the dialog variable, the second is the control name, the third is the name of the routine you have written for the control, and the optional fourth argument is an index to select between multiple routines. You can set the callback routines for your dialog controls anywhere in your application: before opening your dialog with either DLGMODAL or DLGMODELESS, or from within another callback routine.

In the TEMP example, the main program calls the DoDialog subroutine to display the Temperature Conversion dialog box.


Dialog Callback Routines

All callback routines should have the following interface:

SUBROUTINE callback ( dlg, control_name, callbacktype)

Where:
dlg
Refers to the dialog box and allows the callback to change values of the dialog controls.

control_name
Is the name of the control that caused the callback.

callbacktype
Indicates what callback is occurring (for example, DLG_CLICKED, DLG_CHANGE, DLG_DBLCLICK).

The last two arguments let you write a single subroutine that can be used with multiple callbacks from more than one control. Typically, you do this for controls comprising a logical group. For example, all the controls in the temperature dialog in the TEMP example are associated with the same callback routine, UpdateTemp. You can also associate more than one callback routine with the same control, but you must then provide an index parameter to indicate which callback is to be used.

The following is an example of a callback routine:

  SUBROUTINE UpdateTemp( dlg, control_name, callbacktype )
  USE DFLOGM
  IMPLICIT NONE
  TYPE (dialog) dlg
  INTEGER control_name
  INTEGER callbacktype
  INCLUDE 'RESOURCE.FD'
  CHARACTER(256) text
  INTEGER cel, far, retint
  LOGICAL retlog
! Suppress compiler warnings for unreferenced arguments.
  INTEGER local_callbacktype
  local_callbacktype = callbacktype

  SELECT CASE (control_name)
    CASE (IDC_EDIT_CELSIUS)
    ! Celsius value was modified by the user so
    ! update both Fahrenheit and Scroll bar values.
      retlog = DlgGet( dlg, IDC_EDIT_CELSIUS, text )
      READ (text, *, iostat=retint) cel
      IF ( retint .eq. 0 ) THEN
        far = (cel-0.0)*((212.0-32.0)/100.0)+32.0
        WRITE (text,*) far
        retlog = DlgSet( dlg, IDC_EDIT_FAHRENHEIT,                    &
    &                    TRIM(ADJUSTL(text)) )
        retlog = DlgSet( dlg, IDC_SCROLLBAR_TEMPERATURE, cel,         &
    &                    DLG_POSITION )
      END IF
    CASE (IDC_EDIT_FAHRENHEIT)
    ! Fahrenheit value was modified by the user so
    ! update both celsius and Scroll bar values.
       retlog = DlgGet( dlg, IDC_EDIT_FAHRENHEIT, text )
       READ (text, *, iostat=retint) far
       IF ( retint .eq. 0 ) THEN
         cel = (far-32.0)*(100.0/(212.0-32.0))+0.0
         WRITE (text,*) cel
         retlog = DlgSet( dlg, IDC_EDIT_CELSIUS, TRIM(ADJUSTL(text)) )
         retlog = DlgSet( dlg, IDC_SCROLLBAR_TEMPERATURE, cel,        &
    &                     DLG_POSITION )
       END IF
    CASE (IDC_SCROLLBAR_TEMPERATURE)
    ! Scroll bar value was modified by the user so
    ! update both Celsius and Fahrenheit values.
       retlog = DlgGet( dlg, IDC_SCROLLBAR_TEMPERATURE, cel,          &
    &                   DLG_POSITION  )
       far = (cel-0.0)*((212.0-32.0)/100.0)+32.0
       WRITE (text,*) far
       retlog = DlgSet( dlg, IDC_EDIT_FAHRENHEIT, TRIM(ADJUSTL(text)) )
       WRITE (text,*) cel
       retlog = DlgSet( dlg, IDC_EDIT_CELSIUS, TRIM(ADJUSTL(text)) )
    END SELECT
  END SUBROUTINE UpdateTemp

Each control in a dialog box, except a pushbutton, has a default callback that performs no action. The default callback for a pushbutton's click event sets the return value of the dialog to the pushbutton's name and then exits the dialog. This makes all pushbuttons exit the dialog by default, and gives the OK and CANCEL buttons good default behavior. A routine that calls DLGMODAL can then test to see which pushbutton caused the modal dialog to exit.

Callbacks for a particular control are called after the value of the control has been changed by the user's action. Calling DLGSET does not cause a callback to be called for the changing value of a control. In particular, when inside a callback, performing a DLGSET on a control will not cause the associated callback for that control to be called.

Calling DLGSET before or after DLGMODAL or DLGMODELESS has been called also does not cause the callback to be called. If the callback needs to be called, it can be called manually using CALL after the DLGSET is performed.


Using a Modeless Dialog Box

To display a modeless dialog box, call the DLGMODELESS function. A modeless dialog box remains displayed until the DLGEXIT routine is called, either explicitly or by a default button callback. The application must provide a message loop to process Windows messages and must call the DLGISDLGMESSAGE function at the beginning of the message loop.

The variable of type DIALOG passed to DLGMODELESS must remain in memory for the duration of the dialog box (from the DLGINIT call through the DLGUNINIT call). The variable can be declared as global data in a Fortran module, as a variable with the STATIC attribute (or statement), or in a calling procedure that is active for the duration on the dialog box. For more information, see the Syntax for DLGMODELESS.

Modeless dialog boxes are typically used in a Fortran Windows project. A modeless dialog box can be used in a Fortran Console, Fortran DLL, or Fortran Static Library application as long as the requirements for using a modeless dialog box (discussed in the previous paragraphs) are met. For example, see the Visual Fortran sample ...\Df98\Samples\Dialog\Dllprgrs.

As an example of using a modeless dialog box, the following code is the WinMain function of an application that displays a modeless dialog box as its main window:

  integer*4 function WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
  !DEC$ IF DEFINED(_X86_)
  !DEC$ ATTRIBUTES STDCALL, ALIAS : '_WinMain@16' :: WinMain
  !DEC$ ELSE
  !DEC$ ATTRIBUTES STDCALL, ALIAS : 'WinMain' :: WinMain
  !DEC$ ENDIF

     use dfwin
     use dflogm

     integer(4) hInstance
     integer(4) hPrevInstance
     integer(4) lpszCmdLine
     integer(4) nCmdShow

     ! Include the constants provided by the Resource Editor
     include 'resource.fd'

     ! A dialog box callback
     external ThermometerSub

     ! Variables
     type (dialog) dlg
     type (T_MSG)  mesg
     integer(4)	 ret
     logical(4)	 lret

     ! Create the thermometer dialog box and set up the controls and callbacks
     lret = DlgInit(IDD_THERMOMETER, dlg_thermometer)
     lret = DlgSetSub(dlg_thermometer, IDD_THERMOMETER, ThermometerSub)
     lret = DlgSet(dlg_thermometer, IDC_PROGRESS1, 32, DLG_RANGEMIN)
     lret = DlgSet(dlg_thermometer, IDC_PROGRESS1, 212, DLG_RANGEMAX)
     lret = DlgSet(dlg_thermometer, IDC_PROGRESS1, 32)
     lret = DlgModeless(dlg_thermometer, nCmdShow)

     ! Read and process messages until GetMessage returns 0 because
     ! PostQuitMessage has been called
     do while( GetMessage (mesg, NULL, 0, 0) )
        ! Note that DlgIsDlgMessage must be called in order to give
        ! the dialog box first chance at the message.
        if ( DlgIsDlgMessage(mesg) .EQV. .FALSE. ) then
            lret = TranslateMessage( mesg )
            ret  = DispatchMessage( mesg )
        end if
     end do

     ! Cleanup dialog box memory
     call DlgUninit(dlg)

     ! The return value is the wParam of the Quit message
     WinMain = mesg.wParam
     return
  end function


Using Fortran AppWizards to Help Add Modal Dialog Box Coding

Any Fortran project type can use a modal dialog box. Thus, when you create a project, you can use any of the Fortran Project AppWizards to help you create a project that uses a modal dialog box.

To create a "Hello World" Fortran Console application that uses a modal dialog box to display "Hello World!":

  1. Create a new project with the Fortran Console project type named HelloDlg. After you create the project, the Fortran Console AppWizard appears. Select the "A Hello World sample project" option. Your workspace and source file (HelloDlg.f90) will be created for you.

  2. In the Insert menu, select Resource... and select Dialog. Create the box using the dialog resource editor, as follows:
    1. Delete the Cancel button (click the Cancel button and press the Delete key).
    2. Add a new static text control to the dialog box.
    3. You can enlarge or resize the static text control if needed.
    4. Double click on the static text control to edit its properties. Change the Caption to "Hello World!." Under the Styles tab, you might change the Align text option to Center.
    5. Dismiss the dialog box by clicking the x in the upper-right corner of the window.

  3. In the File menu, select Save As... and save the resources to a file named HelloDlg.rc in the project directory.

  4. In the Project menu, select Add To Project -> Files. Select HelloDlg.rc and click OK.

  5. Edit (double-click its name in the FileView ) the file HelloDlg.f90:
    • After the program HELLODLG line, add the following line:
       USE DFLOGM
    • Replace the line:
        print *, 'Hello World'

      With the following lines:

        include 'resource.fd'
  type (DIALOG) dlg
  logical lret
  integer iret
  lret = DlgInit(IDD_DIALOG1, dlg)
  iret = DlgModal(dlg)
  call DlgUninit(dlg)

    In the code above:

    • The USE DFLOGM line includes the DFLOGM module interfaces to the Dialog routines.
    • The line include 'resource.fd' includes the .fd file.
    • The function reference to DLGINIT initializes the dialog box.
    • The function reference to DLGMODAL displays the dialog box.
    • The call to DLGUNINIT frees the dialog box resources.

  6. Build the Hellodlg Fortran Console project application. When you execute the application, the dialog box you created appears in front of the Console window:

    displayed output from hellodlg project

  7. Click OK to dismiss the dialog box.

For Visual Fortran applications using the Fortran Windows project type, you can use the Fortran Windows Project AppWizard to help you add dialog coding for a modeless dialog box.

For information about coding requirements for modal and modeless dialog boxes, see Initializing and Activating the Dialog Box.


Using Fortran AppWizards to Help Add Modeless Dialog Box Coding

To use a modeless dialog box, you typically use a Fortran Windows project type. The Fortran Windows Project AppWizard helps you add coding for using a modeless dialog box.

When you create a project and specify the Fortran Windows project, the Fortran Windows Project AppWizard displays four options (press the F1 key to view an explanation of these options).

Select one of the following to help learn about dialog coding where a dialog box is the primary window of the application:

  • A simple Dialog Based Application

    To create an application where a dialog box is the main window of the application, without a menu bar, choose the A simple Dialog Based Application option.

    This creates the skeleton of an entire application that you can immediately build and run to display a sample dialog box. You can add controls to the dialog box and add dialog procedure calls to manipulate the controls and handle dialog callbacks. A number of the sample projects in the ...\SAMPLES\DIALOG\ directory were started using the A simple Dialog Based Application option.

  • A simple Single Document Interface (SDI)

    To create an application where a dialog box is the main window of the application with a menu bar, choose the A simple Single Document Interface (SDI) option.

    This also creates the skeleton of an entire application that you can immediately build and run. You can add a dialog box to the client area of the main window (as explained later).

In the template-like code generated when you select A simple Dialog Based Application option:

  • After you create a project with the A simple Dialog Based Application option, build it, and execute it, the following dialog box is displayed:

    dialog box created and displayed by appwizard

  • Some of the code specific to the dialog routine interfaces and data declarations follows. For this example, the project name is FWin. The project name is used in some of the data declarations:
        use dflogm
    use FWin_dialogGlobals
    .
    .
    .
    include 'resource.fd'

    external FWin_dialogSub
    external FWin_dialogApply

  ! Variables
    type (T_MSG)            mesg
    integer*4               ret
    logical*4               lret

    The FWin_dialogGlobals module is defined in a separate source file in that project. The FWin_dialogSub and FWin_dialogApply are subroutines defined later in the main source file that are callback routines for different controls for the dialog box.

  • The code specific to creating the dialog follows:
        lret = DlgInit(IDD_FWIN_DIALOG_DIALOG, gdlg)
    if (lret == .FALSE.) goto 99999
    lret = DlgSetSub(gdlg, IDD_FWIN_DIALOG_DIALOG, FWin_dialogSub)
    lret = DlgSetSub(gdlg, IDM_APPLY, FWin_dialogApply)
    lret = DlgModeless(gdlg, nCmdShow)
    if (lret == .FALSE.) goto 99999

    Notes for this example:

    DlgInit initializes the dialog box.

    The first call to DlgSetSub assigns a callback subroutine to the Exit button. It associates the FWin_dialogSub subroutine with the dialog box identifier IDD_FWIN_DIALOG_DIALOG (project name is FWin_Dialog). The FWin_dialogSub routine contains code to terminate the program.

    The second call to DlgSetSub associates FWin_dialogApply with the Apply button identifier IDM_APPLY. The user should add code in the FWin_dialogApply subroutine to take appropriate action.

    DlgModeless displays the initialized modeless dialog box, which is ready for user input.

  • The code specific to processing messages (message loop) to react to user input follows:
        ! Read and process messages
    do while( GetMessage (mesg, NULL, 0, 0) )
       if ( DlgIsDlgMessage(mesg) .EQV. .FALSE. ) then
           lret = TranslateMessage( mesg )
           ret  = DispatchMessage( mesg )
       end if
    end do

    Notes for this example:

    The GetMessage Win32 call inside a DO WHILE loop returns a message from the calling thread's message queue.

    DlgIsDlgMessage determines whether the specified message is intended for one of the currently displayed modeless dialog boxes, or a specific dialog box.

    The TranslateMessage Win32 call translates virtual-key messages into character messages.

    The DispatchMessage Win32 call dispatches a message to a window procedure.

  • The dialog box is terminated and its resources are released by calling DlgUninit:
       call DlgUninit(gdlg)

In the template-like code generated when you select A simple Single Document Interface (SDI) AppWizard option, to add the dialog box to the client area of the main window:

  1. In the Insert menu, select Resource... and create a new Dialog box. Edit the Dialog Properties. Select the Styles tab and set Styles to Child and Border to Thin.

  2. In the main source file, add the following USE statement:
      USE dflogm
  3. In the main source file, in the function MainWndProc, add a case to handle the WM_CREATE message. In this case, initialize the dialog box in the normal manner. To display the dialog box, call:
       lret = DlgModeless(dlg, SW_SHOWNA, hwndParent)

    In this call, hwndParent is the window handle of the application's main window.

  4. In the main source file, add a call to DlgIsDlgMessage to the message loop, before the call to the Win32 routine TranslateAccelerator. It should look like:
       ! Read and process messages
   do while( GetMessage (mesg, NULL, 0, 0) )
     if ( DlgIsDlgMessage(mesg, dlg) .EQV. .FALSE. ) then
       if ( TranslateAccelerator (mesg%hwnd, haccel, mesg) == 0) then
          lret = TranslateMessage( mesg )
          ret  = DispatchMessage( mesg )
       end if
     end if
   end do
  5. Optionally, if you want to allow the user to resize the main window, add a case to handle the WM_RESIZE message and change the layout of the dialog box based upon its size.

See the FXPLORER Visual Fortran Sample in ...\SAMPLES\DIALOG for an example of this type of application.


Using Dialog Controls in a DLL

You can use a dialog box that is defined in a DLL. To do so, you must inform the dialog routines that the dialog resource is located in the DLL, rather than in the main application. The dialog routines will look for the dialog resource in the main application by default.

To do this, initialize your dialog box using DlgInitWithResourceHandle rather than DlgInit. As compared to DlgInit, DlgInitWithResourceHandle takes an additional argument named "hinst". The "hinst" argument is the module instance handle in which the dialog resource can be found. For a DLL, this handle is passed into the DLL entry point, DllMain.

An example of a DllMain function follows:

  module dll_globals
     integer(4) ghInst    ! DLL instance handle
  end module dll_globals

  !********************************************************************
  !*   FUNCTION: DllMain(HANDLE, DWORD, LPVOID)
  !*
  !*   PURPOSE:  DllMain is called by Windows when
  !*     the DLL is initialized, Thread Attached, and other times.
  !*     Refer to SDK documentation, as to the different ways this
  !*     may be called.
  !*
  !*     The DllMain function should perform additional initialization
  !*     tasks required by the DLL.  DllMain should return a value of 1
  !*     if the initialization is successful.
  !*
  !*********************************************************************

  integer(4) function DllMain (hInst, ul_reason_being_called, lpReserved)
  !DEC$ IF DEFINED(_X86_)
  !DEC$ ATTRIBUTES STDCALL, ALIAS : '_DllMain@12' :: DllMain
  !DEC$ ELSE
  !DEC$ ATTRIBUTES STDCALL, ALIAS : 'DllMain' :: DllMain
  !DEC$ ENDIF

     use dll_globals

     integer(4) hInst
     integer(4) ul_reason_being_called
     integer(4) lpReserved

     !  Save the module instance handle in a global variable
     !  This would typically be in a Module or a COMMON block.
     ghInst =  hInst

     DllMain = 1
     return
  end

One way to use DlgInitWithResourceHandle is to build a resource-only DLL. A resource-only DLL contains an .RC file, but no code. It is useful for building an application that supports multiple languages. You can create a main application and several resource-only DLLs (one for each language) and call the Win32 LoadLibrary routine at the beginning of your application to load the appropriate resource-only DLL. To use a dialog box from the resource-only DLL, first call LoadLibrary (see the Platform SDK online documentation) to return the instance handle that you can use when you call DlgInitWithResourceHandle.

When you create a Fortran DLL project, you can create a resource-only DLL using the Fortran Dynamic Link Library AppWizard:

  1. In the Fortran Dynamic Link Library AppWizard, select "An empty DLL application."
  2. Complete creating the project.
  3. In the Project menu, select Add to Project...Files to add your .RC file and the RESOURCE.H file that defines the identifiers of the controls.
  4. In the Project menu:
    • Click Settings
    • Click Link tab
    • Add the /noentry switch to the end of the options in the Project Options edit box


Dialog Routines

You can use dialog routines as you would any intrinsic procedure or run-time routine.

As described in Using Dialogs, Visual Fortran supports two types of dialog boxes: modal and modeless. You can use a modal dialog box with any Fortran project type. You can use a modeless dialog box only with the Fortran Windows project types.

The dialog routines can:

  • Initialize and close the dialog box
  • Retrieve user input from a dialog box
  • Display data in the dialog box
  • Modify the dialog box controls

The include file (.FD) of the dialog box contains the names of the dialog controls that you specified in the Properties box of the Resource Editor when you created the dialog box. The module DFLOGM.MOD contains predefined variable names and type definitions. These control names, variables, and type definitions are used in the dialog routine argument lists to manage your dialog box.

The dialog routines are listed in the following table:

Dialog Routine | Description
DLGEXIT | Closes an open dialog
DLGFLUSH | Updates the dialog display
DLGGET | Gets the value of a control variable
DLGGETCHAR | Gets the value of a character control variable
DLGGETINT | Gets the value of an integer control variable
DLGGETLOG | Gets the value of a logical control variable
DLGINIT | Initializes the dialog
DLGINITWITHRESOURCEHANDLE | Initializes the dialog (alternative to DLGINIT)
DLGISDLGMESSAGE | Determines whether a message is intended for a modeless dialog box
DLGISDLGMESSAGEWITHDLG | Determines whether a message is intended for a modeless dialog box (alternative to DLGISDLGMESSAGE)
DLGMODAL | Displays a modal dialog box
DLGMODALWITHPARENT | Displays a modal dialog box (alternative to DLGMODAL)
DLGMODELESS | Displays a modeless dialog box
DLGSENDCTRLMESSAGE | Sends a message to a control
DLGSET | Assigns a value to a control variable
DLGSETCHAR | Assigns a value to a character control variable
DLGSETCTRLEVENTHANDLER | Assigns a routine to handle an ActiveX control event.
DLGSETINT | Assigns a value to an integer control variable
DLGSETLOG | Assigns a value to a logical control variable
DLGSETRETURN | Sets the return value for DLGMODAL
DLGSETSUB | Assigns a defined callback routine to a control
DLGSETTITLE | Sets the dialog title
DLGUNINIT | Deallocates memory for an initialized dialog

These routines are described in the Language Reference (see also Dialog Procedures: table).


Dialog Controls

Each dialog control in a dialog box has a unique integer identifier and name. You specify the name in the Properties box for each control within the Resource Editor, and the Resource Editor assigns the PARAMETER attribute and an integer value to each control name. You can refer to a control by its name, for example IDC_SCROLLBAR_TEMPERATURE, or by its integer value, which you can read from the include (.FD) file.

Each dialog control has one or more variables associated with it, called control indexes. These indexes can be integer, logical, character, or external. For example, a plain Button has three associated variables: one is a logical value associated with its current enabled state, one is a character variable that determines its title, and the third is an external variable that indicates the subroutine to be called if a mouse click occurs.

Dialog controls can have multiple variables of the same type. For example, the scroll bar control has four integer variables associated with it:

  • Scroll bar position
  • Scroll bar minimum range
  • Scroll bar maximum range
  • Position change if the user clicks on the scroll bar space next to the slide (big step)

Dialog controls and their indexes are discussed in:

  • Control Indexes
  • Available Indexes for Each Dialog Control
  • Specifying Control Indexes


Control Indexes

The value of a dialog control's index is set with the DLGSET functions: DLGSET, DLGSETINT, DLGSETLOG, DLGSETCHAR, and DLGSETSUB. The control name and control index name are arguments to the DLGSET functions and specify the particular control index being set. For example:

   retlog = DlgSet( dlg, IDC_SCROLLBAR_TEMPERATURE, 45, DLG_POSITION )

The index DLG_POSITION specifies the scroll bar position is set to 45. Consider the following:

   retlog = DlgSet( dlg, IDC_SCROLLBAR_TEMPERATURE, 200, DLG_RANGEMAX)

In this statement, the index DLG_RANGEMAX specifies the scroll bar maximum range is set to 200. The DLGSET functions have the following syntax:

result = DLGSET (dlg, control_name, value, control_index_name)

The control_index_name determines what the value in the DLGSET function means.

The control index names are declared in the module DFLOGM.MOD and should not be declared in your routines. Available control indexes and how they specify the interpretation of the value argument are listed in the following Control Indexes table.

Control Index | How the Value is Interpreted
DLG_ADDSTRING | Used with DLGSETCHAR to add an entry to a List box or Combo box
DLG_BIGSTEP | The amount of change that occurs in a Scroll bar's or Slider's position when the user clicks beside the Scroll bar's or slider's slide (default = 10)
DLG_CHANGE | A subroutine called after the user has modified a control and the control has been updated on the screen
DLG_CLICKED | A subroutine called when the control receives a mouse-click
DLG_DBLCLICK | A subroutine called when a control is double-clicked
DLG_DEFAULT | Same as not specifying a control index
DLG_ENABLE | The enable state of the control (value = .TRUE. means enabled, value = .FALSE. means disabled)
DLG_GAINFOCUS | A subroutine called when an Edit Box receives input focus.
DLG_IDISPATCH | The object pointer of an ActiveX control.
DLG_LOSEFOCUS | A subroutine called when an Edit Box loses input focus.
DLG_NUMITEMS | The total number of items in a List box, Combo box, or Tab control
DLG_POSITION | The current position of the Scroll bar, Spin, Slider, or Progress bar. Also, the current cursor position in the edit box.
DLG_RANGEMIN | The minimum value of a Scroll bar's, Spin's, Slider's, or Progress' position (default = 1 for scroll bar, 0 for other controls)
DLG_RANGEMAX | The maximum value of a Scroll bar's, Spin's, Slider's, or Progress' position (default = 100)
DLG_SELCHANGE | A subroutine called when the selection in a List Box or Combo Box changes
DLG_SELCHANGING | A subroutine called when the selected Tab control is about to be changed. In this subroutine, calling DLGGETINT with the index DLG_STATE refers to the Tab that was active before the change.
DLG_SMALLSTEP | The amount of change that occurs in a Slider's position when the user presses the keyboard arrow keys (default = 1)
DLG_STATE | The user changeable state of a control
DLG_TEXTLENGTH | The length of text in an edit box.
DLG_TICKFREQ | The interval frequency for tick marks in a Slider (default = 1)
DLG_TITLE | The title text associated with a control
DLG_UPDATE | A subroutine called after the user has modified the control state but before the control has been updated on the screen

The index names associated with dialog controls do not need to be used unless there is more than one variable of the same type for the control and you do not want the default variable. For example:

  retlog = DlgSet(dlg, IDC_SCROLLBAR_TEMPERATURE, 45, DLG_POSITION)
  retlog = DlgSet(dlg, IDC_SCROLLBAR_TEMPERATURE, 45)

These statements both set the Scroll bar position to 45, because DLG_POSITION is the default control index for the scroll bar.

Dialog Indexes

The control identifier specified in DLGSETSUB can also be the identifier of the dialog box. In this case, the index must be one of the values listed in the Dialog Indexes table:

Dialog Index | How the Value is Interpreted
DLG_INIT | A subroutine called after the dialog box is created but before it is displayed (with callbacktype=DLG_INIT) and immediately before the dialog box is destroyed (with callbacktype=DLG_DESTROY).
DLG_SIZECHANGE | A subroutine called after the dialog box is resized.

For more information on dialog controls, see Available Indexes for Each Dialog Control.


Available Indexes for Each Dialog Control

The available indexes and defaults for each of the controls are listed in the following table:

Dialog Controls and Their Indexes

Control Type | Integer Index Name | Logical Index Name | Character Index Name | Subroutine Index Name
ActiveX control | DLG_IDISPATCH | DLG_ENABLE |  |
Button |  | DLG_ENABLE | DLG_TITLE | DLG_CLICKED
Check box |  | DLG_STATE (default) DLG_ENABLE | DLG_TITLE | DLG_CLICKED
Combo box | DLG_NUMITEMS Sets or returns the total number of items in a list | DLG_ENABLE | Use DLG_STATE, DLG_ADDSTRING, or an index: DLG_STATE By default, sets or returns the text of the selected item or first item in the list DLG_ADDSTRING Used with DLGSETCHAR to add a new item. It automatically increments DLG_NUMITEMS. An index, 1 to n Sets or returns the text of a particular item | DLG_SELCHANGE (default) DLG_DBLCLICK DLG_CHANGE DLG_UPDATE
Drop-down list box | Use DLG_NUMITEMS or DLG_STATE: DLG_NUMITEMS (default) Sets or returns the total number of items in a list DLG_STATE Sets or returns the index of the selected item | DLG_ENABLE | Use DLG_STATE, DLG_ADDSTRING, or an index: DLG_STATE By default, sets or returns the text of the selected item or first item in the list, or you can include an index, 1 to n, to set or return indicates the text of a particular item DLG_ADDSTRING Used with DLGSETCHAR to add a new item. It automatically increments DLG_NUMITEMS. | DLG_SELCHANGE (default) DLG_DBLCLICK
Edit box | DLG_TEXTLENGTH (default) Sets or returns the length of the text in the edit box. DLG_POSITION Sets or returns the cursor position | DLG_ENABLE | DLG_STATE | DLG_CHANGE (default) DLG_UPDATE DLG_GAINFOCUS DLG_LOSEFOCUS
Group box |  | DLG_ENABLE | DLG_TITLE |
List box | Use DLG_NUMITEMS or an index: DLG_NUMITEMS Sets or returns the total number of items in a list An index, 1 to n Determines which list items have been selected and their order | DLG_ENABLE | Use DLG_STATE, DLG_ADDSTRING, or an index: DLG_STATE By default, returns the text of the first selected item DLG_ADDSTRING Used with DLGSETCHAR to add a new item. It automatically increments DLG_NUMITEMS. An index, 1 to n Sets or returns the text of a particular item | DLG_SELCHANGE (default) DLG_DBLCLICK
Picture |  | DLG_ENABLE |  |
Progress bar | DLG_POSITION (default) DLG_RANGEMIN DLG_RANGEMAX | DLG_ENABLE |  |
Radio button |  | DLG_STATE (default) DLG_ENABLE | DLG_TITLE | DLG_CLICKED
Scroll bar | DLG_POSITION (default) DLG_RANGEMIN DLG_RANGEMAX DLG_BIGSTEP | DLG_ENABLE |  | DLG_CHANGE
Slider | DLG_POSITION (default) DLG_RANGEMIN DLG_RANGEMAX DLG_SMALLSTEP DLG_BIGSTEP DLG_TICKFREQ | DLG_ENABLE |  | DLG_CHANGE
Spin controls | DLG_POSITION (default) DLG_RANGEMIN DLG_RANGEMAX | DLG_ENABLE |  | DLG_CHANGE
Static text |  | DLG_ENABLE | DLG_TITLE |
Tab control | Use DLG_NUMITEMS (default), DLG_STATE, or an index: DLG_NUMITEMS Sets or returns the total number of tabs DLG_STATE Sets or returns the currently selected tab An index, 1 to n Sets or returns the dialog name of the dialog box associated with a particular tab | DLG_ENABLE | Use DLG_STATE or an index: DLG_STATE By default, sets or returns the currently selected tab An index, 1 to n Sets or returns the text of a particular Tab | DLG_SELCHANGE (default) DLG_SELCHANGING

For an overview on control indexes, see Control Indexes.


Specifying Control Indexes

Where there is only one possibility for a particular dialog control's index type (integer, logical, character, or subroutine), you do not need to specify the control index name in an argument list. For example, you can set the Static text control IDC_TEXT_CELSIUS to a new value with either of the following statements:

  retlog = DLGSETCHAR (dlg, IDC_TEXT_CELSIUS, "New Celsius Title",  &
 &                     DLG_TITLE)
  retlog = DLGSET (dlg, IDC_TEXT_CELSIUS, "New Celsius Title")

You do not need the control index DLG_TITLE because there is only one character index for a Static text control. The generic function DLGSET chooses the control index to change based on the argument type, in this case CHARACTER.

For each type of index, you can use the generic DLGSET function or the specific DLGSET function for that type: DLGSETINT, DLGSETLOG, or DLGSETCHAR.

For example, you can disable the Static text control IDC_TEXT_CELSIUS by setting its logical value to .FALSE. with either DLGSET or DLGSETLOG:

  retlog = DLGSETLOG (dlg, IDC_TEXT_CELSIUS, .FALSE., DLG_ENABLE)
  retlog = DLGSET (dlg, IDC_TEXT_CELSIUS, .FALSE., DLG_ENABLE)

In both these cases, the control index DLG_ENABLE can be omitted because there is only one logical control index for Static text controls.

You can query the value of a particular control index with the DLGGET functions, DLGGET, DLGGETINT, DLGGETLOG, and DLGGETCHAR. For example:

  INTEGER current_val
  LOGICAL are_you_enabled
     retlog = DLGGET (dlg, IDC_SCROLLBAR_TEMPERATURE, current_val,      &
    &                 DLG_RANGEMAX)
     retlog = DLGGET (dlg, IDC_SCROLLBAR_TEMPERATURE, are_you_enabled,  &
    &                 DLG_ENABLE)

This code returns the maximum range and the enable state of the scroll bar. The arguments you declare (current_val and are_you_enabled in the preceding example) to hold the queried values must be of the same type as the values retrieved. If you use specific DLGGET functions such as DLGGETINT or DLGGETCHAR, the control index value retrieved must be the appropriate type. For example, you cannot use DLGGETCHAR to retrieve an integer or logical value. The DLGGET functions return .FALSE. for illegal type combinations. You cannot query for the name of an external callback routine.

In general, it is better to use the generic functions DLGSET and DLGGET rather than their type-specific variations because then you do not have to worry about matching the function to type of value set or retrieved. DLGSET and DLGGET perform the correct operation automatically, based on the type of argument you pass to them.

More information on these routines is available in the Language Reference.


Using Dialog Controls

The dialog controls provided in the Resource Editor are versatile and flexible and when used together can provide a sophisticated user-friendly interface for your application. This section discusses the available dialog controls.

Any control can be disabled by your application at any time, so that it no longer changes or responds to the user. This is done by setting the control index DLG_ENABLE to .FALSE. DLGSET or DLGSETLOG. For example:

  LOGICAL retlog
  retlog = DLGSET (dlg, IDC_CHECKBOX1, .FALSE., DLG_ENABLE)

This example disables the control named IDC_CHECKBOX1.

When you create your dialog box in the Resource Editor, the dialog controls are given a tab order. When the user hits the Tab key, the dialog box focus shifts to the next control in the tab order. By default, the tab order of the controls follows the order in which they were created. This may not be the order you want.

You can change the order by opening the Layout menu and choosing Tab Order (or by pressing the key combination Ctrl+D) in the Resource Editor. A tab number will appear next to each control. Click the mouse on the control you want to be first, then on the control you want to be second in the tab order and so on. Tab order also determines which control gets the focus if the user presses the Group box hotkey. (See Using Group Boxes.)

For information on Visual Fortran Samples that use the Dialog functions, see the ...\DF98\SAMPLES\DIALOG folder.

The following sections describe the function and use of the dialog controls:

  • Using Static Text
  • Using Edit Boxes
  • Using Group Boxes
  • Using Check Boxes and Radio Buttons
  • Using Buttons
  • Using List Boxes and Combo Boxes
  • Using Scroll Bars
  • Using Pictures
  • Using Progress Bars
  • Using Spin Controls
  • Using Sliders
  • Using Tab Controls
  • Setting Return Values and Exiting

For information on using ActiveX controls in a dialog, see Using ActiveX Controls.


Using Static Text

Static text is an area in the dialog that your application writes text to. The user cannot change it. Your application can modify the Static text at any time, for instance to display a current user selection, but the user cannot modify the text. Static text is typically used to label other controls or display messages to the user.


Using Edit Boxes

An Edit box is an area that your application can write text to at anytime. However, unlike Static Text, the user can write to an Edit box by clicking the mouse in the box and typing. The following statements write to an Edit box:

  CHARACTER(20) text /"Send text"/
  retlog = DLGSET (dlg, IDC_EDITBOX1, text)

The next statement reads the character string in an Edit box:

  retlog = DLGGET (dlg, IDC_EDITBOX1, text)

The values a user enters into the Edit box are always retrieved as character strings, and your application needs to interpret these strings as the data they represent. For example, numbers entered by the user are interpreted by your application as character strings. Likewise, numbers you write to the Edit box are sent as character strings. You can convert between numbers and strings by using internal read and write statements to make type conversions.

To read a number in the Edit box, retrieve it as a character string with DLGGET or DLGGETCHAR, and then execute an internal read using a variable of the numeric type you want (such as integer or real). For example:

  REAL    x
  LOGICAL retlog
  CHARACTER(256) text
  retlog = DLGGET (dlg, IDC_EDITBOX1, text)
  READ (text, *) x

In this example, the real variable x is assigned the value that was entered into the Edit box, including any decimal fraction.

Complex and double complex values are read the same way, except that your application must separate the Edit box character string into the real part and imaginary part. You can do this with two separate Edit boxes, one for the real and one for the imaginary part, or by requiring the user to enter a separator between the two parts and parsing the string for the separator before converting. If the separator is a comma (,) you can read the string with two real edit descriptors without having to parse the string.

To write numbers to an Edit box, do an internal write to a string, then send the string to the Edit box with DLGSET. For example:

  INTEGER  j
  LOGICAL  retlog
  CHARACTER(256) text
  WRITE (text,'(I4)') j
  retlog = DLGSET (dlg, IDC_EDITBOX1, text)

Use the DLG_TEXTLENGTH control index to get or set the length of the characters in the edit box. The length is automatically updated when:

  • Your program calls DLGSET to set the text in the edit box (trailing blanks are stripped before setting the edit box).
  • The user modifies the text in the edit box.

If you want to set the text with significant trailing blanks, call DLGSET to set the text followed by DLGSET with the DLG_TEXTLENGTH index to set the length that you want.

Use the DLG_POSITION index to get or set the current cursor position in the edit box. Note that setting the cursor position cancels any current selection in the edit box.


Using Group Boxes

A Group box visually organizes a collection of controls as a group. When you select Group box in Resource Editor, you create an expanding (or shrinking) box around the controls you want to group and give the group a title. You can add a hotkey to your group title with an ampersand (&). For example, consider the following group title:

  &Temperature

This causes the "T" to be underlined in the title and makes it a hotkey. When the user presses the key combination ALT+T, the focus of the dialog box shifts to the next control after the Group box in the tab order. This control should be a control in the group. (You can view and change the tab order from the Layout/Tab Order menu option in the Resource Editor.)

Disabling the Group box disables the hotkey, but does not disable any of the controls within the group. As a matter of style, you should generally disable the controls in a group when you disable the Group box.


Using Check Boxes and Radio Buttons

Check boxes and Radio buttons present the user with an either-or choice. A Radio button is pushed or not, and a Check box is checked or not. You use DLGGET or DLGGETLOG to check the state of these controls. Their state is a logical value that is .TRUE. if they are pushed or checked, and .FALSE. if they are not. For example:

  LOGICAL pushed_state, checked_state, retlog
  retlog = DLGGET (dlg, IDC_RADIOBUTTON1, pushed_state)
  retlog = DLGGET (dlg, IDC_CHECKBOX1, checked_state)

If you need to change the state of the button, for initialization or in response to other user input, you use DLGSET or DLGSETLOG. For example:

  LOGICAL retlog
  retlog = DLGSET (dlg, IDC_RADIOBUTTON1, .TRUE.)
  retlog = DLGSET (dlg, IDC_CHECKBOX1, .TRUE.)

Radio buttons are typically used in a group where the user can select only one of a set of radio buttons. When using Radio buttons with the Dialog routines, use the following guidelines:

  • Each Radio button should have the "Auto" style set. This is the default for a new Radio button.
  • The first Radio button in a group should have the "Group" style set. This is not the default for a new Radio button.
  • The remaining Radio buttons in the group should not have the "Group" style set, and should immediately follow the first button in the dialog box "Tab order". The default tab order is the order in which you create the controls. You can view and change the tab order from the Layout/Tab Order menu option in the Resource Editor.
  • When the user selects a Radio button in a group, its state is set to .TRUE. and the state of the other Radio buttons in the group is set to .FALSE..
  • To set the currently selected Radio button from your code, call DLGSETLOG to set the selected Radio button to .TRUE.. Do not set the other Radio buttons to .FALSE.. This is handled automatically.


Using Buttons

Unlike Check Boxes and Radio Buttons, Buttons do not have a state. They do not hold the value of being pushed or not pushed. When the user clicks on a Button with the mouse, the Button's callback routine is called. Thus,the purpose of a Button is to initiate an action. The external procedure you assign as a callback determines the action initiated. For example:

  LOGICAL retlog
  EXTERNAL DisplayTime
  retlog = DlgSetSub( dlg, IDC_BUTTON_TIME, DisplayTime)

Visual Fortran dialog routines do not support user-drawn Buttons.


Using List Boxes and Combo Boxes

List boxes and Combo boxes are used when the user needs to select a value from a set of many values. They are similar to a set of Radio buttons except that List boxes and Combo boxes are scrollable and can contain more items than a set of Radio buttons which are limited by the screen display area. Also, unlike Radio buttons, the number of entries in a List box or Combo box can change at run-time.

The difference between a List box and a Combo box is that a List box is simply a list of items, while a Combo box is a combination of a List box and an Edit box. A List box allows the user to choose multiple selections from the list at one time, while a Combo box allows only a single selection, but a Combo box allows the user to edit the selected value while a List box only allows the user to choose from the given list.

A Drop-down list box looks like a Combo box since it has a drop-down arrow to display the list. Like a Combo box, only one selection can be made at a time in a Drop-down list box, but, like a List box, the selected value cannot be edited. A Drop-down list box serves the same function as a List box except for the disadvantage that the user can choose only a single selection, and the advantage that it takes up less dialog screen space.

Visual Fortran dialog routines do not support user-drawn List boxes or user-drawn Combo boxes. You must create List boxes and Combo boxes with the Resource Editor.

The following sections describe how to use List boxes and Combo boxes:

  • Using List boxes
  • Using Combo boxes
  • Using Drop-down List boxes

Using List Boxes

For both List boxes and Combo boxes, the control index DLG_NUMITEMS determines how many items are in the box. Once this value is set, you set the text of List box items by specifying a character string for each item index. Indexes run from 1 to the total number of list items set with DLG_NUMITEMS. For example:

  LOGICAL retlog
  retlog = DlgSet ( dlg, IDC_LISTBOX1, 3, DLG_NUMITEMS )
  retlog = DlgSet ( dlg, IDC_LISTBOX1, "Moe", 1 )
  retlog = DlgSet ( dlg, IDC_LISTBOX1, "Larry", 2 )
  retlog = DlgSet ( dlg, IDC_LISTBOX1, "Curly", 3 )

These function calls to DLGSET put three items in the List box. The initial value of each List box entry is a blank string and the value becomes nonblank after it has been set.

You can change the list length and item values at any time, including from within callback routines. If the list is shortened, the set of entries is truncated. If the list is lengthened, blank entries are added. In the preceding example, you could extend the list length and define the new item with the following:

  retlog = DLGSET ( dlg, IDC_LISTBOX1, 4)
  retlog = DLGSET ( dlg, IDC_LISTBOX1, "Shemp", 4)

Since List boxes allow selection of multiple entries, you need a way to determine which entries are selected. When the user selects a List box item, it is assigned an integer index. You can test which list items are selected by reading the selection indexes in order until a zero value is read. For example, if in the previous List box the user selected Moe and Curly, the List box selection indexes would have the following values:

Selection Index | Value
1 | 1 (for Moe)
2 | 3 (for Curly)
3 | 0 (no more selections)

If Larry alone had been selected, the List box selection index values would be:

Selection Index | Value
1 | 2 (for Larry)
2 | 0 (no more selections)

To determine the items selected, the List box values can be read with DLGGET until a zero is encountered. For example:

  INTEGER j, num, test
  INTEGER, ALLOCATABLE :: values(:)
  LOGICAL retlog

  retlog = DLGGET (dlg, IDC_LISTBOX1, num, DLG_NUMITEMS)
  ALLOCATE (values(num))
  j = 1
  test = -1
  DO WHILE (test .NE. 0)
     retlog = DLGGET (dlg, IDC_LISTBOX1, values(j), j)
     test = values(j)
     j = j + 1
  END DO

In this example, j is the selection index and values(j) holds the list numbers, of the items selected by the user, if any.

To read a single selection, or the first selected item in a set, you can use DLG_STATE, since for a List Box DLG_STATE holds the character string of the first selected item (if any). For example:

  ! Get the string for the first selected item.
  retlog = DLGGET (dlg, IDC_LISTBOX1, str, DLG_STATE)

Alternatively, you can first retrieve the list number of the selected item, and then get the string associated with that item:

  INTEGER value
  CHARACTER(256) str
    ! Get the list number of the first selected item.
    retlog = DLGGET (dlg, IDC_LISTBOX1, value, 1)
    ! Get the string for that item.
    retlog = DLGGET (dlg, IDC_LISTBOX1, str, value)

In these examples, if no selection has been made by the user, str will be a blank string.

In the Properties/Styles box in the Resource Editor, List boxes can be specified as sorted or unsorted. The default is sorted, which causes List box items to be sorted alphabetically starting with A. If a List box is specified as sorted, the items in the list are sorted whenever they are updated on the screen. This occurs when the dialog box is first displayed and when the items are changed in a callback.

The alphabetical sorting follows the ASCII collating sequence, and uppercase letters come before lowercase letters. For example, if the List box in the example above with the list "Moe," "Larry," "Curly," and "Shemp" were sorted, before a callback or after DLGMODAL returned, index 1 would refer to "Curly," index 2 to "Larry," index 3 to "Moe," and index 4 to "Shemp." For this reason, when using sorted List boxes, indexes should not be counted on to be the same once the dialog is displayed and any change is made to the list items.

You can also call DLGSETCHAR with the DLG_ADDSTRING index to add items to a List box or Combo box. For example:

  retlog = DlgSet(dlgtab, IDC_LIST, "Item 1", DLG_ADDSTRING)

When you use DLG_ADDSTRING, the DLG_NUMITEMS control index of the List or Combo box is automatically incremented.

When adding items to a sorted list or Combo box, using DLG_ADDSTRING can be much easier than the alternative (setting DLG_NUMITEMS and then setting items using an index value), because you need not worry about the list being sorted and the index values changing between calls.

Using Combo Boxes

A Combo box is a combination of a List box and an Edit box. The user can make a selection from the list that is then displayed in the Edit box part of the control, or enter text directly into the Edit box.

All dialog values a user enters are character strings, and your application must interpret these strings as the data they represent. For example, numbers entered by the user are returned to your application as character strings.

Because user input can be given in two ways, selection from the List box portion or typing into the Edit box portion directly, you need to register two callback types with DLGSETSUB for a Combo box. These callback types are dlg_selchange to handle a new list selection by the user, and dlg_update to handle text entered by the user directly into the Edit box portion. For example:

  retlog = DlgSetSub( dlg, IDC_COMBO1, UpdateCombo, dlg_selchange )
  retlog = DlgSetSub( dlg, IDC_COMBO1, UpdateCombo, dlg_update )

A Combo box list is created the same way a List box list is created, as described in the previous section, but the user can select only one item from a Combo box at a time. When the user selects an item from the list, Windows automatically puts the item into the Edit box portion of the Combo box. Thus, there is no need, and no mechanism, to retrieve the item list number of a selected item.

If the user is typing an entry directly into the Edit box part of the Combo box, again Windows automatically displays it and you do not need to. You can retrieve the character string of the selected item or Edit box entry with the following statement:

  ! Returns the character string of the selected item or Edit box entry as str.
  retlog = DLGGET (dlg, IDC_COMBO1, str)

Like List boxes, Combo boxes can be specified as sorted or unsorted. The notes about sorted List boxes also apply to sorted Combo boxes.

You have three choices for Combo box Type in the Styles tab of Combo box Properties:

  • Simple
  • Drop list
  • Drop-down

Simple and Drop-down are the same, except that a simple Combo box always displays the Combo box choices in a list, while a Drop-down list Combo box has a Drop-down button and displays the choices in a Drop-down list, conserving screen space. The Drop list type is halfway between a Combo box and a List box and is described below.

Using Drop-Down List Boxes

To create a Drop-down list box, choose a Combo box from the control toolbar and place it in your dialog. Double-click the left mouse button on the Combo box to open the Properties box. On the Styles Tab, choose Drop List as the control type.

A Drop-down list box has a drop-down arrow to display the list. Like a Combo box, only one selection can be made at a time in the list, but like a List Box, the selected value cannot be edited. A Drop-down list box serves the same function as a List box except for the disadvantage that the user can choose only a single selection, and the advantage that it takes up less dialog screen space.

A Drop-down list box has the same control indexes as a Combo box with the addition of another INTEGER index to set or return the list number of the item selected in the list. For example:

  INTEGER num
    ! Returns index of the selected item.
    retlog = DLGGET (dlg, IDC_DROPDOWN1, num, DLG_STATE)


Using Scroll Bars

With a Scroll bar, the user determines input by manipulating the slide up and down or right and left. Your application sets the range for the Scroll bar, and thus can interpret a position of the slide as a number. If you want to display this number to the user, you need to send the number (as a character string) to a Static text or Edit Box control.

You set the lower and upper limits of the Scroll bar range by setting the control index DLG_RANGEMIN and DLG_RANGEMAX with DLGSET or DLGSETINT. The default values are 1 and 100. For example:

  LOGICAL retlog
  retlog = DLGSET (dlg, IDC_SCROLLBAR1, 212, DLG_RANGEMAX)

You get the slide position by retrieving the control index DLG_POSITION with DLGGET or DLGGETINT. For example:

  INTEGER slide_position
  retlog = DLGGET (dlg, IDC_SCROLLBAR1, slide_position, DLG_POSITION)

You can also set the increment taken when the user clicks in the blank area above or below the slide in a vertical Scroll bar, or to the left or right of the slide in a horizontal Scroll bar, by setting the control index DLG_BIGSTEP. For example:

  retlog = DLGSET (dlg, IDC_SCROLLBAR1, 20, DLG_BIGSTEP)

When the user clicks on the arrow buttons of the Scroll bar, the position is always incremented or decremented by 1.

The maximum value (DLG_POSITION) that a scroll bar can report (that is, the maximum scrolling position) depends on the page size (DLG_BIGSTEP). If the scroll bar has a page size greater than one, the maximum scrolling position is less than the maximum range value (DLG_RANGEMAX or DLG_RANGE). You can use the following formula to calculate the maximum scrolling position:

  MaxScrollPos = MaxRangeValue - (PageSize - 1)

For example, if a scroll bar has DLG_RANGEMAX = 100 (100 is the default value of DLG_RANGEMAX) and DLG_BIGSTEP = 10 (10 is the default value of DLG_BIGSTEP), then the maximum DLG_POSITION is 91 (100 - (10 - 1)).

The maximum DLG_POSITION of scroll bars in the Visual Fortran V5 (and Microsoft Fortran PowerStation V4) Dialog Procedures is the same value as the maximum range value (DLG_RANGE).

This allows your application to implement a "proportional" scroll bar. The size of the scroll box (or thumb) is determined by the value of DLG_BIGSTEP and should represent a "page" of data (that is, the amount of data visible in the window).

When the user clicks in the "shaft" of the scroll bar, the next (or previous) page is displayed. The top of the thumb (for a vertical scroll bar) or the left edge of the thumb (for a horizontal scroll bar) represents the position of the scroll bar (DLG_POSITION).

The size of the thumb represents the amount of data currently visible. There is a minimum thumb size so as not to affect usability. When the scroll bar is at its maximum position, the position will represent the position in the data such that the last "page" of data is visible in the window. When the top (or left edge) of the scroll bar is at the mid-point of the shaft, DLG_POSITION will be the mid-point of the range and the mid-point of the data should be displayed at the top of the window.


Using Pictures

The Picture control is an area of your dialog box in which your application displays a picture.

The user cannot change it, since it is an output-only window. It does not respond to user input and therefore does not support any callbacks.

The picture displayed can be set using the Properties dialog box in the Resource Editor. The options that can be fully defined using the Resource Editor include a:

  • Icon
  • Bitmap
  • Frame
  • Rectangle

When using the Resource editor, you need to double-click on the border of the picture to display the Picture Properties box. If the Properties box displayed has a title of Dialog Properties instead of Picture Properties, dismiss the Dialog Properties box and try to select the border before you perform the double-click. The Picture Properties box allows you to select the Type of picture as well as specify the Image for certain picture types.

For example, to add an existing BMP (Bitmap) file to a dialog:

  1. After you open your project workspace, from the Insert menu, click Resource.
  2. Select the Resource type (such as Icon or Bitmap) and then select whether it is a new resource, an Import (existing) resource, or Custom resource. In our example, we will specify an existing Bitmap file we have previously copied into our project directory (click Import).
  3. After we specify the resource, its name appears in the ResourceView under the appropriate resource type (such as bitmap).
  4. Add a picture to the dialog box, by dragging the picture icon from the Control toolbar to the appropriate place in the dialog box. You can resize the picture as needed. The default picture type is frame.
  5. Carefully double-click on the border of the picture area to display the Picture Properties box. If the Dialog Properties box appears instead of Picture Properties, dismiss the Dialog Properties box and try again.
  6. In the Picture Properties box, select the Type of picture. If you select a type of Bitmap or Icon, for example, you can select the Image from the list of available project resources.
  7. You can move the picture as needed.
  8. Dismiss the Picture Properties box.


Using Progress Bars

The Progress bar is a window that can be used to indicate the progress of a lengthy operation. It consists of a rectangle that is gradually filled as an operation progresses.

Your application sets the range of the Progress bar, using DLG_RANGEMIN and DLG_RANGEMAX, and the current position, using DLG_POSITION. Both the minimum and maximum range values must be between 0 and 65535.

A Progress bar is an output-only window. It does not respond to user input and therefore does not support any callbacks.


Using Spin Controls

The Spin control contains up and down arrows that allow the user to step through values. Your application sets or gets the range of the Spin control's values, using DLG_RANGEMIN and DLG_RANGEMAX, and the current value, using DLG_POSITION.

The Spin control is usually associated with a companion control that is called a "buddy window." To the user, the Spin control and its buddy window often look like a single control. You can specify that the Spin control automatically position itself next to its buddy window and that it automatically set the title of its buddy window to its current value. This is accomplished by setting the "Auto buddy" and "Set buddy integer" styles on the Spin control.

The buddy window is usually an Edit Box or Static Text control. When the "Auto buddy" style is set, the Spin control automatically uses the previous control in the dialog box tab order as its buddy window.

The Spin Control calls the DLG_CHANGE callback whenever the user changes the current value of the control.

The Spin control is named the "Up-down" control in Windows programming documentation.


Using Sliders

The Slider Control is a window that contains a slider and optional tick marks. Your application sets or gets the range of the Slider control's values, using DLG_RANGEMIN and DLG_RANGEMAX, and the current value, using DLG_POSITION. Your application can also set:

  • The number of logical positions the slider moves in response to keyboard input from the arrow keys using DLG_SMALLSTEP.

  • The number of logical positions the slider moves in response to keyboard input, such as the PAGE UP or PAGE DOWN keys, or mouse input, such as clicks in the slider's channel, using DLG_BIGSTEP.

  • The interval frequency for tick marks on the slider using DLG_TICKFREQ.

The Slider Control calls the DLG_CHANGE callback whenever the user changes the current value of the control.

The Slider control is named the "Trackbar" control in Windows programming documentation.


Using Tab Controls

The Tab control is like the dividers in a notebook or the labels on a file cabinet. By using a Tab control, an application can define multiple pages for the same area of a dialog box. Each page is associated with a particular Tab and only one page is displayed at a time.

The control index DLG_NUMITEMS determines how many Tabs are contained in the Tab control. For each Tab, you specify the label of the Tab using DLGSETCHAR and an index value from 1 to the number of Tabs set with DLG_NUMITEMS. Each Tab has an associated dialog box that is displayed when the Tab is selected. You specify the dialog box using DLGSETINT with the dialog name and an index value corresponding to the the Tab. For example, the code below defines three Tabs in a Tab control. The Tab with the label "Family" is associated with the dialog box named IDD_TAB_DIALOG1, and so on.

  !  Set initial Tabs
  lret = DlgSet(gdlg, IDC_TAB, 3)
  lret = DlgSet(gdlg, IDC_TAB, "Family", 1)
  lret = DlgSet(gdlg, IDC_TAB, "Style", 2)
  lret = DlgSet(gdlg, IDC_TAB, "Size", 3)
  lret = DlgSet(gdlg, IDC_TAB, IDD_TAB_DIALOG1, 1)
  lret = DlgSet(gdlg, IDC_TAB, IDD_TAB_DIALOG2, 2)
  lret = DlgSet(gdlg, IDC_TAB, IDD_TAB_DIALOG3, 3)

You define each of the Tab dialogs using the resource editor as you do for the dialog box that contains the Tab control. In the Dialog Properties, you must make the following style settings for each Tab dialog:

  1. Set the "Style" to "Child"
  2. Set "Border" to "None"
  3. Uncheck "Title Bar"

Before displaying the dialog box that contains the Tab control (using DLGMODAL or DLGMODELESS):

  1. Call DLGSETSUB to define a DLG_INIT callback for the dialog box
  2. Call DLGINIT for each Tab dialog

In the DLG_INIT callback of the dialog box that contains the Tab control, if the callbacktype is DLG_INIT, call DLGMODELESS for each of the Tab dialog boxes. Specify SW_HIDE as the second parameter, and the window handle of the Tab control as the third parameter. After calling DLGMODELESS, call DLGSET with the DLG_STATE index to set the initial Tab. For example:

   ! When the Main dialog box is first displayed, call DlgModeless to
  ! display the Tab dialog boxes.  Note the use of SW_HIDE.  The
  ! Dialog Functions will "show" the proper Tab dialog box.
  if (callbacktype == dlg_init) then
    hwnd = GetDlgItem(dlg % hwnd, IDC_TAB)
    lret = DlgModeless(gdlg_tab1, SW_HIDE, hwnd)
    lret = DlgModeless(gdlg_tab2, SW_HIDE, hwnd)
    lret = DlgModeless(gdlg_tab3, SW_HIDE, hwnd)

    ! Note that we must set the default Tab after the calls to
    ! DlgModeless.  Otherwise, no Tab dialog box will be displayed
    ! initially.
    lret = DlgSet(dlg, IDC_TAB, 1, dlg_state)

Call DLGUNINIT for each Tab dialog when you are done with it.

For a complete example of using a Tab control, see the Visual Fortran Sample ShowFont in the ...\DF98\SAMPLES\DIALOG folder.


Setting Return Values and Exiting

When the user selects the dialog's OK or CANCEL button, your dialog procedure is exited and the dialog box is closed. DLGMODAL returns the control name (associated with an integer identifier in your include (.FD) file) of the control that caused it to exit; for example, IDOK or IDCANCEL.

If you want to exit your dialog box on a condition other than the user selecting the OK or CANCEL button, you need to include a call to the dialog subroutine DLGEXIT from within your callback routine. For example:

SUBROUTINE EXITSUB (dlg, exit_button_id, callbacktype)
USE DFLOGM
TYPE (DIALOG) dlg
INTEGER exit_button_id, callbacktype
...
  CALL DLGEXIT (dlg)

The only argument for DLGEXIT is the dialog derived type. The dialog box is exited after DLGEXIT returns control back to the dialog manager, not immediately after calling DLGEXIT. That is, if there are other statements following DLGEXIT within the callback routine that contains it, those statements are executed and the callback routine returns before the dialog box is exited.

If you want DLGMODAL to return with a value other than the control name of the control that caused the exit, (or -1 if DLGMODAL fails to open the dialog box), you can specify your own return value with the subroutine DLGSETRETURN. For example:

TYPE (DIALOG) dlg
INTEGER altreturn
...
altreturn = 485
CALL DLGSETRETURN (dlg, altreturn)
CALL DLGEXIT(dlg)

To avoid confusion with the default failure condition, use return values other than -1.

It is not possible to return a value when a modeless dialog box exits. However, you can call DLGSETSUB to set the DLG_INIT callback routine to have a procedure called immediately before the dialog box is destroyed.

If you want the user to be able to close the dialog from the system menu or by pressing the ESC key, you need a control that has the ID of IDCANCEL. When a system escape or close is performed, it simulates pressing the dialog button with the ID IDCANCEL. If no control in the dialog has the ID IDCANCEL, then the close command will be ignored (and the dialog can not be closed in this way).

If you want to enable system close or ESC to close a dialog, but do not want a cancel button, you can add a button with the ID IDCANCEL to your dialog and then remove the visible property in the button's Properties box. Pressing ESC will then activate the default click callback of the cancel button and close the dialog.


Using ActiveX Controls

The dialog routines support the use of ActiveX controls. That is, the dialog routines can act as an ActiveX control container. The FXPLORER and MMPLAYER samples in the ...\SAMPLES\DIALOG folder are examples of using an ActiveX control in a Visual Fortran application.

Using an ActiveX control in a dialog box requires four steps discussed in the following sections:

  1. Using the Resource Editor to Insert an ActiveX Control discusses using the resource editor to insert the ActiveX control into the dialog box.
  2. Using the Fortran Module Wizard to Generate Code discusses using the Fortran Module Wizard to generate a module that allows you to use the methods, properties, and events of the ActiveX control from Fortran.
  3. Adding Code to Your Application discusses adding code to your application to manipulate the ActiveX control and respond to control events.
  4. Target System Requirements describes how to ensure that the ActiveX control and the dialog procedure ActiveX container DLL are present and registered on the target system.


Using the Resource Editor to Insert an ActiveX Control

To add ActiveX controls to a dialog box:

  1. In the Resource dialog editor window, right click and hold to display the pop-up (shortcut) menu.
  2. Click the Insert ActiveX Control item in the shortcut menu.
  3. Click the right mouse button in any clear area in the dialog box.
  4. Select the Insert ActiveX Control item from the menu. A dialog box appears displaying the list of ActiveX controls that are registered on your system.
  5. Select one of the listed controls and press OK to add it to your dialog box.

Once you insert the ActiveX control, you can modify it using the resource editor like other controls. You can move, resize, and delete the ActiveX control. You can also modify its properties. ActiveX controls often have a large set of properties that you can modify.


Using the Fortran Module Wizard to Generate Code

An ActiveX control is an Automation object. ActiveX controls typically support methods, properties, and events. ActiveX controls use events to notify an application that something has happened to the control. Common examples of events include clicks on the control, data entered using the keyboard, and changes in the control's state. When these actions occur, the control issues an event to alert the application.

The application, in return, uses methods and properties to communicate with the control. Methods are functions that perform an action on the ActiveX control. For example, you would use a method to tell an Internet Explorer ActiveX control to load a particular URL. Properties hold information about the state of an object, for example, the font being used by a control to draw text.

The Fortran Module Wizard generates Fortran 90 modules that simplify calling COM and Automation objects from Fortran programs. To run the Fortran Module Wizard, in the Tools menu, click Fortran Module Wizard.

The module wizard asks a series of questions. For an ActiveX control, choose the Type Library Containing Automation Information option in the initial Module Wizard screen. In the Type Library screen, choose the ActiveX control that you want to use. Typically, this is a file with a .OCX extension. See the documentation on the ActiveX control to determine its filename. You may select individual components of the ActiveX control to process using the Module Wizard, but typically you can let the wizard default to processing all of the components.

After entering the information and pressing the Generate button, the Fortran Module Wizard asks you for the name of the source file to be generated. It then asks COM to open the type library and generates a file containing Fortran modules. To add the newly created file to your project, in the Project menu, click Add To Project -> Files.

For more information:

  • About using the Fortran Module Wizard, see Using COM and Automation Objects.


Adding Code to Your Application

The structure of your application remains the same as when using a dialog box that does not contain an ActiveX control. See Writing a Dialog Application for details. This section discusses programming specific to ActiveX controls.

Your application must call COMINITIALIZE before calling DLGINIT with a dialog box that contains an ActiveX control. Your application must include the statement USE DFCOM to access COMINITIALIZE. Your application must call COMUNINITIALIZE when you are done using ActiveX controls, but not before calling DLGUNINIT for the dialog box that contains the ActiveX control.

You can call the methods of an ActiveX control and set and retrieve its property values using the interfaces generated by the Fortran Module Wizard or by using the DFAUTO routines. To do this, you must have the object's IDispatch interface pointer. Use the DLGGET function with the ActiveX control's name, the DLG_IDISPATCH control index, and an integer variable to receive the IDispatch pointer. For example:

  retlog = DlgGet( dlg, IDC_ACTIVEX, idispatch, DLG_IDISPATCH )

You do not need to specify the index DLG_IDISPATCH because it is the default integer index for an ActiveX control.

Note however, that the control's IDispatch pointer is not available until after the control has been created and is only valid until the dialog box is closed. The control is created during the call to DLGMODAL or DLGMODELESS. If you call DLGGET to retrieve the IDispatch pointer before calling DLGMODAL or DLGMODELESS, the value returned will be 0.

Do not call COMRELEASEOBJECT with the iDispatch pointer returned by DLGGET. The dialog procedures use a reference counting optimization since the lifetime of the control is guaranteed to be less than the lifetime of the dialog box.

If you want to use a method or property of a control before the dialog box is displayed to your application's user, you can use a DLG_INIT callback. Call DLGSETSUB using the dialog box name and the DLG_INIT index to define the callback. For example:

   retlog = DlgSetSub( dlg, IDD_DIALOG, DlgSub, DLG_INIT )

The DLG_INIT callback is called after the dialog box is created but before it is displayed (with callbacktype=DLG_INIT) and immediately before the dialog box is destroyed (with callbacktype=DLG_DESTROY). The DLG_INIT callback is the soonest that the control's IDispatch pointer is available. The DLG_DESTROY callback is the latest that this pointer is valid. After the DLG_DESTROY callback, the ActiveX control is destroyed.

The following example shows using a DLG_INIT callback to reset the state of a control property before it is destroyed:

  SUBROUTINE mmplayerSub( dlg, id, callbacktype )
    !DEC$ ATTRIBUTES DEFAULT :: mmplayerSub
    use dflogm
    use dfcom
    use dfauto
    implicit none
    type (dialog) dlg
    integer id, callbacktype
    include 'resource.fd'
    integer obj, iret
    logical lret
    if (callbacktype == dlg_init) then
        lret = DlgGet(dlg, IDC_ACTIVEMOVIECONTROL1, obj)
        !  Add any method or property calls here before the
        !  dialog box is displayed
    else if (callbacktype == dlg_destroy) then
        !  Reset the filename to "" to "close" the current file
        lret = DlgGet(dlg, IDC_ACTIVEMOVIECONTROL1, obj)
        iret = AUTOSETPROPERTY(obj, "FileName", "")
    endif
  END SUBROUTINE mmplayerSub

The module generated by the Fortran Module Wizard for an ActiveX control contains a number of sections:

  • ! CLSIDs
    Parameters of derived type GUID which identify the ActiveX control class. Your application typically doesn't need to use this parameter.
  • ! IIDs
    Parameters of derived type GUID which identify source (event) interfaces of the ActiveX control. Your application can use these values in calls to DLGSETCTRLEVENTHANDLER (see below).
  • ! Enums
    Parameters of type integer that identify constants used in the ActiveX control's interfaces.
  • ! Interfaces
    Interfaces for the source (event) interfaces that are defined by the ActiveX control. There may be 0, 1, or more source interfaces implemented by the control. A control does not have to support events.
  • ! Module Procedures
    Wrapper routines that make it easy to call the control's methods and get or retrieve the control's properties.

See Calling the Routines Generated by the Module Wizard for more information on using the method and property interfaces generated by the Fortran Module Wizard.

In addition to methods and properties, ActiveX controls also define events to notify your application that something has happened to the control. The dialog procedures provide a routine, DLGSETCTRLEVENTHANDLER, that allows you to define a routine to be executed when an event occurs.

The DLGSETCTRLEVENTHANDLER function has the following interface:

integer DlgSetCtrlEventHandler( dlg, controlid, handler, dispid, iid )

The arguments are as follows:

dlg | (Input) Derived type DIALOG. Contains dialog box parameters.
controlid | (Input) Integer. Specifies the identifier of a control within the dialog box (from the .FD file).
handler | (Input) EXTERNAL. Name of the routine to be called when the event occurs.
dispid | (Input) Integer. Specifies the member id of the method in the event interface that identifies the event
iid | (Input, Optional) Derived type(GUID). Specifies the Interface identifier of the source (event) interface. If not supplied, the default source interface of the ActiveX control is used.

Consider the following function call:

  ret = DlgSetCtrlEventHandler( dlg, IDC_ACTIVEMOVIECONTROL1, &
    ActiveMovie_ReadyStateChange, -609, IID_DActiveMovieEvents2 )

In this function call:

  • IDC_ACTIVEMOVIECONTROL1 identifies an ActiveMovie control in the dialog box.
  • ActiveMovie_ReadyStateChange is the name of the event handling routine.
  • -609 is the member id of the ActiveMovie's control ReadyStateChange event. You can get this number from:
    • The module that the Fortran Module Wizard generated. There is a "MEMBERID = nn" comment generated for each method in a source interface (see the example below).
    • The documentation of the ActiveX control.
    • A tool that allows you to examine the type information of the ActiveX control, for example, the OLE-COM Object Viewer in the Visual Fortran folder.
  • IID_DActiveMovieEvents2 is the identifier of the source (event) interface.

The interface generated by the Fortran Module Wizard for the ReadyStateChange event follows:

 INTERFACE
    !Reports that the ReadyState property of the ActiveMovie Control has changed
    ! MEMBERID = -609
    SUBROUTINE DActiveMovieEvents2_ReadyStateChange($OBJECT, ReadyState)
        INTEGER(4), INTENT(IN)	:: $OBJECT	 ! Object Pointer
        !DEC$ ATTRIBUTES VALUE	:: $OBJECT
        INTEGER(4)	:: ReadyState
        !DEC$ ATTRIBUTES VALUE	:: ReadyState
        !DEC$ ATTRIBUTES STDCALL :: DActiveMovieEvents2_ReadyStateChange
     END SUBROUTINE DActiveMovieEvents2_ReadyStateChange
  END INTERFACE

The handler that you define in your application must have the same interface. Otherwise, your application will likely crash in unexpected ways because of the application's stack getting corrupted.

Note that an object is always the first parameter in an event handler. This object value is a pointer to the control's source (event) interface, not the IDispatch pointer of the control. You can use DLGGET as described above to retrieve the control's IDispatch pointer.


Target System Requirements

Any ActiveX control that you use must be properly installed and registered on your machine and any machine that you distribute your application to. See the documentation for the ActiveX control for information on how to redistribute it.

The dialog routine ActiveX control container support is implemented in the files DFDLGnnn.DLL that can be found in the ...\DF\REDIST folder on the Visual Fortran CD-ROM. This DLL must be present and registered on any machine that you distribute your application to.

To register a DLL, use REGSVR32.EXE, located in the Windows system directory. REGSVR32 takes a single argument: the path of the DLL. You can alternatively use VFRUNxxx to install the complete set of Visual Fortran run-time files. You can download Visual Fortran redistributable files (VFRUNxxx) from the download/update area of Compaq Fortran Web site:

http://www.compaq.com/fortran


Drawing Graphics Elements

The graphics routines provided with Visual Fortran set points, draw lines, draw text, change colors, and draw shapes such as circles, rectangles, and arcs. This section assumes you have read the overview in Using QuickWin.

This section uses the following terms:

  • The origin (point 0, 0) is the upper-left corner of the screen or the client area (defined user area) of the child window being written to. The x-axis and y-axis start at the origin. You can change the origin in some coordinate systems.
  • The horizontal direction is represented by the x-axis, increasing to the right.
  • The vertical direction is represented by the y-axis, increasing down.
  • Some graphics adapters offer a color palette that can be changed.
  • Some graphics adapters (VGA and SVGA) allow you to change the color that a color index refers to by providing a color value that describes a new color. The color value indicates the mix of red, green, and blue in a screen color. A color value is always an INTEGER(4) number.

The sections on drawing graphics are organized as follows:

  • Working with Graphics Modes
  • Adding Color
  • Understanding Coordinate Systems
  • Advanced Graphics Using OpenGL


Working with Graphics Modes

To display graphics, you need to set the desired graphics mode using SETWINDOWCONFIG, and then call the routines needed to create the graphics.

These sections explain each step:

  • Checking the Current Graphics Mode
  • Setting the Graphics Mode
  • Writing a Graphics Program


Checking the Current Graphics Mode

Call GETWINDOWCONFIG to get the child window settings. The DFLIB.F90 module in the \DF98\INCLUDE subdirectory defines a derived type, windowconfig, that GETWINDOWCONFIG uses as a parameter:

 TYPE windowconfig
   INTEGER(2) numxpixels      ! Number of pixels on x-axis
   INTEGER(2) numypixels      ! Number of pixels on y-axis
   INTEGER(2) numtextcols     ! Number of text columns available
   INTEGER(2) numtextrows     ! Number of text rows available
   INTEGER(2) numcolors       ! Number of color indexes
   INTEGER(4) fontsize        ! Size of default font
   CHARACTER(80) title        ! window title
   INTEGER(2) bitsperpixel    ! Number of bits per pixel
 END TYPE windowconfig

By default, a QuickWin child window is a scrollable text window 640x480 pixels, has 30 lines and 80 columns, and a font size of 8x16. Also by default, a Standard Graphics window is Full Screen. You can change the values of window properties at any time with SETWINDOWCONFIG, and retrieve the current values at any time with GETWINDOWCONFIG.


Setting the Graphics Mode

Use SETWINDOWCONFIG to configure the window for the properties you want. To set the highest possible resolution available with your graphics driver, assign a -1 value for numxpixels, numypixels, numtextcols, and numtextrows in the windowconfig derived type. This causes Fortran Standard Graphics applications to start in Full Screen mode.

If you specify less than the largest graphics area, the application starts in a window. You can use ALT+ENTER to toggle between Full Screen and windowed views. If your application is a QuickWin application and you do not call SETWINDOWCONFIG, the child window defaults to a scrollable text window with the dimensions of 640x480 pixels, 30 lines, 80 columns, and a font size of 8x16. The number of colors depends on the video driver used.

If SETWINDOWCONFIG returns .FALSE., the video driver does not support the options specified. The function then adjusts the values in the windowconfig derived type to ones that will work and are as close as possible to the requested configuration. You can then call SETWINDOWCONFIG again with the adjusted values, which will succeed. For example:

  LOGICAL statusmode
  TYPE (windowconfig) wc
  wc%numxpixels  = 1000
  wc%numypixels  = 300
  wc%numtextcols = -1
  wc%numtextrows = -1
  wc%numcolors   = -1
  wc%title = "Opening Title"C
  wc%fontsize = #000A000C ! 10 X 12
  statusmode = SETWINDOWCONFIG(wc)
  IF (.NOT. statusmode) THEN statusmode = SETWINDOWCONFIG(wc)

If you use SETWINDOWCONFIG, you should specify a value for each field ( –1 or your own number for numeric fields, and a C string for the title). Calling SETWINDOWCONFIG with only some of the fields specified can result in useless values for the other fields.


Writing a Graphics Program

Like many programs, graphics programs work well when written in small units. Using discrete routines aids debugging by isolating the functional components of the program. The following example program and its associated subroutines show the steps involved in initializing, drawing, and closing a graphics program.

The SINE program draws a sine wave. Its procedures call many of the common graphics routines. The main program calls five subroutines that carry out the actual graphics commands (also located in the SINE.F90 file):

  ! SINE.F90 - Illustrates basic graphics commands.
  !
    USE DFLIB
    CALL graphicsmode( )
    CALL drawlines( )
    CALL sinewave( )
    CALL drawshapes( )
    END
     .
     .
     .

For information on the subroutines used in the SINE program, see:

  • graphicsmode in section Activating a Graphics Mode
  • drawlines in section Drawing Lines on the Screen
  • sinewave in section Drawing a Sine Curve
  • drawshapes in section Adding Shapes

The SINE program's output appears in the following figure. The SINE routines are in the Visual Fortran Sample TUTORIAL folder. The project is built as a Fortran Standard Graphics application.

Sine Program Output


Activating a Graphics Mode

If you call a graphics routine without setting a graphics mode with SETWINDOWCONFIG, QuickWin automatically sets the graphics mode with default values.

SINE selects and sets the graphics mode in the subroutine graphicsmode, which selects the highest possible resolution for the current video driver:

  SUBROUTINE graphicsmode( )
    USE DFLIB
    LOGICAL             modestatus
    INTEGER(2)          maxx, maxy
    TYPE (windowconfig) myscreen
    COMMON              maxx, maxy

 !  Set highest resolution graphics mode.

    myscreen.numxpixels=-1
    myscreen.numypixels=-1
    myscreen.numtextcols=-1
    myscreen.numtextrows=-1
    myscreen.numcolors=-1
    myscreen.fontsize=-1
    myscreen.title = " "C ! blank

    modestatus=SETWINDOWCONFIG(myscreen)

 !  Determine the maximum dimensions.

    modestatus=GETWINDOWCONFIG(myscreen)
    maxx=myscreen.numxpixels - 1
    maxy=myscreen.numypixels - 1
  END SUBROUTINE

Pixel coordinates start at zero, so, for example, a screen with a resolution of 640 horizontal pixels has a maximum x-coordinate of 639. Thus, maxx (the highest available x-pixel coordinate) must be 1 less than the total number of pixels. The same applies to maxy.

To remain independent of the video mode set by graphicsmode, two short functions convert an arbitrary screen size of 1000x1000 pixels to whatever video mode is in effect. From now on, the program assumes it has 1000 pixels in each direction. To draw the points on the screen, newx and newy map each point to their physical (pixel) coordinates:

  ! NEWX - This function finds new x-coordinates.

    INTEGER(2) FUNCTION newx( xcoord )

    INTEGER(2) xcoord, maxx, maxy
    REAL(4) tempx
    COMMON maxx, maxy

    tempx = maxx / 1000.0
    tempx = xcoord * tempx + 0.5
    newx = tempx
    END FUNCTION

  ! NEWY - This function finds new y-coordinates.
  !
    INTEGER(2) FUNCTION newy( ycoord )
    INTEGER(2) ycoord, maxx, maxy
    REAL(4) tempy
    COMMON maxx, maxy

    tempy = maxy / 1000.0
    tempy = ycoord * tempy + 0.5
    newy = tempy
    END FUNCTION

You can set up a similar independent coordinate system with window coordinates, described in Understanding Coordinate Systems.


Drawing Lines on the Screen

SINE next calls the subroutine drawlines, which draws a rectangle around the outer edges of the screen and three horizontal lines that divide the screen into quarters. (See Sine Program Output.)

 !  DRAWLINES - This subroutine draws a box and
 !  several lines.

 SUBROUTINE drawlines( )
    USE DFLIB

    EXTERNAL        newx, newy
    INTEGER(2)      status, newx, newy, maxx, maxy
    TYPE (xycoord)  xy
    COMMON          maxx, maxy
 !
 !  Draw the box.

    status = RECTANGLE( $GBORDER, INT2(0), INT2(0), maxx, maxy )
    CALL SETVIEWORG( INT2(0), newy( INT2( 500 ) ), xy )    ! This sets
 !           the new origin to 0 for x and 500 for y. See comment after subroutine.

 !  Draw the lines.

    CALL MOVETO( INT2(0), INT2(0), xy )
    status = LINETO( newx( INT2( 1000 )), INT2(0))
    CALL SETLINESTYLE( INT2( #AA3C ))
    CALL MOVETO( INT2(0), newy( INT2( -250 )), xy )
    status = LINETO(newx( INT2( 1000 )),newy( INT2( -250 )))
    CALL SETLINESTYLE( INT2( #8888 ))
    CALL MOVETO(INT2(0), newy( INT2( 250 )), xy )
    status = LINETO( newx( INT2( 1000 )),newy( INT2( 250 ) ) )
 END SUBROUTINE

The first argument to RECTANGLE is the fill flag, which can be either $GBORDER or $GFILLINTERIOR. Choose $GBORDER if you want a rectangle of four lines (a border only, in the current line style), or $GFILLINTERIOR if you want a solid rectangle (filled in with the current color and fill pattern). Choosing the color and fill pattern is discussed in Adding Color and Adding Shapes.

The second and third RECTANGLE arguments are the x- and y-coordinates of the upper-left corner of the rectangle. The fourth and fifth arguments are the coordinates for the lower-right corner. Because the coordinates for the two corners are ( 0, 0 ) and ( maxx, maxy ), the call to RECTANGLE frames the entire screen.

The program calls SETVIEWORG to change the location of the viewport origin. By resetting the origin to (0, 500) in a 1000x1000 viewport, you effectively make the viewport run from (0, -500) at the top left of the screen to (1000, 500) at the bottom right of the screen:

  CALL SETVIEWORG( INT2(0), newy( INT2( 500 ) ), xy )

Changing the coordinates illustrates the ability to alter the viewport coordinates to whatever dimensions you prefer. (Viewports and the SETVIEWORG routine are explained in more detail in Understanding Coordinate Systems.)

The call to SETLINESTYLE changes the line style from a solid line to a dashed line. A series of 16 bits tells the routine which pattern to follow. A "1" indicates a solid pixel and "0" an empty pixel. Therefore, 1111 1111 1111 1111 represents a solid line. A dashed line might look like 1111 1111 0000 0000 (long dashes) or 1111 0000 1111 0000 (short dashes). You can choose any combination of ones and zeros. Any INTEGER(2) number in any base is an acceptable input, but binary and hexadecimal numbers are easier to envision as line-style patterns.

In the example, the hexadecimal constant #AA3C equals the binary value 1010 1010 0011 1100. You can use the decimal value 43580 just as effectively.

When drawing lines, first set an appropriate line style. Then, move to where you want the line to begin and call LINETO, passing to it the point where you want the line to end. The drawlines subroutine uses the following code:

  CALL SETLINESTYLE(INT2( #AA3C ) )
  CALL MOVETO( INT2(0), newy( INT2( -250 ) ), xy )
  dummy = LINETO( newx( INT2( 1000 )), newy( INT2( -250 )))

MOVETO positions an imaginary pixel cursor at a point on the screen (nothing appears on the screen), and LINETO draws a line. When the program called SETVIEWORG, it changed the viewport origin, and the initial y-axis range of 0 to 1000 now corresponds to a range of –500 to +500. Therefore, the negative value –250 is used as the y-coordinate of LINETO to draw a horizontal line across the center of the top half of the screen, and the value of 250 is used as the y-coordinate to draw a horizontal line across the center of the bottom half of the screen.


Drawing a Sine Curve

With the axes and frame in place, SINE is ready to draw the sine curve. The sinewave routine calculates the x and y positions for two cycles and plots them on the screen:

  ! SINEWAVE - This subroutine calculates and plots a sine wave.

  SUBROUTINE sinewave( )

     USE DFLIB

     INTEGER(2)    dummy, newx, newy, locx, locy, i
     INTEGER(4)    color
     REAL          rad
     EXTERNAL      newx, newy

     PARAMETER    ( PI = 3.14159 )
  !
  !  Calculate each position and display it on the screen.
     color = #0000FF ! red
  !
     DO i = 0, 999, 3
        rad   = -SIN( PI * i / 250.0 )
        locx  = newx( i )
        locy  = newy( INT2( rad * 250.0 ) )
        dummy = SETPIXELRGB( locx, locy, color )
     END DO
  END SUBROUTINE

SETPIXELRGB takes the two location parameters, locx and locy, and sets the pixel at that position with the specified color value (red).


Adding Shapes

After drawing the sine curve, SINE calls drawshapes to put two rectangles and two ellipses on the screen. The fill flag alternates between $GBORDER and $GFILLINTERIOR:

 ! DRAWSHAPES - Draws two boxes and two ellipses.
 !
   SUBROUTINE drawshapes( )

      USE DFLIB

      EXTERNAL    newx, newy
      INTEGER(2)  dummy, newx, newy
   !
   !  Create a masking (fill) pattern.
   !
      INTEGER(1) diagmask(8), horzmask(8)
      DATA diagmask / #93, #C9, #64, #B2, #59, #2C, #96, #4B /
      DATA horzmask / #FF, #00, #7F, #FE, #00, #00, #00, #CC /
   !
   !  Draw the rectangles.
   !
      CALL SETLINESTYLE( INT2(#FFFF ))
      CALL SETFILLMASK( diagmask )
      dummy = RECTANGLE( $GBORDER,newx(INT2(50)),newy(INT2(-325)), &
      & newx(INT2(200)),newy(INT2(-425)))
      dummy = RECTANGLE( $GFILLINTERIOR,newx(INT2(550)), &
      & newy(INT2(-325)),newx(INT2(700)),newy(INT2(-425)))
   !
   !  Draw the ellipses.
   !
      CALL SETFILLMASK( horzmask )
      dummy = ELLIPSE( $GBORDER,newx(INT2(50)),newy(INT2(325)), &
      & newx(INT2(200)),newy(INT2(425)))
      dummy = ELLIPSE( $GFILLINTERIOR,newx(INT2(550)), &
      & znewy(INT2(325)),newx(INT2(700)),newy(INT2(425)))
    END SUBROUTINE

The call to SETLINESTYLE resets the line pattern to a solid line. Omitting this routine causes the first rectangle to appear with a dashed border, because the drawlines subroutine called earlier changed the line style to a dashed line.

ELLIPSE draws an ellipse using parameters similar to those for RECTANGLE. It, too, requires a fill flag and two corners of a bounding rectangle. The following figure shows how an ellipse uses a bounding rectangle:

Bounding Rectangle

The $GFILLINTERIOR constant fills the shape with the current fill pattern. To create a pattern, pass the address of an 8-byte array to SETFILLMASK. In drawshapes, the diagmask array is initialized with the pattern shown in the following table:

Fill Patterns

Bit pattern                  Value in diagmask
Bit No.7 6 5 4 3 2 1 0
       x o o x o o x x       diagmask(1) = #93
       x x o o x o o x       diagmask(2) = #C9
       o x x o o x o o       diagmask(3) = #64
       x o x x o o x o       diagmask(4) = #B2
       o x o x x o o x       diagmask(5) = #59
       o o x o x x o o       diagmask(6) = #2C
       x o o x o x x o       diagmask(7) = #96
       o x o o x o x x       diagmask(8) = #4B


Adding Color

The Visual Fortran QuickWin Library supports color graphics. The number of total available colors depends on the current video driver and video adapter you are using. The number of available colors you use depends on the graphics functions you choose. The different color modes and color functions are discussed and demonstrated in the following sections:

  • Color Mixing
  • VGA Color Palette
  • Using Text Colors


Color Mixing

If you have a VGA machine, you are restricted to displaying at most 256 colors at a time. These 256 colors are held in a palette. You can choose the palette colors from a range of 262,144 colors (256K), but only 256 at a time. Some display adapters (most SVGAs) are capable of displaying all of the 256K colors and some (true color display adapters) are capable of displaying 256 * 256 * 256 = 16.7 million colors.

If you use a palette, you are restricted to the colors available in the palette. In order to access all colors available on your system, you need to specify an explicit Red-Green-Blue (RGB) value, not a palette index.

When you select a color index, you specify one of the colors in the system's predefined palette. SETCOLOR, SETBKCOLOR, and SETTEXTCOLOR set the current color, background color, and text color to a palette index.

SETCOLORRGB, SETBKCOLORRGB, and SETTEXTCOLORRGB set the colors to a color value chosen from the entire available range. When you select a color value, you specify a level of intensity with a range of 0 - 255 for each of the red, green, and blue color values. The long integer that defines a color value consists of 3 bytes (24 bits) as follows:

  MSB                    LSB
  BBBBBBBB GGGGGGGG RRRRRRRR

where R, G, and B represent the bit values for red, green, and blue intensities. To mix a light red (pink), turn red all the way up and mix in some green and blue:

  10000000 10000000 11111111

In hexadecimal notation, this number equals #8080FF. To set the current color to this value, you can use the function:

  i = SETCOLORRGB (#8080FF)

You can also pass decimal values to this function. Keep in mind that 1 (binary 00000001, hex 01) represents a low color intensity and that 255 (binary 11111111, hex FF) equals full color intensity. To create pure yellow (100-percent red plus 100-percent green) use this line:

  i = SETCOLORRGB( #00FFFF )

For white, turn all of the colors on:

  i = SETCOLORRGB( #FFFFFF)

For black, set all of the colors to 0:

  i = SETCOLORRGB( #000000)

RGB values for example colors are in the following table.

RGB Color Values
Color | RGB Value | Color | RGB Value
Black | #000000 | Bright White | #FFFFFF
Dull Red | #000080 | Bright Red | #0000FF
Dull Green | #008000 | Bright Green | #00FF00
Dull Yellow | #008080 | Bright Yellow | #00FFFF
Dull Blue | #800000 | Bright Blue | #FF0000
Dull Magenta | #800080 | Bright Magenta | #FF00FF
Dull Turquoise | #808000 | Bright Turquoise | #FFFF00
Dark Gray | #808080 | Light Gray | #C0C0C0

If you have a 64K-color machine and you set an RGB color value that is not equal to one of the 64K preset RGB color values, the system approximates the requested RGB color to the closest available RGB value. The same thing happens on a VGA machine when you set an RGB color that is not in the palette. (You can remap your VGA color palette to different RGB values; see VGA Color Palette.)

However, although your graphics are drawn with an approximated color, if you retrieve the color with GETCOLORRGB, GETBKCOLORRGB, or GETTEXTCOLORRGB, the color you specified is returned, not the actual color used. This is because the SETCOLORRGB functions do not execute any graphics, they simply set the color and the approximation is made when the drawing is made (by ELLIPSE or ARC, for example).

GETPIXELRGB and GETPIXELSRGB do return the approximated color actually used, because SETPIXELRGB and SETPIXELSRGB actually set a pixel to a color on the screen and the approximation, if any, is made at the time they are called.


VGA Color Palette

A VGA machine is capable of displaying at most 256 colors at a time. QuickWin provides support for VGA monitors and more advanced monitors that are set at 256 colors. Only a 256-color palette (or less) is supported internally regardless of the current number of colors set for the display (in the Control Panel). The number of colors you select for your VGA palette depends on your application, and is set by setting the wc%numcolors variable in the windowconfig derived type to 2, 16, or 256 with SETWINDOWCONFIG.

An RGB color value must be in the palette to be accessible to your VGA graphic displays. You can change the default colors and customize your color palette by using REMAPPALETTERGB to change a palette color index to any RGB color value. The following example remaps the color index 1 (default blue color) to the pure red color value given by the RGB value #0000FF. After this is executed, whatever was displayed as blue will appear as red:

  USE DFLIB
  INTEGER(4) status
  status = REMAPPALETTERGB( 1, #0000FF )  ! Reassign color index 1
                                          ! to RGB red

REMAPALLPALETTERGB remaps one or more color indexes simultaneously. Its argument is an array of RGB color values that are mapped into the palette. The first color number in the array becomes the new color associated with color index 0, the second with color index 1, and so on. At most 236 indexes can be mapped, because 20 indexes are reserved for system use.

If you request an RGB color that is not in the palette, the color selected from the palette is the closest approximation to the RGB color requested. If the RGB color was previously placed in the palette with REMAPPALETTERGB or REMAPALLPALETTERGB, then that exact RGB color is available.

Remapping the palette has no effect on 64K-color machines, SVGA, or true-color machines, unless you limit yourself to a palette by using color index functions such as SETCOLOR. On a VGA machine, if you remap all the colors in your palette and display that palette in graphics, you cannot then remap and simultaneously display a second palette.

For instance, in VGA 256-color mode, if you remap all 256 palette colors and display graphics in one child window, then open another child window, remap the palette and display graphics in the second child window, you are attempting to display more than 256 colors at one time. The machine cannot do this, so whichever child window has the focus will appear correct, while the one without the focus will change color.

Note: Machines that support more than 256 colors will not be able to do animation by remapping the palette. Windows operating systems create a logical palette that maps to the video hardware palette. On video hardware that supports a palette of 256 colors or less, remapping the palette maps over the current palette and redraws the screen in the new colors.

On large hardware palettes that support more than 256 colors, remapping is done into the unused portion of the palette. It does not map over the current colors nor redraw the screen. So, on machines with large palettes (more than 256 colors), the technique of changing the screen through remapping, called palette animation, cannot be used. See the Platform SDK Manual for more information.

Symbolic constants (names) for the default color numbers are supplied in the graphics modules. The names are self-descriptive; for example, the color numbers for black, yellow, and red are represented by the symbolic constants $BLACK, $YELLOW, and $RED.


Using Text Colors

SETTEXTCOLORRGB (or SETTEXTCOLOR) and SETBKCOLORRGB (or SETBKCOLOR) set the foreground and background colors for text output. All use a single argument specifying the color value (or color index) for text displayed with OUTTEXT and WRITE. For the color index functions, colors are represented by the range 0-31. Index values in the range of 16-31 access the same colors as those in the range of 0-15.

You can retrieve the current foreground and background color values with GETTEXTCOLORRGB and GETBKCOLORRGB or the color indexes with GETTEXTCOLOR and GETBKCOLOR. Use SETTEXTPOSITION to move the cursor to a particular row and column. OUTTEXT and WRITE print the text at the current cursor location.

For more information on these routines, see the appropriate routines in the Language Reference.


Understanding Coordinate Systems

Several different coordinate systems are supported by the Visual Fortran QuickWin Library. Text coordinates work in rows and columns; physical coordinates serve as an absolute reference and as a starting place for creating custom window and viewport coordinates. Conversion routines make it simple to convert between different coordinate systems.

The coordinate systems are demonstrated and discussed in the following sections:

  • Text Coordinates
  • Graphics Coordinates
  • Real Coordinates Sample Program


Text Coordinates

The text modes use a coordinate system that divides the screen into rows and columns as shown in the following figure:

Text Screen Coordinates

Text coordinates use the following conventions:

  • Numbering starts at 1. An 80-column screen contains columns 1-80.
  • The row is always listed before the column.

If the screen displays 25 rows and 80 columns (as shown in the above Figure), the rows are numbered 1-25 and the columns are numbered 1-80. The text-positioning routines, such as SETTEXTPOSITION and SCROLLTEXTWINDOW, use row and column coordinates.


Graphics Coordinates

Three coordinate systems describe the location of pixels on the screen:

  • Physical coordinates
  • Viewport coordinates
  • Window coordinates

In all three coordinate systems, the x-coordinate is listed before the y-coordinate.

Physical Coordinates

Physical coordinates are integers that refer to pixels in a window's client area. By default, numbering starts at 0, not 1. If there are 640 pixels, they are numbered 0-639.

Suppose your program calls SETWINDOWCONFIG to set up a client area containing 640 horizontal pixels and 480 vertical pixels. Each individual pixel is referred to by its location relative to the x-axis and y-axis, as shown in the following figure:

Physical Coordinates

The upper-left corner is the origin. The x- and y-coordinates for the origin are always (0, 0).

Physical coordinates refer to each pixel directly and are therefore integers (that is, the window's client area cannot display a fractional pixel). If you use variables to refer to pixel locations, declare them as integers or use type-conversion routines when passing them to graphics functions. For example:

ISTATUS = LINETO( INT2(REAL_x), INT2(REAL_y))

If a program uses the default dimension of a window, the viewport (drawing area) is equal to 640x480. SETVIEWORG changes the location of the viewport's origin. You pass it two integers, which represent the x and y physical screen coordinates for the new origin. You also pass it an xycoord type that the routine fills with the physical coordinates of the previous origin. For example, the following line moves the viewport origin to the physical screen location (50, 100):

  TYPE (xycoord) origin
  CALL SETVIEWORG(INT2(50), INT2(100), origin)

The effect on the screen is illustrated in the following figure:

Origin Coordinates Changed by SETVIEWORG

The number of pixels hasn't changed, but the coordinates used to refer to the points have changed. The x-axis now ranges from -50 to +589 instead of 0 to 639. The y-axis now covers the values -100 to +379.

All graphics routines that use viewport coordinates are affected by the new origin, including MOVETO, LINETO, RECTANGLE, ELLIPSE, POLYGON, ARC, and PIE. For example, if you call RECTANGLE after relocating the viewport origin and pass it the values (0, 0) and (40, 40), the upper-left corner of the rectangle would appear 50 pixels from the left edge of the screen and 100 pixels from the top. It would not appear in the upper-left corner of the screen.

SETCLIPRGN creates an invisible rectangular area on the screen called a clipping region. You can draw inside the clipping region, but attempts to draw outside the region fail (nothing appears outside the clipping region).

The default clipping region occupies the entire screen. The QuickWin Library ignores any attempts to draw outside the screen.

You can change the clipping region by calling SETCLIPRGN. For example, suppose you entered a screen resolution of 320x200 pixels. If you draw a diagonal line from (0, 0) to (319, 199), the upper-left to the lower-right corner, the screen looks like the following figure:

Line Drawn on a Full Screen

You could create a clipping region by entering:

  CALL SETCLIPRGN(INT2(10), INT2(10), INT2(309), INT2(189))

With the clipping region in effect, the same LINETO command would put the line shown in the following figure on the screen:

Line Drawn Within a Clipping Region

The dashed lines indicate the outer bounds of the clipping region and do not actually print on the screen.

Viewport Coordinates

The viewport is the area of the screen displayed, which may be only a portion of the window's client area. Viewport coordinates represent the pixels within the current viewport. SETVIEWPORT establishes a new viewport within the boundaries of the physical client area. A standard viewport has two distinguishing features:

  • The origin of a viewport is in the upper-left corner.
  • The default clipping region matches the outer boundaries of the viewport.

SETVIEWPORT has the same effect as SETVIEWORG and SETCLIPRGN combined. It specifies a limited area of the screen in the same manner as SETCLIPRGN, then sets the viewport origin to the upper-left corner of the area.

Window Coordinates

Functions that refer to coordinates on the client-area screen and within the viewport require integer values. However, many applications need floating-point values—for frequency, viscosity, mass, and so on. SETWINDOW lets you scale the screen to almost any size. In addition, window-related functions accept double-precision values.

Window coordinates use the current viewport as their boundaries. A window overlays the current viewport. Graphics drawn at window coordinates beyond the boundaries of the window—the same as being outside the viewport—are clipped.

For example, to graph 12 months of average temperatures on the planet Venus that range from –50 to +450, add the following line to your program:

  status = SETWINDOW(.TRUE., 1.0D0, -50.0D0, 12.0D0, 450.0D0)

The first argument is the invert flag, which puts the lowest y value in the lower-left corner. The minimum and maximum x- and y-coordinates follow; the decimal point marks them as floating-point values. The new organization of the screen is shown in the following figure:

Window Coordinates

January and December plot on the left and right edges of the screen. In an application like this, numbering the x-axis from 0.0 to 13.0 provides some padding space on the sides and would improve appearance.

If you next plot a point with SETPIXEL_W or draw a line with LINETO_W, the values are automatically scaled to the established window.

To use window coordinates with floating-point values:

  1. Set a graphics mode with SETWINDOWCONFIG.
  2. Use SETVIEWPORT to create a viewport area. This step is not necessary if you plan to use the entire screen.
  3. Create a real-coordinate window with SETWINDOW, passing a LOGICAL invert flag and four DOUBLE PRECISION x- and y-coordinates for the minimum and maximum values.
  4. Draw graphics shapes with RECTANGLE_W and similar routines. Do not confuse RECTANGLE (the viewport routine) with RECTANGLE_W (the window routine for drawing rectangles). All window function names end with an underscore and the letter W ( _W).

Real-coordinate graphics give you flexibility and device independence. For example, you can fit an axis into a small range (such as 151.25 to 151.45) or into a large range (–50000.0 to +80000.0), depending on the type of data you graph. In addition, by changing the window coordinates, you can create the effects of zooming in or panning across a figure. The window coordinates also make your drawings independent of the computer's hardware. Output to the viewport is independent of the actual screen resolution.


Real Coordinates Sample Program

The program REALG.F90 shows how to create multiple window-coordinate sets, each in a separate viewport, on a single screen. REALG.F90 is a Visual Fortran Sample in the TUTORIAL folder.

  ! REALG.F90 (main program) - Illustrates coordinate graphics.
  !
      USE DFLIB
      LOGICAL              statusmode
      TYPE (windowconfig)  myscreen
      COMMON               myscreen
  !
  !   Set the screen to the best resolution and maximum number of
  !   available colors.
      myscreen.numxpixels  = -1
      myscreen.numypixels  = -1
      myscreen.numtextcols = -1
      myscreen.numtextrows = -1
      myscreen.numcolors   = -1
      myscreen.fontsize    = -1
      myscreen.title       = " "C
      statusmode = SETWINDOWCONFIG(myscreen)
      IF(.NOT. statusmode) statusmode = SETWINDOWCONFIG(myscreen)

      statusmode = GETWINDOWCONFIG( myscreen )
      CALL threegraphs( )
      END
      .
      .
      .

The main body of the program is very short. It sets the window to the best resolution of the graphics driver (by setting the first four fields to -1) and the maximum number of colors (by setting numcolors to –1). The program then calls the threegraphs subroutine that draws three graphs. The program output is shown in the following figure:

REALG Program Output

The gridshape subroutine, which draws the graphs, uses the same data in each case. However, the program uses three different coordinate windows.

The two viewports in the top half are the same size in physical coordinates, but have different window sizes. Each window uses different maximum and minimum values. In all three cases, the graph area is two units wide. The window in the upper-left corner has a range in the x-axis of four units (4 units wide); the window in the upper-right corner has a range in the x-axis of six units, which makes the graph on the right appear smaller.

In two of the three graphs, one of the lines goes off the edge, outside the clipping region. The lines do not intrude into the other viewports, because defining a viewport creates a clipping region.

Finally, the graph on the bottom inverts the data with respect to the two graphs above it.

The next section describes and discusses the subroutine invoked by REALG.F90:

Drawing the Graphs

The main program calls threegraphs, which prints the three graphs:

  SUBROUTINE threegraphs()
    USE DFLIB
    INTEGER(2)           status, halfx, halfy
    INTEGER(2)           xwidth, yheight, cols, rows
    TYPE (windowconfig)  myscreen
    COMMON               myscreen

    CALL CLEARSCREEN( $GCLEARSCREEN )
    xwidth  = myscreen.numxpixels
    yheight = myscreen.numypixels
    cols    = myscreen.numtextcols
    rows    = myscreen.numtextrows
    halfx   = xwidth / 2
    halfy   = (yheight / rows) * ( rows / 2 )
 !
 !  First window
 !
    CALL SETVIEWPORT( INT2(0), INT2(0), halfx - 1, halfy - 1 )
    CALL SETTEXTWINDOW( INT2(1), INT2(1), rows / 2, cols / 2 )
    status = SETWINDOW( .FALSE., -2.0_8, -2.0_8, 2.0_8, 2.0_8)
 !  The 2.0_8 notation makes these constants REAL(8)

    CALL gridshape( rows / 2 )
    status = RECTANGLE( $GBORDER,INT2(0),INT2(0),halfx-1,halfy-1)
 !
 !  Second window
 !
    CALL SETVIEWPORT( halfx, INT2(0), xwidth - 1, halfy - 1 )
    CALL SETTEXTWINDOW( INT2(1), (cols/2) + 1, rows/2, cols)
    status = SETWINDOW( .FALSE., -3.0D0, -3.0D0, 3.0D0, 3.0D0)
 !  The 3.0D0 notation makes these constants REAL(8)

    CALL gridshape( rows / 2 )
    status = RECTANGLE_W( $GBORDER, -3.0_8,-3.0_8,3.0_8, 3.0_8)

 !
 !  Third window
 !
    CALL SETVIEWPORT( 0, halfy, xwidth - 1, yheight - 1 )
    CALL SETTEXTWINDOW( (rows / 2 ) + 1, 1_2, rows, cols )
    status = SETWINDOW( .TRUE., -3.0_8, -1.5_8, 1.5_8, 1.5_8)
    CALL gridshape( INT2( (rows / 2) + MOD( rows, INT2(2))))
    status = RECTANGLE_W( $GBORDER, -3.0_8, -1.5_8, 1.5_8, 1.5_8)
  END SUBROUTINE

Although the screen is initially clear, threegraphs makes sure by calling the CLEARSCREEN routine to clear the window:

  CALL CLEARSCREEN( $GCLEARSCREEN )

The $GCLEARSCREEN constant clears the entire window. Other options include $GVIEWPORT and $GWINDOW, which clear the current viewport and the current text window, respectively.

After assigning values to some variables, threegraphs creates the first window:

  CALL SETVIEWPORT( INT2(0), INT2(0), halfx - 1, halfy - 1)
  CALL SETTEXTWINDOW( INT2(1), INT2(1), rows / 2, cols / 2)
  status = SETWINDOW( .FALSE., -2.0_8, -2.0_8, 2.0_8, 2.0_8)

The first instruction defines a viewport that covers the upper-left quarter of the screen. The next instruction defines a text window within the boundaries of that border. Finally, the third instruction creates a window with both x and y values ranging from –2.0 to 2.0. The .FALSE. constant causes the y-axis to increase from top to bottom, which is the default. The _8 notation identifies the constants as REAL(8).

Next, the function gridshape inserts the grid and plots the data, and a border is added to the window:

  CALL gridshape( rows / 2 )
  status = RECTANGLE( $GBORDER,INT2(0),INT2(0),halfx-1,halfy-1)

This is the standard RECTANGLE routine, which takes coordinates relative to the viewport, not the window.

The gridshape subroutine plots the data on the screen.

 ! GRIDSHAPE - This subroutine plots data for REALG.F90
 !
  SUBROUTINE gridshape( numc )

    USE DFLIB
    INTEGER(2)           numc, i, status
    INTEGER(4)           rgbcolor, oldcolor
    CHARACTER(8)         str
    REAL(8)              bananas(21), x
    TYPE (windowconfig)  myscreen
    TYPE (wxycoord)      wxy
    TYPE (rccoord)       curpos
    COMMON               myscreen
  !
  !  Data for the graph:
  !
     DATA bananas / -0.3, -0.2, -0.224, -0.1, -0.5, 0.21, 2.9, &
     & 0.3, 0.2, 0.0, -0.885, -1.1, -0.3, -0.2, &
     & 0.001, 0.005, 0.14, 0.0, -0.9, -0.13, 0.31 /
  !
  !  Print colored words on the screen.
  !

     IF(myscreen.numcolors .LT. numc) numc = myscreen.numcolors-1
     DO i = 1, numc
         CALL SETTEXTPOSITION( i, INT2(2), curpos )
         rgbcolor = 12**i -1
         rgbcolor = MODULO(rgbcolor, #FFFFFF)
         oldcolor = SETTEXTCOLORRGB( rgbcolor )
         WRITE ( str, '(I8)' ) rgbcolor
         CALL OUTTEXT( 'Color ' // str )
     END DO
  !
  !  Draw a double rectangle around the graph.
  !
     oldcolor = SETCOLORRGB( #0000FF ) ! full red
     status = RECTANGLE_W( $GBORDER, -1.00_8, -1.00_8, 1.00_8,1.00_8)
  ! constants made REAL(8) by appending _8
     status = RECTANGLE_W( $GBORDER, -1.02_8, -1.02_8, 1.02_8, 1.02_8)
  !
  !  Plot the points.
  !
     x = -0.90
     DO i = 1, 19
         oldcolor = SETCOLORRGB( #00FF00 ) ! full green
         CALL MOVETO_W( x, -1.0_8, wxy )
         status = LINETO_W( x, 1.0_8 )
         CALL MOVETO_W( -1.0_8, x, wxy )
         status = LINETO_W( 1.0_8, x )
         oldcolor = SETCOLORRGB( #FF0000 ) ! full blue
         CALL MOVETO_W( x - 0.1_8, bananas( i ), wxy )
         status = LINETO_W( x, bananas( i + 1 ) )
         x = x + 0.1
     END DO

     CALL MOVETO_W( 0.9_8, bananas( i ), wxy )
     status = LINETO_W( 1.0_8, bananas( i + 1 ) )
     oldcolor = SETCOLORRGB( #00FFFF ) ! yellow
  END SUBROUTINE

The routine names that end with _W work in the same way as their viewport equivalents, except that you pass double-precision floating-point values instead of integers. For example, you pass INTEGER(2) to LINETO, but REAL(8) values to LINETO_W.

The two other windows are similar to the first. All three call the gridshape function, which draws a grid from location (–1.0, –1.0) to (1.0, 1.0). The grid appears in different sizes because the coordinates in the windows vary. The second window ranges from (–3.0, –3.0) to (3.0, 3.0), and the third from (–3.0, –1.5) to (1.5, 1.5), so the sizes change accordingly.

The third window also contains a .TRUE. inversion argument. This causes the y-axis to increase from bottom to top, instead of top to bottom. As a result, this graph appears upside down with respect to the other two.

After calling gridshape, the program frames each window, using a statement such as the following:

  status = RECTANGLE_W( $GBORDER, -3.0_8, -1.5_8, 1.5_8, 1.5_8)

The first argument is a fill flag indicating whether to fill the rectangle's interior or just to draw its outline. The remaining arguments are the x and y coordinates for the upper-left corner followed by the x and y coordinates for the lower-right corner. RECTANGLE takes integer arguments that refer to the viewport coordinates. RECTANGLE_W takes four double-precision floating-point values referring to window coordinates.

After you create various graphics elements, you can use the font-oriented routines to polish the appearance of titles, headings, comments, or labels. Using Fonts from the Graphics Library describes in more detail how to print text in various fonts with font routines.


Advanced Graphics Using OpenGL

OpenGL is a library of graphic functions that create sophisticated graphic displays such as 3-D images and animation. OpenGL is commonly available on workstations. Writing to this standard allows your program to be ported easily to other platforms.

OpenGL windows are used independently of and in addition to any console, QuickWin and regular Windows windows your application uses. Every window in OpenGL uses a pixel format, and the pixels carry, among other things, RGB values, opacity values, and depth values so that pixels with a small depth (shallow) overwrite deeper pixels. The basic steps in creating OpenGL applications are:

  • Specify the pixel format
  • Specify how the pixels will be rendered on the video device
  • Call OpenGL commands

OpenGL programming is straightforward, but requires a particular initialization and order, like other software tools. References to get you started are:

  • The OpenGL Reference Manual, Addison-Wesley, ISBN 0-201-46140-4.
  • The OpenGL Programming Guide, Addison-Wesley, ISBN 0-201-46138-2.
  • OpenGL SuperBible: The Complete Guide to OpenGL Programming on Windows NT and Windows 95, Richard Wright and Michael Sweet, Waite Group Press (Division of Sams Publishing), 1996, ISBN 1-57169-073-5.
  • OpenGL documentation in the Platform SDK title in HTML Help Viewer.
  • The OpenGL description from the Microsoft Visual C++ manuals.

Visual Fortran provides an OpenGL module, DFOPNGL.MOD, invoked with the USE statement line:

  USE DFOPNGL

When you use this module, all constants and interfaces that bind Fortran to the OpenGL routines become available. Any link libraries required to link with an OpenGL program are automatically searched if USE DFOPNGL is present in your Fortran program.

An OpenGL window can be opened from a console, Windows, or QuickWin application. The OpenGL window uses OpenGL calls exclusively, not normal Graphic Device Interface (GDI) calls. Likewise, OpenGL calls cannot be made within an ordinary Windows window or QuickWin child window, because special initialization is required for OpenGL calls.

The Fortran OpenGL identifiers are the same as the C identifiers (such as using a GL_ prefix for constants), except that the gl prefix is changed to fgl for routines. The data types in the OpenGL C binding are translated to Fortran types as shown in the following table:

OpenGL/C Type | Fortran Data Type
GLbyte | INTEGER(1)
GLshort | INTEGER(2)
GLint, GLsizei | INTEGER(4)
GLfloat, GLclampf | REAL(4)
GLdouble, GLclampd | REAL(8)
GLubyte | INTEGER(1)
GLboolean | LOGICAL
GLushort | INTEGER(2)
GLuint, GLenum, GLbitfield | INTEGER(4)
GLvoid | not needed
pointers | INTEGER

If you include (USE) the parameter constant definitions from DFOPNGLT.F90 (such as by USE DFOPNGL), you can use the constants to specify the kind type, such as INTEGER(K_GLint) instead of INTEGER(4).

Visual Fortran Samples that use OpenGL are available in separate folders in ...\DF98\SAMPLES\ADVANCED\OPENGL. For example, OLYMPIC is a Fortran QuickWin project and CUBE5 is a Fortran Windows project.


Using Fonts from the Graphics Library

The Visual Fortran Graphics Library includes routines that print text in various sizes and type styles. These routines provide control over the appearance of your text and add visual interest to your screen displays.

This section assumes you have read Drawing Graphics Elements and that you understand the general terminology it introduces. You should also be familiar with the basic properties of both the SETWINDOWCONFIG and MOVETO routines. Also, remember that graphics programs containing graphics routines must be built as Fortran QuickWin or Fortran Standard Graphics applications.

The project type is set in the visual development environment when you select New from the File menu, then click on the Projects tab, and select Fortran QuickWin or Fortran Standard Graphics Application from the application types listed. Graphics applications can also be built with the /libs:qwin or /libs:qwins compiler option.

Font types and the use of fonts are described in the following sections:

  • Available Typefaces
  • Using Fonts
  • SHOWFONT.F90 Example


Available Typefaces

A font is a set of text characters of a particular size and style.

A typeface (or type style) refers to the style of the displayed text—Arial, for example, or Times New Roman.

Type size measures the screen area occupied by individual characters. The term comes from the printer's lexicon, but uses screen pixels as the unit of measure rather than the traditional points. For example, "Courier 12 9" denotes the Courier typeface, with each character occupying a screen area of 12 vertical pixels by 9 horizontal pixels. The word "font", therefore implies both a typeface and a type size.

The QuickWin Library's font routines use all Windows operating system installed fonts. The first type of font used is a bitmap (or raster-map) font. Bitmap fonts have each character in a binary data map. Each bit in the map corresponds to a screen pixel. If the bit equals 1, its associated pixel is set to the current screen color. Bit values of 0 appear in the current background color.

The second type of font is called a TrueType font. Some screen fonts look different on a printer, but TrueType fonts print exactly as they appear on the screen. TrueType fonts may be bitmaps or soft fonts (fonts that are downloaded to your printer before printing), depending on the capabilities of your printer. TrueType fonts are scalable and can be sized to any height. It is recommended that you use TrueType fonts in your graphics programs.

Each type of font has advantages and disadvantages. Bitmapped characters appear smoother on the screen because of the predetermined pixel mapping. However, they cannot be scaled. You can scale TrueType text to any size, but the characters sometimes do not look quite as solid as the bitmapped characters on the screen. Usually this screen effect is hardly noticeable, and when printed, TrueType fonts are as smooth or smoother than bitmapped fonts.

The bitmapped typefaces come in preset sizes measured in pixels. The exact size of any font depends on screen resolution and display type.


Using Fonts

QuickWin's font routines can use all the Windows operating system installed fonts. To use fonts in your program, you must:

  1. Initialize the fonts.
  2. Select a current font from the initialized fonts.
  3. Display font text with OUTGTEXT.


Initializing Fonts

A program that uses fonts must first organize the fonts into a list in memory, a process called initializing. The list gives the computer information about the available fonts.

Initialize the fonts by calling the INITIALIZEFONTS routine:

     USE DFLIB
     INTEGER(2) numfonts
     numfonts = INITIALIZEFONTS( )

If the computer successfully initializes one or more fonts, INITIALIZEFONTS returns the number of fonts initialized. If the function fails, it returns a negative error code.


Setting the Font and Displaying Text

Before a program can display text in a particular font, it must know which of the initialized fonts to use. SETFONT makes one of the initialized fonts the current (or "active") font. SETFONT has the following syntax:

SETFONT(options)

The function's argument consists of letter codes that describe the desired font: typeface, character height and width in pixels, fixed or proportional, and attributes such as bold or italic. These options are discussed in detail in the SETFONT entry in the Language Reference. For example:

  USE DFLIB
  INTEGER(2) index, numfonts
  numfonts = INITIALIZEFONTS ( )
  index = SETFONT('t''Cottage''h18w10')

This sets the typeface to Cottage, the character height to 18 pixels and the width to 10 pixels.

The following example sets the typeface to Arial, the character height to 14, with proportional spacing and italics (the pi codes):

  index = SETFONT('t''Arial''h14pi')

If SETFONT successfully sets the font, it returns the font's index number. If the function fails, it returns a negative integer. Call GRSTATUS to find the source of the problem; its return value indicates why the function failed. If you call SETFONT before initializing fonts, a run-time error occurs.

SETFONT updates the font information when it is used to select a font. GETFONTINFO can be used to obtain information about the currently selected font. SETFONT sets the user fields in the fontinfo type (a derived type defined in DFLIB.MOD), and GETFONTINFO returns the user-selected values. The following user fields are contained in fontinfo:

  TYPE fontinfo
    INTEGER(2) type ! 1 = truetype, 0 = bit map
    INTEGER(2) ascent ! Pixel distance from top to baseline
    INTEGER(2) pixwidth ! Character width in pixels, 0=prop
    INTEGER(2) pixheight ! Character height in pixels
    INTEGER(2) avgwidth ! Average character width in pixels
    CHARACTER(32) facename ! Font name
  END TYPE fontinfo

To find the parameters of the current font, call GETFONTINFO. For example:

   USE DFLIB
   TYPE (fontinfo) font
   INTEGER(2) i, numfonts
   numfonts = INITIALIZEFONTS()
   i = SETFONT ( ' t ' 'Arial ' )
   i = GETFONTINFO(font)
   WRITE (*,*) font.avgwidth, font.pixheight, font.pixwidth

After you initialize the fonts and make one the active font, you can display the text on the screen.

To display text on the screen after selecting a font:

  1. Select a starting position for the text with MOVETO.
  2. Optionally, set a text display angle with SETGTEXTROTATION.
  3. Send the text to the screen (in the current font) with OUTGTEXT.

MOVETO moves the current graphics point to the pixel coordinates passed to it when it is invoked. This becomes the starting position of the upper-left corner of the first character in the text. SETGTEXTROTATION can set the text's orientation in increments of one-tenth of a degree.


SHOWFONT.F90 Example

The Visual Fortran Sample program SHOWFONT.F90 in the ...\DF98\SAMPLES\TUTORIAL folder displays text in the fonts available on your system. (Once the screen fills with text, press Enter to display the next screen.) An abbreviated version follows. SHOWFONT calls SETFONT to specify the typeface. MOVETO then establishes the starting point for each text string. The program sends a message of sample text to the screen for each font initialized:

! Abbreviated version of SHOWFONT.F90.
    USE DFLIB

    INTEGER(2) grstat, numfonts,indx, curr_height
    TYPE (xycoord) xyt
    TYPE (fontinfo) f
    CHARACTER(6) str     ! 5 chars for font num
                          ! (max. is 32767), 1 for 'n'

! Initialization.
    numfonts=INITIALIZEFONTS( )
    IF (numfonts.LE.0) PRINT *,"INITIALIZEFONTS error"
    IF (GRSTATUS().NE.$GROK) PRINT *,'INITIALIZEFONTS GRSTATUS error.'
    CALL MOVETO (0,0,xyt)
    grstat=SETCOLORRGB(#FF0000)
    grstat=FLOODFILLRGB(0, 0, #00FF00)
    grstat=SETCOLORRGB(0)
! Get default font height for comparison later.
    grstat = SETFONT('n1')
    grstat = GETFONTINFO(f)
    curr_height = f.pixheight
! Done initializing, start displaying fonts.
    DO indx=1,numfonts
       WRITE(str,10)indx
       grstat=SETFONT(str)
       IF (grstat.LT.1) THEN
          CALL OUTGTEXT('SetFont error.')
       ELSE
          grstat=GETFONTINFO(f)
          grstat=SETFONT('n1')
          CALL OUTGTEXT(f.facename(:len_trim(f.facename)))
          CALL OUTGTEXT(' ')
! Display font.
          grstat=SETFONT(str)
          CALL OUTGTEXT('ABCDEFGabcdefg12345!@#$%')
       END IF
! Go to next line.
       IF (f.pixheight .GT. curr_height) curr_height=f.pixheight
       CALL GETCURRENTPOSITION(xyt)
       CALL MOVETO(0,INT2(xyt.ycoord+curr_height),xyt)
    END DO
10  FORMAT ('n',I5.5)
    END


Using National Language Support Routines

Visual Fortran provides a complete National Language Support (NLS) library of language-localization routines and multibyte-character routines. You can use these routines to write applications in many different languages.

In many languages, the standard ASCII character set is not enough because it lacks common symbols and punctuation (such as the British pound sign), or because the language uses a non-ASCII script (such as Cyrillic for Russian) or because the language consists of too many characters for each to be represented by a single byte (such as Chinese).

In the case of many non-ASCII languages, such as Arabic and Russian, an extended single-byte character set is sufficient. You need only change the language locale and codepage, which can be done at a system level or within your program. However, Eastern languages such as Japanese and Chinese use thousands of separate characters that cannot be encoded as single-byte characters. Multibyte characters are needed to represent them.

Character sets are stored in tables called code sets. There are three components of a code set: the locale, which is a language and country (since, for instance, the language Spanish may vary among countries), the codepage, which is a table of characters to make up the computer's alphabet, and the font used to represent the characters on the screen. These three components can be set independently. Each computer running Windows operating systems comes with many code sets built into the system, such as English, Arabic, and Spanish. Multibyte code sets, such as Chinese and Japanese, are not standard but come with special versions of the operating system (for instance, Windows NT-J comes with the Japanese code set).

The default code set is obtained from the operating system when a program starts up. When you install your operating system, you should install the system supplied code sets. Thereafter, they are always available. You can switch among them by:

  • Open the Control Panel (available from Settings)
  • Click the Regional Settings icon
  • Choose from the dropdown list of available locales (languages and countries).

When you select a new locale, it becomes the default system locale, and will remain the default locale until you change it. Each locale has a default codepage associated with it, and a default currency, number, and date format.

Note: The default codepage does not change when you select a new locale until you reboot your computer.

You can change the currency, number, and date format in the International dialog box or the Regional Setting dialog box independently of the locale.

The locale determines the character set available to the user. The locale you select becomes the default for the NLS routines described in this section, but the NLS routines allow you to change locales and their parameters from within your programs. These routines are useful for creating original foreign-language programs or different versions of the same program for various international markets. Changes you make to the locale from within a program affect only the program. They do not change the system default settings.

The codepage you select, which can be set independently, controls the multibyte (MB routines) character routines described in this section. Only users with special multibyte-character code sets installed on their computers need to use MB routines. The standard code sets all use single-byte character code sets.

Note that in Visual Fortran source code, multibyte characters can be used only in character strings and source comments. They cannot be used within variable names or statements. Like program changes to the locale, program changes to codepages affect only the program, not the system defaults.

The NLS and MB routines are contained in the library DFNLS.LIB, which consists of DFNLS.MOD and DFNLS.F90. To access the routines, the following statement should be present in any program unit that uses NLS or MB routines:

  USE DFNLS

This section includes a discussion of character sets and the NLS library routines:

  • Single and Multibyte Character Sets
  • National Language Support Library Routines


Single and Multibyte Character Sets

The ASCII character set defines the characters from 0 to 127 and an extended set from 128 to 255. Several alternative single-byte character sets, primarily European, define the characters from 0 to 127 identically to ASCII, but define the characters from 128 to 255 differently. With this extension, 8-bit representation is sufficient for defining the needed characters in most European-derived languages. However, some languages, such as Japanese Kanji, include many more characters than can be represented with a single byte. These languages require multibyte coding.

A multibyte character set consists of both one-byte and two-byte characters. A multibyte-character string can contain a mix of single and double-byte characters. A two-byte character has a lead byte and a trail byte. In a particular multibyte character set, the lead and trail byte values can overlap, and it is then necessary to use the byte's context to determine whether it is a lead or trail byte.


National Language Support Library Routines

The library routines for handling extended and multibyte character sets are divided into three categories:

  • Locale Setting and Inquiry Routines to set locales (local code sets) and inquire about their current settings
  • NLS Formatting Routines to format dates, currency, and numbers
  • Multibyte Character Routines for using multi-byte characters

All of these routines are described in detail in the Language Reference, A to Z Reference.

In the descriptions that follow, function and parameter names are given with a mixture of upper- and lowercase letters. This is to make the names easier to understand. You can use any case for these names when writing your applications.


Locale Setting and Inquiry Routines

At program startup, the current language and country setting is retrieved from the operating system. The user can change this setting through the Control Panel Regional Settings icon. The current codepage is also retrieved from the system.

There is a system default console codepage and a system default Windows codepage. Console programs retrieve the system console codepage, while Windows programs (including QuickWin applications) retrieve the system Windows codepage.

The NLS Library provides routines to determine the current locale (local code set), to return parameters of the current locale, to provide a list of all the system supported locales, and to set the locale to another language, country and/or codepage. These routines are summarized in the following table. Note that the locales and codepages set with these routines affect only the program or console that calls the routine. They do not change the system defaults or affect other programs or consoles.

Routines to Set and Inquire about the Locales

Name | Procedure Type | Description
NLSSetLocale | Function | Sets the language, country and codepage
NLSGetLocale | Subroutine | Retrieves the current language, country and codepage
NLSGetLocaleInfo | Function | Retrieves requested information about the current local code set
NLSEnumLocales | Function | Returns all the languages and country combinations supported by the system
NLSEnumCodepages | Function | Returns all the supported codepages on the system
NLSSetEnvironmentCodepage | Function | Changes the codepage for the current console
NLSGetEnvironmentCodepage | Function | Returns the codepage number for the system (Window) codepage or the console codepage

As an example:

     USE DFNLS
     INTEGER(4) strlen, status
     CHARACTER(40) str

     strlen = NLSGetLocaleInfo(NLS$LI_SDAYNAME1, str)
     print *, str    ! prints Monday
     strlen = NLSGetLocaleInfo(NLS$LI_SDAYNAME2, str)
     print *, str    ! prints Tuesday
     strlen = NLSGetLocaleInfo(NLS$LI_SDAYNAME3, str)
     print *, str    ! prints Wednesday
! Change locale to Spanish, Mexico
     status = NLSSetLocale("Spanish", "Mexico")
     strlen = NLSGetLocaleInfo(NLS$LI_SDAYNAME1, str)
     print *, str    ! prints lunes
     strlen = NLSGetLocaleInfo(NLS$LI_SDAYNAME2, str)
     print *, str    ! prints martes
     strlen = NLSGetLocaleInfo(NLS$LI_SDAYNAME3, str)
     print *, str    ! prints miércoles
     END


NLS Formatting Routines

You can set time, date, currency and number formats from the Control Panel, by clicking on the Regional Settings icon. The NLS Library also provides formatting routines for the current locale. These routines are summarized in the following table. These routines return strings in the current codepage, set by default at program start or by NLSSetLocale.

All the formatting routines return the number of bytes in the formatted string (not the number of characters, which can vary if multibyte characters are included). If the output string is longer than the formatted string, the output string is blank padded. If the output string is shorter than the formatted string, an error occurs, NLS$ErrorInsufficientBuffer is returned, and nothing is written to the output string.

Formatting Routines

Name | Procedure Type | Description
NLSFormatCurrency | Function | Formats a number string and returns the correct currency string for the current locale
NLSFormatDate | Function | Returns a correctly formatted string containing the date for the current locale
NLSFormatNumber | Function | Formats a number string and returns the correct number string for the current locale
NLSFormatTime | Function | Returns a correctly formatted string containing the time for the current locale

As an example:

     USE DFNLS
     INTEGER(4) strlen, status
     CHARACTER(40) str
     strlen = NLSFormatTime(str)
     print *, str             ! prints               11:42:24 AM
     strlen = NLSFormatDate(str, flags= NLS$LongDate)
     print *, str             ! prints        Friday, July 14, 2000
     status = NLSSetLocale ("Spanish", "Mexico")
     strlen = NLSFormatTime(str)
     print *, str             ! prints               11:42:24
     print *, str             ! prints viernes 14 de julio de 2000


Multibyte Character Routines

All of the routines in this section are intended for use with Multibyte Character Sets (MBCS). Examples of such characters sets are Japanese, Korean, and Chinese. The routines in this section work from the current codepage, set with NLSSetLocale and read back with NLSGetLocale. String comparison routines, such as MBLLT, are based on the current language and country settings.

Routines discussed in this section are:

  • MBCS Inquiry Routines
  • MBCS Conversion Routines
  • MBCS Fortran Equivalent Routines
  • Standard Fortran Routines That Handle MBCS Characters


MBCS Inquiry Routines

The MBCS inquiry routines provide information on the maximum length of multibyte characters, the length, number and position of multibyte characters in strings, and whether a multibyte character is a leading or trailing byte. These routines are summarized in the following table. The NLS library provides a parameter, MBLenMax, defined in the NLS module to be the longest length (in bytes) of any character, in any codepage. This parameter can be useful in comparisons and tests. To determine the maximum character length of the current codepage, use the MBCurMax function.

MBCS Inquiry Routines

Name | Procedure Type | Description
MBCharLen | Function | Returns the length of the first multibyte character in a string
MBCurMax | Function | Returns the longest possible multibyte character for the current codepage
MBLead | Function | Determines whether a given character is the first byte of a multibyte character
MBLen | Function | Returns the number of multibyte characters in a string, including trailing spaces
MBLen_Trim | Function | Returns the number of multibyte characters in a string, not including trailing spaces
MBNext | Function | Returns the string position of the first byte of the multibyte character immediately after the given string position
MBPrev | Function | Returns the string position of the first byte of the multibyte character immediately before the given string position
MBStrLead | Function | Performs a context sensitive test to determine whether a given byte in a character string is a lead byte

As an example:

    USE DFNLS
    CHARACTER(4) str
    INTEGER status
    status = NLSSetLocale ("Japan")
    str = " ·, " ¿"
    PRINT '(1X,''String by char = '',\)'
    DO i = 1, len(str)
       PRINT '(A2,\)',str(i:i)
    END DO
    PRINT '(/,1X,''MBLead = '',\)'
    DO i = 1, len(str)
       PRINT '(L2,\)',mblead(str(i:i))
    END DO
    PRINT '(/,1X,''String as whole = '',A,\)',str
    PRINT '(/,1X,''MBStrLead = '',\)'
    DO i = 1, len(str)
       PRINT '(L1,\)',MBStrLead(str,i)
    END DO
    END

This code produces the following output for str = · , " ¿


MBCS Conversion Routines

There are four MBCS conversion routines:

  • Two convert Japan Industry Standard characters to Microsoft Kanji characters or vice versa.
  • Two convert between a codepage multibyte character string and a Unicode string.

These routines are summarized in the following table.

MBCS Conversion Routines

Name | Procedure Type | Description
MBConvertMBToUnicode | Function | Converts a character string from a multibyte codepage to a Unicode string
MBConvertUnicodeToMB | Function | Converts a Unicode string to a multibyte character string of the current codepage
MBJISToJMS | Function | Converts a Japan Industry Standard (JIS) character to a Microsoft Kanji (Shift JIS or JMS) character
MBJMSToJIS | Function | Converts a Microsoft Kanji (Shift JIS or JMS) character to a Japan Industry Standard (JIS) character


MBCS Fortran Equivalent Routines

The NLS Library provides several functions that are the exact equivalents of Fortran 90 functions except that the MBCS equivalents allow character strings to contain multibyte characters. These routines are summarized in the following table.

MBCS Fortran Equivalent Routines

Name | Procedure Type | Description
MBINCHARQQ | Function | Same as INCHARQQ but can read a single multibyte character at once and returns the number of bytes read
MBINDEX | Function | Same as INDEX except that multibyte characters can be included in its arguments
MBLGE, MBLGT, MBLLE, MBLLT, MBLEQ, MBLNE | Functions | Same as LGE, LGT, LLE, LLT and the operators .EQ. and .NE. except that multibyte characters can be included in their arguments
MBSCAN | Function | Same as SCAN except that multibyte characters can be included in its arguments
MBVERIFY | Function | Same as VERIFY except that multibyte characters can be included in its arguments

The following example is included in Visual Fortran Samples in the ...\DF98\SAMPLES\TUTORIAL folder as MBCOMP.FOR:

    USE DFNLS

    INTEGER(4) i, len(7), infotype(7)
    CHARACTER(10) str(7)
    LOGICAL(4) log4

    data infotype / NLS$LI_SDAYNAME1, NLS$LI_SDAYNAME2, &
   & NLS$LI_SDAYNAME3, NLS$LI_SDAYNAME4, &
   & NLS$LI_SDAYNAME5, NLS$LI_SDAYNAME6, &
   & NLS$LI_SDAYNAME7 /
    WRITE(*,*) 'NLSGetLocaleInfo'
    WRITE(*,*) '----------------'
    WRITE(*,*) ' '
    WRITE(*,*) 'Getting the names of the days of the week...'

    DO i = 1, 7
       len(i) = NLSGetLocaleInfo(infotype(i), str(i))
       WRITE(*, 11) 'len/str/hex = ', len(i), str(i), str(i)
    END DO
 11 FORMAT (1X, A, I2, 2X, A10, 2X, '[', Z20, ']')

    WRITE(*,*) ' '
    WRITE(*,*) 'Lexically comparing the names of the days...'

    DO i = 1, 6
       log4 = MBLGE(str(i), str(i+1), NLS$IgnoreCase)
       WRITE(*, 12) 'Is day ', i, ' GT day ', i+1, '? Answer = ', log4
    END DO
 12 FORMAT (1X, A, I1, A, I1, A, L1)

    WRITE(*,*) ' '
    WRITE(*,*) 'Done.'
    END

This code produces the following output when the locale is Japan:


Standard Fortran Routines That Handle MBCS Characters

This section describes Fortran routines that work as usual even if MBCS characters are included in strings.

Because a space can never be a lead or tail byte, many routines that deal with spaces work as expected on strings containing MBCS characters. Such functions include:

  • ADJUSTL( string )
  • ADJUSTR( string )
  • TRIM( string )

Some routines work with the computer collating sequence to return a character in a certain position in the sequence or the position in the sequence of a certain character. These functions are not dependent on a particular collating sequence. (You should note, however, that elsewhere in this manual the ASCII collating sequence is mentioned in reference to these functions.) Such functions use position and c values between 0 and 255 (inclusive) and include:

  • ACHAR( position )
  • CHAR( position [, kind ])
  • IACHAR( c )
  • ICHAR( c )

Because Fortran uses character lengths instead of NULLs to indicate the length of a string, some functions work solely from the length of the string, and not with the contents of the string. This function works as usual on strings containing MBCS characters, and include:

REPEAT ( string, ncopies )


Portability Library

Visual Fortran includes functions and subroutines that ease porting of code from a different platform to a PC, or allow you to write code on a PC that is compatible with other platforms. Frequently used functions are included in a module called DFPORT.

This chapter describes how to use the portability module, and describes routines available in the following categories:

  • Using the Portability Library
  • Routines for Information Retrieval
  • Device and Directory Information Routines
  • Process Control Routines
  • Numeric Routines
  • Input and Output With Portability Routines
  • Date and Time Routines
  • Error Handling Routines
  • Miscellaneous String and Sorting Routines
  • Other Compatibility Routines

When writing new code, use Fortran 95/90 contains intrinsic procedures whenever possible (for portability and performance reasons). Fortran 95/90 contains intrinsic procedures for many of the portability functions. The portability routines are extensions to the Fortran 95 standard.


Using the Portability Library

You can use the portability library (DFPORT) in one of two ways:

  • Add the statement USE DFPORT to your program. This USE statement includes the DFPORT module.
  • Call portability routines using the correct parameters and return value.

The portability library DFPORT.LIB library is passed to the linker by default during linking. To prevent DFPORT.LIB library from being passed to the linker, specify the /fpscomp:nolibs option.

Using the DFPORT module provides interface blocks and parameter definitions for the routines, as well as compiler verification of calls.

Some routines in this library can be called with different sets of arguments, and sometimes even as a function instead of a subroutine. In these cases, the arguments and calling mechanism determine the meaning of the routine. The DFPORT module contains generic interface blocks that give procedure definitions for these routines.


Routines for Information Retrieval

Routines classified as information retrieval routines return information about system commands, command-line arguments, environment variables, and process or user information.

All portability routines that take path names also accept long file names or UNC (Universal Naming Convention) file names. A forward slash in a path name is treated as a backslash. All path names can contain drive specifications as well as MBCS (multiple-byte character set) characters. For information on MBCS characters, see Using National Language Support Routines.

Portability Routine | Description
IARGC | Returns the index of the last command-line argument
GETENV | Searches the environment for a given string, and returns its value if found
GETGID | Returns the group ID of the user
GETLOG | Get user's login name
GETPID | Returns the process ID of the process
GETUID | Returns the user ID of the user of the process
HOSTNAM | Returns the name of the user's host

Group, user, and process ID are INTEGER(4) variables. Login name and host name are character variables. The functions GETGID and GETUID are provided for portability, but always return 1.

IARGC is best used with GETARG. GETARG, which returns command line arguments, is available in the standard Visual Fortran library; you do not have to specify USE DFPORT in your program unit.

For more information:

  • See Device and Directory Information.


Device and Directory Information Routines

You can retrieve information about devices, directories, and files with the functions listed below. File names can be long file names or UNC file names. A forward slash in a path name is treated as a backslash. All path names can contain drive specifications.

Portability Routine | Description
CHDIR | Changes the current working directory
FSTAT | Returns information about a logical file unit
GETCWD | Returns the current working directory path name
RENAME | Renames a file
STAT, LSTAT | Returns information about a named file
UNLINK | Removes a directory entry from the path

Standard Fortran 90 provides the INQUIRE statement, which returns detailed file information either by file name or unit number. Use INQUIRE as an equivalent to FSTAT, LSTAT or STAT. LSTAT and STAT return the same information; STAT is the preferred function.


Process Control Routines

Process control routines control the operation of a process or subprocess. You can wait for a subprocess to complete with either SLEEP or ALARM, monitor its progress and send signals via KILL, and stop its execution with ABORT.

In spite of its name, KILL does not necessarily stop execution of a program. Rather, the routine signaled could include a handler routine that examines the signal and takes appropriate action depending on the code passed.

Portability Routine | Description
ABORT | Stops execution of the current process, clears I/O buffers, and writes a string to external unit 0
ALARM | Executes an external subroutine after waiting a specified number of seconds
KILL | Sends a signal code to a process ID
SIGNAL | Changes the action for a signal
SLEEP | Suspends program execution for a specified number of seconds
SYSTEM | Executes a command in a separate shell

Note that when you use SYSTEM, commands are run in a separate shell. Defaults set with the SYSTEM function, such as current working directory or environment variables, do not affect the environment the calling program runs in.

The portability library does not include the FORK routine. On U*X systems, FORK creates a duplicate image of the parent process. Child and parent processes each have their own copies of resources, and become independent from one another. With Windows operating systems, you can create a child process (called a thread), but both parent and child processes share the same address space and share system resources. If you need to create another process, use the CreateProcess Win32 API routine.

For information on how to implement threading, see Creating Multithread Applications.


Numeric Routines

Numeric routines are available for calculating Bessel functions, data type conversion, and generating random numbers:

Portability Routine | Description
BESJ0, BESJ1, BESJN, BESY0, BESY1, BESYN | Computes the single precision values of Bessel functions of the first and second kind of orders 1, 2, and n, respectively
DBESJ0, DBESJ1, DBESJN, DBESY0, DBESY1, DBESYN | Computes the double-precision values of Bessel functions of the first and second kind of orders 1, 2, and n, respectively
LONG | Converts an INTEGER(2) variable to an INTEGER(4) type
SHORT | Converts an INTEGER(4) variable to an INTEGER(2) type
IRAND, IRANDM | Returns a positive integer in the range 0 through (2**31)-1, or (2**15)-1 if called without an argument
RAN | Returns random values in the range 0 through 1.0
RAND, DRAND | Returns random values in the range 0 through 1.0
DRANDM, RANDOM | Returns random values in the range 0 through 1.0
SRAND | Seeds the random number generator used with IRAND and RAND.
BIC, BIS, BIT | Perform bit level clear, set, and test for integers

Some of these functions have equivalents in standard Fortran 95/90. Data object conversion can be accomplished by using the INT intrinsic function instead of LONG or SHORT. The intrinsic subroutines RANDOM_NUMBER and RANDOM_SEED perform the same functions as the random number functions listed in the previous table.

Other bit manipulation functions such as AND, XOR, OR, LSHIFT, and RSHIFT are intrinsic functions. You do not need the DFPORT module to access them. Standard Fortran 95/90 includes many bit operation procedures; these are listed in the Bit Operation Procedures table in the Language Reference.


Input and Output With Portability Routines

The portability library contains routines that change file properties, read and write characters and buffers, and change the offset position in a file. These input and output routines can be used with standard Fortran input or output statements such as READ or WRITE on the same files, provided that you take into account the following:

  • When used with direct files, after an FSEEK, GETC, or PUTC operation, the record number is the number of the next whole record. Any subsequent normal Fortran I/O to that unit occurs at the next whole record. For example, if you seek to absolute location 1 of a file whose record length is 10, the NEXTREC returned by an inquire would be 2. If you seek to absolute location 10, NEXTREC would still return 2.
  • On units with CARRIAGECONTROL='FORTRAN' (the default), PUTC and FPUTC characters are treated as carriage control characters if they appear in column 1.
  • On sequentially formatted units, the C string "\n"c, which represents the carriage return/line feed escape sequence, is written as CHAR(13) (carriage return) and CHAR(10) (line feed), instead of just line feed, or CHAR(10). On input, the sequence 13 followed by 10 is returned as just 10. (The length of character string "\n"c is 1 character, whose ASCII value, indicated by ICHAR('\n'c), is 10.)
  • Reading and writing is in a raw form for direct files. Separators between records can be read and overwritten. Therefore, be careful if you continue using the file as a direct file.

I/O errors arising from the use of these routines result in a Visual Fortran run-time error.

Portability Routine | Description
ACCESS | Checks a file for accessibility according to mode
CHMOD | Changes file attributes
FGETC | Reads a character from an external unit
FLUSH | Flushes the buffer for an external unit to its associated file
FPUTC | Writes a character to an external unit
FSEEK | Repositions a file on an external unit
FTELL | Returns the offset, in bytes, from the beginning of the file
GETC | Reads a character from unit 5
PUTC | Writes a character to unit 6

All path names can include drive specifications, forward slashes, or backslashes.

Some portability file I/O routines have equivalents in standard Fortran 95/90. For example, you could use the ACCESS function to check a file specified by name for accessibility according to mode. It tests a file for read, write, or execute permission, as well as checking to see if the file exists. It works on the file attributes as they exist on disk, not as a program's OPEN statement specifies them.

Instead of ACCESS, you can use the INQUIRE statement with the ACTION parameter to check for similar information. (The ACCESS function always returns 0 for read permission on FAT files, meaning that all files have read permission.)


Date and Time Routines

Various date and time routines are available to determine system time, or convert it to local time, Greenwich Mean Time, arrays of date and time elements, or an ASCII character string.

The sample output column of the following table assumes the current date to be 2/24/97 7:11 pm Pacific Daylight Time. The third column shows what each routine returns, either when reporting the current time or when that date and time is passed to it in an appropriate argument. Full details of parameters and output are given in the description of each routine (A to Z Reference) in the Language Reference.

Portability Routine | Description | Sample output
CLOCK | Current time in "hh:mm:ss" format using a 24-hour clock | 19:11:00
CTIME | Converts a system time to a 24-character ASCII string | "Wed Feb 24 19:11:00 1999"
DATE | A string representation of the current date | As a subroutine: "24-Feb-99" As a function: "02/24/99"
DTIME | Elapsed CPU time since later of (1) start of program, or (2) most recent call to DTIME | (/0.0, 0.0/) (Actual results depend on the program and the system)
ETIME | Elapsed CPU time since the start of program execution | (/0.0, 0.0/) (Actual results depend on the program and the system)
FDATE | The current date and time as an ASCII string | "Wed Feb 24 19:11:00 1999"
GMTIME | Greenwich Mean Time as a 9-element integer array | (/0,12,03,24,2,97,3,55,0/)
IDATE | Current date either as one 3-element array or three scalar parameters (month, day, year) | (1) (/24,2,1999/) (2) month=2, day=24, year=99
ITIME | Current time as a 3-element array (hour, minute, second) | (/7,11,00/)
JDATE | Current date as an 8-character string with the Julian date | "99055 "
LTIME | Local time as a 9-element integer array | (/0,11,7,24,2,99,3,55,0/)
RTC | Number of seconds since 00:00:00 GMT, Jan 1, 1970 | 762145860
SECNDS | The number of seconds since midnight, less the value of its argument | 0.00
TIME | As a subroutine, returns the time formatted as hh:mm:ss As a function, returns the time in seconds since midnight GMT Jan 1, 1970 | Subroutine: "07:11:00" Function: 762145860
TIMEF | The number of seconds since the first time this function was called (or zero) | 0.0

TIME and DATE are available as either a function or subroutine. Because of the name duplication, if your programs do not include the USE DFPORT statement, each separately compiled program unit can use only one of these versions. For example, if a program calls the subroutine TIME once, it cannot also use TIME as a function.

Standard Fortran 95/90 includes date and time intrinsic subroutines. For more information, see DATE_AND_TIME in the Language Reference.


Error Handling Routines

The following routines are available for detecting and reporting errors:

Portability Routine | Description
IERRNO | Returns the last error code
GERROR | Returns the IERRNO error code as a string variable
PERROR | Sends an error message, preceded by a string, for the last error detected

IERRNO error codes are analogous to errno on U*X systems. The DFPORT module provides parameter definitions for many of U*X's errno names, found typically in errno.h on U*X systems.

IERRNO is updated only when an error occurs. For example, if a call to the GETC function results in an error, but two subsequent calls to PUTC succeed, a call to IERRNO returns the error for the GETC call. Examine IERRNO immediately after returning from one of the portability library routines. Other standard Fortran 90 routines might also change the value to an undefined value.

If your application uses multithreading, remember that IERRNO is set on a per-thread basis.


Miscellaneous Routines

Miscellaneous String and Sorting Routines

The following routines perform miscellaneous string and sorting operations:

Portability Routine | Description
LNBLNK | Returns the index of the last non-blank character in a string.
QSORT | Sorts a one-dimensional array of a specified number of elements of a named size.
RINDEX | Returns the index of the last occurrence of a substring in a string.

For information on equivalent standard Fortran 95/90 character procedures, see Character Procedures in the Language Reference.


Other Compatibility Routines

If you need to call a routine not listed in the portability library, you may find it in the standard Visual Fortran library. Routines implemented as intrinsic or in the DFLIB module are:

Procedure | Description
AND | Bitwise AND
OR | Bitwise OR
XOR | Bitwise XOR
FREE | Frees dynamic memory
GETARG | Returns command line arguments
MALLOC | Allocates dynamic memory
LSHIFT | Left bitwise shift
RSHIFT | Right bitwise shift
EXIT | Exits program with a return code

Visual Fortran does not support certain other functions, such as:

Routine | Description | Similar Visual Fortran Functionality
CMVGM, CMVGN, CMVGP, CMVGT, CMVGZ | Conditional merge | MERGE intrinsic function
FORK | Creates an identical process | CreateProcess, System
LINK | Creates a hard link between two files | none
SYMLNK | Creates a symbolic link between two files | none
Note: CreateProcess is a Win32 API routine described in Creating Multithread Applications.

Replace conditional merge routines with the standard Fortran 95/90 intrinsic MERGE routine, using the following arguments:

Routine | Fortran 95/90 Replacement
CVMGP(tsrc, fsrc, mask) | MERGE(tsrc, fsrc, mask >= 0)
CVMGM(tsrc, fsrc, mask) | MERGE(tsrc, fsrc, mask < 0)
CVMGZ(tsrc, fsrc, mask) | MERGE(tsrc, fsrc, mask = 0)
CVMGN(tsrc, fsrc, mask) | MERGE(tsrc, fsrc, mask /= 0)
CVMGT(tsrc, fsrc, mask) | MERGE(tsrc, fsrc, mask = .TRUE.)

There is no analogy to U*X file system links or soft links under Windows.

There is also no analogy to the U*X FORK routine, since FORK creates a duplicate image of the parent process which is independent from the parent process. With Windows operating systems, both parent and child processes share the same address space and share system resources. For more information on creating child processes, see Creating Multithread Applications.


Files, Devices, and I/O Hardware

This chapter discusses Visual Fortran files and devices, and using your input/output (I/O) hardware. Together with the sections on I/O statements and I/O editing, these sections explain where and how Fortran data is input and output.

Files and devices are where data is stored and retrieved, I/O editing determines how the data is organized when it is read or written, and I/O statements determine what input/output operations are performed on the data.

The following topics are discussed:

  • Devices and Files
  • I/O Hardware
  • Using the Console
  • Using the Serial I/O Port Routines


Devices and Files

In Fortran's I/O system, data is stored and transferred among files. All I/O data sources and destinations are considered files. Devices such as the screen, keyboard and printer are external files, as are data files stored on a device such as a disk.

Variables in memory can also act as a file on a disk, and are typically used to convert ASCII representations of numbers to binary form. When variables are used in this way, they are called internal files.

The discussion of I/O files is divided into two sections:

  • Logical Devices, which describes logical unit specifiers, external files, and internal files.
  • Files, which describes the types of files, file access, record types, and Microsoft Fortran PowerStation compatible files.


Logical Devices

Every file, internal or external, is associated with a logical device. You identify the logical device associated with a file by a unit specifier (UNIT=). The unit specifier for an internal file is the name of the character variable associated with it. The unit specifier for an external file is either a number you assign with the OPEN statement, a number preconnected as a unit specifier to a device, or an asterisk (*).

External unit specifiers that are preconnected to certain devices do not have to be opened. External units that you connect are disconnected when program execution terminates or when the unit is closed by a CLOSE statement.

A unit must not be connected to more than one file at a time, and a file must not be connected to more than one unit at a time. You can OPEN an already opened file but only to change some of the I/O options for the connection, not to connect an already opened file or unit to a different unit or file.

You must use a unit specifier for all I/O statements, except in the following three cases:

  • ACCEPT, which always reads from standard input, unless the FOR_ACCEPT environment variable is defined.
  • INQUIRE by file, which specifies the filename, rather than the unit with which the file is associated
  • PRINT, which always writes to standard output, unless the FOR_PRINT environment variable is defined.
  • READ statements that contain only an I/O list and format specifier, which read from standard input (UNIT=5), unless the FOR_READ environment variable is defined.
  • WRITE statements that contain only an I/O list and format specifier, which write to standard output, unless the FOR_PRINT environment variable is defined.
  • TYPE, which always writes to standard output, unless the FOR_TYPE environment variable is defined.

External Files

A unit specifier associated with an external file must be either an integer expression or an asterisk (*). The integer expression must be in the range 0 (zero) to a maximum value of 2,147,483,640. The following example connects the external file UNDAMP.DAT to unit 10 and writes to it:

   OPEN (UNIT = 10, FILE = 'undamp.dat')
   WRITE (10, '(A18,\)') ' Undamped Motion:'

The asterisk (*) unit specifier specifies the keyboard when reading and the screen when writing. The following example uses the asterisk specifier to write to the screen:

   WRITE (*, '(1X, A30,\)') ' Write this to the screen.'

Visual Fortran has four units preconnected to external files (devices), as shown in the following table.

External Unit Specifier | Description
Asterisk (*) | Always represents the keyboard and screen (unless the appropriate environment variable is defined, such as FOR_READ).
0 | Initially represents the screen (unless FORT0 is defined)
5 | Initially represents the keyboard (unless FORT5 is defined)
6 | Initially represents the screen (unless FORT6 is defined)

The asterisk (*) specifier is the only unit specifier that cannot be reconnected to another file, and attempting to close this unit causes a compile-time error. Units 0, 5, and 6, however, can be connected to any file with the OPEN statement. If you close unit 0, 5, or 6, it is automatically reconnected to its respective device the next time an I/O statement attempts to use that unit.

When you omit the file name in the OPEN statement or use an implicit OPEN, you can define the environment variable FORTn to specify the file name for a particular unit number (n) (except when the compiler option /fpscomp:filesfromcmd is not specified). For example, if you want unit 6 to write to a file instead of standard output, set the environment variable FORT6 to the path and filename to be used before you run the program.

The following example writes to the preconnected unit 6 (the screen), then reconnects unit 6 to an external file and writes to it, and finally reconnects unit 6 to the screen and writes to it:

      REAL a, b
!  Write to the screen (preconnected unit 6).
     WRITE(6, '('' This is unit 6'')')
!  Use the OPEN statement to connect unit 6
!  to an external file named 'COSINES'.
     OPEN (UNIT = 6, FILE = 'COSINES', STATUS = 'NEW')
     DO a = 0.1, 6.3, 0.1
          b = COS (a)
!  Write to the file 'COSINES'.
           WRITE (6, 100) a, b
100        FORMAT (F3.1, F5.2)
     END DO
!  Close it.
     CLOSE (6)
!  Reconnect unit 6 to the screen, by writing to it.
     WRITE(6,' ('' Cosines completed'')')
     END

Internal Files

The unit specifier associated with an internal file is a character string or character array. There are two types of internal files:

  • An internal file that is a character variable, character array element, or noncharacter array element that has exactly one record, which is the same length as the variable, array element, or noncharacter array element.
  • An internal file that is a character array, a character derived type, or a noncharacter array that is a sequence of elements, each of which is a record. The order of records is the same as the order of array elements or type elements, and the record length is the length of one array element or the length of the derived-type element.

Follow these rules when using internal files:

  • Use only formatted I/O, including I/O formatted with a format specification and list-directed I/O. (List-directed I/O is treated as sequential formatted I/O.) Namelist formatting is not allowed.
  • If the character variable is an allocatable array or array part of an allocatable array, the array must be allocated before use as an internal file. If the character variable is a pointer, it must be associated with a target.
  • Use only READ and WRITE statements. You cannot use file connection (OPEN, CLOSE), file positioning (REWIND, BACKSPACE) or file inquiry (INQUIRE) statements with internal files.

You can read and write internal files with FORMAT I/O statements or list-directed I/O statements exactly as you can external files. Before an I/O statement is executed, internal files are positioned at the beginning, before the first record.

With internal files, you can use the formatting capabilities of the I/O system to convert values between external character representations and Fortran internal memory representations. That is, reading from an internal file converts the ASCII representations into numeric, logical, or character representations, and writing to an internal file converts these representations into their ASCII representations.

This feature makes it possible to read a string of characters without knowing its exact format, examine the string, and interpret its contents. It also makes it possible, as in dialog boxes, for the user to enter a string and for your application to interpret it as a number.

If less than an entire record is written to an internal file, the rest of the record is filled with blanks.

In the following example, str and fname specify internal files:

    CHARACTER(10) str
    INTEGER n1, n2, n3
    CHARACTER(14) fname
    INTEGER   i

    str = " 1   2   3"
! List-directed READ sets n1 = 1, n2 = 2, n3 = 3.
    READ(str, *) n1, n2, n3
    i = 4
! Formatted WRITE sets fname = 'FM004.DAT'.
    WRITE (fname, 200) i
200 FORMAT ('FM', I3.3, '.DAT')


Files

File organization refers to the way records are physically arranged on a storage device.

Record type refers to whether records in a file are all the same length, are of varying length, or use other conventions to define where one record ends and another begins.

Record access refers to the method used to read records from or write records to a file, regardless of its organization. The way a file is organized does not necessarily imply the way in which the records within that file will be accessed.

Fortran supports two kinds of file organizations: sequential and relative. The organization of a file is specified by means of the ORGANIZATION keyword in the OPEN statement. Relative files must be stored on disk. However, sequential files can be stored on either magnetic tape or disk. Other peripheral devices, such as terminals, pipes, card readers, and line printers, are treated as sequential files.

A sequentially organized file consists of records arranged in the sequence in which they are written to the file (the first record written is the first record in the file, the second record written is the second record in the file, and so on). As a result, records can be added only at the end of the file. Attempting to add records at someplace other than the end of the file will result in the file begin truncated at the end of the record just written.

Within a relative file are numbered positions, called cells. These cells are of fixed equal length and are consecutively numbered from 1 to n, where 1 is the first cell, and n is the last available cell in the file. Each cell either contains a single record or is empty. Records in a relative file are accessed according to cell number. A cell number is a record's relative record number; its location relative to the beginning of the file. By specifying relative record numbers, you can directly retrieve, add, or delete records regardless of their locations. (Detecting deleted records is only available if you specified the /vms option when the program was compiled. For information, see the /vms option.)

Fortran supports two methods of file access (sequential and direct) and three kinds of file structure (formatted, unformatted, and binary). Sequential-access and direct-access files can have any of the three file structures. The following kinds of files are possible:

  • Formatted Sequential
  • Formatted Direct
  • Unformatted Sequential
  • Unformatted Direct
  • Binary Sequential
  • Binary Direct

Each kind of file has advantages and the best choice depends on the application you are developing:

  • Formatted Files

    You create a formatted file by opening it with the FORM='FORMATTED' option, or by omitting the FORM parameter when creating a sequential file. The records of a formatted file are stored as ASCII characters; numbers that would otherwise be stored in binary form are converted to ASCII format. Each record ends with the ASCII carriage return (CR) and line feed (LF) characters.

    If you need to view a data file's contents, use a formatted file. You can load a formatted file into a text editor and read its contents directly, that is, the numbers would look like numbers and the strings like character strings, whereas an unformatted or binary file looks like a set of hexadecimal characters.

  • Unformatted Files

    You create an unformatted file by opening it with the FORM='UNFORMATTED' option, or by omitting the FORM parameter when creating a direct-access file. An unformatted file is a series of records composed of physical blocks. Each record contains a sequence of values stored in a representation that is close to that used in program memory. Little conversion is required during input/output.

    The lack of formatting makes these files quicker to access and more compact than files that store the same information in a formatted form. However, if the files contain numbers, you will not be able to read them with a text editor.

  • Binary Files

    You create a binary file by specifying FORM='BINARY'. Binary files are the most compact, and good for storing large amounts of data.

  • Sequential-Access Files

    Data in sequential files must be accessed in order, one record after the other (unless you change your position in the file with the REWIND or BACKSPACE statements). Some methods of I/O are possible only with sequential files, including nonadvancing I/O, list-directed I/O, and namelist I/O. Internal files also must be sequential files. You must use sequential access for files associated with sequential devices.

    A sequential device is a physical storage device that does not allow explicit motion (other than reading or writing). The keyboard, screen, and printer are all sequential devices.

  • Direct-Access Files

    Data in direct-access files can be read or written to in any order. Records are numbered sequentially, starting with record number 1. All records have the length specified by the RECL option in the OPEN statement. Data in direct files is accessed by specifying the record you want within the file. If you need random access I/O, use direct-access files. A common example of a random-access application is a database.

All files are composed of records. Each record is one entry in the file. It can be a line from a terminal or a logical record on a magnetic tape or disk file. All records within one file are of the same type.

In Fortran, the number of bytes written to a record must be less than or equal to the record length. One record is written for each unformatted READ or WRITE statement. A formatted READ or WRITE statement can transfer more than one record using the slash (/) edit descriptor.

For binary files, a single READ or WRITE statement reads or writes as many records as needed to accommodate the number of bytes being transferred. On output, incomplete formatted records are padded with spaces. Incomplete unformatted and binary records are padded with undefined bytes (zeros).

The remainder of this section contains information about:

  • Record Types
  • Microsoft Fortran PowerStation Compatible Files (when /fpscomp was specified during compilation)


Record Types

An I/O record is a collection of data items, called fields, that are logically related and are processed as a unit. The record type refers to the convention for storing fields in records.

The record type of the data within a file is not maintained as an attribute of the file. The results of using a record type other than the one used to create the file are indeterminate.

If you omit /fpscomp:ioformat during compilation, the following six record types are available:

Record Type | Available File Organizations and Portability Considerations
Fixed-length | Relative or sequential file organizations.
Variable-length | Sequential file organization only. The variable-length record type is generally the most portable record type across multi-vendor platforms.
Segmented | Sequential file organization only and only for unformatted sequential access. The segmented record type is unique to Compaq Fortran and should not be used for portability with programs written in languages other than Fortran or for places where Compaq Fortran is not used. However, because the segmented record type is unique to Compaq Fortran products, formatted data in segmented files can be ported across Compaq Fortran platforms.
Stream (uses no record delimiter) | Sequential file organization only.
Stream_CR (uses CR as record delimiter) | Sequential file organization only.
Stream_LF (uses CR and LF as record delimiter) | Sequential file organization only.

Fixed-Length Records

When you specify fixed-length records, you are specifying that all records in the file contain the same number of bytes. When you open a file that is to contain fixed-length records, you must specify the record size using the RECL keyword. A sequentially organized opened file for direct access must contain fixed-length records, to allow the record position in the file to be computed correctly.

For relative files, the layout and overhead of fixed-length records depends upon whether the program accessing the file was compiled using the /vms option or whether the /vms option was omitted:

  • For relative files where the /vms option was omitted (the default), each record has no control information.
  • For relative files where the /vms option was specified, each record has one byte of control information at the beginning of the record.

The following figure shows the record layout of fixed-length records.

Variable-Length Records

Variable-length records can contain any number of bytes, up to a specified maximum record length, and only apply to sequential files. These records are generally prefixed and suffixed by four bytes of control information containing count fields. The 4-byte integer value stored in each count field indicates the number of data bytes (excluding overhead bytes) in that particular variable-length record.

The record layout of variable-length records appears below.

The count field of a variable-length record is available when you read the record by issuing a READ statement with a Q format descriptor. You can then use the count field information to determine how many bytes should be in the associated I/O list.

Files written with variable-length records by Compaq Fortran programs usually cannot be accessed as text files. Instead, use the Stream_LF record format for text files with records of varying length.

Segmented Records

A segmented record is a single logical record consisting of one or more variable-length, unformatted records in a sequentially organized disk file. Unformatted data written to sequentially organized files using sequential access is stored as segmented records by default.

Segmented records are useful when you want to write exceptionally long records but cannot or do not wish to define one long variable-length record, perhaps because virtual memory limitations can prevent program execution. By using smaller, segmented records, you reduce the chance of problems caused by virtual memory limitations on systems on which the program may execute.

For disk files, the segmented record is a single logical record that consists of one or more segments. Each segment is a physical record. A segmented (logical) record can exceed the absolute maximum record length (2.14 billion bytes), but each segment (physical record) individually cannot exceed the maximum record length.

To access an unformatted sequential file that contains segmented records, specify FORM='UNFORMATTED' and RECORDTYPE='SEGMENTED' when you open the file. Otherwise, the file may be processed erroneously.

As shown below, the layout of segmented records consists of 4 bytes of control information followed by the user data.

The control information consists of a 2-byte integer record length count (includes the 2 bytes used by the segment identifier), followed by a 2-byte integer segment identifier that identifies this segment as one of the following:

  • The first segment (equals 1)
  • The last segment (equals 2)
  • The only segment (equals 3)
  • One of the segments between the first and last segments (equals 0)

If the specified record length is an odd number, the user data will be padded with a single blank (1 byte), but this extra byte is not added to the 2-byte integer record length count.

Stream File Data

A stream file is not grouped into records and contains no control information. Stream files are used with CARRIAGECONTROL='NONE' and contain character or binary data that is read or written only to the extent of the variables specified on the input or output statement.

The layout of a stream file appears below.

Stream_CR Records

A stream_CR record is a variable-length record whose length is indicated by explicit record terminators embedded in the data, not by a count. These terminators are automatically added when you write records to a stream-type file, and they are removed when you read records. Stream_CR files use only a carriage-return as the terminator, so Stream_CR files must not contain embedded carriage-return characters.

The layout of stream_CR records appears below.

Stream_LF Records

A stream_LF record is a variable-length record whose length is indicated by explicit record terminators embedded in the data, not by a count. These terminators are automatically added when you write records to a stream-type file, and they are removed when you read records. Stream_LF files use a carriage return followed by line-feed (new line) as the terminator, so Stream_LF files must not contain embedded line-feed (new line) characters. This is the usual operating system text file record type.

The layout of stream_LF records appears below.


Microsoft Fortran PowerStation Compatible Files

When using the /fpscomp options for Microsoft Fortran PowerStation compatibility, the following types of files are possible:

  • Formatted Sequential Files

    A formatted sequential file is a series of formatted records written sequentially and read in the order in which they appear in the file. Records can vary in length and can be empty. They are separated by carriage return (0D) and line feed (0A) characters as shown in the following figure.

    Formatted Records in a Formatted Sequential File

    An example of a program writing three records to a formatted sequential file is given below. The resulting file is shown in the following figure.

       OPEN (3, FILE='FSEQ')
! FSEQ is a formatted sequential file by default.
   WRITE (3, '(A, I3)') 'RECORD', 1
   WRITE (3, '()')
   WRITE (3, '(A11)') 'The 3rd One'
   CLOSE (3)
   END

    Formatted Sequential File

  • Formatted Direct Files

    In a formatted direct file, all of the records are the same length and can be written or read in any order. The record size is specified with the RECL option in an OPEN statement and should be equal to or greater than the number of bytes in the longest record.

    The carriage return (CR) and line feed (LF) characters are record separators and are not included in the RECL value. Once a direct-access record has been written, you cannot delete it, but you can rewrite it.

    During output to a formatted direct file, if data does not completely fill a record, the compiler pads the remaining portion of the record with blank spaces. The blanks ensure that the file contains only completely filled records, all of the same length. During input, the compiler by default also pads the input if the input list and format require more data than the record contains.

    You can override the default blank padding on input by setting PAD='NO' in the OPEN statement for the file. If PAD='NO', the input record must contain the amount of data indicated by the input list and format specification. Otherwise, an error occurs. PAD='NO' has no effect on output.

    An example of a program writing two records, record one and record three, to a formatted direct file is given below. The result is shown in the following figure.

       OPEN (3,FILE='FDIR', FORM='FORMATTED', ACCESS='DIRECT',RECL=10)
   WRITE (3, '(A10)', REC=1) 'RECORD ONE'
   WRITE (3, '(I5)', REC=3) 30303
   CLOSE (3)
   END

    Formatted Direct File

  • Unformatted Sequential Files

    Unformatted sequential files are organized slightly differently on different platforms. This section describes unformatted sequential files created by Visual Fortran when the /fpscomp option (such as /fpscomp:(ioformat,general)) was specified. If you are accessing files from another platform that organizes them differently, see Converting Unformatted Numeric Data or you can use the conversion utility in the ...\DF98\SAMPLES\TUTORIAL folder called UNFSEQ.F90.

    The records in an unformatted sequential file can vary in length. Unformatted sequential files are organized in chunks of 130 bytes or less called physical blocks. Each physical block consists of the data you send to the file (up to 128 bytes) plus two 1-byte "length bytes" inserted by the compiler. The length bytes indicate where each record begins and ends.

    A logical record refers to an unformatted record that contains one or more physical blocks. (See the following figure.) Logical records can be as big as you want; the compiler will use as many physical blocks as necessary.

    When you create a logical record consisting of more than one physical block, the compiler sets the length byte to 129 to indicate that the data in the current physical block continues on into the next physical block. For example, if you write 140 bytes of data, the logical record has the structure shown in the following figure.

    Logical Record in Unformatted Sequential File

    The first and last bytes in an unformatted sequential file are reserved; the first contains a value of 75, and the last holds a value of 130. Fortran uses these bytes for error checking and end-of-file references.

    The following program creates the unformatted sequential file shown in the following figure:

    !   Note: The file is sequential by default
!         -1 is FF FF FF FF hexadecimal.
!
   CHARACTER xyz(3)
   INTEGER(4) idata(35)
   DATA      idata /35 * -1/, xyz /'x', 'y', 'z'/

!
! Open the file and write out a 140-byte record:
! 128 bytes (block) + 12 bytes = 140 for IDATA, then 3 bytes for XYZ.
   OPEN (3, FILE='UFSEQ',FORM='UNFORMATTED')
   WRITE (3) idata
   WRITE (3) xyz
   CLOSE (3)
   END

    Unformatted Sequential File

  • Unformatted Direct Files

    An unformatted direct file is a series of unformatted records. You can write or read the records in any order you choose. All records have the same length, given by the RECL specifier in an OPEN statement. No delimiting bytes separate records or otherwise indicate record structure.

    You can write a partial record to an unformatted direct file. Visual Fortran pads these records to the fixed record length with ASCII NULL characters. Unwritten records in the file contain undefined data.

    The following program creates the sample unformatted direct file shown in the following figure:

       OPEN (3, FILE='UFDIR', RECL=10,&
     & FORM = 'UNFORMATTED', ACCESS = 'DIRECT')
   WRITE (3, REC=3) .TRUE., 'abcdef'
   WRITE (3, REC=1) 2049
   CLOSE (3)
   END

    Unformatted Direct File

  • Binary Sequential Files

    A binary sequential file is a series of values written and read in the same order and stored as binary numbers. No record boundaries exist, and no special bytes indicate file structure. Data is read and written without changes in form or length. For any I/O data item, the sequence of bytes in memory is the sequence of bytes in the file.

    The next program creates the binary sequential file shown in the following figure:

    !  NOTE: 07 is the bell character
!     Sequential is assumed by default.
!
   INTEGER(1) bells(4)
   CHARACTER(4) wys(3)
   CHARACTER(4) cvar
   DATA bells /4*7/
   DATA cvar /' is '/,wys /'What',' you',' see'/

   OPEN (3, FILE='BSEQ',FORM='BINARY')
   WRITE (3) wys, cvar
   WRITE (3) 'what ', 'you get!'
   WRITE (3) bells
   CLOSE (3)
   END

    Binary Sequential File

  • Binary Direct Files

    A binary direct file stores records as a series of binary numbers, accessible in any order. Each record in the file has the same length, as specified by the RECL argument to the OPEN statement. You can write partial records to binary direct files; any unused portion of the record will contain undefined data.

    A single read or write operation can transfer more data than a record contains by continuing the operation into the next records of the file. Performing such an operation on an unformatted direct file would cause an error. Valid I/O operations for unformatted direct files produce identical results when they are performed on binary direct files, provided the operations do not depend on zero padding in partial records.

    The following program creates the binary direct file shown in the following figure:

       OPEN (3, FILE='BDIR',RECL=10,FORM='BINARY',ACCESS='DIRECT')
   WRITE (3, REC=1) 'abcdefghijklmno'
   WRITE (3) 4,5
   WRITE (3, REC=4) 'pq'
   CLOSE (3)
   END

    Binary Direct File


I/O Hardware

Most of your hardware configuration and setup is done through your computer's operating system. To connect and communicate with your printer, for example, you should read your system and printer manuals. This section describes how Visual Fortran refers to physical devices and shortcuts for printing text and graphics from the Microsoft visual development environment.

For more information:

  • Printing
  • Physical Devices


Printing

The simplest way to print a file while you are in the visual development environment is to choose File/Print from the file menu. You are prompted for the file name and the file is printed on the printer connected to your computer.

You can also print files with the extension .F90, .FOR, .FD, .FI, or .RC by dragging the file from Windows Explorer and dropping it on the Print Manager icon.

If you have drawn graphics on the screen and want to print the screen, the simplest way is to press the key combination ALT+PRINT SCREEN. This copies the active window (the one with graphical focus) onto the Clipboard. (If you only press PRINT SCREEN, it prints your entire screen including any background applications.)

Once you have copied your screen onto the Clipboard, open Paintbrush and select Edit/Paste to paste the image from the Clipboard into Paintbrush, then select File/Print to print it to the printer connected to your computer. You can also save the image as a bitmap (.BMP) file.


Physical Devices

I/O statements that do not refer to a specific file or I/O device read from standard input and write to standard output. Standard input is the keyboard, and standard output is the screen (console). To perform input and output on a physical device other than the keyboard or screen, you specify the device name as the filename to be read from or written to.

Some physical device names are determined by the host operating system; others are recognized by Visual Fortran. Extensions on most device names are ignored.

Filenames for Device I/O

Device | Description
CON | Console (standard output)
PRN | Printer
COM1 | Serial port #1
COM2 | Serial port #2
COM3 | Serial port #3
COM4 | Serial port #4
LPT1 | Parallel Port #1
LPT2 | Parallel Port #2
LPT3 | Parallel Port #3
LPT4 | Parallel Port #4
NUL | NULL device. Discards all output; contains no input
AUX | Serial port #1
LINE 1 | Serial port #1
USER 1 | Standard output
ERR 1 | Standard error
CONOUT$ | Standard output
CONIN$ | Standard input

1 If you use one of these names with an extension—for example, LINE.TXT—Fortran will write to a file rather than to the device.

Examples of opening physical devices as units are:

   OPEN (UNIT = 4, FILE = 'PRN')
   OPEN (UNIT = 7, FILE = 'LPT2', ERR = 100)


Using the Console

On Windows systems, a console window typically allows input and output of characters (not graphics).

Certain console windows allow use of command-line interaction for programmers. For example, the Fortran Command Prompt available from the Compaq Visual Fortran program folder provides a command-line environment where Visual Fortran environment variables are already set. Similarly, the Command Prompt window provided by the operating system provides a general-purpose command-line console environment.

The primary purpose of an application's console window is to display and accept characters. For example, data written (explicitly or implicitly) by Fortran WRITE (or other) statements to Fortran logical unit 6 display characters on a console window. Similarly, data read by Fortran READ (or other) statements to unit 5 accept keyboard character input.

The console consists of two components:

  • The actual console window that shows the characters on the screen.
  • The console buffer that contains the characters to be displayed.

If the console screen buffer is bigger than the console window, scroll bars are provided automatically. The size of the console screen buffer must be larger (or equal to) the size of the console window (if not, an error occurs).

For applications that need to display more than a few hundred lines of text, the ability to scroll quickly through the text is important. Also, the maximum size of the console window buffer differs between Windows operating systems:

  • On a Windows 98, Windows Me, or Windows 95 system, the number of character lines is limited to about 40-50 pages of output with 132-character lines.
  • On a Windows NT or Windows 2000 system, the number of character lines is substantially larger than on Windows 98, Windows Me, and Windows 95 systems.

Fortran Console applications automatically provide a console. Fortran QuickWin (and Fortran Standard Graphics) applications do not provide a console, but display output and accept input from Fortran statements by using the program window.

Different Visual Fortran project types do or do not provide an application console window:

Project Type | Description of Console Provided
Fortran Console | Provides a console window since it is intended to be used for character-cell applications that use only text. When you run a Fortran Console application from a command prompt, the existing console environment is used. When you run the application from Windows or Developer Studio (by clicking on ! Execute program-name in the Build menu), a new console environment is created. The limits do not differ greatly whether the console is an existing command prompt or created by Windows or Developer Studio, but Windows NT and Windows 2000 systems have substantially greater capacity than Windows 98, Windows Me, and Windows 95 systems. Basic use of a console is described in Code Samples of Console Use.
Fortran QuickWin or Fortran Standard Graphics | Does not provide a console, but output to unit 6 and input to unit 5 are directed to the application program window, which can handle both text and graphics. However, because the program window must handle both text and graphics, it is not very efficient for just text-only use. A Fortran QuickWin or Fortran Standard Graphics program window (or child window) provides a console-like window. See Console Use for Fortran QuickWin and Fortran Standard Graphics Applications.
Fortran Windows | Does not provide a console window, but the user can create a console by using Win32 routines. See Console Use for Fortran Windows Applications and Fortran DLL Applications.
Fortran DLL | Does not provide a console window, but the user can create a console by using Win32 routines. See Console Use for Fortran Windows Applications and Fortran DLL Applications.
Fortran Static Library | Depends upon the project type of the main application that references the object code in the library (see above project types).

In addition to the Win32 routines mentioned below, there are other Win32 routines related to console use in the Platform SDK documentation, under Windows Base Services, File and I/O, Consoles and Character-Mode Support.

Console Use for Fortran QuickWin and Fortran Standard Graphics Applications

For a Fortran QuickWin or Fortran Standard Graphics application, because the default program window handles both graphics and text, the use of a QuickWin window may not be very efficient:

  • QuickWin windows use lots of memory and thus cannot be larger than a certain size.
  • They can be slow to scroll.

Although you can access the console window using WRITE and READ (or other) statements, applications that require display of substantial lines of text, consider creating a DLL that creates a separate console window for efficiency. The DLL application needs to call Win32 routines to allocate the console, display text, accept keyed input, and free the console resources.

For a Fortran QuickWin project that uses a DLL to create and use a console, see the CONAPP Visual Fortran sample in ...\Df98\Samples\QuickWin.

Basic use of a console is described in Code Samples of Console Use.

Console Use for Fortran Windows Applications and Fortran DLL Applications

With a Fortran Windows or Fortran DLL application, attempting to write to the console using WRITE and READ (or other) statements before a console is created results in a run-time error (such as error performing WRITE).

A console created by a Fortran DLL is distinct from any application console window associated with the main application. A Fortran DLL application has neither a console nor an application window created for it, so it must create (allocate) its own console using Win32 routines. When used with a Fortran QuickWin or Fortran Standard Graphics application main program, the Fortran DLL can provide its main application with a very efficient console window for text-only use.

Like a Fortran DLL application, a Fortran Windows application has neither a console nor an application window created for it, so it must create its own console using Win32 routines. After allocating a console in a Fortran DLL, the handle identifier returned by the GetStdHandle Win32 routine refers to the actual console the DLL creates.

When the Fortran Windows application does create a console window, it is very efficient for text-only use. The handle identifier returned by the GetStdHandle Win32 routine refers to the actual console the Fortran Windows application creates.

For information about creating a console, see Allocating and Deallocating a Console below.

Code Samples for Console Use

The following sections shows sample code for using a console:

  • Allocating and Deallocating a Console for Fortran Windows and DLL Applications
  • Extending Size of the Console Window and Console Buffer for console use in any project type
  • Writing and Reading Characters at a Cursor Position for console use in any project type

Allocating and Deallocating a Console

To create a console, you use the AllocConsole routine. When you are done with the console, free its resources with a FreeConsole routine. For example, the following code allocates the console, enlarges the buffer size, writes to the screen, waits for any key to be pressed, and deallocates the console:

! The following USE statement provides Fortran interfaces to Win32 routines
     USE DFWIN
! Begin data declarations
     integer lines,length
     logical status
     integer handle
     Type(T_COORD) wpos

! Set buffer size variables
     length = 80
     lines  = 90
! Begin executable code
!   Allocate a console
     status = AllocConsole() ! get a console window of the currently set size
     handle = GetStdHandle(STD_OUTPUT_HANDLE)
     wpos.x = length   ! must be >= currently set console window line length
     wpos.y = lines    ! must be >= currently set console window number of lines

     ! Set a console buffer bigger than the console window. This provides
     ! scroll bars on the console window to scroll through the console buffer

     status = SetConsoleScreenBufferSize(handle, wpos)

     ! Write to the screen as needed. Add a READ to pause before deallocation

     write (*,*) "This is the console output! It might display instructions or data "
     write (*,*) " "
     write (*,*) "Press any key when done viewing "
     read (*,*)

!   Deallocate the console to free its resources.

     status = FreeConsole()

Calling Win32 routines is described in Calling Win32 Routines and the Visual Fortran Windows Module.

If you are using a DLL, your DLL code will need to create subprograms and export their symbols to the main program (see Creating Fortran DLLs).

Basic use of a console is described in Extending Size of the Console Window and Console Buffer and Writing and Reading Characters at a Cursor Position.

Extending the Size of the Console Window and Console Buffer

When you execute a Fortran Console application, the console is already allocated. You can specify the size of the console window, size of the console buffer, and the location of the cursor.

If needed, you can extend the size of the console buffer and console window by using the following Win32 routines:

  1. You first need to obtain the handle of the console window using the GetStdHandle routine. For example:
     ! USE statements to include routine interfaces
    use dflib
    use dfwin

 ! Data declarations
    integer fhandle
    logical lstat
 ! Executable code
    fhandle = GetStdHandle(STD_OUTPUT_HANDLE)
 ! ...
  2. If needed, you can obtain the size of the:
    • Console window by using the GetConsoleWindowInfo routine
    • Console buffer by using the GetConsoleScreenBufferInfo routine

    For example:

     ! USE statements to include routine interfaces
    use dflib
    use dfwin
 ! Data declarations
    integer fhandle
    logical lstat
    Type(T_CONSOLE_SCREEN_BUFFER_INFO) conbuf
        type (T_COORD)        dwSize
        type (T_SMALL_RECT)   srWindow

    fhandle = GetStdHandle(STD_OUTPUT_HANDLE)

 ! Executable code to get console buffer size
     lstat = GetConsoleScreenBufferInfo(fhandle, conbuf)
     write (*,*) " "
     write (*,*) "Window coordinates= ", conbuf.srWindow
     write (*,*) "Buffer size= ", conbuf.dwSize

 ! ...
  3. To set the size of the console window and buffer, use the SetConsoleWindowInfo and SetConsoleScreenBufferSize routines with the fhandle value returned previously:
     ! USE statements to include routine interfaces
    use dflib
    use dfwin
 ! Data declarations
    integer nlines, ncols
    logical lstat
    Type(T_COORD) wpos
    Type(T_SMALL_RECT) sr
    Type(T_CONSOLE_SCREEN_BUFFER_INFO) cinfo

 ! Executable code to set console window size
    sr.top    =   0
    sr.left   =   0
    sr.bottom =   40 ! <= console buffer height -1
    sr.right  =   60 ! <= console buffer width  -1
    lstat = SetConsoleWindowInfo(fhandle, .TRUE., sr)

 ! Executable code to set console buffer size
     nlines = 100
     ncols  =  80
     wpos.x = ncols  ! columns >= console window width
     wpos.y = nlines ! lines   >= console window height
     lstat = SetConsoleScreenBufferSize(fhandle, wpos)
 ! ...

Writing and Reading Characters at a Cursor Position

You can position the cursor as needed using the SetConsoleCursorPosition routine before you write characters to the screen:

 ! Use previous data declarations
 ! Position and write two lines
    wpos.x = 5 ! 6 characters from left
    wpos.y = 5 ! 6 lines down
    lstat = SetConsoleCursorPosition(fhandle, wpos)
    write(*,*) 'Six across Six down'
 ! ...

You read from the screen at an appropriate place, but usually you should set the cursor relative to the starting screen location:

  ! Use previous and the following data declaration
    CHARACTER(Len=50) charin
 ! Go back to beginning position of screen
    wpos.x = 0 ! 0 characters from left
    wpos.y = 0 ! 0 lines down
    lstat = SetConsoleCursorPosition(fhandle, wpos)
 ! Position character input at start of line 11
    wpos.x = 0 ! first character from left
    wpos.y = 10 ! 11 lines down
    lstat = SetConsoleCursorPosition(fhandle, wpos)
    read(*,*) charin
 ! ...

For console I/O, you can use Win32 routines WriteConsoleLine and ReadConsoleLine instead of Fortran WRITE and READ statements.


Using the Serial Port I/O Routines

The SPORT_xxx routines help the Fortran programmer perform basic input and output to serial ports. The programming model is much the same as a normal file except the user does a connect (SPORT_CONNECT) and release (SPORT_RELEASE) to the port instead of an open and close of a file.

Two types of read and write operations (as determined in a mode on the connect call) are provided:

  • Read and write arbitrary data from/to the port using SPORT_READ_DATA and SPORT_WRITE_DATA.
  • Read and writes line-terminated data using SPORT_READ_LINE and SPORT_WRITE_LINE.

Once any I/O operation has been requested on the port, an additional thread is started that keeps a read outstanding on the port so that data will not be missed.

The SPORT_SET_STATE and SPORT_SET_TIMEOUTS routines allow you to set basic port parameters such as baud rate, stop bits, timeouts, and so on. Additionally, you can call SPORT_GET_HANDLE to return the Win32 handle to the port so that you can call Win32 Communication Functions to implement additional needs.

Calling the Serial Port I/O Routines

The SPORT_xxx routines are functions that return an error status:

  • An error status of 0 (zero) indicates success
  • Other values are Win32 error values that indicate an error

As described in the calling syntax, these routines require the following USE statement:

   USE DFLIB

The USE DFLIB statement includes the routine definitions in the compilation. You may also need to add a USE DWINTY statement to your program because some Win32 constants may be required that are typically defined in the DFWINTY module.

Many arguments are optional. If a constant is used where an argument is both input and output, a probe for writeability is done before the output. Thus, in many cases, a constant may be used without creating a temporary variable. It should be noted, however, that doing so may not be compatible with all Fortran implementations.

Run-Time Behavior of the Serial Port I/O Routines

To help ensure that data overruns do not occur, the SPORT_xxx run-time support creates a separate thread that maintains an outstanding read to the connected port. This thread is started when any read or write operation is performed to the port using the affiliated read/write routine. As such, port parameters must not be changed after you have started reading or writing to the port. Instead, you should set up the port parameters after connecting to the port and then leave them unchanged until after the port has been released.

If the parameters of the port must be changed more dynamically, use the SPORT_CANCEL_IO routine to ensure that no I/O is in progress. Additionally, that call will kill the helper thread so that it will automatically pick up the new, correct, parameters when it restarts during the next I/O operation.

Serial Port Usage

Depending upon the application, serial port programming can be very simple or very complex . The SPORT_xxx routines are intended to provide a level of support that will help the user implement simple applications as well as providing a foundation that can be used for more complex applications. Users needing to implement full serial port protocols (such as a PPP/SLIP implementation or some other complex protocol) should use the Win32 Communication Functions directly to achieve the detailed level of control needed in those cases. Simple tasks, such as communicating with a terminal or some other data collection device are well suited for implementations using the SPORT_xxx routines.

You should first familiarize yourself with the hardware connection to the serial device. Typical connections used today involve either a 9 pin/wire connector or a 25 pin/wire connector. Many cables do not implement all 9 or 25 connections in order to save on costs. For certain applications these subset cables may work just fine but others may require the full 9 or 25 connections. All cables will implement the Receive/SendData signals as well as the SignalGround. Without these signals, there can be no data transfer. There are two other categories of important signals:

  • Signals used for flow control

    Flow control signals tell the device/computer on the other end of the cable that data may be sent or that they should wait. Typically, the RequestToSend/ClearToSend signals are used for this purpose. Other signals such as DataSetReady or DataTerminalReady may also be used. Make sure that the cable used implements all the signals required by your hardware/software solution. Special characters (normally as XON/XOFF) may also be used to control the flow of data instead of or in addition to the hardware signals. Check your specific application to see what cabling is needed.

  • Signals that indicate status or state of a modem or phone connection.

    These signals may not be required if the connection between the computer and the device is direct and not through a modem. This signals typically convey information such as the state of the carrier (CarrierDetect) or if the phone line is ringing (Ring). Again, make sure the the cable used implements all the signals required for your application.

After the correct physical connection has been set up the programmer must become familiar with the data protocol used to communicate with the remote device/system.

Many simple devices terminate parcels of data with a "record terminator" (often a carriage return or line feed character). Other devices may simply send data in fixed length packets or packets containing some sort of count information. The two types of I/O routines provided by the SPORT_xxx support (line oriented using SPORT_READ_LINE and SPORT_WRITE_LINE or transfer raw data using SPORT_READ_DATA and SPORT_WRITE_DATA) can handle these two types of data transfer. The programmer must become familiar with the particular application to determine which type of I/O is more appropriate to use.

List of Serial Port Routines

The SPORT routines are:

  • SPORT_CANCEL_IO
  • SPORT_CONNECT
  • SPORT_GET_HANDLE
  • SPORT_GET_TIMEOUTS
  • SPORT_GET_STATE
  • SPORT_PEEK_DATA
  • SPORT_PEEK_LINE
  • SPORT_PURGE
  • SPORT_READ_DATA
  • SPORT_READ_LINE
  • SPORT_RELEASE
  • SPORT_SET_STATE
  • SPORT_SET_TIMEOUTS
  • SPORT_SHOW_STATE
  • SPORT_SPECIAL_FUNC
  • SPORT_WRITE_DATA
  • SPORT_WRITE_LINE

The SPORT_xxx routines call Win32 routines. For example, the SPORT_SET_STATE routine calls the Win32 routine SetCommState, which uses the DCB Communications Structure. The Win32 Communication Functions and Communication Structures are described in the Platform SDK section on Windows Base Services, subsection Files and I/O, under Communication Reference.

For more information:

  • About calling Win32 routines from Fortran programs, see Calling Win32 Routines.
  • About communications and using the Win32 Communications routines, see the Platform SDK descriptions below the following headings: Communications and Communications Functions


Using COM and Automation Objects

Visual Fortran provides a wizard to simplify the use of Component Object Model (COM) and Automation (formerly called OLE Automation) objects. The Visual Fortran Module Wizard generates Fortran 95/90 modules that simplify calling COM and Automation services from Fortran programs. This Fortran code lets you invoke routines in a dynamic link library, methods of an Automation object, and member functions of a Component Object Model (COM) object.

The following sections describe the use of COM and Automation objects as clients with Visual Fortran:

  • Overview of COM and Automation Objects
  • The Role of the Module Wizard
  • Using the Module Wizard to Generate Code
  • Calling the Routines Generated by the Module Wizard
  • Getting a Pointer to an Object's Interface
  • Additional Resources about COM and Automation

For information on creating a COM server with Visual Fortran, see Creating a COM Server.


Overview of COM and Automation Objects

This section provides a brief overview of:

  • COM Objects
  • Automation Objects
  • Object Servers

COM Objects

The Component Object Model (COM) provides mechanisms for creating reusable software components. COM is an object-based programming model designed to promote software interoperability; that is, to allow two or more applications or components to easily cooperate with one another, even if they were written by different vendors at different times, in different programming languages, or if they are running on different machines running different operating systems.

With COM, components interact with each other and with the system through collections of function calls, also known as methods or member functions or requests, called interfaces. An interface is a semantically related set of member functions. The interface as a whole represents a feature of an object. The member functions of an interface represent the operations that make up the feature. In general, an object can support multiple interfaces and you can use COMQueryInterface to get a pointer to any of them.

The Visual Fortran COM routines provide a Fortran interface to basic COM functions.

Automation Objects

The capabilities of an Automation object resemble those of a COM object. An Automation object is in fact a COM object that implements the interface IDispatch. An Automation object exposes:

  • Methods, which are functions that perform an action on an object. These are very similar to the member functions of COM objects.
  • Properties, which hold information about the state of an object. A property can be represented by a pair of methods; one for getting the property's current value, and one for setting the property's value.

The Visual Fortran AUTO routines provide a Fortran interface to invoking an automation object's methods and setting and getting its properties.

Object Servers

COM and Automation objects are made available to users by COM and Automation servers. A COM or Automation server can be implemented either as:

  • A DLL that is loaded into your process
  • A separate executable program. The separate executable program can reside on the same system as your application or on a different system.


The Role of the Module Wizard

To use COM and Automation objects from a Fortran program:

  1. Find or install the object server on the system. COM and Automation objects can be registered:

    • By other programs you install.
    • By creating the object server yourself, for example, by using the Visual Fortran COM Server wizard, Visual C++, or Visual Basic.

    For example, the Microsoft visual development environment registers certain objects during installation (see the documentation on the Developer Studio object model).

    Creating an object server involves deciding what type of object and what type of interfaces or methods should be available. The object's server must be designed, coded, and tested like any other application. For information about object server creation, see Creating a COM Server.

  2. Determine:

    • Whether the object has a COM interface, Automation interface, or both.
    • Where the object's type information is located.

    You should be able to obtain this information from the object's documentation. You can use the OLE-COM Object Viewer tool (provided in the Compaq Visual Fortran program folder) to determine the characteristics of an object on your system.

  3. Use the Visual Fortran module wizard to generate code.

    The Visual Fortran module wizard is a application that interactively asks certain questions about the object, including its name, type, and other information. The information collected by the module wizard is used in the generated code. To learn about using the Visual Fortran module wizard, see Using the Module Wizard to Generate Code.

  4. Write a Fortran 90 program to invoke the code generated by the Visual Fortran module wizard.

    To understand more about calling the interfaces and jacket routines created by the module wizard, see Calling Routines Generated by the Module Wizard.


Using the Module Wizard to Generate Code

To run the Visual Fortran Module Wizard, choose the Tools menu item Fortran Module Wizard. The module wizard asks a series of questions, including the name and type of the object as well as certain characteristics. If you have not already obtained the object's characteristics, see The Role of the Module Wizard.

The Visual Fortran Module Wizard presents a series of dialog boxes that allow you to select the type of information needed.

An object's type information contains programming language independent descriptions of the object's interfaces. Depending on the implementation of the object, type information can be obtained from the running object (see Automation Object below) or from a type library.

A type library is a collection of type information for any number of object classes, interfaces, and so on. A type library can also be used to describe the routines in a DLL. You can store a type library in a file of its own (usually with an extension of .TLB) or it can be part of another file. For example, the type library that describes a DLL can be stored in the DLL itself.

After you start the Module Wizard (Tools menu, Fortran Module Wizard), a dialog box requests the source of the type information that describes the object you need to use. You need to determine what type of object it is (or DLL) and how it makes its type information available. The choices are:

  • Automation Object
  • Type Library containing Automation information
  • Type Library containing COM interface information
  • Type Library containing DLL information
  • DLL containing type information

Object servers typically contain the type library in the same file (either .dll or .exe) as the object implementation.

Many objects implement dual interfaces, which supports both COM and Automation. For an object that supports dual interfaces, you can choose either of these options:

  • Type Library containing Automation information
  • Type Library containing COM interface information

The COM object interfaces tend to be more efficient (better run-time performance).

ActiveX controls implement an Automation interface. When using an ActiveX control, choose the Type Library containing Automation interface information option.

Most DLLs do not provide a type library that describes the programming interfaces in the DLL, and therefore cannot be used by the Module Wizard.

For these reasons, the Automation Information (second option) or COM Interface Information (third option) are the most commonly used.

The following initial screen appears after you select the Visual Fortran Module Wizard:

Initial Module Wizard Screen

initial module wizard screen

After you select one of the five choices, one of two different screens will appear depending on the selection made. The "Module Name" in the initial Module Wizard screen is used as the name of the Fortran module being generated. It is also used as the default file name of the generated source file.

If You Select Automation Object

If you select Automation Object, the following screen appears:

Application Object Screen

application object screen

Microsoft recommends that object servers provide a type library. However some applications do not, but do provide type information dynamically when running. Use this option for such an application. Enter the name of the application, name of the object, and version number. The version number is optional. If you do not specify it, you will get the latest version of the object. Note that this method only works for objects that provide a programmatic identifier (ProgID). ProgIDs are entered into the system registry and identify, among other things, the executable program that is the object's server.

After entering the information and pressing the Generate button, the Fortran Module Wizard asks you for the name of the source file to be generated. It then asks COM to create an instance of the object identified by the ProgID that the wizard constructs using the supplied information. COM starts the object's server if it needs to do so. The wizard then asks the object for its type information and generates a file containing Fortran modules.

If You Select Other Options

After selecting any of the remaining options in the initial screen and press the "Next" button, the Module Wizard displays the following screen:

Type Library Screen

type library screen

Choose the type library (or file containing the type library), and optionally specific components of the type library.

At the top of the dialog box is a combo box that lists all of the type libraries that have been registered with the system. You will notice a number of different file extensions, for example, .OLB (object libraries) and .OCX (ActiveX controls). Select a type library from the list or press Browse to find the file using the standard "Open" dialog box. Once you have selected a type library press the Show button to list the components you can select from the type library. By default, the Fortran Module Wizard will use all of the components. Optionally, you can select the ones desired from the list.

After entering the information and pressing the "Generate" button, the Fortran Module Wizard asks you for the name of the source file to be generated. It then asks COM to open the type library and generates a file containing Fortran modules.

The Fortran Module Wizard also has a command-line interface. The MODWIZ command has the following form:

MODWIZ [options] typeinfo-name

For a list of MODWIZ command options and an explanation of typeinfo-name, type the following command in a Fortran Command Prompt (available from the Visual Fortran program folder):

   MODWIZ /?


Calling Routines Generated by the Module Wizard

Calling the Routines Generated by the Module Wizard

Although Fortran 95/90 does not support objects, it does provide Fortran 95/90 modules. A module is a set of declarations that are grouped together under a global name, and are made available to other program units by using the USE statement.

The Fortran Module Wizard generates a source file containing one or more modules. The types of information placed in the modules include:

  • Derived-type definitions are Fortran equivalents of data structures that are found in the type information.
  • Constant definitions are Fortran PARAMETER declarations that include identifiers and enumerations found in the type information.
  • Procedure interface definitions are Fortran interface blocks that describe the procedures found in the type information.
  • Procedure definitions are Fortran functions and subroutines that are jacket routines for the procedures found in the type information.

The jacket routines make the external procedures easier to call from Fortran by handling data conversion and low-level invocation details.

The use of modules allows the Visual Fortran Module Wizard to encapsulate the data structures and procedures exposed by an object or DLL in a single place. You can then share these definitions in multiple Fortran programs.

The appropriate USE statement needs to be added in your program, as well as function invocations or subroutine calls.

The routines generated by the Visual Fortran Module Wizard are designed to be called from Fortran. These routines in turn call the appropriate system routines (not designed to be called from Fortran), thereby simplifying the coding needed to use COM and Automation objects.

Visual Fortran provides a set of run-time routines that present to the Fortran programmer a higher level abstraction of the COM and Automation functionality. The Fortran interfaces that the Wizard generates hide most of the differences between Automation objects and COM objects.

Depending on the options specified, the following routines can be present in the generated code:

DFCOM Routines (COMxxxxx)
COMAddObject Reference | Adds a reference to an object's interface.
COMCLSIDFromProgID | Passes a programmatic identifier and returns the corresponding class identifier.
COMCLSIDFromString | Passes a class identifier string and returns the corresponding class identifier.
COMCreateObjectByGUID | Passes a class identifier and creates an instance of an object. It returns a pointer to the object's interface.
COMCreateObjectByProgID | Passes a programmatic identifier and creates an instance of an object. It returns a pointer to the object's IDispatch interface.
COMGetActiveObjectByGUID | Pass a class identifier and returns a pointer to the interface of a currently active object.
COMGetActiveObjectByProgID | Passes a programmatic identifier and returns a pointer to the IDispatch interface of a currently active object.
COMInitialize | Initializes the COM library. You must initialize the library before calling any other COM or AUTO routine.
COMIsEqualGUID | Determines if two GUIDs are the same.
COMGetFileObject | Passes a file name and returns a pointer to the IDispatch interface of an Automation object that can manipulate the file.
COMQueryInterface | Passes an interface identifier and it returns a pointer to an object's interface.
COMReleaseObject | Indicates that the program is done with a reference to an object's interface.
COMStringFromGUID | Passes a GUID and returns the corresponding string representation.
COMUninitialize | Uninitializes the COM library. This must be the last COM routine that you call.
DFAUTO Automation Routines (AUTOxxxxx)
AUTOAddArg | Passes an argument name and value and adds the argument to the argument list data structure.
AUTOAllocateInvokeArgs | Allocates an argument list data structure that holds the arguments that you will pass to AUTOInvoke.
AUTODeallocateInvokeArgs | Deallocates an argument list data structure.
AUTOGetExceptInfo | Retrieves the exception information when a method has returned an exception status.
AUTOGetProperty | Passes the name or identifier of the property and gets the value of the Automation object's property.
AUTOGetPropertyByID | Passes the member ID of the property and gets the value of the Automation object's property into the argument list's first argument.
AUTOGetPropertyInvokeArgs | Passes an argument list data structure and gets the value of the Automation object's property specified in the argument list's first argument.
AUTOInvoke | Passes the name or identifier of an object's method and an argument list data structure. It invokes the method with the passed arguments.
AUTOSetProperty | Passes the name or identifier of the property and a value. It sets the value of the Automation object's property.
AUTOSetPropertyByID | Passes the member ID of the property and sets the value of the Automation object's property using the argument list's first argument.
AUTOSetPropertyInvokeArgs | Passes an argument list data structure and sets the value of the Automation object's property specified in the argument list's first argument.

Visual Fortran Samples include several projects in the ...\DF98\SAMPLES\ADVANCED\COM folder that demonstrate the use of the Fortran Module Wizard. For example:

  • AUTODICE uses Automation to drive Microsoft Excel® 97 to create a chart from Fortran data.
  • DSBUILD uses Automation to drive the visual development environment to rebuild a project configuration.
  • DSLINES uses COM to drive the Microsoft visual development environment to edit a Fortran source file and convert Debug lines (column 1) to IFDEF directives.
  • IWEB uses COM interfaces to start a Web browser and direct the browser to open a specified URL.

Example of Generated Code Used by the DSLINES Sample

The DLINES Sample contains the code that invokes this and other Microsoft visual development environment functionality using COM interfaces.

The following code shows an annotated version of a portion of the code generated by the Fortran Module Wizard from the COM type information in ...\Common\MSDev98\Bin\devshl.dll. This COM type information describes the top-level objects in the Microsoft visual development environment object model.

 INTERFACE
 !  Saves the document to disk.

 INTEGER*4 FUNCTION IGenericDocument_Save($OBJECT, vFilename, &
                    vBoolPrompt, pSaved)
 USE DFWINTY
 INTEGER*4, INTENT(IN)	:: $OBJECT     ! Object Pointer

 !DEC$ ATTRIBUTES VALUE	:: $OBJECT

 TYPE (VARIANT), INTENT(IN)  :: vFilename   ! (Optional Arg)
 !DEC$ ATTRIBUTES VALUE      :: vFilename
 TYPE (VARIANT), INTENT(IN)  :: vBoolPrompt	! (Optional Arg)
 !DEC$ ATTRIBUTES VALUE      :: vBoolPrompt

 INTEGER*4, INTENT(OUT)      :: pSaved          ! Void
 !DEC$ ATTRIBUTES REFERENCE  :: pSaved
 !DEC$ ATTRIBUTES STDCALL    :: IGenericDocument_Save
 END FUNCTION IGenericDocument_Save
 END INTERFACE

 POINTER(IGenericDocument_Save_PTR, IGenericDocument_Save) ! routine pointer

Notes for this example:

If the type information provides a comment that describes the member function, then the comment is placed before the beginning of the procedure.

The first argument to the procedure is always $OBJECT. It is a pointer to the object's interface. The remaining argument names are determined from the type information. For information on how to get a pointer to an object's interface, see Getting a Pointer to an Object's Interface.

This is an example of an ATTRIBUTES directive statement used to specify the calling convention of an argument.

A VARIANT is a data structure that can contain any type of Automation data. It contains a field that identifies the type of data and a union that holds the data value. The use of a VARIANT argument allows the caller to use any data type that can be converted into the data type expected by the member function.

Nearly every COM member function returns a status of type HRESULT. Because of this, if a COM member function produces output it uses output arguments to return the values. In this example, the "pSaved" argument returns a routine specific status value.

The interface of a COM member function looks very similar to the interface for a dynamic link library function with one major exception. Unlike a DLL function, the address of a COM member function is never known at program link time. You must get a pointer to an object's interface at run-time, and the address of a particular member function is computed from that.

The following code shows an annotated version of the wrapper generated by the Fortran Module Wizard for the "Save" function. The name of a wrapper is the same as the name of the corresponding member function, prefixed with a "$" character.

  ! Saves the document to disk.
  INTEGER*4 FUNCTION $IGenericDocument_Save($OBJECT, vFilename, &
                    vBoolPrompt, pSaved)
  !DEC$ ATTRIBUTES DLLEXPORT	:: $IGenericDocument_Save
  IMPLICIT NONE

  INTEGER*4, INTENT(IN)	:: $OBJECT	 ! Object Pointer
  !DEC$ ATTRIBUTES VALUE	:: $OBJECT
  TYPE (VARIANT), INTENT(IN), OPTIONAL	:: vFilename
  !DEC$ ATTRIBUTES REFERENCE	:: vFilename
  TYPE (VARIANT), INTENT(IN), OPTIONAL	:: vBoolPrompt
  !DEC$ ATTRIBUTES REFERENCE	:: vBoolPrompt
  INTEGER*4, INTENT(OUT)	:: pSaved	! Void
  !DEC$ ATTRIBUTES REFERENCE	:: pSaved

  INTEGER*4 $RETURN
  INTEGER*4 $VTBL		    ! Interface Function Table
  POINTER($VPTR, $VTBL)
  TYPE (VARIANT) :: $VAR_vFilename
  TYPE (VARIANT) :: $VAR_vBoolPrompt
  IF (PRESENT(vFilename)) THEN
      $VAR_vFilename = vFilename
  ELSE
     $VAR_vFilename = OPTIONAL_VARIANT
  END IF
  IF (PRESENT(vBoolPrompt)) THEN
     $VAR_vBoolPrompt = vBoolPrompt
  ELSE
    $VAR_vBoolPrompt = OPTIONAL_VARIANT
  END IF
  $VPTR = $OBJECT		   ! Interface Function Table
  $VPTR = $VTBL + 84	! Add routine table offset
  IGenericDocument_Save_PTR = $VTBL
  $RETURN = IGenericDocument_Save($OBJECT, $VAR_vFilename, &
  $VAR_vBoolPrompt, pSaved)
  $IGenericDocument_Save = $RETURN
  END FUNCTION $IGenericDocument_Save

Notes for this example:

The wrapper takes the same argument names as the member function interface.

The wrapper computes the address of the member function from the interface pointer and an offset found in the interface's type information. In implementation terms, an interface pointer is a pointer to a pointer to an array of function pointers called an "Interface Function Table".

Arguments to a COM or Automation routine can be optional. The wrapper handles the invocation details for specifying an optional argument that is not present in the call.

The offset of the "Save" member function is 84. The code assigns the computed address to the function pointer IGenericDocument_Save_PTR, which was declared with the interface shown above, and then calls the function.

The DLINES Sample contains the code that invokes this and other Microsoft visual development environment functionality using COM interfaces.

Example of Generated Code Used by the DSBUILD Sample

The DSBUILD example contains the code that invokes this and other Microsoft visual development environment functionality using Automation interfaces.

The following code shows an annotated version of a portion of the code generated by the Fortran Module Wizard from the Automation type information in ...\Common\MSDev98\Bin\devshl.dll.

 ! Rebuilds all files in a specified configuration.
 SUBROUTINE IApplication_RebuildAll($OBJECT, Configuration, $STATUS)
 !DEC$ ATTRIBUTES DLLEXPORT :: IApplication_RebuildAll
 IMPLICIT NONE

 INTEGER*4, INTENT(IN)            :: $OBJECT        ! Object Pointer
 !DEC$ ATTRIBUTES VALUE           :: $OBJECT
 TYPE (VARIANT), INTENT(IN), OPTIONAL :: Configuration
 !DEC$ ATTRIBUTES REFERENCE          :: Configuration
 INTEGER*4, INTENT(OUT), OPTIONAL    :: $STATUS       ! Method status
 !DEC$ ATTRIBUTES REFERENCE          :: $STATUS
 INTEGER*4 $$STATUS
 INTEGER*4 invokeargs
 invokeargs = AUTOALLOCATEINVOKEARGS()
 IF (PRESENT(Configuration)) CALL AUTOADDARG(invokeargs, '$ARG1', &
                    Configuration, AUTO_ARG_IN)
 $$STATUS = AUTOINVOKE($OBJECT, 28, invokeargs)
 IF (PRESENT($STATUS)) $STATUS = $$STATUS
 CALL AUTODEALLOCATEINVOKEARGS (invokeargs)
 END SUBROUTINE IApplication_RebuildAll

Notes for this example:

The first argument to the procedure is always $OBJECT. It is a pointer to an Automation object's IDispatch interface. The last argument to the procedure is always $STATUS. It is an optional argument that you can specify if you wish to examine the return status of the method. The IDispatch Invoke member function returns a status of type HRESULT. An HRESULT is a 32-bit value. It has the same structure as a Win32 error code. In between the $OBJECT and $STATUS arguments are the method arguments' names determined from the type information. Sometimes, the type information does not provide a name for an argument. The Fortran Module Wizard creates a "$ARGn" name in this case.

AUTOAllocateInvokeArgs allocates a data structure that is used to collect the arguments that you will pass to the method. AUTOAddArg adds an argument to this data structure.

AUTOInvoke invokes the named method passing the argument list. This returns a status result.

If the caller supplied a status argument, the code copies the status result to it.

AUTODeallocateInvokeArgs deallocates the memory used by the argument list data structure.

The DSBUILD Sample in the ...\DF98\Samples\Advanced\COM\ folder contains the code that invokes this and other Microsoft visual development environment functionality using Automation interfaces.


Getting a Pointer to an Object's Interface

Object Identification

Object identification enables the use of COM objects created by disparate groups of developers. To provide a method of uniquely identifying an object class regardless of where it came from, COM uses globally unique identifiers (GUIDs). A GUID is a 16-byte integer value that is guaranteed (for all practical purposes) to be unique across space and time. COM uses GUIDs to identify object classes, interfaces, and other things that require unique identification.

To create an instance of an object, you need to tell COM what the GUID of the object is. While using 16-byte integers for identification is fine for computers, it poses a challenge for the typical developer. So, COM also supports the use of a less precise, textual name called a programmatic identifier (ProgID). A ProgID takes the form:

  application_name.object_name.object_version

Obtaining the Pointer to an Object's Interface

To use the routines generated by the Module Wizard, your application must get a pointer to an object's interface. This pointer is used as the value of the $OBJECT argument, which is the first argument of every interface generated by the Module Wizard.

Typically, your application obtains its first object pointer by calling the COM routine COMCreateObject. COMCreateObject creates a new instance of an object class. COMCreateObject is the generic name of the two subroutines COMCreateObjectByProgID and COMCreateObjectByGUID:

  • Use COMCreateObjectByProgID to create Automation objects. It accepts the progID of an object and returns a pointer to the object's IDispatch interface.
  • Use COMCreateObjectByGUID to create both COM and Automation objects.

The arguments to COMCreateObjectByGUID are as follows:

  • The first argument is a class identifier (CLSID) that uniquely identifies the object's class. The Module Wizard defines a GUID parameter for each class selected from the Type library. These are given the name in the form: CLSID_class-name.
  • The second argument allows you to limit the type(s) of server that the call will accept. Most of the time you can use CLSCTX_ALL to accept any type of server.
  • The third argument is an interface identifier (IID) that specifies the particular object interface you are requesting:
    • To request an Automation interface, use IID_IDispatch.
    • To request a COM interface, the Module Wizard defines a GUID parameter for each interface selected from the type library. These are given a name in the form: IID_interface-name.
  • The fourth argument is an output parameter that returns the object's interface pointer.

The COMCreateObjectByProgID and COMCreateObjectByGUID subroutines return an interface pointer of an object that the server has defined as being externally creatable. However, not all objects are externally creatable. Often, a server implements a hierarchy of objects, or object model. COMCreateObject is called to obtain a pointer to an interface of the root object in the hierarchy. Methods and/or properties of the root object are used to obtain pointers to child objects, and so on, down the hierarchy. You can see examples of this in the Autodice, Dlines, and DSbuild Visual Fortran samples.

All objects must implement the IUnknown interface. Every object also implements one or more additional interfaces. You can always get a pointer to any of the object's interfaces from any of the object's interface pointers by using the COMQueryInterface subroutine. It is important that you have a pointer to the correct object interface when calling a routine generated by the Module Wizard. If not, your application will likely crash.

Releasing the Pointer to an Object's Interface

When you have finished using an object's interface pointer, you must call COMReleaseObject with the pointer. This includes object pointers that you have received using any method, including COMCreateObject, COMQueryInterface, or by calling an object's method.


Additional Resources about COM and Automation

There are a number of published books and articles about COM and Automation. Compaq lists some of these publications as additional resources to assist customers who want to learn more about the subject matter. This list does not comment—either negatively or positively—on any documents listed or not yet listed. Books and related resources about COM and Automation include:

  • Inside COM+ Base Services by Guy Eddon, Henry Eddon. Published by Microsoft Press (Redmond, Washington) 1999
  • Understanding COM+ by David S. Platt. Published by Microsoft Press (Redmond, Washington) 1999
  • Inside Distributed COM by Guy Eddon; Henry Eddon. Published by Microsoft Press (Redmond, Washington) 1998
  • Inside COM by Dale Rogerson. Published by Microsoft Press (Redmond, Washington) 1996
  • Understanding ActiveX and OLE by David Chappell. Published by Microsoft Press (Redmond, Washington) 1996
  • Automation Programmer's Reference by Microsoft. Published by Microsoft Press (Redmond, Washington) 1997
  • ActiveX Controls Inside Out, Second Edition by Adam Denning. Published by Microsoft Press (Redmond, Washington) 1997
  • Platform SDK online version (HTML Help Viewer, provided with MSDN and Visual Fortran). Relevant titles include Platform SDK, COM and ActiveX Object Services.
  • Visual C++ User's Guide online version (HTML Help Viewer, provided with MSDN and Visual Fortran)

Microsoft Press has a URL of http://mspress.microsoft.com.


Creating a COM Server

This section assumes that you are familiar with the COM-related terms and concepts presented in Using COM and Automation Objects and related sections, such as Overview of COM and Automation Objects. These sections (starting with Using COM and Automation Objects) discuss using COM and Automation objects from a Visual Fortran application, using the Fortran Module Wizard. That is, using a Visual Fortran application as a client of a COM server.

The Component Object Model (COM) supports a model of client server interaction between a user of an object, the client, and the implementor of the object, the server.

The Visual Fortran Professional and Enterprise Editions provide the capability to create a COM server. This section and its subsections discusses creating a COM server using Visual Fortran:

  • Advantages of a COM Server
  • What You Need to Provide and What the Fortran COM Server Wizard Will Do
  • Using the Fortran COM Server Wizard, which includes:
    • Specifying the Fortran COM Server as a Developer Studio Add-in
    • Creating a Fortran COM Server Project
    • Using the Fortran COM Server Wizard to Define your COM Server
    • Adding a Property
    • Working with the Hierarchy Pane
    • Description of Property Pages
    • Modifying the Generated Code
    • Build Notes
    • Visual C++ ClassView
    • Using Example Clients
    • Modifying Your COM Servers
  • Interface Design Considerations, which includes:
    • Method and Properties Data Types
    • COM Status Codes: HRESULT
    • Visual Basic and Visual C++ Client Notes
  • Advanced COM Server Topics, which includes:
    • Choosing Between DLL or EXE COM Servers
    • DLL Server Surrogates
    • Discussion of Wizard Code Generation
    • Adding Support for COM ErrorInfo Objects
    • Threading Models
    • Marshalling, Proxies and Stubs
    • A Map of the Generated "Do Not Edit" Code
  • Deploying the Server on Another System


Advantages of a COM Server

A COM server consists of the implementation of one or more object classes. An object class is a type that describes the complete public calling interface ("signature") of an object. It describes the functionality that you want to make available to the users of the object. The COM server creates instances of the class, called objects, at the request of clients.

Some of the advantages of implementing your Fortran code as a COM server include:

  • A COM server is a reusable component, which allows multiple applications to use the server. The classes specified by the server define a "contract" between the server and its clients. The server can change the specific implementation of the functionality without breaking the contract. That is, without requiring clients to be changed or rebuilt.
  • A COM server is programming-language independent. Multiple development tools can be used to access the server's functionality, including Visual Basic, Visual C++, and Visual Fortran.
  • A COM server is self-describing. The server provides a type library that describes the classes and interfaces. Many tools can take advantage of this information and relieve the client programmer from needing to understand low-level invocation details, such as calling conventions. This is a great improvement over multi-language programming with DLLs, where the client programmer has to understand the details of data types and calling conventions.
  • A COM server is self-registering. The clients do not need to worry about where the server is located on their system, as COM finds this information in the system registry.
  • A COM server can be implemented as an in-process server. Like a DLL, it is loaded into the client's process. A COM server can also be implemented as a separate application and can even reside on a separate machine.

Visual Fortran provides the Fortran COM Server Wizard. The wizard generates the Fortran code necessary to implement a COM server, and allows you to concentrate on the code that is specific to the functionality that your server provides to its clients.

As explained in Overview of COM and Automation Objects, COM supports two types of servers: COM servers and Automation servers. The Fortran COM Server Wizard can only create a COM server or a server that supports dual interfaces. The wizard cannot create an Automation-only interface.

For more information about creating COM servers using Visual Fortran, see What You Need to Do and What the COM Server Wizard Will Do.


What You Need to Provide and What the Fortran COM Server Wizard Will Do

The Fortran COM Server Wizard generates a Developer Studio project and a number of source files that implement all of the infrastructure of a COM server. You use the Fortran COM Server Wizard's user interface to define the implementation of one or more object classes, including its interface(s), and method(s). You need to define fields in the derived-type for each instance and to write code for those fields, if necessary. You also need to write code needed to implement each method.

What Information You Need to Provide

To use the Fortran COM Server Wizard to create a COM server, you first need to describe to the Fortran COM Server Wizard the class(es) that you want to implement.

A class implements one or more COM interfaces. In COM terminology, an interface is a semantically related set of functions. The interface as a whole represents a "feature", or set of related functionality, that is implemented by the class. An interface contains methods, otherwise known as member functions. A method is a routine that performs one of the actions that make up the feature. When using the Fortran COM Server Wizard, methods are Fortran functions that take arguments and return a value like any other Fortran function.

Consider a simple example of a class that we will create using the Fortran COM Server Wizard, called AddingMachine. The class contains a single interface that we call IAdd. By convention, all interface names begin with a capital letter "I". We define three methods in the IAdd interface:

  • Clear, which takes no arguments and sets the current value of the adding machine to 0.
  • Add, which takes a single REAL argument, the amount to add to the current value.
  • GetValue, which returns the current value.

The Clear method, Add method, and GetValue method allow you to perform specific, distinct tasks with the IAdd interface from any language that supports a COM client. The Fortran COM Server Wizard provides a user interface to enter this information about the class (in this case the AddingMachine class), which is discussed later in Using the COM Server Wizard.

An interface can also contain properties. Properties are method pairs that set or return information about the state of an object. When you add a property to an interface, you are actually adding one or two methods. This is discussed further in Adding a Property.

Another important concept is the data associated with an object. A key concept of object-oriented programming is encapsulation. Encapsulation means that all of the details about how the object is implemented, including the data that it uses and the logic that it uses to perform its work, is hidden from the client. The client's only access to the object is through the interfaces that the object supports.

You need to define the data that the object uses and code the logic of the methods. For the data, the Fortran COM Server Wizard uses the model that each instance of the object has an associated instance of a Fortran derived-type. The code generated by the wizard takes care of creating and destroying the instances of the derived-type as objects are created and destroyed.

You define the fields of the derived-type. For example, with our AddingMachine, each AddingMachine object needs to store the current value. The derived-type associated with each AddingMachine object would contain a single field of type REAL. We name it CurrentValue. Note that each instance of the AddingMachine object has its own instance of the derived-type and its own CurrentValue. This means that the server could support multiple clients simultaneously and each client would see its own AddingMachine. That is, each client is unaffected by the existence of other clients. The derived-type associated with each object is discussed in detail in Creating a Fortran COM Server Project.

To summarize, at a high level, what you need to do to create a COM server using the Fortran COM Server Wizard:

  • Define the class(es), interface(s), method(s), and properties using the Wizard's user interface.
  • Define the fields in the derived-type that is associated with each instance of a class.
  • Write code that initializes the fields in the derived-type (if necessary), and code that releases any resources used by the fields in the derived-type (if necessary).
  • Write the code that implements the methods.

What the COM Server Will Provide

The Fortran COM Server Wizard generates a Developer Studio project and a number of source files that implement all of the infrastructure, or "plumbing", of the COM server. The generated files take care of such tasks as:

  • Defining the GUIDs that uniquely identify your classes and interfaces. For a discussion of GUIDs, see Getting a Pointer to an Object's Interface.
  • Registering the server and your classes and interfaces on the system.
  • Implementing the class factory that creates instances of your object.
  • Creating the Interface Definition Library (IDL) and type library that describes your classes and interfaces. For a discussion of type libraries, see Using the Module Wizard to Generate Code.
  • Implementing the IUnknown and IDispatch interfaces for your object. All of the interfaces created by the Fortran COM Server Wizard are derived from IUnknown or IDispatch (dual interfaces).
  • Creating and destroying instances of the derived-type associated with your object.
  • Invoking the Fortran routines that implement your object's methods.

The majority of these source files are generated fully by the Fortran COM Server Wizard and are not modified by you. Other files contain the skeleton or template of your derived-type and methods. You edit these Fortran source files to fill in your implementation. You will see how this is done as we work through the AddingMachine example.

For information on using the Fortran COM Server Wizard user interface to create a COM server, see Using the COM Server Wizard.


Using the Fortran COM Server Wizard

This section shows how to create a project, specify the COM server characteristics, generate code for, and implement an example Fortran COM server project called Adder. It contains the following topics:

  • Specifying the Fortran COM Server as a Developer Studio Add-in
  • Creating a Fortran COM Server Project
  • Using the Fortran COM Server Wizard to Define Your COM Server
  • Adding a Property
  • Working with the Hierarchy Pane
  • Description of Property Pages
  • Modifying the Generated Code
  • Build Notes
  • Visual C++ ClassView
  • Using Example Clients
  • Modifying Your COM Servers

Specifying the Fortran COM Server as a Developer Studio Add-in

The Fortran COM Server Wizard is implemented as a Developer Studio Add-in. After you install Visual Fortran, you need to register and load the Fortran COM Server Wizard on your system. If you have not already done so, do the following:

  1. In the Tools menu, click Customize
  2. Click the Add-in and Macros tab
  3. Enable the check box for the Fortran COM Server Wizard if it is displayed in the list
  4. If it is not displayed, click the Browse button and find the CSAddin.dll file, in the ...\Microsoft Visual Studio\Common\MSDev98\Addins\Df98\ directory.
  5. Click the Close button

You only need to perform this procedure once on your system.

Creating a Fortran COM Server Project

The first step in creating a Fortran COM Server is to create a new project. Start Developer Studio. In File menu, click New.

In the New Projects dialog box, select (click) the Fortran COM Server project type, as shown below (if Microsoft Visual C++ is installed on your system, additional project types will appear):

specify the fortran com server project type

The Fortran COM Server Wizard is implemented as a Developer Studio Add-in and must be registered and loaded on your system. If you receive a message that begins with "The Fortran COM Server Wizard Add-in is not loaded into Developer Studio ...", follow the instructions in Initializing the Fortran COM Server as a Developer Studio Add-in.

In this case:

  1. Enter "Adder" as the name of the project.
  2. Accept or modify the project folder location.
  3. Click the OK button. (If you click <Back, the previous screen appears, allowing you to change the name, location, or project type of the project being created.)

To define the initial attributes of the Fortran COM server project being created, additional information is requested. The following screen shows the Fortran COM Server AppWizard. You use the project AppWizard once per project to create the project files and skeleton template (as with other project types). The Fortran COM Server AppWizard requests the type of server (DLL or EXE), the class name, interface name, and the class derived type name:

specify com server type and project attributes

In this case:

  1. Accept the default server type (DLL).
  2. Type the class name AddingMachine. Default text appears for the default interface name and class derived type name.
  3. Shorten the default interface name to IAdd.
  4. Accept the default class derived type name.
  5. Click the Finish button. (If you click Cancel, project creation is terminated.)

A summary screen appears that summarizes the location and template information created for this project:

verify project creation attributes

After you click OK, the project is created and the Fortran COM Server Wizard appears.

Using the Fortran COM Server Wizard to Define your COM Server

The Fortran COM Server Wizard lets you interactively define the attributes of your COM server. It lets you define and name classes, interfaces, methods, and so on. The user interface contains two panes:

  • The left pane is a tree control that displays your classes, interfaces, methods, and so on in a hierarchy.
  • The right pane is a property page that displays the properties of the selected element in the hierarchy.

The Fortran COM Server Wizard is automatically invoked by the Fortran COM Server AppWizard, so you can enter the initial definition of your server. You can, but you are not required to, fully define the server at this point. You can partially define your project and close your project workspace. Later, after you start Developer Studio and open the project workspace again, you can start the Fortran COM Server Wizard by clicking the Fortran COM Server Wizard menu item in the View menu.

With our example COM server, the initial screen of the Fortran COM Server Wizard now appears, displaying the type library GUID and the type library version:

initial fortran com server wizard screen

In this case, you need to expand the hierarchy to select the IAdd interface name:

  1. Click the plus sign (+) to open the COM server name (and project name) Adder.
  2. Click the plus sign (+) to open the class name AddingMachine.
  3. Click the IAdd interface name.

The screen appears as follows:

interface iadd properties and choosing whether to use a dual interface

If the Dual Interface check box is checked, click the Dual Interface check box to uncheck it. The Adder sample only supports a COM server interface.

The hierarchy is as follows:

  • The root is the COM server itself, Adder. This is also the project name.
  • The immediate children of the COM server are classes. Our hierarchy initially contains a single class, AddingMachine. You can add additional classes to the COM server.
  • The immediate children of a class are interfaces and the class derived-type. Our hierarchy contains the interface IAdd and the class derived-type AddingMachine_InstanceData. Each class contains one, and only one, class derived-type. You can add additional interfaces to the class.
  • The immediate children of an interface are methods (one or more).
  • The immediate children of a method are the method arguments (one or more).

You can use the Fortran COM Server Wizard's graphical user interface to add a class, interface, method, property, or argument:

  1. Select the parent item.
  2. Click the Add button.
  3. Type the requested name (and other requested text).
  4. Click OK.

To delete an item:

  1. Select the item to be deleted.
  2. Click the Delete button.

For our example Adder COM server, add the methods to the IAdd interface:

  1. Verify that the IAdd interface is selected (highlighted).
  2. Click the New button.

The following screen appears:

adding a method to a class

The active buttons displayed depend on the selected (highlighted) item (COM server, class, interface, method, or argument) in the hierarchy. The active buttons represent the types that are valid in the current context. For example, the Argument button is inactive since an interface was selected and an Argument must be added to a method.

In this case:

  1. Select the Method type.
  2. Type Clear as the name of the first method of the IAdd interface.
  3. Click OK.

Because the Clear method takes no arguments, you can now add a second method, named Add:

  1. Click (select) the IAdd interface.
  2. Click the New button.
  3. Type the second method name, Add.
  4. Click OK.

The Add method requires an argument, which we will name Operand. To add the Operand argument:

  1. Click (select) the Add method.
  2. Click the New button.
  3. Type the argument name, Operand.
  4. Click OK.

Before you click OK, the screen appears as follows:

adding the operand argument to the add method

After you click OK, the Fortran COM Server Wizard screen adds the Operand argument and displays its properties.

The default data type of an argument is INTEGER(4).

In our example:

  1. Use the Fortran data type combo box to change the data type to REAL(4) (as follows):
    after adding the operand argument
  2. Leave the default values for Interface data and Intent.

We need to add the last method:

  1. Click (select) the IAdd interface.
  2. Click the New button.
  3. Type the method name, GetValue.
  4. Click OK.

The GetValue method requires an argument, which we will name CurrentValue. To add the CurrentValue argument:

  1. Select the GetValue method.
  2. Click the New button.
  3. Type the argument name, CurrentValue.
  4. Click OK.

For the CurrentValue argument:

  1. Use the Fortran data type combo box to change the data type to REAL(4)
  2. Leave the default values for Interface data.
  3. Change the Intent to Out.
  4. Click the Return value check box.

The screen appears as follows:

screen after adding currentvalue argument

In our example, the server definition is now complete. Click the Save button to dismiss the Fortran COM Server Wizard. The project is now displayed, including the TODO.TXT file, allowing you to modify the generated code.

For detailed information about the property pages (right pane) for server, class, interface, method, argument, or instance properties, see Description of Property Pages.

To change the definition of your server later, select the Fortran COM Server Wizard menu item in the View menu.

Adding a Property

In addition to methods, an interface can contain properties. Properties are method pairs that set or return information about the state of an object. Typically, a property corresponds to a field in the object's derived type. For example, in the AddingMachine example, we could have used a CurrentValue property rather than a GetValue (and SetValue) methods.

A property is primarily an Automation concept. In a COM interface, a property is implemented as one or two methods:

  • A get_property-name method
  • A put_property-name method

A property can be defined as read-only or write-only. In this case, there will be a single get_ or put_ method.

Defining an interface member as a property, rather than a method, can affect the syntax used by the client of your server. For example, Visual Basic uses a different syntax for getting or putting a property than for invoking a method. If the client language has a specific property syntax, it typically looks similar to setting a field in a record, rather than making a call.

To add a property to your interface:

  1. Click (select) the interface in the hierarchy pane.
  2. Click the New button. The New dialog appears. Do the following:
    • Select the Property type.
    • Type a name for the property. The completed screen appears as follows:
      adding a new property
    • Click OK. The following screen appears:
      specifying the property's attributes
  3. In the New Property dialog box, define the attributes of the property. This includes:
    • Whether the property has both get_ and put_ methods.
    • The integer Automation identifier of this property.
    • The data type of this property.
  4. Click OK.

One or two methods are added to your interface. Two methods are added if you select both the get_ and put_ methods. One method is added if it is read-only or write-only. The properties methods and the argument that identifies the property value are fully defined and do not need to be modified.

A property method typically only has the single argument that represents the property value. You can add additional arguments if it makes sense. For example, additional arguments might be added if the property is an array of values, where an integer index argument is added to the property method.

When adding additional arguments to a property method, make sure that they are added before the property value argument. That is, the property value argument must always be the last argument to the property method. You can use drag-and-drop in the hierarchy pane to change the order of arguments. The order in the method is always the order that appears in the hierarchy pane.

Working with the Hierarchy Pane

As you have seen in the AddingMachine example, the hierarchy pane represents the definition of your server; that is, the classes, interfaces, methods, and so on. The hierarchy pane's user interface supports the following functionality:

Expand/contract an area | When the Fortran COM Server wizard is initially displayed, the hierarchy is fully contracted. Click the plus sign (+) next to an item to display its children. At this point, the + changes to a -. Click the - to hide the children. Double-clicking on an item also toggles its expand/contract state.
Add a new entry | To add a new entry to the hierarchy, select the entry that will precede the new entry in the hierarchy. Then click the New... button or click the right mouse button to display the pop-up hierarchy pane context menu and select one of the New... entries in the context menu.
Delete an entry | To delete an entry from the hierarchy, select the item to be deleted. Then click the Delete button or click the right mouse button to display the pop-up hierarchy pane context menu and select the Delete entry in the context menu. A confirmation dialog box is displayed to ensure that you do not accidentally delete items. All of an item's children are deleted when the item is deleted.
Rename a member | To rename an entry in the hierarchy, select the item to be renamed. Wait a few seconds (to avoid double-clicking) and then click the item again. The item's name will enter editing mode allowing you to change the name. Press the Enter key when you have finished editing the name.
Change the order of items The order of some of the entries in the hierarchy is very important. In particular:
  • The order of the methods in an interface define the order of the methods in the class' VTBL. Changing the order of the methods will break an existing client.
  • The order of the arguments in a method define the order of the arguments in the method's interface. Changing the order of the arguments will break an existing client.

The hierarchy pane supports drag-and-drop to allow you to change the order of items. To move an item, click and drag the item and drop it on the item that you want to precede it in the hierarchy.

Description of Property Pages

Property pages appear in the right pane of the Fortran COM Server Wizard window. Different property pages apply to:

  • Server Properties
  • Class Properties
  • Interface Properties
  • Method Properties
  • Argument Properties
  • Instance Type Properties

Server Properties:

Type Library GUID | The unique identifier of the server's type library. There is usually no reason to change this from the default value generated by the Fortran COM Server Wizard.
Type Library Version | The current version of the Type Library.

Class Properties:

ProgID | The version independent program ID (or text alias) for the class. The ProgID can be used in calls such as COMCreateObjectByProgID.
Version | The current version of the class. It is appended to the ProgID to define the version-specific ProgID.
Short name | A short name for the class. It is used in some of the generated file names.
Description | A string used as the default value of the class' ProgID keys in the registry. This string is often used by tools, such as the OLE-COM Object Viewer, that display a list of the objects that are registered on the system.
Help String | A string used to set the class' help string attribute in the IDL file.
Threading model | The threading model of the class. The two choices are Apartment and Single. See Threading Models in Advanced COM Server Topics for information about the implications of this choice.
CLSID | The unique identifier of the class. There is usually no reason to change this from the default value generated by the Wizard.

Interface Properties:

Dual Interface | If checked, then the dual interface attribute is set in the IDL file. A dual interface supports both COM and Automation clients.
Uses only Automation data types | If checked, then the interface uses only Automation-compatible data types as described in Method Data Types.
Default interface | If checked, then the default interface attribute is set for this interface in the IDL file. The default attribute represents the default programmability interface of the object, and is intended for use by macro languages.
Help String | A string used to set the interface's help string attribute in the IDL file.
IID | The unique identifier of the interface. There is usually no reason to change this from the default value generated by the Wizard.

Method Properties:

ID | The identifier of the method used by Automation clients.
Help string | A string used to set the method's help string attribute in the IDL file.
Property Method | If checked, then the method is the get_ or put_ method of a property.

Argument Properties:

Fortran data type | The Fortran data type of the argument. Select one of the data types from the list, or type in the data type. See Method Data Types for a discussion of the implications of your choice.
Interface data type | The IDL data type. If you select one of the Fortran data types from the predefined list, then this field defaults to the corresponding IDL data type. Select one of the data types from the list, or type in the data type. See Method Data Types for a discussion of the implications of your choice
Intent The INTENT of the argument, one of the following list:
  • In - the argument value is read but not modified by the method
  • Out - the argument value is not read, but is modified by the method
  • InOut - the argument value is both read and modified by the method
By Reference | Indicates that an argument is passed by reference rather than by value. Only valid with Intent In. Intent Out and Intent InOut are automatically passed by reference.
Return Value | If checked, the argument represents the return value of the method. Only valid with Intent Out.
Array argument | If checked, then the argument is an array rather than scalar argument. When checked, fill in the Array Description fields to describe the shape of the array.
Optional argument | If checked, then the argument is optional. Optional arguments are passed using the Variant data type.
Array Description fields | These fields describe the shape of an array argument. They are enabled when the Array argument field is checked.

Instance Type Properties:

Module | The name used for the module defined in the UclassnameTY.f90 file.
Constructor | The name used for the class constructor defined in the UclassnameTY.f90 file.
Destructor | The name used for the class destructor defined in the UclassnameTY.f90 file.

Modifying the Generated Code

After you either click the Save button to dismiss the Fortran COM Server Wizard or open the project workspace, the project is displayed, including the TODO.TXT file.

The TODO.TXT file informs you of changes made to your project by the Wizard, and lets you know when you need to make changes. After the initial invocation of the Wizard, TODO.TXT lists the files that were added to the project. The source files are added to two folders in your FileView pane:

  • Source files that you will need to modify are placed in the Source Files folder.
  • Files that are totally generated by the Wizard are placed in the Do Not Edit folder. It is futile to modify the files in the Do Not Edit folder, since these files are regenerated each time you invoke the Wizard and change the definition of the server (edits you make to these files will be lost).

Click:

  1. The plus sign (+) at the Adder files line
  2. The plus sign (+) at the Source Files folder

The project screen appears as follows:

adder project screen

The two files that you need to modify with a text editor are in the Source Files folder:

  • UAddingMachineTY.f90 contains a module that defines your class derived-type.
  • UIAdd.f90 contains the implementation of the IAdd methods.

We will first modify the file UAddingMachineTY.f90. To edit the file UAddingMachineTY.f90, either double-click its file name in the FileView pane or use the Open menu item in the File menu. The original file UAddingMachineTY.f90 contains the following code:

A file named Uclass-nameTY.f90 is created for each class defined by the server. The file contains a module named AddingMachine_USE (in the form classname_USE). There are three places in this module where you may need to add code specific to your class:

  • The first entry in the module is your class derived-type. Initially it contains an "integer dummy" field to allow the module to be compiled without error. If your class has per-object data, remove the "integer dummy" field line and add your data to the derived-type. For the AddingMachine class, we add the following where the object stores the current value:
     real(4) CurrentValue
    The module also contains two module procedures by the names AddingMachine_CONSTRUCTOR and AddingMachine_DESTRUCTOR (referred to as classname_CONSTRUCTOR and classname_DESTRUCTOR below).

  • The classname_CONSTRUCTOR procedure is called immediately after an instance of the class derived-type is created because of the creation of a new object. This function is where you initialize the fields of the class derived-type, if necessary. The new derived-type is passed as an argument to the function. For the AddingMachine class, we initialize the current value to 0 by adding the following statement:
      ObjectData%CurrentValue = 0
  • The classname_DESTRUCTOR procedure is called immediately before an instance of the class derived-type is destroyed because an object is being destroyed. This function is where you release any resources used by the fields of the class derived-type, if necessary. The derived-type is passed as an argument to the function. For the AddingMachine class, there is nothing that needs to be added.

We will now modify the other source file UIAdd.f90. Either double-click its file name in the FileView pane or use the File menu, Open item. The original file UIAdd.f90 contains the following code:

A file by the name Uinterfacename.f90 (for example UIadd.f90) is created for each interface defined by the class. The file contains the methods of the class. Each method is named interfacename_methodname, for example: "IAdd_Clear". Each method is a function that is passed the class derived-type as the first argument. This gives the function access to the per-object data. Each function returns a 32-bit COM status code called an HRESULT. S_OK is a parameter that defines a success status. For additional information on COM status codes, see COM Status Codes: HRESULT.

You replace the "! TODO: Add implementation" line in each method with the code for the method. For the IAdd interface, below is the implementation of its three methods:

 IAdd_Clear:	ObjectData%CurrentValue = 0

 IAdd_Add:	ObjectData%CurrentValue = ObjectData%CurrentValue + Operand

 IAdd_GetValue:	CurrentValue = ObjectData%CurrentValue

Save the file and from the Build menu, click Build Adder.dll to build the server. The COM server is now complete.

Build Notes

The Developer Studio project created by the Fortran AppWizard performs two additional steps not done in a typical Fortran project:

  • The build uses the MIDL compiler to compile the IDL file that describes the server. The MIDL compiler creates the server's Type library and generates C files that can be used in MIDL-based Marshalling (see Marshalling, Proxies and Stubs).

    The MIDL compiler uses the Visual C++ preprocessor by default during compilation. If the AppWizard determined that Visual C++ was not installed, it sets the MIDL options to use the Fortran preprocessor FPP instead. The options added are:

      /cpp_cmdfpp /cpp_opt  "/a /m/extend_source 132"
  • A custom build step is added to register the COM server on your system. For a DLL COM server, registration is done using the REGSVR32 program. REGSVR32 could fail if the Window system directory is not on the Developer Studio's Executables Files list. On Windows NT and Windows 2000 systems, this is the \Winnt\System32 directory. On Windows 9x systems, this is typically the \Windows\System directory. If the registration step fails, do the following:

    1. In the Tools menu, click Options.
    2. Scroll to the Directories tab.
    3. Select the Executable files from the list.
    4. Add the windows system directory at the bottom of the list of directories.
    5. Click OK

For an EXE COM server, the COM server itself is run with the /REGSERVER command-line option.

Visual C++ ClassView

If you also have Microsoft Visual C++ Version 6 installed on your system, you will notice that your server definition also appears in the Visual C++ ClassView pane. This occurs because the Visual C++ ClassView software can read and understand the IDL file created by the Fortran COM Server wizard.

Note: Do not attempt to use the Visual C++ ClassView pane to modify the your server's definition. Always use the Fortran COM Server wizard to modify classes created by the Fortran COM Server wizard.

Using Example Clients

The server is now ready to be called by any COM client. The completed Adder sample is provided in the ...Df98\Samples\Advanced\COM\Adder directory. This directory also contains three clients written in Visual Fortran, Visual Basic, and Visual C++.

To build the sample clients, first build the Adder sample. The GUIDs used by the sample COM clients work with the Adder Sample (not the GUIDs created in the example).

If you followed the example COM server AddingMachine in earlier sections (starting with Creating a Fortran COM Server Project), the AddingMachine server that you created is identical to the Adder sample except for the GUID's assigned to the AddingMachine object. The Fortran COM Server AppWizard always generates new GUIDs for a new project.

Each client displays a dialog box that provides the user interface to the Adding Machine. Below are notes on each of the clients:

  • VFAdder, the Visual Fortran client

    The VFAdder client is created using the Fortran Windows Application AppWizard. VFAdder is a simple Dialog Based Application. The main dialog box is defined to have Clear and Add buttons, an edit box to enter the addend, and a static text field that displays the current value:

    vfadder client

    The Fortran Module Wizard creates the module (AddingMachine.f90) that defines the IAdd interface methods for use from Fortran. Code is added to the beginning of the WinMain routine to initialize COM and create an AddingMachine object:

      call COMINITIALIZE(ret)
  call COMCREATEOBJECTBYGUID (CLSID_AddingMachine, CLSCTX_ALL, IID_IAdd, &
  & gAddingMachine, status)
  call Check_Status(status,  " Unable to create AddingMachine object")

    The subroutine added as the handler of the Add button (VFAdderAdd) calls the $IAdd_Add routine and the $IAdd_GetValue routine:

    !  Call the AddingMachine Add method
    lret = DlgGet(dlg, IDC_EDIT_ADDEND, text)
    read(text, *) addend
    status = $IAdd_Add(gAddingMachine, addend)
   call Check_Status(status,  " Add method returned failure status")

!  Set the Current Value text field
    status = $IAdd_GetValue(gAddingMachine, value)
    write(text, *) value
    call Check_Status(status,  " GetValue method returned failure status")
    lret = DlgSet(dlg, IDC_CURRENTVALUE, text)

    The subroutine added as the handler of the Clear button (VFAdderClear) calls the $IAdd_Clear routine in a similar way. Code is added at the end of the WinMain routine to uninitialize COM and release the AddingMachine object:

       if (gAddingMachine /= NULL) then
           ret = COMReleaseObject(gAddingMachine)
   endif
   call COMUNINITIALIZE()
  • VBAdder, the Visual Basic V6 client

    VBAdder is created from a new Standard EXE project. The form is modified to be similar to the VFAdder dialog box above. The first step in using the AddingMachine object from Visual Basic is to select the References menu item from the Project menu. Find AddingMachine 1.0 Type Library in the list and select it. Visual Basic reads the information from the type library and becomes aware of the AddingMachine object, the IAdd interface, and its methods. These will appear in the choices that the Visual Basic editor makes available to you as you enter code for the project.

    The following code is added to the VBAdder project:

    • An instance of the AddingMachine object is created by adding the following line to the General Declarations area:
      Dim Adder As New AddingMachine
    • The code for the Add button Click method is:
       Private Sub Add_Click()
    Dim Value As Single
    Adder.Add (Addend.Text)
    CurrentValue.Caption = Adder.GetValue
    Addend.Text = ""
 End Sub
    • The code for the Clear button Click method is:
       Private Sub Clear_Click()
    Adder.Clear
    CurrentValue.Caption = Adder.GetValue
 End Sub
    • The code for the Exit button Click method is:
       Private Sub Exit_Click()
    End
 End Sub
  • VCAdder, the Visual C++ V6 client

    VCAdder is created using the MFC AppWizard (exe). The Dialog based option is selected in the wizard. The dialog box controls are copied from the VFAdder dialog box and pasted into the VCAdder dialog box.

    The following statement is added to VCAdder.h in order to give the source files access to the AddingMachine object, the IAdd interface and its methods:

     #import "..\Adder.dll"

    A member variable is added to the CVCAdderApp application class to hold the pointer to the AddingMachine object:

     AddingMachineLib::IAddPtr m_pIAdd;

    Code is added to the beginning of the CVCAdderApp::InitInstance method to initialize COM and create an AddingMachine object:

        CoInitialize(NULL);
    m_pIAdd.CreateInstance(__uuidof(AddingMachineLib::AddingMachine));

    The MFC Class Wizard is used to add:

    • A member variable for the Addend edit field, m_Addend
    • A member variable for the CurrentValue static text field, m_CurrentValue
    • Member functions for the clicked message on the Add, Clear, and Exit buttons - OnAdd, OnClear, and OnExit

    OnAdd calls the Add method and the GetValue method.

     void CVCAdderDlg::OnAdd()
 {
    HRESULT hr;
    UpdateData();
    double addend = atof(m_Addend);
    hr = theApp.m_pIAdd->Add((float)addend);
    float value = theApp.m_pIAdd->GetValue();
    char buffer[32];
    sprintf(buffer, "%10.10G", value);
    m_CurrentValue = buffer;
    m_Addend = "";
    UpdateData(FALSE);
 }

    OnClear calls the Clear method and the GetValue method in a similar way.

    Code is added at the end of the CVCAdderApp::InitInstance method to release the AddingMachine object and uninitialize COM:

       m_pIAdd.Release();
    CoUninitialize();

For design considerations and notes on using Visual Basic and Visual C++ clients, see Visual Basic and Visual C++ Client Notes.

Modifying Your COM Servers

You can modify the server to change the properties of any entry in the hierarchy, add new entries to the hierarchy, move entries in the hierarchy, or remove entries from the hierarchy.

You use the same user interface of the Fortran COM Server Wizard that you used to create the COM server, simplifying any additions, deletions, or changes to your COM server definition. However, you need to pay careful attention to the following files when you modify the COM server definition:

  • View the TODO.TXT file. The TODO.TXT serves as a log of the changes you have made to the server definition. You may delete entries from TODO.TXT that are no longer useful to you. TODO.TXT is simply a text file that the wizard appends messages to.
  • New versions of the source files in the Source files folder generated by the Fortran COM Server Wizard do not overwrite existing source files, since you may have modified existing source files. New source files are in the form of the original file name with a plus sign (+) appended, such as UIADD+.f90. Use the text editor to copy-and-paste the newly generated definitions into your previously modified source code (described below), as instructed by text in the TODO.TXT file.

The Fortran COM Server Wizard regenerates the files in the Do Not Edit folder whenever the server definition changes.

To display the Fortran COM Server Wizard:

  1. Start Developer Studio
  2. Open a COM server project created by the Fortran COM Server AppWizard
  3. Click the Fortran COM Server Wizard menu item in the View menu (see Using the Fortran COM Server Wizard to Define your COM Server)

Once you have published an interface and clients are using it, COM rules state that you must not change the interface. Instead, you should create a new interface, in addition to the original one, and change the name. A common practice is to append a 2 to the name, for the second version of the interface. For example, IAdd would become IAdd2. The second version of your class should support both the original and new interfaces. Old clients continue to work using the original interface. New clients can use the new interface with the new functionality.

The new interface has a different interface ID (IID) than the original interface. The text name is for the convenience of programmers. The IID uniquely identifies the interface.

The Fortran COM Server Wizard adds messages to TODO.TXT anytime the Wizard makes a change to the project and anytime that you make a change to the server definition that requires you to manually edit one or more of the source files. For example, if you add a new method to the IAdd interface, SetValue, that sets the current value to a specific number, the Wizard generates new code to implement the new method in your server. Some of the new code is in the files in the Do Not Edit folder. The Wizard automatically changes these files.

However, a new method skeleton needs to be added to the UIADD.f90 file in the Source Files folder. The wizard never creates a new file with the same name as a file in the Source Files folder, because that would cause the edits that you have made to the files to be lost. Instead, the wizard generates a file with a plus sign (+) appended to the end of the name, for example: UIADD+.f90. The file UIADD+.f90 contains the skeleton of the new method, IAdd_SetValue. In this case, the following message is added to TODO.TXT, and TODO.TXT is opened in the Developer Studio text editor:

The file UIAdd+.f90 has been generated with the following changes.
You must merge these changes with the existing file UIAdd.f90.
The method IAdd_SetValue has been added.

You must use a text editor to copy the new method skeleton from the UIADD+.f90 file and paste it into the UIADD.f90 file.

Whenever a change is made to your server definition, "+" versions of the files in the Source Files folder are generated. You can ignore these files except when TODO.TXT informs you of an action you need to take.

Other changes that would require you to manually merge changes into your source files include:

  • Adding a new property.
  • Changing the arguments of an existing method.
  • Renaming a class, interface or method.
  • Deleting a class, interface or method.


Interface Design Considerations

This section provides information that should be considered when designing a Fortran COM server. It contains the following topics:

  • Method and Properties Data Types
  • COM Status Codes: HRESULT
  • Visual Basic and Visual C++ Client Notes

Method and Properties Data Types

COM places some restrictions on the data types used in COM methods and properties. The reason for the restrictions is that COM can pass arguments between threads, processes and machines. This raises issues that are not present in older technologies, such as DLLs, that always run in the same address space as the caller.

COM defines set of data types called Automation-compatible data types. These are the only data types that can be used in Automation and Dual interfaces. There are two advantages to restricting your COM interface to these data types:

  • Your server will be usable from clients written in the largest set of languages, including Visual Fortran, Visual Basic, and Visual C++.
  • COM will automatically handle the passing of arguments between threads, processes and machines. This is called Type Library Marshalling. For more information, see Marshalling, Proxies and Stubs in Advanced COM Server Topics.

To restrict your server to Automation-compatible data types:

  1. Select "Use only Automation data types" on the Interface property page. When defining a dual interface, this is automatically set.
  2. Use only the following combinations of "Fortran data type" and "Interface data type" on the Argument property page.

    Note that Visual Fortran does not support the Currency, Decimal, or User Defined Type, Automation-compatible data types.

Fortran Date Type | Interface Data Type
INTEGER(1) | unsigned char
INTEGER(2) | short
INTEGER(4) | long SCODE Int
INTEGER(INT_PTR_KIND()) | IUnknown* IDispatch*
REAL(4) | float
REAL(8) | double DATE
LOGICAL(2) | VARIANT_BOOL
LOGICAL(4) | long
CHARACTER(1) | unsigned char
CHARACTER(*) | BSTR
BYTE | unsigned char
TYPE(VARIANT) | VARIANT (containing one of the above types or SafeArray)

If you decide not to restrict your interface to Automation-compatible data types, the next approach is to restrict your interface to data types that can be described in the Interface Description Language (IDL).

The Fortran COM Server Wizard automatically generates the IDL file from the description of your server. The MIDL compiler compiles the IDL file into a type library. MIDL can also automatically generate the code needed handle the passing of arguments between threads, processes and machines. Note, however, that a C compiler is required to use this option. For more information, see Marshalling, Proxies and Stubs in Advanced COM Server Topics.

If you decide not to restrict your interface to IDL data types, your only remaining options are:

  • Implement Custom Marshalling - For more information, see Marshalling, Proxies and Stubs in Advanced COM Server Topics.
  • Decide that you will never use your server across apartment, thread, or process boundaries. The server will not be usable in this manner because there is no way to pass the arguments across these boundaries.

COM Status Codes: HRESULT

Each function returns a 32-bit COM status code called an HRESULT. An HRESULT is divided into fields:

  • The top bit (31) indicates whether the function succeeded or failed. The bit is set if the function failed. In Fortran, you can compare the HRESULT to < 0 as a test to see if a function failed.
  • Bits 16 to 27 contain a facility code to indicate the facility that issued the HRESULT. Microsoft pre-defines a number of facility codes for its own use. If you create your own status codes, use FACILITY_ITF. All other facility codes are reserved by Microsoft.
  • The first 16 bits, or low word, contain the error code specific to the error that occurred.

A typical HRESULT error value could be a value such as 0x80070057. The first hex digit, 8, indicates that bit 31 is set and that this is an error value. Bits 16 to 27 contain the value 7. This indicates the facility FACILITY_WIN32. The low word contains the value 0057. This is the specific code that identifies the error as E_INVALIDARG.

To view the text description that corresponds to a system HRESULT value, use the Error Lookup tool in the Compaq Visual Fortran program folder. For example, entering the value 0x80070057 retrieves the text message "The parameter is incorrect ", as shown below:

error lookup tool

You can also search for HRESULT values in the WINERROR.H file in the \VC\INCLUDE directory on the Visual Fortran CD-ROM.

A COM server can also provide extended error information through the ErrorInfo objects. See Adding Support for COM ErrorInfo Objects.

Visual Basic and Visual C++ Client Notes

To use an object from Visual Basic, you must add a "reference" to the object to the Visual Basic project. Use the References item in the Project menu to display a list of the registered objects. Select the object in the list to inform Visual Basic that you will be using the object.

Here are some points to be aware of when writing a server that can be used with Visual Basic clients:

  • Use only the Automation-compatible data types (see Method and Property Data Types).
  • Arguments to a method can be passed ByVal, ByRef, or they can be the function return value.
  • An argument to be passed ByVal, must be defined with Intent set to In.
  • An argument to be passed ByRef, must be defined with Intent set to InOut.
  • A function return value must be defined with Intent set to Out. It must have the Return Value field checked. The argument must be the final argument of the method.
  • An array is always passed as a SafeArray ByRef. Therefore it must be defined with Intent set to InOut.
  • To use an argument of the Visual Basic Boolean data type, set the Fortran data type to LOGICAL(2) and set the Interface data type to VARIANT_BOOL.

To use an object from Visual C++, use the #import directive. The syntax of the #import directive is:

  #import "filename" [attributes]
  #import <filename> [attributes]

The filename is the name of the file containing the type library information. The directive makes the information in the type library available to your source file as a set of C++ classes. See the Visual C++ documentation for additional information and examples.


Advanced COM Server Topics

Advanced topics about Fortran COM Servers described in this section include:

  • Choosing Between DLL or EXE COM Servers
  • DLL Server Surrogates
  • Discussion of Wizard Code Generation
  • Adding Support for COM ErrorInfo Objects
  • Threading Models
  • Marshalling, Proxies and Stubs
  • A Map of the Generated "Do Not Edit" Code

Choosing Between DLL or EXE COM Servers

The basic tradeoff in choosing between a DLL (in-process) COM server and an EXE (out-of-process) COM server is one of performance vs. robustness:

  • A DLL server provides the advantage of performance over an EXE server. Since the DLL server is loaded into the client's address space, there is less overhead involved in method calls. If the client code and the server object live in the same COM apartment, method calls are as efficient as DLL routine calls.
  • An EXE server provides the advantage of robustness over a DLL server. Since the server object lives in a separate address space, the object cannot be affected by client memory handling bugs, and vice-versa. If the server crashes, the client doesn't necessarily crash — as long as the client checks the results of all method calls and takes steps to recover from a "dead" object.

In addition to the tradeoff between performance and robustness, the following factors should also be considered:

  • With an EXE server, the object can run in a separate security context from the client. With a DLL server, the code of the object's methods executes using the client's access token.
  • An EXE server can be run on a remote machine using COM's distributed object support.

You can load a DLL server into a "surrogate" to gain the benefits of an EXE server. This is explained in the next section.

DLL Server Surrogates

An in-process DLL server can be run in a separate process with the help of a surrogate. A surrogate runs as a separate process, loads the DLL server, and provides all of the mechanism that allows the DLL server to act as a local server. Windows provides a standard surrogate named DLLHOST.EXE. The primary advantage of using a surrogate is fault isolation. That is, if the server crashes it does not crash the client, and vice versa. The disadvantage is performance. There is significant performance overhead in executing methods in a separate application, as opposed to in a DLL.

A DLL server is associated with a surrogate via entries in the system registry. This is done by associating the DLL server with an AppID. An AppID is a GUID. When using the standard surrogate, you can use the CLSID of a class in the DLL as the AppID, or a newly generated GUID. To generate a new GUID, use GUIDGEN.EXE in the Developer Studio Tools subdirectory:

  1. Under the HKEY_CLASSES_ROOT\CLSID\{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx} key of the class, add an AppID entry with the value of the CLSID. Using the AddingMachine class as an example, the registry key would be HKEY_CLASSES_ROOT\CLSID\{904245FC-DD6D-11D3-9835-0000F875E193} and the AppID value would be {904245FC-DD6D-11D3-9835-0000F875E193}.
  2. Under the HKEY_CLASSES_ROOT\AppID key, add a key using the AppID. Using the AddingMachine class as an example, the registry key would be HKEY_CLASSES_ROOT\AppID\{904245FC-DD6D-11D3-9835-0000F875E193}. Use the class name for the default value of the key, for example, "AddingMachine Class". Add a "DllSurrogate" entry with an empty string for the value.

To use a surrogate, the system must be running Windows 2000, Windows NT 4.0 Service Pack 2 or later, Windows 98, Windows Me, or Windows 95 with the DCOM update.

The client must request CLSCTX_LOCAL_SERVER rather than CLSCTX_INPROC_SERVER to use the surrogate rather than loading the DLL server in-process. Using a surrogate requires that the DLL server have a proxy/stub registered since the method invocations are between different processes. For information on proxies/stubs, see Marshalling, Proxies and Stubs.

It is also possible to write a custom surrogate. See the online Win32 Platform SDK documentation for information.

Discussion of Wizard Code Generation

The Wizard generates the code for your project from the files in the subdirectory of your project named project-nametemplates. The project-name.hie file contains the definition of your COM server in an undocumented text language. You should not manually edit the project-name.hie file – the Wizard does this for you.

Most of the other files in the project-nametemplates directory are templates of the source files generated for your project. These templates contain source code that is copied "as-is" to the generated sources, and embedded directives that guide the Wizard in generating the code specific to the COM server that you define. The directives use the information in the project-name.hie file. The directives are undocumented and subject to change.

When you create a new Fortran COM Server project, the AppWizard creates the project-nametemplates directory and copies the templates from the Visual Fortran COM Server Wizard templates directory, ...\Df98\Templates\COMServer.

The files in the COM Server Wizard templates directory may change with each release of Visual Fortran, but the templates in your project-nametemplates directory are never automatically updated. For example, if you create a COM server using Visual Fortran Version 6.5 and the next release of Visual Fortran (such as Version 6.5A) contains updated templates, the templates for your COM server are not automatically updated to the new 6.5A templates. If you modify the definition of your server, your project continues to use the 6.5 templates that it was created with. This has the advantage of not introducing different code into a project that you have developed and tested.

However, there are two cases where you may want to modify the templates that are used by your project:

  • A new release of Visual Fortran may contain additional features that can be used in your COM server project. Some of the new features may depend upon the new templates. These features will not be available to a pre-existing project unless you update the templates in the project-nametemplates directory. You do this by copying all of the files in the Visual Fortran COM Server Wizard templates directory ...\Df98\Templates\COMServer into the project-nametemplates directory, replacing all files with the same name. Your project will then use the new templates the next time that the definition of your server is modified and the project sources are regenerated.
  • When you want to modify the code generated by the Wizard. You may edit a template in your project-nametemplates directory. Editing code that is copied "as-is" is straight forward. Attempting to modify the embedded directives is unsupported and could cause the Wizard to fail when using the modified template. The embedded directives begin with an @ (at-sign) character. The next character determines the type of directive. The end of many directives is also delimited by an @ character followed by the matching end character for the type of directive. For example, @[ and @] are the delimiters for one type of directive.

The advantage of modifying a template is that you can customize the code generated by the Wizard. The disadvantages of modifying a template are:

  • You must be very careful not to modify a template in a manner that causes the Wizard to generate bad code or fail.
  • You will not be able to update the project templates with the templates from a new release of Visual Fortran without having to re-apply your modifications to the new templates.

Adding Support for COM ErrorInfo Objects

COM supports ErrorInfo objects to allow a server to return more complete error information than is returned in an HRESULT. An ErrorInfo object returns the contextual description of the error, the source of the error, and the interface ID of the interface that originated the error. The ErrorInfo object can also include a pointer to an entry in a help file that provides help information on dealing with the error.

To support ErrorInfo objects, your server must implement the ISupportErrorInfo interface. You can add a default implementation of this interface to your server:

  • Select the class that you want to support ErrorInfo objects in the hierarchy pane.
  • Click the right mouse button on the class to invoke the context-sensitive menu of the class and select the "Add Pre-defined Interface" menu item.
  • Select ISupportErrorInfo in the "Select an Interface" dialog box and click OK.

ISupportErrorInfo contains a single method, InterfaceSupportsErrorInfo. The default implementation returns S_OK, which is sufficient if all of the interfaces of the class support ErrorInfo objects. Otherwise, you should modify the method to test the passed in interface ID and return S_OK for those interfaces that do support ErrorInfo objects, and E_FAIL for those that do not.

When an interface that supports ErrorInfo objects is going to return an error status in HRESULT, it should also initialize an ErrorInfo object using the ICreateErrorInfo interface. See the ...\Df98\SAMPLES\ADVANCED\COM\ERRORINFO sample for an example of using ErrorInfo objects in Fortran. See the Platform SDK documentation for more information on ErrorInfo objects.

Threading Models

The Wizard supports two COM threading models for the classes that you create in a DLL COM server, Apartment and Single. The Wizard uses the Apartment threading model (also known as the Single Threaded Apartment model "STA") by default. The basic rules of the Apartment threading model are:

  • If two objects, A and B, are created in the same STA thread, and A is processing a method call, no other client can call either A or B until A completes.
  • If B is created in a different thread from A, B can accept a method call while A is still processing and vice versa.

This means that if the class shares any global data among its objects, the global data must be protected from simultaneous access using thread synchronization primitives. This is because two instances of the class could be running in different threads. However the per-object instance data, that is, the fields in the class derived-type, are protected from simultaneous access by COM mechanisms. This is true except in the case where an object calls out to another object that triggers a reentrant invocation of the first object.

A class using the Single threading model need not worry about simultaneous access to class global data, as well as per-object data. All objects of the class are created in a single thread and therefore only a single object of the class can be executing at any time.

An EXE COM server generated by the wizard is single threaded. All method invocations are serialized by the server's message queue. Therefore, with an EXE server, you need not worry about simultaneous access to class global data, as well as per-object data.

Explaining the COM threading models in detail is beyond the scope of this documentation. See the Win32 Platform SDK documentation for additional information.

Marshalling, Proxies and Stubs

COM supports the use of objects in separate processes (as when using an EXE server or a DLL surrogate), and the threading models described above, by the use of marshalling, proxies and stubs. This section presents an overview of marshalling, proxies and stubs. See the Win32 documentation for further information.

Marshalling is the process of reading the parameters for a method call and preparing them for transmission to another execution context (for example, thread, process, or machine). Marshalling is done by a proxy. From the client's perspective, a proxy has the same interface as the object itself. The proxy's job is to make the object look like an object in the same execution context as the client.

Proxies allow client code to be unconcerned about where the object actually lives. A proxy marshalls method parameters and transmits them to a stub associated with the object in the server. The stub unmarshalls the parameters and invokes the method in the server. From the server's perspective, this is no different than when it is called from a client in the same execution context. A server that is not an in-process DLL server always requires a proxy/stub pair. An in-process DLL server requires a proxy/stub pair when the client and object are in different apartments.

There are three ways to assign a proxy/stub pair to a server:

Type Library Marshalling: | If you use only Automation-compatible data types in your methods and properties, COM can automatically use the "Universal Marshaller" as the proxy/stub for the server. The Universal Marshaller uses the description of the server in the type library to decide how to marshall the parameters. This is known as type library marshalling. Using type library marshalling requires no effort on your part, other than restricting your server to Automation-compatible data types.
MIDL-based Marshalling: | Your project uses the MIDL compiler to compile the IDL description of the server into a type library. At the same time, the MIDL compiler also generates the C source code necessary to build a proxy/stub DLL for the server. You must have a C compiler to build a proxy/stub DLL from the MIDL generated code. The proxy/stub DLL is itself an in-process DLL server and needs to be registered with the system. You would need to use MIDL-based marshalling if your server uses non-Automation-compatible data types, and is used by a client in a different execution context.
Custom Marshalling: | Your server can implement its own marshalling by implementing the IMarshall interface. This approach typically involves a lot of work and is done for performance reasons.

A Map of the Generated "Do Not Edit" Code

This section presents an overview of which parts of the COM server functionality are implemented in which of the "Do Not Edit" source files generated by the wizard:

File Name | Description
server.idl | Contains the IDL description of the server. It is compiled by the MIDL compiler to produce the server's type library.
servernameglobal.f90 | Contains the global data and functions for the server.
dllmain.f90 (DLL server) | Contains the exported functions that are required of all COM Server DLLs. This includes DllMain, DLLRegisterServer, DLLUnregisterServer, DllGetClassObject, and DllCanUnloadNow.
server.def (DLL server) | Declares the exported functions for the linker.
exemain.f90 (EXE server) | Contains the main entry point of an EXE server. It also processes the command-line argument.
serverhelper.f90 | Contains helper functions for the server.
clsfactty.f90 | Contains definitions of the IClassFactory interface that is used to create instances of the classes defined by the server.
clsfact.f90 | Contains methods of the IClassFactory interface that is used to create instances of the classes defined by the server.
classnameTY.f90 | Defines a module that contains definitions of parameters and types used in the implementation of the class. It also contains the implementation of the IUnknown methods of the class. A separate instance of this file is generated for each class defined in the server.
interfacename.f90 | Defines a module that contains the Fortran interfaces of the methods in the interface. It also contains the implementation of the Fortran "wrappers" that are called directly from the class' VTBL and call the methods implemented by the user. A separate instance of this file is generated for each interface defined in the class.


Deploying the Server on Another System

When you have finished developing the COM server, you may want to deploy it on another system. Besides the server itself, you need to install the Fortran run-time DLLs and register the server:

  1. Install (or copy) the COM server to an appropriate directory.

  2. Register the server:

    • To register a DLL server, use the REGSVR32.EXE system tool, a command-line tool. To register the DLL server, specify the path to the DLL and its file name (dll_path) by typing the following command:
         REGSVR32 dll_path

      The file REGSVR32.EXE is in your system directory, such as the \Winnt\System32 on Windows NT or Windows 2000 systems or \Windows\System on Windows 9x systems. If this directory is not in your PATH, include its path before the REGSVR32 command.

    • To register a an EXE server, run the server with the /REGSERVER command-line opton. For example:
         exe_path /REGSERVER
  3. Use the VFRUN tool to install the necessary run-time DLLs and related files. The VFRUN tool provides the run-time redistributable files for Visual Fortran applications, in the form of a self-installing kit. VFRUN is described in the Compaq Visual Fortran Installing and Getting Started and in the release notes. You can download the run-time redistributable files VFRUN kit from the Visual Fortran Web page (click Downloads area):
    http://www.compaq.com/fortran

If you are using MIDL-based Marshalling or Custom Marshalling, then the marshalling DLL also needs to be installed and registered. For information on marshalling, see Marshalling, Proxies and Stubs in Advanced COM Server Topics.


Programming with Mixed Languages

Mixed-language programming is the process of building programs in which the source code is written in two or more languages. It allows you to:

  • Call existing code that is written in another language
  • Use procedures that may be difficult to implement in a particular language
  • Gain advantages in processing speeds

Mixed-language programming is possible among the 32-bit languages Visual Fortran, Visual C/C++, Visual Basic, and MASM. Mixed-language programming in Win32 is different from that in 16-bit environments, and in many respects it is easier.

To properly create mixed-language programs, rules must be established for naming variables and procedures, for stack use, and for argument passing among routines written in different languages. These rules, as a whole, are the calling convention.

A calling convention includes:

  • Stack considerations
    • Does a routine receive a varying or fixed number of arguments?
    • Which routine clears the stack after a call?
  • Naming conventions
    • Is lowercase or uppercase significant or not significant?
    • Are external names altered?
  • Argument passing protocol
    • Are arguments passed by value or by reference?
    • What are the equivalent data types and data structures among languages?

This section provides information on the calling conventions available when writing routines written in Fortran, C, Visual C++, Visual Basic, and ia32 assembly language. It is organized into the following topics:

  • Overview of Mixed-Language Issues
  • Exchanging and Accessing Data in Mixed-Language Programming
  • Handling Data Types in Mixed-Language Programming
  • Visual Fortran/Visual C++ Mixed-Language Programs
  • Fortran/Visual Basic Mixed-Language Programs
  • Fortran/MASM Mixed-Language Programs


Overview of Mixed-Language Issues

Mixed-language programming involves a call from a routine written in one language to a function, procedure, or subroutine written in another language. For example, a Fortran main program may need to execute a specific task that you want to program separately in an assembly-language procedure, or you may need to call an existing DLL or system procedure.

Mixed-language programming is possible with Visual Fortran, Visual C/C++, Visual Basic, and assembly language (MASM) because each language implements functions, subroutines, and procedures in approximately the same way. The following table shows how different kinds of routines from each language correspond to each other. For example, a C main program could call an external void function, which is actually implemented as a Fortran subroutine.

Language Equivalents for Calls to Routines

Language | Call with Return Value | Call with No Return Value
Fortran | FUNCTION | SUBROUTINE
C and Visual C++ | function | (void) function
Visual Basic | Function | Sub
Assembly language | Procedure | Procedure

There are some important differences in the way languages implement routines. Argument passing, naming conventions and other interface issues must be thoughtfully and consistently reconciled between any two languages to prevent program failure and indeterminate results. However, the advantages of mixed-language programming often make the extra effort worthwhile.

A summary of a few mixed-language advantages and restrictions follows:

  • Fortran/Assembly Language

    Assembly-language routines are small and execute very quickly because they do not require initialization as do high-level languages like Fortran and C. Also, they allow access to hardware instructions unavailable to the high-level language user. In a Fortran/assembly-language program, compiling the main routine in Fortran gives the assembly code access to Fortran high-level procedures and library functions, yet allows freedom to tune the assembly-language routines for maximum speed and efficiency. The main program can also be an assembly-language program.

  • Fortran/Visual Basic

    A mix of Fortran and Visual Basic 4.0 or higher (32-bit) allows you to use the easy-to-implement user-interface features of Visual Basic, yet do all your computation, especially floating-point math, in Fortran routines. In a Fortran/Visual Basic program, the main routine must be Visual Basic. It is not possible to call Basic routines from Fortran. You can call Visual Basic routines as callbacks, but the main program must be Visual Basic.

  • Fortran/C (or C++)

    Generally, Fortran/C programs are mixed to allow one to use existing code written in the other language. Either Fortran or C can call the other, so the main routine can be in either language.

    To use the same Microsoft visual development environment for multiple languages, you must have the same version of the visual development environment for your languages (see Mixed-Language Development Support in Compaq Visual Fortran Installing and Getting Started).

This section provides an explanation of the keywords, attributes, and techniques you can use to reconcile differences between Fortran and other languages. Adjusting calling conventions, adjusting naming conventions and writing interface procedures are discussed in the next sections:

  • Adjusting Calling Conventions in Mixed-Language Programming
  • Adjusting Naming Conventions in Mixed-Language Programming
  • Prototyping a Procedure in Fortran

After establishing a consistent interface between mixed-language procedures, you then need to reconcile any differences in the treatment of individual data types (strings, arrays, and so on). This is discussed in Exchanging and Accessing Data in Mixed-Language Programming .

Note: This section uses the term "routine" in a generic way, to refer to functions, subroutines, and procedures from different languages.


Adjusting Calling Conventions in Mixed-Language Programming

The calling convention determines how a program makes a call to a routine, how the arguments are passed, and how the routines are named (discussed in the section on Adjusting Naming Conventions in Mixed-Language Programming). In a single-language program, calling conventions are nearly always correct, because there is one default for all routines and because header files or Fortran module files with interface blocks enforce consistency between the caller and the called routine.

In a mixed-language program, different languages cannot share the same header files. If, as a result, you link Fortran and C routines that use different calling conventions, the error is not apparent until the bad call is made at run-time. During execution, the bad call causes indeterminate results and/or a fatal error, often somewhere in the program that has no apparent relation to the actual cause: memory/stack corruption due to calling errors. Therefore, you should check carefully the calling conventions for each mixed-language call.

The discussion of calling conventions between languages applies only to external procedures. You cannot call internal procedures from outside the program unit that contains them.

A calling convention affects programming in five ways:

  1. The caller routine uses a calling convention to determine the order in which to pass arguments to another routine; the called routine uses a calling convention to determine the order in which to receive the arguments passed to it. In Fortran, you can specify these conventions in a mixed-language interface with the INTERFACE statement or in a data or function declaration. 32-bit Visual C/C++ and Fortran both pass arguments in order from left to right.
  2. The caller routine and the called routine use a calling convention to determine which of them is responsible for adjusting the stack in order to remove arguments when the execution of the called routine is complete. You can specify these conventions with ATTRIBUTES (c DEC$ ATTRIBUTES compiler directive) options such as C or STDCALL.
  3. The caller routine and the called routine use a calling convention to select the option of passing a variable number of arguments.
  4. The caller routine and the called routine use a calling convention to pass arguments by value (values passed) or by reference (addresses passed). Individual Fortran arguments can also be designated with ATTRIBUTES option VALUE or REFERENCE.
  5. The caller routine and the called routine use a calling convention to establish naming conventions for procedure names. You can establish any procedure name you want, regardless of its Fortran name, with the ALIAS directive (or ATTRIBUTES option ALIAS). This is useful because C anmd Basic are case sensitive, while Fortran is not.

Specific calling-convention issues are discussed in the following sections:

  • ATTRIBUTES Properties and Calling Conventions
  • Stack Considerations in Calling Conventions
  • Fortran/C Calling Conventions
  • Fortran/Visual Basic Calling Conventions
  • Fortran/MASM Calling Conventions


ATTRIBUTES Properties and Calling Conventions

The ATTRIBUTES properties (or options) C, STDCALL, REFERENCE, VALUE, and VARYING all affect the calling convention of routines. You can specify:

  • The C, STDCALL, REFERENCE, and VARYING properties for an entire routine.
  • The VALUE and REFERENCE properties for individual arguments.

By default, Fortran passes all data by reference (except the hidden length argument of strings, which is passed by value). If the C or STDCALL option is used, the default changes to passing almost all data except arrays by value. However, in addition to the calling-convention options C and STDCALL, you can specify argument options, VALUE and REFERENCE, to pass arguments by value or by reference, regardless of the calling convention option. Arrays can only be passed by reference.

Different Fortran calling conventions can be specified by declaring the Fortran procedure to have certain attributes. For example, on ia32 systems:

   INTERFACE
      SUBROUTINE MY_SUB (I)
          !DEC$ ATTRIBUTES C, ALIAS:'_My_Sub' :: MY_SUB   ! ia32 systems
          INTEGER I
      END SUBROUTINE MY_SUB
   END INTERFACE

This code (on ia32 systems) declares a subroutine named MY_SUB with the C property and the external name _My_Sub set with the ALIAS property.

On ia64 systems, there is no leading underscore for external names like MY_SUB, so the correct !DEC$ ATTRIBUTES line is:

      !DEC$ ATTRIBUTES C, ALIAS:'My_Sub' :: MY_SUB  ! ia64 systems

To write code for both ia32 and ia64 platforms, use the conditional compilation features of the IF Directive Construct, perhaps using the predefined preprocessor macros listed under the /define option (such as _M_IX86 and _M_IA64).

The following table summarizes the effect of the most common Fortran calling-convention directives.

Calling Conventions for ATTRIBUTES Options
Default C STDCALL C, REFERENCE STDCALL, REFERENCE
Argument
Scalar | Reference | Value | Value | Reference | Reference
Scalar [value] | Value | Value | Value | Value | Value
Scalar [reference] | Reference | Reference | Reference | Reference | Reference
String | Reference, either Len:Mixed or Len:End | String(1:1) | String(1:1) | Reference, either Len:Mixed or Len:End | Reference, either Len:Mixed or Len:End
String [value] | Error | String(1:1) | String(1:1) | String(1:1) | String(1:1)
String [reference] | Reference, either Len:Mixed or No Len | Reference, No Len | Reference, No Len | Reference, No Len | Reference, No Len
Array | Reference | Reference | Reference | Reference | Reference
Array [value] | Error | Error | Error | Error | Error
Array [reference] | Reference | Reference | Reference | Reference | Reference
Derived Type | Reference | Value, size dependent | Value, size dependent | Reference | Reference
Derived Type [value] | Value, size dependent | Value, size dependent | Value, size dependent | Value, size dependent | Value, size dependent
Derived Type [reference] | Reference | Reference | Reference | Reference | Reference
F90 Pointer | Descriptor | Descriptor | Descriptor | Descriptor | Descriptor
F90 Pointer [value] | Error | Error | Error | Error | Error
F90 Pointer [reference] | Descriptor | Descriptor | Descriptor | Descriptor | Descriptor
Procedure Name
Suffix | @n (ia32 systems) | none | @n (ia32 systems) | none | @n (ia32 systems)
Case | Upper Case | Lower Case | Lower Case | Lower Case | Lower Case
Stack Cleanup | Callee | Caller | Callee | Caller | Callee

The terms in the above table mean the following:

[value] | Argument assigned the VALUE attribute.
[reference] | Argument assigned the REFERENCE attribute.
Value | The argument value is pushed on the stack. All values are padded to the next 4-byte boundary.
Reference On ia32 systems, the 4-byte argument address is pushed on the stack.
On ia64 systems, the 8-byte argument address is pushed on the stack.
Len:Mixed or Len:End For certain string arguments:
  • Len:Mixed applies when /iface:mixed_str_len_arg is set. The length of the string is pushed (by value) on the stack immediately after the address of the beginning of the string.
  • Len:End applies when /iface:nomixed_str_len_arg is set. The length of the string is pushed (by value) on the stack after all of the other arguments.
Len:Mixed or No Len For certain string arguments:
  • Len:Mixed applies when /iface:mixed_str_len_arg is set. The length of the string is pushed (by value) on the stack immediately after the address of the beginning of the string.
  • No Len applies when /iface:nomixed_str_len_arg is set. The length of the string is not available to the called procedure.
No Len | For string arguments, the length of the string is not available to the called procedure.
String(1:1) | For string arguments, the first character is converted to INTEGER(4) as in ICHAR(string(1:1)) and pushed on the stack by value.
Error | Produces a compiler error.
Descriptor On ia32 systems, the 4-byte address of the array descriptor.
On ia64 systems, the 8-byte address of the array descriptor.
@n | On ia32 systems, the at sign (@) followed by the number of bytes (in decimal) required for the argument list.
Size dependent On ia32 systems, derived-type arguments specified by value are passed as follows:
  • Arguments from 1 to 4 bytes are passed by value.
  • Arguments from 5 to 8 bytes are passed by value in two registers (two arguments).
  • Arguments more than 8 bytes provide value semantics by passing a temporary storage address by reference.
Upper Case | Procedure name in all uppercase.
Lower Case | Procedure name in all lowercase.
Callee | The procedure being called is responsible for removing arguments from the stack before returning to the caller.
Caller | The procedure doing the call is responsible for removing arguments from the stack after the call is over.

The following table shows which Fortran ATTRIBUTES options match other language calling conventions.

Matching Calling Conventions

Other Language Calling Convention | Matching ATTRIBUTES Option
Visual C/C++ cdecl (default) | C
Visual C/C++ __stdcall | STDCALL
Visual Basic | none
Visual Basic CDECL keyword | C
MASM C (in PROTO and PROC declarations) | C
MASM STDCALL (in PROTO and PROC declarations) | STDCALL

The ALIAS option can be used with any other Fortran calling-convention option to preserve mixed-case names. You can also use the DECORATE option with ALIAS option so the external name specified in ALIAS has prefix and postfix decorations performed on it that are associated with the calling mechanism that is in effect.

Note: When interfacing to the Windows graphical user interface or making API calls, you will typically use STDCALL. See Creating Windows Applications for more information on Windows programming.


Stack Considerations in Calling Conventions

In the C calling convention, the calling routine always adjusts the stack immediately after the called routine returns control. This produces slightly larger object code because the code that restores the stack must exist at every point a procedure is called. In the STDCALL calling convention, the called procedure controls the stack. The code to restore the stack resides in the called procedure, so the code needs to appear only once.

However, the C calling convention makes calling with a variable number of arguments possible. Since in the C calling convention the caller cleans up the stack, it is possible to write a routine with a variable number of arguments. Therefore, it has the same address relative to the frame pointer, regardless of how many arguments are actually passed. Because of this, when the calling routine controls the stack, it knows how many arguments it passed, how big they are and where they reside in the stack. It can thus skip passing an argument and still keep track.

You can call routines with a variable number of arguments by including the ATTRIBUTES C and VARYING options in your interface to a routine. The VARYING option prevents Fortran from enforcing a matching number of arguments in routines. The VARYING option is not necessary with intrinsic Fortran 90 routines with optional arguments, where argument order and/or keywords determine which arguments are present and which are absent.

In MASM, stack control is also set by the C or STDCALL convention declared for the procedure, but you can write MASM code to control the stack within the procedure any way you wish. In addition, you can specify the USES option in the PROC directive to save and restore certain registers automatically.


Fortran/C Calling Conventions

In C and Visual C++ modules, you can specify the STDCALL calling convention by using the __stdcall keyword in a function prototype or definition. The __stdcall convention is also used by window procedures and API functions. As an example, the following C language prototype sets up a function call to a subroutine using the STDCALL calling convention:

  extern void __stdcall FORTRAN_ROUTINE (int n);

Alternatively, instead of changing the calling convention of the C code, you can adjust the Fortran source code by using the C option. This is set with the ATTRIBUTES directive. For example, the following declaration assumes the subroutine is called with the C calling convention:

  SUBROUTINE CALLED_FROM_C (A)
     !DEC$ ATTRIBUTES C :: CALLED_FROM_C
     INTEGER A


Fortran/Visual Basic Calling Conventions

You establish Fortran subroutines and functions in Visual Basic forms and the Fortran routines are then invoked from a Basic module. A Fortran routine has to be a DLL (dynamic-link library) to be called from Basic. For more information on DLLs, see Fortran Dynamic-Link Library Projects and Creating Fortran DLLs.

The calling-convention ALIAS directive (or ATTRIBUTES property ALIAS) is needed if mixed-case names are to be preserved (by default Fortran translates names to all uppercase). However, two special cases require different treatment:

  • If a varying number of arguments are to be passed, the C and VARYING properties are needed in the Fortran procedure definition and the CDECL keyword needed in the Basic DECLARE statement in order to establish the C calling and naming convention.
  • When passing character arguments, the Fortran routine must not pass the hidden length of character arguments, such as by using the ATTRIBUTES property STDCALL for the routine and specifying the REFERENCE property for any character arguments. Since STDCALL also lowercases Fortran names, the Fortran subprogram name should be referenced in lowercase from the Visual Basic program.

The following Fortran and Visual Basic statements establish an example Fortran function to be called from Basic:

!  Fortran Subprogram establishing Fortran function.
       INTERFACE
          DOUBLE PRECISION FUNCTION GetFVal (r1)
             !DEC$ ATTRIBUTES ALIAS:'GetFVal' :: GetFVal
             !DEC$ ATTRIBUTES VALUE :: r1
             REAL r1
          END FUNCTION
       END INTERFACE

'FORM.FRM Basic Form to establish Fortran function
Declare Function GetFVal Lib "C:\f90\FVAL.DLL" (ByVal r1 As Single) As Double


Fortran/MASM Calling Conventions

You specify the calling convention for a MASM procedure in the PROTO and PROC directives. The STDCALL option in the PROTO and PROC directives tells the procedure to use the STDCALL calling convention. The C option in the PROTO and PROC directives tells the procedure to use the C calling convention. The USES option in the PROC directive specifies which registers to save and restore in the called MASM routine. The VARARG option to the PROTO and PROC directives specifies that the procedure allows a variable number of arguments.

For example, the following Fortran and MASM statements set up a MASM function that can be called from Visual Fortran, using the STDCALL calling convention:

 ! Fortran STDCALL interface prototype.
      INTERFACE
         INTEGER FUNCTION forfunc(I1, I2)
         !DEC$ ATTRIBUTES STDCALL :: forfunc
         INTEGER I1
         INTEGER(2) I2
      END INTERFACE
      WRITE (*,*) forfunc(I1,I2)
 ! End Fortran STDCALL interface

 ;MASM STDCALL Prototype
          .MODEL FLAT, STDCALL
 forfunc PROTO STDCALL, forint: SDWORD, shorti: ptr SWORD
          .CODE
 forfunc PROC STDCALL, forint: SDWORD, shorti: ptr SWORD
          ...
 forfunc ENDP END

The following Fortran and MASM statements set up a Fortran-callable MASM function using the C calling convention:

 ! Fortran C interface prototype
      INTERFACE
         INTEGER FUNCTION Forfunc (I1, I2)
         !DEC$ ATTRIBUTES C, ALIAS:'Forfunc' :: Forfunc
         INTEGER I1
         INTEGER(2) I2
      END INTERFACE
      WRITE(*,*) Forfunc (I1, I2)
      END
 ! End Fortran C interface

 ;MASM C PROTOTYPE
         .MODEL FLAT, C
  Forfunc PROTO C, forint:SDWORD, shorti: ptr SWORD
         .CODE
  Forfunc PROC C, forint:SDWORD, shorti: ptr SWORD
         ...
  Forfunc ENDP END


Adjusting Naming Conventions in Mixed-Language Programming

The ATTRIBUTES options C and STDCALL determine naming conventions as well as calling conventions. Calling conventions specify how arguments are moved and stored; naming conventions specify how symbol names are altered when placed in an .OBJ file. Names are an issue for external data symbols shared among parts of the same program as well as among external routines. Symbol names (such as the name of a subroutine) identify a memory location that must be consistent among all calling routines.

Parameter names (names given in a procedure definition to variables that are passed to it) are never affected.

Names are altered because of case sensitivity (in C, Visual Basic, and MASM), lack of case sensitivity (in Fortran), name decoration (in Visual C++), or other issues. If naming conventions are not reconciled, the program cannot successfully link and you will receive an "unresolved external" error.

This section discusses:

  • Visual C/C++ and Visual Basic Naming Conventions
  • MASM Naming Conventions
  • Naming Conventions for Fortran, C, Visual C++, Visual Basic, and MASM
  • Reconciling the Case of Names
  • Fortran Module Names and ATTRIBUTES


Visual C/C++ and Visual Basic Naming Conventions

Visual C/C++ and Visual Basic preserve case sensitivity in their symbol tables while Fortran by default does not, a difference that requires attention. Fortunately, you can use the Fortran directive ATTRIBUTES ALIAS option to resolve discrepancies between names, to preserve mixed-case names, or to override the automatic conversion of names to all uppercase by the Fortran default naming, or the automatic conversion to all lowercase by Fortran's STDCALL and C naming convention.

Visual C++ uses the same calling convention and argument-passing techniques as C, but naming conventions are different because of Visual C++ decoration of external symbols. When the C++ code resides in a .cpp file (created when you select C/C++ file from the visual development environment), C++ name decoration semantics are applied to external names, often resulting in linker errors. The extern "C" syntax makes it possible for a Visual C++ module to share data and routines with other languages by causing Visual C++ to drop name decoration.

The following example declares prn as an external function using the C naming convention. This declaration appears in Visual C++ source code:

  extern "C" { void prn(); }

To call functions written in Fortran, declare the function as you would in C and use a "C" linkage specification. For example, to call the Fortran function FACT from Visual C++, declare it as follows:

  extern "C" { int __stdcall FACT( int n ); }

The extern "C" syntax can be used to adjust a call from Visual C++ to other languages, or to change the naming convention of Visual C++ routines called from other languages. However, extern "C" can only be used from within Visual C++. If the Visual C++ code does not use extern "C" and cannot be changed, you can call Visual C++ routines only by determining the name decoration and generating it from the other language. Such an approach should only be used as a last resort, because the decoration scheme is not guaranteed to remain the same between versions.

Use of extern "C" has some restrictions:

  • You cannot declare a member function with extern "C".
  • You can specify extern "C" for only one instance of an overloaded function; all other instances of an overloaded function have Visual C++ linkage.

For more information on the extern "C" linkage specification, see the Microsoft Visual C++ Language Reference.


MASM Naming Conventions

In MASM (Microsoft Assembler, for ia32 systems), specifying the C or STDCALL naming convention in PROC and PROTO statements preserves case sensitivity if no CASEMAP option exists. The MASM OPTION CASEMAP directive (and the command line option /C) also sets case sensitivity and overrides naming conventions specified within PROTO and PROC statements:

  • CASEMAP: NONE (equivalent to /Cx) preserves the case of identifiers in PUBLIC, COMM, EXTERNDEF, EXTERN, PROTO, and PROC declarations.
  • CASEMAP: NOTPUBLIC (equivalent to /Cp) preserves the case of all user identifiers; this is the default.
  • CASEMAP: ALL (equivalent to /Cu) translates all identifiers to uppercase.


Naming Conventions for Fortran, C, Visual C++, Visual Basic, and MASM

The following table summarizes how Fortran, Visual C/C++, Visual Basic and MASM handle procedure names. Note that for MASM, the table does not apply if the CASEMAP: ALL option is used.

Naming Conventions in Fortran, C, Visual C++, Visual Basic, and MASM

Language | Attributes | Name Translated As | Case of Name in .OBJ File
Fortran | c DEC$ ATTRIBUTES C | _name | All lowercase
Fortran | c DEC$ ATTRIBUTES STDCALL | _name@n | All lowercase
Fortran | default | _name@n | All uppercase
C | cdecl (default) | _name | Mixed case preserved
C | __stdcall | _name@n | Mixed case preserved
Visual C++ | Default | _name@@decoration | Mixed case preserved
Visual Basic | Default | _name@n | Mixed case preserved
MASM | C (in PROTO and PROC declarations) | _name | Mixed case preserved
MASM | STDCALL (in PROTO and PROC declarations) | _name@n | Mixed case preserved

In the preceding table:

  • The leading underscore (such as _name) is used on ia32 systems only (not on ia64 systems).
  • @n represents the stack space, in decimal notation, occupied by parameters on ia32 only (not on ia64 systems).

For example, assume a function is declared in C as:

  extern int __stdcall Sum_Up( int a, int b, int c );

Each integer occupies 4 bytes, so the symbol name placed in the .OBJ file on ia32 systems is:

  _Sum_Up@12

On ia64 systems, the symbol name placed in the .OBJ file is:

  Sum_Up


Reconciling the Case of Names

The following summarizes how to reconcile names between languages:

  • All-Uppercase Names

    If you call a Fortran routine that uses Fortran defaults and cannot recompile the Fortran code, then in C and Visual Basic you must use an all-uppercase name to make the call. In MASM you must either use an all-uppercase name or set the OPTION CASEMAP directive to ALL, which translates all identifiers to uppercase. Use of the __stdcall convention in C code or STDCALL in MASM PROTO and PROC declarations is not enough, because __stdcall and STDCALL always preserve case in these languages. Fortran generates all-uppercase names by default and the C or MASM code must match it.

    For example, these prototypes establish the Fortran function FFARCTAN(angle) where the argument angle has the ATTRIBUTES VALUE property:

    • In C:
       extern float __stdcall FFARCTAN( float angle );
    • In Visual Basic:
        Declare Function FFARCTAN Lib "C:\f90ps\FBAS.DLL" (ByVal angle As Single) As Single
    • In MASM:
       .MODEL FLAT, STDCALL
 FFARCTAN PROTO STDCALL, angle: REAL4
 ...
 FFARCTAN PROC STDCALL, angle: REAL4
  • All-Lowercase Names

    If the name of the routine appears as all lowercase in C or MASM, then naming conventions are automatically correct when the C or STDCALL option is used in the Fortran declaration. Any case may be used in the Fortran source code, including mixed case since the C and STDCALL options change the name to all lowercase. You cannot call a Visual Basic routine from Fortran directly (see Fortran/Visual Basic Mixed-Language Programs), so Basic routine names are never translated.

  • Mixed-Case Names

    If the name of a routine appears as mixed-case in C or MASM and you cannot change the name, then you can resolve this naming conflict by using the Fortran ATTRIBUTES ALIAS option. ALIAS is required in this situation because otherwise Fortran will not preserve the mixed-case name.

    To use the ALIAS option, place the name in quotation marks exactly as it is to appear in the .OBJ file. The following is an example on ia32 systems for referring to the C function My_Proc:

      !DEC$ ATTRIBUTES ALIAS:'_My_Proc' :: My_Proc

    On ia64 systems, this would be coded without the leading underscore as:

      !DEC$ ATTRIBUTES ALIAS:'My_Proc' :: My_Proc


Fortran Module Names and ATTRIBUTES

Fortran module entities (data and procedures) have external names that differ from other external entities. Module names use the convention:

_MODULENAME_mp_ENTITY [ @stacksize ]

MODULENAME is the name of the module and is all uppercase by default. ENTITY is the name of the module procedure or module data contained within MODULENAME. ENTITY is also uppercase by default. _mp_ is the separator between the module and entity names and is always lowercase.

For example:

    MODULE mymod
       INTEGER a
    CONTAINS
       SUBROUTINE b (j)
          INTEGER j
       END SUBROUTINE
    END MODULE

This results in the following symbols being defined in the compiled .OBJ file on ia32 systems:

  _MYMOD_mp_A
  _MYMOD_mp_B@4

Or, on ia64 systems:

  MYMOD_mp_A
  MYMOD_mp_B

Compiler options can affect the naming of module data and procedures.

Note: Except for ALIAS, ATTRIBUTES options do not affect the module name, which remains uppercase.

The following table shows how each ATTRIBUTES option affects the subroutine in the previous example module.

Effect of ATTRIBUTES options on Fortran Module Names

ATTRIBUTES Option Given to Routine 'b' | Procedure Name in .OBJ file on ia32 Systems | Procedure Name in .OBJ file on ia64 Systems
None | _MYMOD_mp_B@4 | MYMOD_mp_B
C | _MYMOD_mp_b | MYMOD_mp_b
STDCALL | _MYMOD_mp_b@4 | MYMOD_mp_b
ALIAS | Overrides all others, name as given in the alias | Overrides all others, name as given in the alias
VARYING | No effect on name | No effect on name

You can write code to call Fortran modules or access module data from other languages. As with other naming and calling conventions, the module name must match between the two languages. Generally, this means using the C or STDCALL convention in Fortran, and if defining a module in another language, using the ALIAS option to match the name within Fortran. Examples are given in the section Using Modules in Mixed-Language Programming.


Protoyping a Procedure in Fortran

Prototyping a Procedure in Fortran

You define a prototype (interface block) in your Fortran source code to tell the Fortran compiler which language conventions you want to use for an external reference. The interface block is introduced by the INTERFACE statement. See Program Units and Procedures, for a more detailed description of the INTERFACE statement.

The general form for the INTERFACE statement is:

INTERFACE
routine statement
[routine ATTRIBUTE options]
[argument ATTRIBUTE options]
formal argument declarations
END routine name
END INTERFACE

The routine statement defines either a FUNCTION or a SUBROUTINE, where the choice depends on whether a value is returned or not, respectively. The optional routine ATTRIBUTE options (such as C and STDCALL) determine the calling, naming, and argument-passing conventions for the routine in the prototype statement. The optional argument ATTRIBUTE options (such as VALUE and REFERENCE) are properties attached to individual arguments. The formal argument declarations are Fortran data type declarations. Note that the same INTERFACE block can specify more than one procedure.

For example, suppose you are calling a C function that has the following prototype:

  extern void My_Proc (int i);

The Fortran call to this function should be declared with the following INTERFACE block on ia32 systems:

  INTERFACE
     SUBROUTINE my_Proc (I)
      !DEC$ ATTRIBUTES C, ALIAS:'_My_Proc' :: my_Proc
      INTEGER I
     END SUBROUTINE my_Proc
  END INTERFACE

Note that:

  • On ia64 systems, the leading underscore in _My_Proc should be omitted. The ATTRIBUTES line on ia64 systems contains:
       !DEC$ ATTRIBUTES C, ALIAS:'My_Proc' :: my_Proc
  • Except in the ALIAS string, the case of My_Proc in the Fortran program does not matter.


Exchanging and Accessing Data in Mixed-Language Programming

You can use several approaches to sharing data between mixed-language routines, which can be used within the individual languages as well. These approaches are:

  • Passing Arguments in Mixed-Language Programming
  • Using Modules in Mixed-Language Programming
  • Using Common External Data in Mixed-Language Programming

Generally, if you have a large number of parameters to work with or you have a large variety of parameter types, you should consider using modules or external data declarations. This is true when using any given language, and to an even greater extent when using mixed languages.


Passing Arguments in Mixed-Language Programming

You can pass data between Fortran and C, Visual C++, Visual Basic, and MASM through calling argument lists just as you can within each language (for example, the argument list a, b and c in CALL MYSUB(a,b,c)). There are two ways to pass individual arguments:

  • By value, which passes the argument's value.
  • By reference, which passes the address of the arguments. On ia32 systems, Fortran, Visual Basic, C, and Visual C++ use 4-byte addresses. On ia64 systems, Fortran uses 8-byte addresses.

You need to make sure that for every call, the calling program and the called routine agree on how each argument is passed. Otherwise, the called routine receives bad data.

The Fortran technique for passing arguments changes depending on the calling convention specified. By default, Fortran passes all data by reference (except the hidden length argument of strings, which is passed by value).

If the ATTRIBUTES C or STDCALL option is used, the default changes to passing all data by value except arrays. If the procedure has the REFERENCE option as well as the C or STDCALL option, all arguments by default are passed by reference.

In Fortran, in addition to establishing argument passing with the calling-convention options C and STDCALL, you can specify argument options, VALUE and REFERENCE, to pass arguments by value or by reference. In mixed-language programming, it is a good idea to specify the passing technique explicitly rather than relying on defaults.

Note: In addition to ATTRIBUTES, the compiler option /iface also establishes some default argument passing conventions (such as for hidden length of strings).

Examples of passing by reference and value for C, Visual Basic and MASM follow. All are interfaces to the example Fortran subroutine TESTPROC below. The definition of TESTPROC declares how each argument is passed. The REFERENCE option is not strictly necessary in this example, but using it makes the argument's passing convention conspicuous.

    SUBROUTINE TESTPROC( VALPARM, REFPARM )
       !DEC$ ATTRIBUTES VALUE :: VALPARM
       !DEC$ ATTRIBUTES REFERENCE :: REFPARM
       INTEGER VALPARM
       INTEGER REFPARM
    END SUBROUTINE
  • Fortran/C example of arguments passed by value and reference

    In C and Visual C++ all arguments are passed by value, except arrays, which are passed by reference to the address of the first member of the array. Unlike Fortran, C and Visual C++ do not have calling-convention directives to affect the way individual arguments are passed. To pass non-array C data by reference, you must pass a pointer to it. To pass a C array by value, you must declare it as a member of a structure and pass the structure. The following C declaration sets up a call to the example Fortran TESTPROC subroutine:

      extern void __stdcall TESTPROC( int ValParm, int *RefParm );
  • Fortran/Visual Basic example of arguments passed by value and reference

    In Visual Basic, arguments are passed by reference by default. To pass arguments by value, you use the keyword BYVAL in front of the argument in the DECLARE statement. For example:

      Declare Sub TESTPROC Lib "C:\f90\TESTPROC.DLL"

      (ByVal Valparm As Long, Refparm As Long)

    Strings are a special case (see the discussion on character strings in Handling Character Strings).

    Arrays of numbers require special handling (see data type considerations in Calling Visual Fortran from Visual Basic.

  • Fortran/MASM example of arguments passed by value and reference

    In MASM, arguments are passed by value by default. Arguments to be passed by reference are designated with PTR in the PROTO and PROC directives. For example:

      TESTPROC PROTO STDCALL, valparm: SDWORD, refparm: PTR SDWORD

    To use an argument passed by value, use the value of the variable. For example:

       mov eax, valparm ; Load value of argument

    This statement places the value of valparm into the EAX register.

    To use an argument passed by reference, use the address of the variable. For example:

       mov ecx, refparm ; Load address of argument
   mov eax, [ecx]   ; Load value of argument

    These statements place the value of refparm into the EAX register.

The following table summarizes how to pass arguments by reference and value. An array name in C is equated to its starting address because arrays are normally passed by reference. You can assign the REFERENCE property to a procedure, as well as to individual arguments.

Passing Arguments by Reference and Value

Language | ATTRIBUTE | Argument Type | To Pass by Reference | To Pass by Value
Fortran | Default | Scalars and derived types | Default | VALUE option
 | C or STDCALL option | Scalars and derived types | REFERENCE option | Default
 | Default | Arrays | Default | Cannot pass by value
 | C or STDCALL option | Arrays | Default | Cannot pass by value
Visual C/C++ |  | Non-arrays | Pointer argument_name | Default
 |  | Arrays | Default | Struct {type} array_name
Visual Basic |  | All types | Default | ByVal
Assembler (ia32) MASM |  | All types | PTR | Default

This table does not describe argument passing of strings and Fortran 95/90 pointer arguments in Visual Fortran, which are constructed differently than other arguments. By default, Fortran passes strings by reference along with the string length. String length placement depends on whether the compiler option /iface:mixed_str_len_arg (immediately after the address of the beginning of the string) or /iface:nomixed_str_len_arg (after all arguments) is set.

Fortran 95/90 array pointers and assumed-shape arrays are passed by passing the address of the array descriptor.

For a discussion of the effect of attributes on passing Fortran 95/90 pointers and strings, see Handling Fortran 90 Pointers and Allocatable Arrays and Handling Character Strings.


Using Modules in Mixed-Language Programming

Modules are the simplest way to exchange large groups of variables with C, because Visual Fortran modules are directly accessible from Visual C/C++. The following example declares a module in Fortran, then accesses its data from C. The Fortran code:

 ! F90 Module definition
     MODULE EXAMP
        REAL A(3)
        INTEGER I1, I2
        CHARACTER(80) LINE
        TYPE MYDATA
           SEQUENCE
           INTEGER N
           CHARACTER(30) INFO
        END TYPE MYDATA
     END MODULE EXAMP

The C code:

  \* C code accessing module data *\
  extern float EXAMP_mp_A[3];
  extern int EXAMP_mp_I1, EXAMP_mp_I2;
  extern char EXAMP_mp_LINE[80];
  extern struct {
             int N;
             char INFO[30];
  } EXAMP_mp_MYDATA;

When the C++ code resides in a .cpp file (created when you select C/C++ file from the visual development environment), C++ semantics are applied to external names, often resulting in linker errors. In this case, use the extern "C" syntax (see Visual C/C++ and Visual Basic Naming Conventions):

  \* C code accessing module data in .cpp file*\
  extern "C" float EXAMP_mp_A[3];
  extern "C" int EXAMP_mp_I1, EXAMP_mp_I2;
  extern "C" char EXAMP_mp_LINE[80];
  extern "C" struct {
             int N;
             char INFO[30];
  } EXAMP_mp_MYDATA;

You can also define a module procedure in C and make that routine part of a Fortran module by using the ALIAS directive. The C code:

   // C procedure
  void pythagoras (float a, float b, float *c)
  {
      *c = (float) sqrt(a*a + b*b);
  }

Using the same example when the C++ code resides in a .cpp file, use the extern "C" syntax (see Visual C/C++ and Visual Basic Naming Conventions):

  // C procedure
  extern "C" void pythagoras (float a, float b, float *c)
  {
      *c = (float) sqrt(a*a + b*b);
  }

The Fortran code to define the module CPROC:

   ! Fortran 95/90 Module including procedure
      MODULE CPROC
         INTERFACE
            SUBROUTINE PYTHAGORAS (a, b, res)
             !DEC$ ATTRIBUTES C :: PYTHAGORAS
             !DEC$ ATTRIBUTES REFERENCE :: res
  ! res is passed by REFERENCE because its individual attribute
  ! overrides the subroutine's C attribute
               REAL a, b, res
  ! a and b have the VALUE attribute by default because
  ! the subroutine has the C attribute
            END SUBROUTINE
         END INTERFACE
      END MODULE

The Fortran code to call this routine using the module CPROC:

   ! Fortran 95/90 Module including procedure
      USE CPROC
         CALL PYTHAGORAS (3.0, 4.0, X)
         TYPE *,X
      END


Using Common External Data in Mixed-Language Programming

Common external data structures include Fortran common blocks, and C structures and variables that have been declared global or external. All of these data specifications create external variables, which are variables available to routines outside the routine that defines them.

This section applies only to Fortran/C and Fortran/MASM mixed-language programs because there is no way to share common data with Visual Basic. You must pass all data between Visual Basic and Fortran as arguments. This process can be streamlined by passing user-defined types between them, described in Handling User-Defined Types.

External variables are case sensitive, so the cases must be matched between different languages, as discussed in the section on naming conventions. Common external data exchange is described in the following sections:

  • Using Global Variables
  • Using Fortran Common Blocks and C Structures

Using Global Variables in Mixed-Language Programming

A variable can be shared between Fortran and C or MASM by declaring it as global (or COMMON) in one language and accessing it as an external variable in the other language. Visual Basic cannot access another language's global data or share its own. In Fortran/Basic programs, variables must be passed as arguments.

In Fortran, a variable can access a global parameter by using the EXTERN option for ATTRIBUTES. For example:

    !DEC$ ATTRIBUTES C, EXTERN :: idata
    INTEGER idata (20)

EXTERN tells the compiler that the variable is actually defined and declared global in another source file. If Fortran declares a variable external with EXTERN, the language it shares the variable with must declare the variable global.

In C, a variable is declared global with the statement:

  int idata[20]; // declared as global (outside of any function)

MASM declares a parameter global (PUBLIC) with the syntax:

PUBLIC [langtype] name

where name is the name of the global variable to be referenced, and the optional langtype is STDCALL or C. The option langtype, if present, overrides the calling convention specified in the .MODEL directive.

Conversely, Fortran can declare the variable global (COMMON) and other languages can reference it as external:

 ! Fortran declaring PI global
  REAL PI
  COMMON /PI/ PI ! Common Block and variable have the same name

In C, the variable is referenced as an external with the statement:

  //C code with external reference to PI
  extern float PI;

Note that the global name C references is the name of the Fortran common block, not the name of a variable within a common block. Thus, you cannot use blank common to make data accessible between C and Fortran. In the preceding example, the common block and the variable have the same name, which helps keep track of the variable between the two languages. Obviously, if a common block contains more than one variable they cannot all have the common block name. (See Using Fortran Common Blocks and C Structures.)

MASM can also access Fortran global (COMMON) parameters with the ATTRIBUTES EXTERN directive. The syntax is:

EXTERN [langtype] name

where name is the name of the global variable to be referenced, and the optional langtype is STDCALL or C.

Using Fortran Common Blocks and C Structures

To reference C structures from Fortran common blocks and vice versa, you must take into account the way the common blocks and structures differ in their methods of storing member variables in memory. Fortran places common block variables into memory in order as close together as possible, with the following rules:

  • A single BYTE, INTEGER(1), LOGICAL(1), or CHARACTER variable in common block list begins immediately following the previous variable or array in memory.
  • All other types of single variables begin at the next even address immediately following the previous variable or array in memory.
  • All arrays of variables begin on the next even address immediately following the previous variable or array in memory, except for CHARACTER arrays which always follow immediately after the previous variable or array.
  • All common blocks begin on a four-byte aligned address.

Because of these padding rules, you must consider the alignment of C structure elements with Fortran common block elements and assure matching either by making all variables exactly equivalent types and kinds in both languages (using only 4-byte and 8-byte data types in both languages simplifies this) or by using the C pack pragmas in the C code around the C structure to make C data packing like Fortran's. For example:

 #pragma pack(2)
 struct {
         int N;
         char INFO[30];
 } examp;
 #pragma pack()

To restore the original packing, you must add #pragma pack( ) at the end of the structure. (Remember: Fortran module data can be shared directly with C structures with appropriate naming.)

Once you have dealt with alignment and padding, you can give C access to an entire common block or set of common blocks. Alternatively, you can pass individual members of a Fortran common block in an argument list, just as you can any other data item. Use of common blocks for mixed-language data exchange is discussed in the following sections:

  • Accessing Common Blocks and C Structures Directly
  • Passing the Address of a Common Block

Accessing Common Blocks and C Structures Directly

You can access Fortran common blocks directly from C by defining an external C structure with the appropriate fields, and making sure that alignment and padding between Fortran and C are compatible. The C and ALIAS ATTRIBUTES options can be used with a common block to allow mixed-case names.

As an example, suppose your Fortran code has a common block named Really, as shown:

   !DEC$ ATTRIBUTES ALIAS:'Really' :: Really
   REAL(4) x, y, z(6)
   REAL(8) ydbl
   COMMON / Really / x, y, z(6), ydbl

You can access this data structure from your C code with the following external data structure:

 #pragma pack(2)
 extern struct {
   float x, y, z[6];
   double ydbl;
 } Really;
 #pragma pack()

You can also access C structures from Fortran by creating common blocks that correspond to those structures. This is the reverse case from that just described. However, the implementation is the same because after common blocks and structures have been defined and given a common address (name), and assuming the alignment in memory has been dealt with, both languages share the same memory locations for the variables.

Passing the Address of a Common Block

To pass the address of a common block, simply pass the address of the first variable in the block, that is, pass the first variable by reference. The receiving C or Visual C++ module should expect to receive a structure by reference.

In the following example, the C function initcb receives the address of a common block with the first variable named n, which it considers to be a pointer to a structure with three fields:

Fortran source code:
!
  INTERFACE
     SUBROUTINE initcb (BLOCK)
       !DEC$ ATTRIBUTES C :: initcb
       !DEC$ ATTRIBUTES REFERENCE :: BLOCK
       INTEGER BLOCK
     END SUBROUTINE
  END INTERFACE
!
  INTEGER n
  REAL(8) x, y
  COMMON /CBLOCK/n, x, y
    .  .  .
  CALL initcb( n )

C source code:
 //
 #pragma pack(2)
 struct block_type
 {
   int n;
   double x;
   double y;
 };
 #pragma pack()
 //
 void initcb( struct block_type *block_hed )
  {
    block_hed->n = 1;
    block_hed->x = 10.0;
    block_hed->y = 20.0;
 }


Handling Data Types in Mixed-Language Programming

Even when you have reconciled calling conventions, naming conventions, and methods of data exchange, you must still be concerned with data types, because each language handles them differently. The following table lists the equivalent data types among Fortran, C, Visual Basic, and MASM:

Equivalent Data Types

Fortran Data Type | C Data Type | Visual Basic Data Type | MASM Data Type
INTEGER(1) char --- SBYTE
INTEGER(2) | short | Integer | SWORD
INTEGER(4) | int, long | Long | SDWORD
INTEGER(8) _int64 --- QWORD
REAL(4) | float | Single | REAL4
REAL(8) | double | Double | REAL8
CHARACTER(1) unsigned char --- BYTE
CHARACTER*(*) | See Handling Character Strings
COMPLEX(4) struct complex4 {
float real, imag;
}; 		--- COMPLEX4 STRUCT 4
real REAL4 0
imag REAL4 0
COMPLEX4 ENDS
COMPLEX(8) struct complex8 {
double real, imag;
}; 		--- COMPLEX8 STRUCT 8
real REAL8 0
imag REAL8 0
COMPLEX8 ENDS
All LOGICAL types | Use integer types for C, MASM, and Visual Basic

The following sections describe how to reconcile data types between the different languages:

  • Handling Numeric, Complex, and Logical Data Types
  • Handling Fortran 90 Array Pointers and Allocatable Arrays
  • Handling Compaq Fortran Pointers
  • Handling Arrays and Visual Fortran Array Descriptors
  • Handling Character Strings
  • Handling User-Defined Types


Handling Numeric, Complex, and Logical Data Types

Normally, passing numeric data does not present a problem. If a C program passes an unsigned data type to a Fortran routine, the routine can accept the argument as the equivalent signed data type, but you should be careful that the range of the signed type is not exceeded.

The table of Equivalent Data Types summarizes equivalent numeric data types for Fortran, MASM, and Visual Visual C/C++.

C, Visual C++, and MASM do not directly implement the Fortran types COMPLEX(4) and COMPLEX(8). However, you can write structures that are equivalent. The type COMPLEX(4) has two fields, both of which are 4-byte floating-point numbers; the first contains the real-number component, and the second contains the imaginary-number component. The type COMPLEX is equivalent to the type COMPLEX(4). The type COMPLEX(8) is similar except that each field contains an 8-byte floating-point number.

Note: On ia32 systems, Fortran functions of type COMPLEX place a hidden COMPLEX argument at the beginning of the argument list. C functions that implement such a call from Fortran must declare this hidden argument explicitly, and use it to return a value. The C return type should be void.

Following are the Visual C/C++ structure definitions for the Fortran COMPLEX types:

 struct complex4 {
    float real, imag;
 };
 struct complex8 {
    double real, imag;
 };

The MASM structure definitions for the Fortran COMPLEX types follow:

  COMPLEX4 STRUCT 4
    real REAL4 0
    imag REAL4 0
  COMPLEX4 ENDS
  COMPLEX8 STRUCT 8
    real REAL8 0
    imag REAL8 0
  COMPLEX8 ENDS

A Fortran LOGICAL(2) is stored as a 2-byte indicator value (0=false, and the /fpscomp:[no]logicals compiler option determines how true values are handled). A Fortran LOGICAL(4) is stored as a 4-byte indicator value, and LOGICAL(1) is stored as a single byte. The type LOGICAL is the same as LOGICAL(4), which is equivalent to type int in C.

You can use a variable of type LOGICAL in an argument list, module, common block, or global variable in Fortran and type int in C for the same argument. Type LOGICAL(4) is recommended instead of the shorter variants for use in common blocks.

The Visual C++ class type has the same layout as the corresponding C struct type, unless the class defines virtual functions or has base classes. Classes that lack those features can be passed in the same way as C structures.


Handling Fortran 95/90 Array Pointers and Allocatable Arrays

How Fortran 95/90 array pointers and arrays are passed is affected by the ATTRIBUTES options in effect, and by the INTERFACE, if any, of the procedure they are passed to. If the INTERFACE declares the array pointer or array with deferred shape (for example, ARRAY(:)), its descriptor is passed. This is true for array pointers and all arrays, not just allocatable arrays. If the INTERFACE declares the array pointer or array with fixed shape, or if there is no interface, the array pointer or array is passed by base address of a contiguous array for non-contiguous array slices, which is like passing the first element of an array.

When a Fortran 95/90 array pointer or array is passed to another language, either its descriptor or its base address can be passed.

The following shows how allocatable arrays and Fortran 95/90 array pointers are passed with different attributes in effect:

  • If the property of the array pointer or array is none, it is passed by descriptor, regardless of the property of the passing procedure (None; C; STDCALL; C, REFERENCE; or STDCALL, REFERENCE).
  • If the property of the array pointer or array is VALUE, an error is returned, regardless of the property of the passing procedure.
  • If the property of the array pointer or array is REFERENCE, it is passed by descriptor, regardless of the property of the passing procedure.

Note that the VALUE option cannot be used with descriptor-based arrays.

When you pass a Fortran array pointer or an array by descriptor to a non-Fortran routine, that routine needs to know how to interpret the descriptor. Part of the descriptor is a pointer to address space, as a C pointer, and part of it is a description of the pointer or array properties, such as its rank, stride, and bounds.

For information about the Visual Fortran array descriptor format, see Handling Arrays and Visual Fortran Array Descriptors.

Fortran 95/90 pointers that point to scalar data contain the address of the data and are not passed by descriptor.

For information about performance implications of passing different types of array arguments, see Use Arrays Efficiently.


Handling Compaq Fortran Pointers

Compaq Fortran (integer) pointers are not the same as Fortran 90 pointers, but are instead like C pointers. On ia32 systems, Compaq Fortran pointers are 4-byte INTEGER quantities. On ia64 systems, Compaq Fortran pointers are 8-byte INTEGER quantities.

When passing a Compaq Fortran pointer to a routine written in another language:

  • The argument should be declared in the non-Fortran routine as a pointer of the appropriate data type.
  • The argument passed from the Fortran routine should be the Compaq Fortran pointer name, not the pointer-based variable name.

    For example, on ia32 systems:
     ! Fortran main program.
      INTERFACE
         SUBROUTINE Ptr_Sub (p)
         !DEC$ ATTRIBUTES C, ALIAS:'_Ptr_Sub' :: Ptr_Sub
            INTEGER p
         END SUBROUTINE Ptr_Sub
      END INTERFACE
      REAL A(10), VAR(10)
      POINTER (p, VAR) ! VAR is the pointer-based
                       ! variable, p is the int.
      p = LOC(A)

      CALL Ptr_Sub (p)
      WRITE(*,*) 'A(4) = ', A(4)
      END
  !

  //C subprogram
      void Ptr_Sub (float *p)
      {
         p[3] = 23.5;
      }

    On ia64 systems, the alias name for Ptr_Sub should not have a leading underscore, as follows:
       !DEC$ ATTRIBUTES C, ALIAS:'Ptr_Sub' :: Ptr_Sub

    When the main Fortran program and C function are built and executed, the following output appears:
       A(4) = 23.50000

When receiving a pointer from a routine written in another language:

  • The argument should be declared in the non-Fortran routine as a pointer of the appropriate data type and passed as usual.
  • The argument received by the Fortran routine should be declared as a Compaq Fortran pointer name, then the POINTER statement should associate it with a pointer-based variable of the appropriate data type (matching the data type of the passing routine). When inside the Fortran routine, use the pointer-based variable to set and access what the pointer points to.

For example, on ia32 systems:

 ! Fortran subroutine.
      SUBROUTINE Iptr_Sub (p)
      !DEC$ ATTRIBUTES C, ALIAS:'_Iptr_Sub' :: Iptr_Sub
         integer VAR(10)
         POINTER (p, VAR)
         OPEN (8, FILE='STAT.DAT')
         READ (8, *) VAR(4) ! Read from file and store the
                            ! fourth element of VAR
      END SUBROUTINE Iptr_Sub
 !

 //C main program
 extern void Iptr_Sub(int *p);

 main ( void )
 {
   int a[10];
   Iptr_Sub (&a[0]);
   printf("a[3] = %i\n", a[3]);
 }

On ia64 systems, the alias name for Iptr_Sub should not have a leading underscore, as follows:
   !DEC$ ATTRIBUTES C, ALIAS:'Iptr_Sub' :: Iptr_Sub

When the main C program and Fortran subroutine are built and executed, the following output appears if the STAT.DAT file contains 4:
   a[3] = 4


Handling Arrays and Fortran 90 Array Descriptors

Handling Arrays and Visual Fortran Array Descriptors

Fortran 95/90 allows arrays to be passed as array elements, as array subsections, or as whole arrays referenced by array name. Within Fortran, array elements are ordered in column-major order, meaning the subscripts of the lowest dimensions vary first.

When using arrays between Fortran and another language, differences in element indexing and ordering must be taken into account. You must reference the array elements individually and keep track of them. Fortran, Visual Basic, MASM and C vary in the way that array elements are indexed. Array indexing is a source-level consideration and involves no difference in the underlying data.

Visual Basic stores arrays and character strings as descriptors: data structures that contain array size and location. This storage difference is transparent to the user, however.

To pass an array from Visual Basic to Fortran, pass the first element of the array. By default, Visual Basic passes variables by reference, so passing the first element of the array will give Fortran the starting location of the array, just as Fortran expects. Visual Basic indexes the first array element as 0 by default, while Fortran by default indexes it as 1. Visual Basic indexing can be set to start with 1 using the statement:

  Option Base 1

Alternatively, in the array declaration in either language you can set the array lower bound to any integer in the range -32,768 to 32,767. For example:

 ' In Basic
 Declare Sub FORTARRAY Lib "fortarr.dll" (Barray as Single)
 DIM barray (1 to 3, 1 to 7) As Single
 Call FORTARRAY(barray (1,1))

 ! In Fortran
 Subroutine FORTARRAY(arr)
    REAL arr(3,7)

In MASM, arrays are one-dimensional and array elements must be referenced byte-by-byte. The assembler stores elements of the array consecutively in memory, with the first address referenced by the array name. You then access each element relative to the first, skipping the total number of bytes of the previous elements. For example:

 xarray    REAL4     1.1, 2.2, 3.3, 4.4 ; initializes
                       ; a four element array with
                       ; each element 4 bytes

Referencing xarray in MASM refers to the first element, the element containing 1.1. To refer to the second element, you must refer to the element 4 bytes beyond the first with xarray[4] or xarray+4. Similarly:

 yarray     BYTE      256 DUP     ; establishes a
                 ; 256 byte buffer, no initialization
 zarray SWORD 100 DUP(0) ; establishes 100
                 ; two-byte elements, initialized to 0

Fortran and C arrays differ in two ways:

  • The value of the lower array bound is different. By default, Fortran indexes the first element of an array as 1. C and Visual C++ index it as 0. Fortran subscripts should therefore be one higher. (Fortran also provides the option of specifying another integer lower bound.)
  • In arrays of more than one dimension, Fortran varies the left-most index the fastest, while C varies the right-most index the fastest. These are sometimes called column-major order and row-major order, respectively.

In C, the first four elements of an array declared as X[3][3] are:

  X[0][0] X[0][1] X[0][2] X[1][0]

In Fortran, the first four elements are:

  X(1,1) X(2,1) X(3,1) X(1,2)

The order of indexing extends to any number of dimensions you declare. For example, the C declaration:

  int arr1[2][10][15][20];

is equivalent to the Fortran declaration:

  INTEGER arr1( 20, 15, 10, 2 )

The constants used in a C array declaration represent extents, not upper bounds as they do in other languages. Therefore, the last element in the C array declared as int arr[5][5] is arr[4][4], not arr[5][5].

The following table shows equivalencies for array declarations.

Equivalent Array Declarations for Different Languages

Language | Array Declaration | Array Reference from Fortran
Fortran DIMENSION x(i, k)
-or-
type x(i, k) 		x(i, k)
Visual Basic | DIM x(i, k) As type | x( i -1, k -1)
Visual C/C++ | type x[ k ] [ i ] | x( i -1, k -1)
MASM | Declare and reference arrays as elements in consecutive storage

Visual Fortran Array Descriptor Format

For cases where Fortran 95/90 needs to keep track of more than a pointer memory address, the Visual Fortran compiler uses an array descriptor, which stores the details of how an array is organized.

When using an explicit interface (by association or procedure interface block), Visual Fortran will generate a descriptor for the following types of array arguments:

  • Pointers to arrays (array pointers)
  • Assumed-shape arrays

Certain data structure arguments do not use a descriptor, even when an appropriate explicit interface is provided. For example, explicit-shape and assumed-size arrays do not use a descriptor. In contrast, array pointers and allocatable arrays use descriptors regardless of whether they are used as arguments.

When calling between Visual Fortran and a non-Fortran language (such as C), using an implicit interface allows the array argument to be passed without a Visual Fortran descriptor (see Passing Array Arguments Efficiently). However, for cases where the called routine needs the information in the Visual Fortran descriptor, declare the routine with an explicit interface and specify the dummy array as either an assumed-shape array or with the pointer attribute.

You can associate a Fortran 95/90 pointer with any piece of memory, organized in any way desired (so long as it is "rectangular" in terms of array bounds). You can also pass Fortran 95/90 pointers to other languages, such as C, and have the other language correctly interpret the descriptor to obtain the information it needs.

However, using array descriptors can increase the opportunity for errors and is not portable:

  • If the descriptor is not defined correctly, the program might access the wrong memory address, possibly causing a General Protection Fault.
  • Array descriptor formats are specific to each Fortran compiler. Code that uses array descriptors is not portable to other compilers or platforms. For example, the Visual Fortran array descriptor format (for Win32 systems) differs from the array descriptor format for Compaq Fortran on Compaq Tru64 UNIX and Compaq OpenVMS systems. The Visual Fortran array descriptor format is the same format used by Microsoft Fortran PowerStation.
  • The array descriptor format might change in the future.

The components of the current Visual Fortran array descriptor on ia32 systems follow:

  • The first longword (bytes 0 to 3) contains the base address. The base address plus the offset defines the first memory location (start) of the array.
  • The second longword (bytes 4 to 7) contains the size of a single element of the array.
  • The third longword (bytes 8 to 11) contains the offset. The offset is added to the base address to define the start of the array.
  • The fourth longword (bytes 12 to 15) contains the low-order bit set if the array has been defined (storage allocated). Other bits may also be set by the compiler within this longword, for example, to indicate a contiguous array.
  • The fifth longword (bytes 16 to 19) contains the number of dimensions (rank) of the array.
  • The remaining longwords (bytes 20 up to 103) contain information about each dimension (up to seven). Each dimension is described by three additional longwords:
    • The number of elements (extent)
    • The distance between the starting address of two successive elements, in bytes.
    • The lower bound

An array of rank one would require three additional longwords for a total of in eight longwords (5 + 3*1) and end at byte 31. An array of rank seven would be described in a total of 26 longwords (5 + 3*7) and end at byte 103.

For example, consider the following declaration:

   integer,target :: a(10,10)
   integer,pointer :: p(:,:)
   p => a(9:1:-2,1:9:3)
   call f(p)
   .
   .
   .

The descriptor for actual argument p would contain the following values:

  • The first longword (bytes 0 to 3) contain the base address (assigned at run-time).
  • The second longword (bytes 4 to 7) is set to 4 (size of a single element).
  • The third longword (bytes 8 to 11) contain the offset (assigned at run-time).
  • The fourth longword (bytes 12 to 15) contains 1 (low bit is set).
  • The fifth longword (bytes 16 to 19) contains 2 (rank).
  • The sixth, seventh, and eighth longwords (bytes 20 to 31) contain information for the first dimension, as follows:
    • 5 (extent)
    • -8 (distance between elements)
    • 1 (the lower bound)
  • For the second dimension, the ninth, tenth, and eleventh longwords (bytes 32 to 43) contain:
    • 3 (extent)
    • 120 (distance between elements)
    • 1 (the lower bound)
  • Byte 43 is the last byte for this example.

For information about performance implications of passing different types of array arguments, see Passing Array Arguments Efficiently.


Handling Character Strings

By default, Visual Fortran passes a hidden length argument for strings. The hidden length argument consists of an unsigned 4-byte integer (ia32 systems) or unsigned 8-byte integer (ia64 systems), always passed by value, immediately following the address of the character string. You can alter the default way strings are passed by using attributes. The following table shows the effect of various attributes on passed strings.

Effect of ATTRIBUTES Options on Character Strings Passed as Arguments

Argument | Default | C | STDCALL | C, REFERENCE | STDCALL, REFERENCE
String | Passed by reference, along with length | First character converted to INTEGER(4) and passed by value | First character converted to INTEGER(4) and passed by value | Passed by reference, along with length | Passed by reference, along with length
String with VALUE option | Error | First character converted to INTEGER(4) and passed by value | First character converted to INTEGER(4) and passed by value | First character converted to INTEGER(4) and passed by value | First character converted to INTEGER(4) and passed by value
String with REFERENCE option | Passed by reference, possibly along with length | Passed by reference, no length | Passed by reference, no length | Passed by reference, no length | Passed by reference, no length

The important things to note about the above table are:

  • Character strings without the VALUE or REFERENCE attribute that are passed to C or STDCALL routines are not passed by reference. Instead, only the first character is passed and it is passed by value.
  • Character strings with the VALUE option passed to C or STDCALL routines are not passed by reference. Instead, only the value of the first character is passed.
  • For string arguments with default ATTRIBUTES, ATTRIBUTES C, REFERENCE, or ATTRIBUTES STDCALL, REFERENCE:
    • When /iface:mixed_str_len_arg is set, the length of the string is pushed (by value) on the stack immediately after the address of the beginning of the string.
    • When /iface:nomixed_str_len_arg is set, the length of the string is pushed (by value) on the stack after all of the other arguments.
  • For string arguments passed by reference with default ATTRIBUTES:
    • When /iface:mixed_str_len_arg is set, the length of the string is pushed (by value) on the stack immediately after the address of the beginning of the string.
    • When /iface:nomixed_str_len_arg is set, the length of the string is not available to the called procedure.

Since all strings in C are pointers, C expects strings to be passed by reference, without a string length. In addition, C strings are null-terminated while Fortran strings are not. There are two basic ways to pass strings between Fortran and C: convert Fortran strings to C strings, or write C routines to accept Fortran strings.

To convert a Fortran string to C, choose a combination of attributes that passes the string by reference without length, and null terminate your strings. For example, on ia32 systems:

   INTERFACE
      SUBROUTINE Pass_Str (string)
        !DEC$ ATTRIBUTES C, ALIAS:'_Pass_Str' :: Pass_Str
        CHARACTER*(*) string
        !DEC$ ATTRIBUTES REFERENCE :: string
      END SUBROUTINE
   END INTERFACE
   CHARACTER(40) forstring
   DATA forstring /'This is a null-terminated string.'C/

On ia64 systems, the first !DEC$ ATTRIBUTES line would omit the leading underscore and be as follows:
   !DEC$ ATTRIBUTES C, ALIAS:'Pass_Str' :: Pass_Str

This example shows the extension of using the null-terminator for the string in the Fortran DATA statement (see C Strings):
   DATA forstring /'This is a null-terminated string.'C/

The C interface is:
  void Pass_Str (char *string)

To get your C routines to accept Fortran strings, C must account for the length argument passed along with the string address. For example:

  ! Fortran code
  INTERFACE
     SUBROUTINE Pass_Str (string)
     CHARACTER*(*) string
  END INTERFACE

The C routine must expect two arguments:
  void __stdcall PASS_STR (char *string, unsigned int length_arg )

This interface handles the hidden-length argument, but you must still reconcile C strings that are null-terminated and Fortran strings that are not. In addition, if the data assigned to the Fortran string is less than the declared length, the Fortran string will be blank padded.

Rather than trying to handle these string differences in your C routines, the best approach in Fortran/C mixed programming is to adopt C string behavior whenever possible. Another good reason for using C strings is that Win32 APIs and most C library functions expect null-terminated strings.

Fortran functions that return a character string using the syntax CHARACTER*(*) place a hidden string argument and the address of the string at the beginning of the argument list.

C functions that implement such a Fortran function call must declare this hidden string argument explicitly and use it to return a value. The C return type should be void. However, you are more likely to avoid errors by not using character-string return functions. Use subroutines or place the strings into modules or global variables whenever possible.

Visual Basic strings must be passed by value to Fortran. Visual Basic strings are actually stored as structures containing length and location information. Passing by value dereferences the structure and passes just the string location, as Fortran expects. For example:

 ! In Basic
  Declare Sub forstr  Lib "forstr.dll" (ByVal Bstring as String)
  DIM bstring As String * 40 Fixed-length string
  CALL forstr(bstring)
 ! End Basic code

 ! In Fortran
  SUBROUTINE forstr(s)
  !DEC$ ATTRIBUTES STDCALL :: forstr
  !DEC$ ATTRIBUTES REFERENCE :: s
  CHARACTER(40) s
  s = 'Hello, Visual Basic!'
  END

The Fortran directive !DEC$ ATTRIBUTES STDCALL and the ATTRIBUTES REFERENCE property on variable argument s together inform Fortran not to expect the hidden length arguments to be passed from the Visual Basic calling program. The name in the Visual Basic program is specified as lowercase since STDCALL makes the Fortran name lowercase.

MASM does not add either a string length or a null character to strings by default. To append the string length, use the syntax:

lenstring BYTE "String with length", LENGTHOF lenstring

To add a null character, append it by hand to the string:

 nullstring BYTE "Null-terminated string", 0


Handling User-Defined Types

Fortran 95/90 supports user-defined types (data structures similar to C structures). User-defined types can be passed in modules and common blocks just as other data types, but the other language must know the type's structure. For example:

Fortran Code:
     TYPE LOTTA_DATA
         SEQUENCE
         REAL A
         INTEGER B
         CHARACTER(30) INFO
         COMPLEX CX
         CHARACTER(80) MOREINFO
      END TYPE LOTTA_DATA
      TYPE (LOTTA_DATA) D1, D2
      COMMON /T_BLOCK/ D1, D2

In the Fortran code above, the SEQUENCE statement preserves the storage order of the derived-type definition.

C Code:
 /* C code accessing D1 and D2 */
 extern struct {
    struct {
       float a;
       int b;
       char info[30];
       struct {
          float real, imag;
          } cx;
       char moreinfo[80];
    } d1, d2;
} T_BLOCK;


Visual Fortran/Visual C++ Mixed-Language Programs

When you understand and reconcile the calling, naming and argument passing conventions between Fortran and C, you are ready to build an application.

If you are using Visual C/C++ you can edit, compile and debug your code within the Microsoft visual development environment. If you are using another C compiler, you can edit your code within the visual development environment by selecting File/New and choosing Visual C/C++ source in the File tab or, after activating the editor, by selecting the View menu Properties item and selecting from the drop-down list.

However, if you are not using Visual C/C++, you must compile your code outside the Microsoft visual development environment and either build the Fortran/C program on the command line or add the compiled C .OBJ file to your Fortran project in the Microsoft visual development environment.

As an example of building from the command line, if you have a main C program CMAIN.C that calls Fortran subroutines contained in FORSUBS.F90, you can create the CMAIN application with the following commands:

  cl /c cmain.c
  DF cmain.obj forsubs.f90

The Fortran (DF) compiler accepts an object file for the main program written in C and compiled by the C compiler. The DF compiler compiles the .F90 file and then has the linker create an executable file under the name CMAIN.EXE using the two object files.

Either compiler can do the linking, regardless of which language the main program is written in; however, if you use the DF compiler first, you must include DFOR.LIB with the C compiler, and you might experience some difficulty with the version of LIBC.LIB used by the C compiler. For these reasons, you may prefer to use the C compiler first or get your project settings for both Fortran and C to agree on the default C library to link against making sure that your application links against one and only one copy of the C library.

When using the visual development environment to build your application, Fortran uses default libraries depending on the information specified in the Fortran tab in the Project menu, Settings item (Project Settings dialog box). You can also specify linker settings with the Linker tab in the Project Settings dialog box.

In the Fortran tab, within the Libraries category, the following options determine the default libraries selected:

  • Use Fortran Run-time Libraries (see Types of Projects)
  • Use Multi-threaded Libraries (see /[no]threads)
  • Use C Debug Libraries (see /[no]dbglibs)

The combinations of these options use the following libraries:

Static or DLL Project? | Use Multi-Theaded Libraries? | Use C Debug Libraries? | Fortran Link Library Used | C Link Library Used
Static | No | No | dfor.lib | libc.lib
Static | No | Yes | dfor.lib | libcd.lib
Static | Yes | No | dformt.lib | libcmt.lib
Static | Yes | Yes | dformt.lib | libcmtd.lib
DLL | No | No | dfordll.lib (dforrt.dll) | msvcrt.lib (msvcrt.dll)
DLL | No | Yes | dfordlld.lib (dforrtd.dll) | msvcrtd.lib (msvcrtd.dll)
DLL | Yes | No | dformd.lib (dformd.dll) | msvcrt.lib (msvcrt.dll)
DLL | Yes | Yes | dformdd.lib (dformdd.dll) | msvcrtd.lib (msvcrtd.dll)

For example, if you select the Single-threaded item in the Use Run-Time Libraries list in the Libraries category of the Fortran tab, this specifies that static (/libs:static), single-threaded (/nothreads), and non-debug (/nodbglibs) libraries will be linked against, namely Fortran library dfor.lib and C/C++ library libc.lib.

If you select Debug Multi-threaded DLL in the Use Run-Time Libraries list in the Libraries category of the Fortran tab, this specifies that DLL (/libs:DLL), multi-threaded (/threads), and debug (/dbglibs) libraries will be linked against, namely Fortran import library dformdd.lib and its DLL library dformdd.dll and C/C++ import library msvcrtd.lib and its DLL library msvcrtd.dll.

The way Visual C++ chooses libraries is also based upon the Project menu Settings item, but within the C/C++ tab. In the Code Generation category, the "Use run-time library" item lists the following C libraries:

Menu Item Selected | CL Option or Project Type Enabled | Default Library Specified in Object File
Single-threaded | /ML | libc.lib
Multithreaded | /MT | libcmt.lib
Multithreaded DLL | /MD | msvcrt.lib (msvcrt.dll)
Debug Single-threaded | /MLd | libcd.lib
Debug Multithreaded | /MTd | libcmtd.lib
Debug Multithreaded DLL | /MDd | msvcrtd.lib (msvcrtd.dll)

If you are using Microsoft Visual C/C++, the Microsoft visual development environment can create mixed Fortran/C applications transparently, with no special directives or steps on your part. You can edit and browse your C and Fortran programs with appropriate syntax coloring for the language. You can add C source files to your Fortran project or Fortran source files to a C project, and they will be compiled and linked automatically.

When you debug a mixed Visual C/Fortran application, the debugger will adjust to the code type as it steps through: the C or Fortran expression evaluator will be selected automatically based on the code being debugged, and the stack window will show Fortran data types for Fortran procedures and C data types for C procedures.

When printing from Visual C++ programs while calling Fortran subprograms that also print, the output may not appear in the order you expect. In Visual C++, the output buffer contents are not written immediately, but written when the buffer is full, the I/O stream is closed or the program terminates normally. The buffer is said to be "flushed" when this occurs.

To make sure interleaving Visual C++ and Fortran program units print in the order expected, you can explicitly flush the Visual C++ buffers after an output command with the flushall, fflush, fclose, setbuf, or setvbuf Visual C++ library calls.

Multithreaded applications should have full multithread support, so if you use DFORMT.LIB, be sure LIBCMT.LIB is specified as a default library.


Fortran/Visual Basic Mixed-Language Programs

Visual Fortran and Visual Basic mixed-language programs typically use:

  • Visual Basic for the user-interface features
  • Visual Fortran for computation

In Fortran/Visual Basic programs, the Visual Basic must be 32-bit (at least Version 5.0). You can also use the Visual Basic for Applications (VBA) included with Microsoft Excel to call Fortran subprograms.

The Visual Basic development environment is separate from the Visual Fortran Version 6 development environment. However, the two languages can coexist in the same final application.

The usual case is to call Fortran subprograms from Visual Basic. Because Visual Basic subprograms are interpreted and not compiled, they cannot be called directly from compiled language programs like Fortran. Instead, Visual Basic creates OLE objects that export properties and routines.

It is also possible for Visual Basic to pass the address of its procedures to a Fortran program, to be called later by that Fortran program as callbacks. Refer to the Visual Fortran Sample in the ...\DF98\SAMPLES\MIXLANG\VB\CALLBACK folder for an example of Visual Fortran calling Visual Basic callback routines.

When calling a Fortran subprogram from Visual Basic, you need to:

  1. Create the Visual Fortran subprogram as a Fortran DLL project
  2. Reference the DLL from Visual Basic with a Declare Sub or Declare Func statement

The following sections discuss Visual Basic calling a Fortran DLL subprogram:

  • Calling Visual Fortran from Visual Basic
  • Visual Basic Debugging Considerations
  • Examples of Fortran/Visual Basic Programs


Calling Visual Fortran from Visual Basic

When calling a Visual Fortran DLL from Visual Basic, important argument passing and data type considerations are:

  • Visual Basic uses the STDCALL standard of argument passing with one exception: it does not append the "@n" count to the name on ia32 systems.
  • Within Visual Basic, you declare the name of the routine that will be called and the arguments to be passed to it. Scalar numeric arguments can be directly passed from Basic and directly used by Fortran, but strings, arrays, and types require some extra handling.

This section discusses the following topics:

  • Declaring the Fortran Routine in Visual Basic
  • Exporting the Routine from the Fortran DLL
  • Data Type Considerations

Declaring the Fortran Routine in Visual Basic

When you declare a Fortran routine in Basic the routine name is exported in exactly the same case as you declared it. Optionally, you can specify a directory path to the Fortran DLL in the declaration.

The following Visual Basic example declares a Fortran subroutine named FortranCall that takes two single-precision arguments:
 Declare Sub FortranCall Lib "d:\MyProjects\FCall.dll" (A1 as Single,
                                A2 as Single)
The following example declares a Fortran function named FortranFunc that takes two integer (32-bit) arguments and returns a single precision value:
 Declare Function FortranFunc Lib "d:\MyProject\FFun.dll" (A1 as Long,
                             A2 as Long)
                                                         As Single

Exporting the Routine from the Fortran DLL

When you create the Fortran DLL, you need to add two additional attributes to the function or subroutine declaration so that it can be accessed from outside the DLL.

The Fortran routine name must be exported from the DLL, and it must be aliased to match exactly the name expected by Basic. The ATTRIBUTES (c DEC$ ATTRIBUTES compiler directive) and ALIAS declarations export the name and alias, as shown below for a Fortran subroutine:
     SUBROUTINE FortranCall
  !DEC$ ATTRIBUTES DLLEXPORT :: FortranCall             ! This exports the name
  !DEC$ ATTRIBUTES ALIAS : "FortranCall" :: FortranCall !This sets it

This is also true for Fortran functions, which must be exported and aliased to match exactly the name expected by Basic:
     REAL Function FortranFunc
  !DEC$ ATTRIBUTES DLLEXPORT :: FortranFunc
  !DEC$ ATTRIBUTES ALIAS : "FortranFunc" :: FortranFunc

Data Type Considerations

When you pass data between Visual Basic and Visual Fortran, you need to keep in mind the calling standard used by the two languages, the size of the data, and the on-disk format of the data.

The following table summaries the calling considerations for the data types:

Data Type | Calling Considerations
Integer | By default, both Visual Basic and Visual Fortran pass integers by reference. The default integer size in Basic is 2 bytes, equivalent to INTEGER(2) in Fortran. No extra action is required by either language to access integer arguments.
Floating point | By default, both Visual Basic and Visual Fortran pass single- and double-precision floating point numbers by reference. The size of a single-precision floating point number is 4 bytes in both languages. The size of a double-precision floating point number is 8 bytes in both languages. No extra action is required by either language to access floating point arguments.
Logical | By default, both Basic and Fortran pass logical data by reference. The default logical size in Basic is two bytes, equivalent to LOGICAL(2) in Fortran. No extra action is required by either language to access logical arguments.
Strings By default, Basic passes strings in a structure called a BSTR. By default, Fortran passes strings in two arguments: the string's address and a hidden argument containing the string's length. These defaults can be easily overridden by making changes in the Basic declaration, and sometimes in the Fortran declaration too.

Whenever you pass a string from Basic to Fortran, the passing mechanism should be declared as ByVal. See the String Passing Examples.

Arrays By default, Basic arrays are 0-based. Fortran arrays are 1-based by default. When you declare a Basic array to be of size n, n+1 elements are allocated, including the 0th element. This can be overridden, as show in the Array Passing Examples.

To pass arrays of numbers from Basic to Fortran, whether they are integer or floating-point numbers, pass the first element. In the Fortran code declare the argument to be an array. Usually the Basic code will pass the number of elements in the array.

To pass arrays of strings or types from Basic to Fortran requires the use of COM utilities to read the structures created by Basic. The arrays are passed as is from Basic, and then extracted in the Fortran code using SafeArrayxx utilities. For more detail, please refer to the Visual Fortran Samples found in the MixLang\VB\arrays and MixLang\VB\typearrays folders.
Types Basic-declared types can be passed from Basic to Fortran. The Basic-declared type will also have to be declared in Fortran; care should be taken to keep the two structures the same. In Fortran, the TYPE should be declared to be packed, usually PACK:2. You should be aware of the default sizes of the TYPE elements in the two languages, and adjust the defaults accordingly.

Note that strings in Basic-declared types are stored as Unicode, which can be declared in Fortran as an array of Integer*2. To access these strings from Fortran, use the Natural Language System (NLS) API calls. For information, see Using National Language Support Routines and the Visual Fortran Samples found in the MixLang\VB\typearrays folder.

String Passing Examples

The following example shows passing strings using the usual case, where the string will have varying length, and the length must also be passed to Fortran ByVal:

Visual Basic code:

  Declare Sub FortString1 Lib "forttest" (ByVal S1 as String,
                      ByVal L1 as Long)
  Dim S1 as String * 12
  Call FortString1(S1, Len(S1))

Visual Fortran code:

  Subroutine FortString1 (mystring)
  !DEC$ ATTRIBUTES DLLEXPORT, ALIAS : "FortString1" :: FortString1
  CHARACTER*(*) mystring

The following example shows shows passing strings where the length of the string will be constant and known by both the Basic and Fortran code, so you do not need to pass the length to Fortran, but you need to tell Fortran not to expect its length:

Visual Basic code:

  Declare Sub FortString2 Lib "forttest" (ByVal S2 as String)
  Dim S2 as String * 25

Visual Fortran code:

  Subroutine FortString2 (mystring)
  !DEC$ ATTRIBUTES DLLEXPORT, ALIAS : "FortString2" :: FortString2
  !DEC$ ATTRIBUTES REFERENCE :: mystring
  CHARACTER*25 mystring

Array Passing Examples

The following example shows shows passing arrays:

Visual Basic code:

 Basic declaration:
    Declare Sub FortArray1 Lib "forttest" (A1 as Long, NumElem as long)
    Dim A1(1:3) as Long
    Call FortArray1(A1(1), 3)

Visual Fortran code:

 Subroutine FortArray1 (Array1, N)
    !DEC$ ATTRIBUTES DLLEXPORT, ALIAS : "FortArray1" :: FortArray1
    Integer array1(N)


Visual Basic Debugging Considerations

This section describes how to debug the Fortran code in the DLL being called by Visual Basic. It is not intended to describe how to debug the Visual Basic code itself. This section describes the following:

  • Debugging the Fortran DLL
  • Visual Basic Error 53: File not found: yy.dll
  • Visual Basic Error 453: Can't find DLL entry point xx in yy.dll

Debugging the Fortran DLL

In Visual Basic, create an executable of your project. Use the pull down menu item File-Make myproject.exe. Note where the executable was created.

In the Visual Fortran development environment:

  1. In the Project menu, click Settings
  2. Click the Debug tab
  3. In the box labelled "Executable for debug session," enter the full path and filename of the executable you created above.

You can now use the full power of the visual development environment debugger to debug your DLL.

If you are using VBA within Microsoft Excel, the steps are similar for debugging your DLL. Enter the full path and filename for Excel into the box labelled "Executable for debug session". Optionally, you can enter the name of the worksheet into the box labeled "Program arguments:". You can now use the visual development environment to debug your DLL.

For a sample Fortran debugging session, see Debugging the Squares Example Program.

Visual Basic Error 53: File not found: yy.dll

If you get the error message "File not found: yy.dll" when you run the Visual Basic application, check the following:

  • If you built the DLL on one system and copied it to another, did you also copy the Fortran run-time DLLs?

    These files are DFORRT.DLL, DFORMD.DLL, and MSVCRT.DLL on the Visual Fortran CD-ROM. They can be freely distributed with your application (see Compaq Visual Fortran Installing and Getting Started).

  • Is the correct path to yy.dll specified in the Basic declaration?

    Carefully check the path and file name in the Visual Basic Declare statement.

Visual Basic Error 453: Can't find DLL entry point xx in yy.dll

If you get the error message "Can't find DLL entry point xx in yy.dll," check the following:

  • Make sure the Fortran code has specified the ATTRIBUTES DLLEXPORT for the routine name (see the cDEC$ ATTRIBUTES compiler directive).
  • Make sure the Fortran code has specified an ATTRIBUTES ALIAS name that exactly matches the name declared by the Basic code (see the cDEC$ ALIAS directive, which also can be used as an ATTRIBUTES option ALIAS).
  • Make sure you are referencing the correct yy.dll.

For an example of calling a Fortran DLL from Visual Basic, see Examples of Fortran/Visual Basic Programs.


Examples of Fortran/Visual Basic Programs

The following brief code demonstrates the interface for a Fortran subroutine and function (free-form Fortran source):

  1. In the visual development environment, create a new project of type Fortran Dynamic-Link Library. Name the project FCALL.
  2. Create a new free-form source file (Project menu, Add to Project, New) for the project named FCALL.F90 with the following code:
     ! Fortran Code  establishing subroutine
 ! Computes the MOD of R1 and 256.0 and stores the
 ! result in the argument NUM

  SUBROUTINE FortranCall (r1, num)

 ! Specify that the routine name is to be made available to callers of the
 ! DLL and that the external name should not have any prefix or suffix

 !DEC$ ATTRIBUTES DLLEXPORT :: FortranCall
 !DEC$ ATTRIBUTES ALIAS:'FortranCall' :: FortranCall

   REAL,INTENT(IN) :: r1           ! Input argument
   REAL,INTENT(OUT) :: num

   num = MOD (r1, 256.0)

 END SUBROUTINE
  3. Build the Fortran DLL as described in Building and Using Dynamic-Link Libraries.
  4. Start Visual Basic and create a new Standard EXE project:
    • On the control toolbar, click the CommandButton icon and then, with the cursor over the form, draw out a button.
    • In the button's Properties box, double-click on Caption and change the caption to "Do it!".
    • Click the TextBox icon and, in the same fashion, draw a text box on the form. In its Properties box, find the Text property and change it to an empty string.
  5. Double-click the Command button on the form - a code window will appear. Fill in the code so that it looks like this:
       Private Sub Command1_Click()
   r1 = 456.78
   Call FortranCall(r1, Num)
   Text1.Text = Str$(Num)
   End Sub
  6. Select Project..Add Module and click Open to create a new module. Add the following code to the module:
       Declare Sub FortranCall Lib"c:\MyProjects\Fcall\Debug\Fcall.dll"
            (r1 As Single, Num As Single)

    Replace the filename with the location of the Fortran DLL, if it is different.

  7. Run the Basic program by pressing F5. Click the Do it! button. The Fortran routine will be called to compute the modulus, returning the result to the Basic code. The Basic code will then convert the result to a string and display it in the text box.

Visual Basic, like Fortran, passes numeric values (such as integers and reals) by reference, so it is not necessary to change the passing mechanism on either side. The ALIAS attribute is required because Visual Basic, even though it uses the STDCALL calling mechanism, does not "decorate" routine names with the @n suffix. If the Fortran routine were also to be called by other Fortran code, it would be appropriate to use the Alias option on the Basic side to name it with the proper suffix.


Fortran/MASM Mixed-Language Programs

With Microsoft Macro Assembler (MASM), you can combine the unique strengths of assembly-language programming with Visual Fortran. If you structure your assembly-language procedures appropriately, you can call them from Visual Fortran programs and subprograms. MASM works with Visual Fortran, C, and Visual C++. These high-level languages can call MASM procedures, and each of the languages can be called from MASM programs. Details of the MASM interfaces with the other languages can be found in the Microsoft MASM Programmer's Guide.

Compile your Fortran source module with Visual Fortran, and assemble your assembly-language procedure with the MASM assembler. Then, link the two object files. The following example shows how to call a MASM assembler-language program from Fortran.

The Fortran code:

   INTERFACE
     INTEGER (4) FUNCTION POWER2 (V,E)
     !DEC$ ATTRIBUTES STDCALL :: Power2
     INTEGER V, E
     END FUNCTION
   END INTERFACE

The MASM code:

  POWER2 PROTO STDCALL, v, e
  ...
  POWER2 PROC STDCALL, v, e
  ...
  POWER2 ENDP
  END

In the example, the Fortran call to MASM is power2(v,e), which is identical to a Fortran function call. Visual Fortran also provides sample mixed-language programs that show calls between Visual Fortran and MASM (see Examples of Fortran/MASM Programming).

There are two differences between this mixed-language call and a call between two Fortran modules:

  1. The subprogram power2(v,e) is implemented in MASM using standard MASM syntax. The PROTO declaration in MASM specifies that the procedure use the STDCALL calling convention.
  2. The INTERFACE statement in the Fortran module specifies the STDCALL calling convention, so the Fortran program uses same convention that the MASM procedure specifies.

This section covers the following topics:

  • Creating a MASM Procedure
  • Fortran/MASM Alignment and Return Value Considerations
  • Examples of Fortran/MASM Programming


Creating a MASM Procedure

Normally you follow these steps in creating a MASM procedure:

  1. Set up the procedure, defining compatible segments and declaring the procedure.
  2. Enter the procedure and set up an appropriate stack frame.
  3. Preserve register values by pushing any registers on the stack that you modify later.
  4. Reserve space on the stack for any local data (optional).
  5. Access arguments in the main body of your procedure.
  6. Deallocate any local data by returning space from the stack.
  7. Restore register values by popping any preserved registers from the stack.
  8. If you called the procedure as a function, return a value (optional).
  9. Set up the caller routine by restoring the caller stack frame.
  10. Exit the procedure and return to the caller program.


Fortran/MASM Alignment and Return Value Considerations

Visual Fortran allows you to specify alignment for all data objects. Requesting alignment specifies that bytes may be added as padding, so that the object and its data start on a natural boundary (see Data Alignment Considerations). The MASM default is byte-alignment, so you should specify an alignment of 4 for MASM structures or use the Fortran compiler option /alignment:keyword (or /Zpn).

Your MASM procedure can return a value to your Fortran routine if you prototype it as a function. All return values of 4 bytes or less (except for floating-point values) are returned in the EAX register.

Procedures that return floating-point values return their results on the floating-point processor stack. This is possible because there is always a coprocessor or emulator available for 32-bit compilers.

To return REAL and COMPLEX floating-point values, records, arrays, and values larger than 4 bytes and return user-defined types larger than 8 bytes from assembly language to Fortran, you must use a special convention. Fortran creates space in the stack segment to hold the actual return value and passes an extra parameter as the last parameter pushed onto the stack. This extra parameter contains the address of the stack space that contains the return value. For user-defined types, values of 4 bytes or less are returned in EAX and values of 5 to 8 bytes are returned in EAX:EDX.

In the assembly procedure, put the data for the return value at the location pointed to by the return value offset. Then copy the return-value offset (located at EBP+8 if you've created a stack frame in your assembly code) to EAX. This is necessary because the calling module expects EAX to point to the return value.

The following table summarizes ways to return values.

Summary of Ways to Return Values

Type of Value to Return | Method of Returning Value
Integer, logical variable, or user-defined type of size 4 bytes or less | Return value in EAX register
Floating-point variable | Return value on the FPU stack
Variable of size more than 4 bytes (strings, complex values) or user-defined types more than 8 bytes | Return value on stack, address of value in EAX register
User-defined structures between 5 and 8 bytes | Return value in EAX:EDX registers.


Examples of Fortran/MASM Programming

Several Visual Fortran sample programs have been provided that illustrate Visual Fortran routines that call MASM procedures. These samples are located in subfolders of the ...\DF98\SAMPLES\MIXLANG\MASM folder and include simple, vecprod, and allocabl.


Creating Multithread Applications

Visual Fortran provides support for creating multithread applications. You should consider using more than one thread if your application needs to manage multiple activities, such as simultaneous keyboard input and calculations. One thread can process keyboard input while a second thread performs data transformation calculations. A third thread can update the display screen based on data from the keyboard thread. At the same time, other threads can access disk files, or get data from a communications port.

When using Windows NT 4 or Windows 2000 on a multiprocessor machine (sometimes called an "SMP machine") you can achieve a substantial speedup on numerically intensive problems by dividing the work among different threads; the operating system will assign the different threads to different processors (symmetric multiprocessing or parallel execution). Even if you have a single-processor machine, multiple-window applications might benefit from multithreading because threads can be associated with different windows; one thread can be calculating while another is waiting for input.

While you might gain execution speed by having a program executed in multiple threads, there is overhead involved in managing the threads. You need to evaluate the requirements of your project to determine whether you should run it with more than one thread.

If your multithreaded code calls functions from the run-time library or does input/output, you must also link your code to the multithreaded version of the run-time libraries instead of the regular single-threaded ones. This is described in Compiling and Linking Multithread Programs and Building Programs and Libraries.

For additional resources about threads, processes, and multithreading, see Other Sources of Information.

For more information:

  • Basic Concepts of Multithreading
  • Writing a Multithread Program
  • Compiling and Linking Multithread Programs
  • Other Sources of Information


Basic Concepts of Multithreading

A thread is a path of execution through a program. It is an executable entity that belongs to one and only one process. Each process has at least one thread of execution, automatically created when the process is created. Your main program runs in the first thread. A Win32 thread consists of a stack, the state of the CPU registers, a security context, and an entry in the execution list of the system scheduler. Each thread shares all of the process's resources.

A process consists of one or more threads and the code, data, and other resources of a program in memory. Typical program resources are open files, semaphores (a method of interthread communication), and dynamically allocated memory. A program executes when the system scheduler gives one of its threads execution control. The scheduler determines which threads should run and when they should run. Threads of lower priority might need to wait while higher priority threads complete their tasks. On multiprocessor machines, the scheduler can move individual threads to different processors to balance the CPU load.

Because threads require less system overhead and are easier to create than an entire process, they are useful for time- or resource-intensive operations that can be performed concurrently with other tasks. Threads can be used for operations such as background printing, monitoring a device for input, or backing up data while it is being edited.

When threads, processes, files, and communications devices are opened, the function that creates them returns a handle. Each handle has an associated Access Control List (ACL) that is used to check the security credentials of the process. Processes and threads can inherit a handle or give one away using functions described in this section. Objects and handles regulate access to system resources. For more information on handles and security, see the Win32 Application Programming Interface reference (such as the Platform SDK online title).

All threads in a process execute independently of one another. Unless you take special steps to make them communicate with each other, each thread operates while completely unaware of the existence of other threads in a process. Threads sharing common resources must coordinate their work by using semaphores or another method of interthread communication. For more information on interthread communication, see Sharing Resources.


Writing a Multithread Program

Multiple threads are best used for:

  • Background tasks such as data calculations, database queries, and input gathering, which do not directly involve window management or user interface.
  • Operations that are independent from one another that can benefit from concurrent processing.
  • Asynchronous tasks such as polling on a serial port.

If your application contains tasks that require a private address space and private resources, you can protect them from the activities of other threads by creating multiple processes rather than multiple threads. See Working with Multiple Processes.

The sections that follow discuss the steps you need to consider in creating a multithread application:

  • Modules for Multithread Programs
  • Starting and Stopping Threads
  • Thread Routine Format
  • Sharing Resources
  • Thread Local Storage (TLS)
  • Synchronizing Threads
  • Handling Errors in Multithread Programs
  • Working with Multiple Processes
  • Table of Multithread Routines


Modules for Multithread Programs

A module called DFMT.MOD is supplied with Visual Fortran. It contains interface statements to the underlying Win32 API routines as well as parameter and structure definitions used by the routines. You need to include a USE DFMT statement in the declarations section of every Fortran program unit (program, subroutine, function, or module) that uses multithread API routines.

The source code for the DFMT module (file name DFMT.F90) contains type definitions and external function declarations. You can use it as an added reference for the calling syntax, number, and type of arguments for a multithread procedure.

Other Windows APIs that support multithreading tasks (such as window management functions) are included in the DFWIN.F90 module, available to your programs with the USE DFWIN statement. For information about creating a Fortran Windows application, see Creating Windows Applications.


Starting and Stopping Threads

When you add threads to a process, you need to consider the costs to your process. Create only the number of threads that help your application respond and perform better. You can save time by multitasking, but remember that additional CPU time is needed to keep track of multiple threads. When you are deciding how many threads to create, you also need to consider what data can be process-specific, and what data is thread-specific. Sharing Resources discusses synchronizing access to variables and data.

One single call to the CreateThread function creates a thread, specifies security attributes and memory stack size, and names the routine for the thread to run. Windows allocates memory for the thread stack in the virtual address space of the application that contains the thread. Once a thread has finished processing, the CloseHandle routine frees the resources used by the thread.

For more information:

  • Starting Threads
  • Stopping Threads
  • Other Thread Support Functions

Starting Threads

The function CreateThread creates a new thread. Its return value is an INTEGER(4) thread handle, used in communicating to the thread and when closing it. The syntax for this function is:

CreateThread (security, stack, thread_func, argument, flags, thread_id)

All arguments are INTEGER(4) variables except for thread_func, which names the routine for CreateThread to run. Minimum requirements for thread_func are discussed in Thread Routine Format. The arguments are as follows:

security | This argument uses the SECURITY_ATTRIBUTES type, defined in DFMT.F90. If security is zero, the thread has the default security attributes of the parent process. For more information about setting security attributes for processes and threads, see the Platform SDK online reference.
stack | Defines the stack size of the new thread. All of an application's default stack space is allocated to the first thread of execution. As a result, you must specify how much memory to allocate for a separate stack for each additional thread your program needs. The CreateThread call allows you to specify the value for the stack size on each thread you create. A value of zero indicates the stack has the same size as the application's primary thread. The size of the stack is increased dynamically, if necessary, up to a limit of 1 MB.
thread_func | The starting address for the thread function.
argument | An optional argument for thread_func. Your program defines this parameter and how it is used.
flags | This argument lets you create a thread that will not begin processing until you signal it. The flags argument can take either of two values: 0 or CREATE_SUSPENDED. If you specify 0, the thread is created and runs immediately after creation. If you specify CREATE_SUSPENDED, the thread is created, but does not run until you call the ResumeThread function.
thread_id | This argument is returned by CreateThread. It is a unique identifier for the thread, which you can use when calling other multithread routines. While the thread is running, no other thread has the same identifier. However, the operating system may use the identifier again for other threads once this one has completed. A thread can be referred to by its handle as well as its unique thread identifier. Synchronization functions such as WaitForSingleObject and WaitForMultipleObjects take the thread handle as an argument.

Stopping Threads

The ExitThread routine allows a thread to stop its own execution. The syntax is:

CALL EXITTHREAD ( [ Termination Status ] )

Termination status may be queried by another thread. A termination status of 0 indicates normal termination. You can assign other termination status values and their meaning in your program.

When the called thread is no longer needed, the calling thread needs to close the handle for the thread. Use the CloseHandle routine to free memory used by the thread. A thread object is not deleted until the last thread handle is closed.

It is possible for more than one handle to be open to a thread: for example, if a program creates two threads, one of which waits for information from the other. In this case, two handles are open to the first thread: one from the thread requesting information, the other from the thread that created it. All handles are closed implicitly when the enclosing process terminates.

The TerminateThread routine allows one thread to terminate another, if the security attributes are set appropriately for both threads. DLLs attached to the thread are not notified that the thread is terminating, and its initial stack is not deallocated. Use Terminate Thread for emergencies only.

Other Thread Support Functions

Scheduling thread priorities is supported through the functions GetThreadPriority and SetThreadPriority. Use the priority class of a thread to differentiate between applications that are time critical and those that have normal or below normal scheduling requirements. If you need to manipulate priorities, be very careful not to give a thread too high a priority, or it can consume all of the available CPU time. A thread with a base priority level above 11 interferes with the normal operation of the operating system. Using REALTIME_PRIORITY_CLASS may cause disk caches to not flush, hang the mouse, and so on.

When communicating with other threads, a thread uses a pseudohandle to refer to itself. A pseudohandle is a special constant that is interpreted as the current thread handle. Pseudohandles are only valid for the calling thread; they cannot be inherited by other threads. The GetCurrentThread function returns a pseudohandle for the current thread. The calling thread can use this handle to specify itself whenever a thread handle is required. Pseudohandles are not inherited.

To get the thread's identifier, use the GetCurrentThreadId function. The identifier uniquely identifies the thread in the system until it terminates. You can use the identifier to specify the thread itself whenever an identifier is required.

Use GetExitCodeThread to find out if a thread is still active, or if it is not, to find its exit status. Call GetLastError for more detailed information on the exit status. If one routine depends on a task being performed by a different thread, use the wait functions described in Synchronizing Threads instead of GetExitCodeThread.


Thread Routine Format

A function or subroutine that runs in a separate thread from the main program can take an argument. The code below shows a skeleton for a function and a subroutine:

  INTEGER(4) FUNCTION thrdfnc(arg)
     USE DFMT
     integer(4) arg
!DEC$ ATTRIBUTES VALUE :: arg
     arg = arg + 1      ! Sample only; real work goes here.
     thrdfnc = 0        ! Sets exit code to 0.
  END FUNCTION

  SUBROUTINE thrdfnc2 (arg2)
     USE DFMT
     integer(4) arg2
!DEC$ ATTRIBUTES VALUE :: arg2
           ! Subroutine work goes here.
     Call exitthread(0) ! Exit code is 0.
  END SUBROUTINE

The arguments arg or arg2 are passed to the function or subroutine when the main program calls CreateThread, as the fourth argument. The arguments arg or arg2 are passed by value.

Threads automatically terminate when the function or subroutine terminates.


Sharing Resources

Each thread has its own stack and its own copy of the CPU registers. Other resources, such as files, units, static data, and heap memory, are shared by all threads in the process. Threads using these common resources must coordinate their work. There are several ways to synchronize resources:

  • Critical section – A block of code that accesses a non-shareable resource. Critical sections are typically used to restrict access to data or code that can only be used by one thread at a time within a process (for example, modification of shared data in a common block).
  • MUTual EXclusion object (Mutex) – A mechanism that allows only one thread at a time to access a resource. Mutexes are typically used to restrict access to a system resource that can only be used by one thread at a time (for example, a printer), or when sharing might produce unpredictable results.
  • Semaphore – A counter that regulates the number of threads that can use a resource. Semaphores are typically used to control access to a specified number of identical resources.
  • Event – An event object announces that an event has happened to one or more threads.

The state of each of these objects is either signaled or not-signaled. A signaled state indicates a resource is available for a process or thread to use it. A not-signaled state indicates the resource is in use.

The routines described in the following sections manage the creation, initialization, and termination of resource sharing mechanisms. Some of them change the state to signaled from not-signaled. The routines WaitForSingleObject and WaitForMultipleObjects also change the signal status of an object. For information on these functions, see Synchronizing Threads.

This section also contains information about:

  • Memory Use and Thread Stacks
  • I/O Operations

For resources about coordinating and synchronizing Win32 threads, see Other Sources of Information.

Critical Sections

Before you can synchronize threads with a critical section, you must initialize it by calling InitializeCriticalSection. Call EnterCriticalSection when beginning to process the global variable, and LeaveCriticalSection when the application is finished with it. Both EnterCriticalSection and LeaveCriticalSection can be called several times within an application. For Multithreaded Visual Fortran Samples that use Critical Sections, see PEEKAPP.F90 or PEEKAPP3.F90.

Mutexes

CreateMutex creates a mutex object. It returns an error if the mutex already exists (one by the same name was created by another process or thread). Call GetLastError after calling CreateMutex to look for the error status ERROR_ALREADY_EXISTS. You can also use the OpenMutex function to determine whether or not a named mutex object exists. When called, OpenMutex returns the object's handle if it exists, or null if a mutex with the specified name is not found. Using OpenMutex does not change a mutex object to a signaled state; this is accomplished by one of the wait routines described in Synchronizing Threads.

ReleaseMutex changes a mutex from the not-signaled state to the signaled state. This function only has an effect if the thread calling it also owns the mutex. When the mutex is in a signaled state, any thread waiting for it can acquire it and begin executing.

Semaphores

Functions for handling semaphores are nearly identical to functions that manage mutexes. CreateSemaphore creates a semaphore, specifying an initial as well as a maximum count for the number of threads that can access the resource. OpenSemaphore, like OpenMutex, returns the handle of the named semaphore object, if it exists. The handle can then be used in any function that requires it (such as one of the wait functions described in Synchronizing Threads). Calling OpenSemaphore does not reduce a resource's available count; this is accomplished by the function waiting for the resource.

Use ReleaseSemaphore to increase the available count for a resource by a specified amount. You can call this function when the thread is finished with the resource. Another possible use is to call CreateSemaphore, specifying an initial count of zero to protect the resource from access during an initialization process. When the application has finished its initialization, call ReleaseSemaphore to increase the resource's count to its maximum.

Events

Event objects can trigger execution of other threads. You can use events if one thread provides data to several other threads. An event object is created by the CreateEvent function. The creating thread specifies the initial state of the object and whether it is a manual-reset or auto-reset event. A manual-reset event is one whose state remains signaled until it is explicitly reset by a call to ResetEvent. An auto-reset event is automatically reset by the system when a single waiting thread is released.

Use either SetEvent or PulseEvent to set an event object's state to signaled. OpenEvent returns a handle to the event, which can be used in other function calls. ReleaseEvent releases ownership of the event.

Memory Use and Thread Stacks

Because each thread has its own stack, you can avoid potential collisions over data items by using as little static data as possible. Design your program to use automatic stack variables for all data that can be private to a thread. All the variables declared in a multithread routine are by default static and shared among the threads. If you do not want one thread to overwrite a variable used by another, you can do one of the following:

  • Declare the variable as AUTOMATIC.
  • Create a vector of variable values, one for each thread, so that the variable values for different threads are in different storage locations. (You can use the single integer parameter passed by CreateThread as an index to identify the thread.)
  • Use Thread Local Storage (TLS).

Variables declared as automatic are placed on the stack, which is part of the thread context saved with the thread. Automatic variables within procedures are discarded when the procedure completes execution.

I/O Operations

Although files and units are shared between threads, you may not need to coordinate the use of these shared resources by threads. Fortran treats each input/output statement as an atomic operation. If two separate threads try to write to the same unit and one thread's output operation has started, the operation will complete before the other thread's output operation can begin.

The operating system does not impose an ordering on threads' access to units or files. For example, the non-determinate nature of multithread applications can cause records in a sequential file to be written in a different order on each execution of the application as each thread writes to the file. Direct access files might be a better choice than sequential files in such a case. If you cannot use direct access files, use mutexes to impose an ordering constraint on input or output of sequential files.

Certain restrictions apply to blocking functions for input procedures in QuickWin programs. For details on these restrictions, see Using QuickWin.


Thread Local Storage

Thread Local Storage (TLS) calls allow you to store per-thread data. TLS is the method by which each thread in a multithreaded process can allocate locations in which to store thread-specific data.

Dynamically bound (run-time) thread-specific data is supported by routines such as TlsAlloc (allocates an index to store data), TlsGetValue (retrieves values from an index), TlsSetValue (stores values into an index), and TlsFree (frees the dynamic storage). Threads allocate dynamic storage and use TlsSetValue to associate the index with a pointer to that storage. When a thread needs to access the storage, it calls TlsGetValue, specifying the index.

When all threads have finished using the index, TlsFree frees the dynamic storage.


Synchronizing Threads

The routines WaitForSingleObject and WaitForMultipleObjects enable threads to wait for a variety of different occurrences, such as thread completion or signals from other threads. They enable threads and processes to wait efficiently, consuming no CPU resources, either indefinitely or until a specified timeout interval has elapsed.

WaitForSingleObject takes an object handle as the first parameter and does not return until the object referenced by the handle either reaches a signaled state or until a specified timeout value elapses. The syntax is:

WaitResult = WaitForSingleObject (ObjectHandle, [ Timeout ] )

If you are using a timeout, specify the value in milliseconds as the second parameter. The value WAIT_INFINITE represents an infinite timeout, in which case the function waits until ObjectHandle completes.

WaitForMultipleObjects is similar, except that its second parameter is an array of Windows object handles. Specify the number of handles to wait for in the first parameter. This can be less than the total number of threads created, and its maximum is 64. The function can either wait until all events have completed, or resume as soon as any one of the objects completes.

Deadlocks occur when a thread waits for objects that never become available. Use the timeout parameter when there is a chance that the thread you are waiting for may never terminate. See Detecting Deadlocks in Multithreaded Win32 Applications," by Ruediger Asche, in the Microsoft Systems Journal, vol. 8, for a discussion of how to find and avoid potential resource collisions.

Suspending and Resuming Threads

You can use SuspendThread to stop a thread from executing. SuspendThread is not particularly useful for synchronization because it does not control the point in the code at which the thread's execution is suspended. However, you could suspend a thread if you need to confirm a user's input that would terminate the work of the thread. If confirmed, the thread is terminated; otherwise, it resumes.

If a thread is created in a suspended state, it does not begin to run until ResumeThread is called with a handle to the suspended thread. This can be useful for initializing the thread's state before it begins to run. Suspending a thread at creation can be useful for one-time synchronization, because ResumeThread ensures that the suspended thread will resume running at the starting point of its code.


Handling Errors in Multithread Programs

Use the GetLastError function to obtain error information if any of the multithreading routines returns an error code. Remember that it returns the error code of the last error, not necessarily the error status of the last call.

Error codes are 32-bit values. Bit 29 is reserved for application-defined error codes. You can set this bit and use SetLastError if you are creating your own dynamic-link library, to emulate Win32 API behavior. Win32 functions only call SetLastError when they fail, not when they succeed.

The last error code value is kept in Thread Local Storage, so that multiple threads do not overwrite each other's values.


Working with Multiple Processes

The multithread libraries provide a number of routines for working with multiple processes. An application can use multiple processes for functions that require a private address space and private resources, to protect them from the activities of other threads. It is usually more efficient to implement multitasking by creating several threads in one process, rather than by creating multiple processes, for these reasons:

  • The system can create and execute threads more quickly than it can create processes, since the code for threads has already been mapped into the address space of the process, while the code for a new process must be loaded.
  • All threads of a process share the same address space and can access the process's global variables, which can simplify communications between threads.
  • All threads of a process can use open handles to resources such as files and pipes.

If you want to create an independent process that runs concurrently with the current one, use CreateProcess. CreateProcess returns a 32-bit process identifier that is valid until the process terminates. ExitProcess stops the process and notifies all DLLs the process is terminating.

Different processes can share mutexes, events, and semaphores (but not critical sections). Processes can also optionally inherit handles from the process that created them (see online help for CreateProcess).

You can obtain information about the current process by calling GetCurrentProcess (returns a pseudohandle to its own process), and GetCurrentProcessId (returns the process identifier). The value returned by these functions can be used in calls to communicate with other processes. GetExitCodeProcess returns the exit code of a process, or an indication that it is still running.

The OpenProcess function opens a handle to a process specified by its process identifier. OpenProcess allows you to specify the handle's access rights and inheritability.

A process terminates whenever one of the following occurs:

  • Any thread of the process calls ExitProcess
  • The primary thread of the process returns
  • The last thread of the process terminates
  • TerminateProcess is called with a handle to the process

ExitProcess is the preferred way to terminate a process because it notifies all attached DLLs of the termination, and ensures that all threads of the process terminate. DLLs are not notified after a call to TerminateProcess.


Table of Multithread Routines

The following table lists routines available for multithread programs. For information about the calling syntax of these routines, see the Platform SDK title in HTML Help Viewer.

Routine | Description
CloseHandle | Closes an open object handle.
CreateEvent | Creates a named or unnamed event object.
CreateMutex | Creates a named or unnamed mutex object.
CreateProcess | Creates a new process and its primary thread.
CreateSemaphore | Creates a named or unnamed semaphore object.
CreateThread | Creates a thread to execute within the address space of the calling process.
DeleteCriticalSection | Releases all resources used by an unowned critical section object.
DuplicateHandle | Duplicates an object handle.
EnterCriticalSection | Waits for ownership of the specified critical section object.
ExitProcess | Ends a process and all its threads.
ExitThread | Ends a thread.
GetCurrentProcess | Returns a pseudohandle for the current process.
GetCurrentProcessId | Returns the process identifier of the calling process.
GetCurrentThread | Returns a pseudohandle for the current thread.
GetCurrentThreadId | Returns the thread identifier of the calling thread.
GetExitCodeProcess | Retrieves the termination status of the specified process.
GetExitCodeThread | Retrieves the termination status of the specified thread.
GetLastError | Returns the calling thread's last-error code value.
GetPriorityClass | Returns the priority class for the specified process.
GetThreadPriority | Returns the priority value for the specified thread.
InitializeCriticalSection | Initializes a critical section object.
LeaveCriticalSection | Releases ownership of the specified critical section object.
OpenEvent | Returns a handle of an existing named event object.
OpenMutex | Returns a handle of an existing named mutex object.
OpenProcess | Returns a handle of an existing process object.
OpenSemaphore | Returns a handle of an existing named semaphore object.
PulseEvent | As a single operation, sets (to signaled) and then resets the state of the specified event object after releasing the appropriate number of waiting threads.
ReleaseMutex | Releases ownership of the specified mutex object.
ReleaseSemaphore | Increases the count of the specified semaphore object by a specified amount.
ResetEvent | Sets the state of the specified event object to nonsignaled.
ResumeThread | Decrements a thread's suspend count. When the suspend count is zero, execution of the thread resumes.
SetEvent | Sets the state of the specified event object to signaled.
SetLastError | Sets the last-error code for the calling thread.
SetPriorityClass | Sets the priority class for the specified process.
SetThreadPriority | Sets the priority value for the specified thread.
SuspendThread | Suspends the specified thread.
TerminateProcess | Terminates the specified process and all of its threads.
TerminateThread | Terminates a thread.
TlsAlloc | Allocates a thread local storage (TLS) index.
TlsFree | Releases a thread local storage (TLS) index, making it available for reuse.
TlsGetValue | Retrieves the value in the calling thread's thread local storage (TLS) slot for a specified TLS index.
TlsSetValue | Stores a value in the calling thread's thread local storage (TLS) slot for a specified TLS index.
WaitForMultipleObjects | Returns either any one or all of the specified objects are in the signaled state or when the time-out interval elapses.
WaitForSingleObject | Returns when the specified object is in the signaled state or the time-out interval elapses.

If a function mentioned in this section is not listed in the preceding table, it is only available through the USE DFWIN statement.


Compiling and Linking Multithread Programs

The support library DFORMT.LIB is a re-entrant library for creating statically linked multithread programs. The DFORMD.LIB library, which calls code in the shared DFORMD.DLL, is also re-entrant. Programs built with DFORMT.LIB do not share Fortran run-time library code or data with any dynamic-link libraries they call. You must link with DFORMD.LIB if you plan to call a DLL.

To build a multithread application that uses the Fortran run-time libraries, you must tell the linker to use a special version of the libraries. You can specify the /threads compiler option from the command line, or in the Microsoft visual development environment in the Project Settings dialog box, as described in the following paragraph.

A sample multithread project THREADS is included in the ...\DF98\SAMPLES\ADVANCED\WIN32\THREADS folder. To build this sample, open the project workspace file and choose Build All from the Build menu. Listed following are the steps for compiling and linking your own multithread program using the visual development environment.

To compile and link your multithread program:

  1. Create a new project. Choose the Project tab, then specify the project type. (The sample THREADS.F90 is a Fortran Windows project.)
  2. Add the file containing the source code to the project.
  3. From the Project menu, select Settings.
    The Project Settings dialog box appears.
  4. Choose the Fortran tab, Fortran Libraries category, and set the Use Multi-Threaded Library check box and set the Use Runtime Libraries to Static (DFORMT.LIB) or DLL (DFORMD.LIB).
  5. Create the executable file by choosing Build All from the Build menu.

The following steps describe how to compile and link the sample multithread program from the command line.

To compile and link the sample multithread program from the command line:

  1. Make sure the library files directory is specified in your LIB environment variable.
  2. Compile and link the program with the DF command-line option /threads.
    For example:
      DF /threads  MYTHREAD.F90

The /threads compiler option (automatically set when you specify a multithread application in the visual development environment) tells the linker to use DFORMT.LIB as a default library.

To compile and link the THREADS.F90 sample, the command is:

  DF /winapp /threads THREADS.F90

The /threads compiler option causes the linker to search the multithread library; the /winapp requests a Fortran Windows application.

Select the compiler options /libs=dll and /threads if you are using both multithread code and DLLs. You can use the /libs=dll and /threads options only with Fortran Console projects, not QuickWin applications.


Other Sources of Information

For a thorough discussion of threads, processes, and multithreading, see Helen Custer's book Inside Windows NT, available from Microsoft Press. Articles on how to accomplish multithreading have also been published in the Microsoft Developer Network (MSDN) CD-ROM and the Microsoft Systems Journal:

  • The Microsoft Developer Network CD-ROM contains several articles on multithreading:
    • "Multiple Threads in the User Interface," by Nancy Winnick Cluts, discusses the ramifications of adding multiple threads to the user interface. This article not only offers alternatives to multiple threads, but also covers window management and message loops for multithreading.
    • "Multithreading for Rookies," by Ruediger R. Asche, focuses on practical applications of multithreading.
    • "Detecting Deadlocks in Multithreaded Win32 Applications," by Ruediger R. Asche, presents deadlock detection techniques. A deadlock is a condition in which the application hangs because two or more threads are waiting for each other to release a shared resource before resuming execution.
    • "Moving Unix Applications to Windows NT," provides an overview of Windows multithreading calls, contrasting them with Unix fork() calls.

  • The Microsoft Systems Journal is also a source of information on multithreading:
    • "Coordinate Win32 threads using manual-reset and auto-reset events," by Jeffrey Richter. October 1993, v8 n10.
    • "Synchronizing Win32 threads using critical sections, semaphores, and mutexes," by Jeffrey Richter. August 1993, v8 n8.


Data Representation

Visual Fortran expects numeric data to be in native little endian order, in which the least-significant, right-most zero bit (bit 0) or byte has a lower address than the most-significant, left-most bit (or byte). For information on using nonnative big endian and Compaq VAX floating-point formats, see Converting Unformatted Numeric Data.

The symbol :A in any figure specifies the address of the byte containing bit 0, which is the starting address of the represented data element.

The following table lists the intrinsic data types used by Visual Fortran, the storage required, and valid ranges. For information on declarating Fortran intrinsic data types, see Type Declaration Statements. For example, the declaration INTEGER(4) is the same as INTEGER(KIND=4) and INTEGER*4.

Compaq Fortran Data Types and Storage

Data Type | Storage | Description
BYTE INTEGER(1) | 1 byte (8 bits) | A BYTE declaration is a signed integer data type equivalent to INTEGER(1).
INTEGER | See INTEGER(2), INTEGER(4), and INTEGER(8). | Signed integer, either INTEGER(2), INTEGER(4), or INTEGER(8). The size is controlled by the /integer_size:nn compiler option. The default is /integer_size:32 (INTEGER(4)).
INTEGER(1) | 1 byte (8 bits) | Signed integer value from -128 to 127.
INTEGER(2) | 2 bytes (16 bits) | Signed integer value from -32,768 to 32,767.
INTEGER(4) | 4 bytes (32 bits) | Signed integer value from -2,147,483,648 to 2,147,483,647.
INTEGER(8) | 8 bytes (64 bits) | Signed integer value from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.
REAL(4) REAL | 4 bytes (32 bits) | Single-precision real floating-point values in IEEE S_floating format ranging from 1.17549435E-38 to 3.40282347E38. Values between 1.17549429E-38 and 1.40129846E-45 are denormalized (subnormal).
REAL(8) DOUBLE PRECISION | 8 bytes (64 bits) | Double-precision real floating-point values in IEEE T_floating format ranging from 2.2250738585072013D-308 to 1.7976931348623158D308. Values between 2.2250738585072008D-308 and 4.94065645841246544D-324 are denormalized (subnormal).
COMPLEX(4) COMPLEX | 8 bytes (64 bits) | Single-precision complex floating-point values in a pair of IEEE S_floating format parts: real and imaginary. The real and imaginary parts range from 1.17549435E-38 to 3.40282347E38. Values between 1.17549429E-38 and 1.40129846E-45 are denormalized (subnormal).
COMPLEX(8) DOUBLE COMPLEX | 16 bytes (128 bits) | Double-precision complex floating-point values in a pair of IEEE T_floating format parts: real and imaginary. The real and imaginary parts each range from 2.2250738585072013D-308 to 1.7976931348623158D308. Values between 2.2250738585072008D-308 and 4.94065645841246544D-324 are denormalized (subnormal).
LOGICAL | See LOGICAL(2), LOGICAL(4), and LOGICAL(8). | Logical value, either LOGICAL(2), LOGICAL(4), or LOGICAL(8). The size is controlled by the /integer_size:nn compiler option. The default is /integer_size:32 (LOGICAL(4)).
LOGICAL(1) | 1 byte (8 bits) | Logical values .TRUE. or .FALSE.
LOGICAL(2) | 2 bytes (16 bits) | Logical values .TRUE. or .FALSE.
LOGICAL(4) | 4 bytes (32 bits) | Logical values .TRUE. or .FALSE.
LOGICAL(8) | 8 bytes (64 bits) | Logical values .TRUE. or .FALSE.
CHARACTER | 1 byte (8 bits) per character | Character data represented by character code convention. Character declarations can be in the form CHARACTER(LEN=n) or CHARACTER*n, where n is the number of bytes or n is (*) to indicate passed-length format.
HOLLERITH | 1 byte (8 bits) per Hollerith character | Hollerith constants.

In addition, you can define binary (bit) constants as explained in the Language Reference.

The following sections discuss the intrinsic data types in more detail:

  • Integer Data Representations
  • Logical Data Representations
  • Native IEEE Floating-Point Representations
  • Character Representation
  • Hollerith Representation


Integer Data Representations

Integer data lengths can be 1-, 2-, 4-, or 8-bytes in length.

The default data size used for an INTEGER data declaration is INTEGER(4) (same as INTEGER(KIND=4)), unless the /integer_size:16 or the /integer_size:64 option was specified.

Integer data is signed with the sign bit being 0 (zero) for positive numbers and 1 for negative numbers.

The following sections discuss integer data:

  • INTEGER(KIND=1) Representation
  • INTEGER(KIND=2) Representation
  • INTEGER(KIND=4) Representation
  • INTEGER(KIND=8) Representation


INTEGER(KIND=1) Representation

INTEGER(1) values range from -128 to 127 and are stored in 1 byte, as shown below.

INTEGER(1) Data Representation

INTEGER(1) Data Representation

Integers are stored in a two's complement representation. For example:

+22 = 16(hex)
 -7 = F9(hex)


INTEGER(KIND=2) Representation

INTEGER(2) values range from -32,768 to 32,767 and are stored in 2 contiguous bytes, as shown below:

INTEGER(2) Data Representation

INTEGER(2) Data Representation

Integers are stored in a two's complement representation. For example:

+22 = 0016(hex)
 -7 = FFF9(hex)


INTEGER(KIND=4) Representation

INTEGER(4) values range from -2,147,483,648 to 2,147,483,647 and are stored in 4 contiguous bytes, as shown below.

INTEGER(4) Data Representation

INTEGER(4) Data Representation

Integers are stored in a two's complement representation.


INTEGER(KIND=8) Representation

INTEGER(8) values range from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 and are stored in 8 contiguous bytes, as shown below.

INTEGER(8) Data Representation

INTEGER(8) Data Representation

Integers are stored in a two's complement representation.


Logical Data Representations

Logical data lengths can be 1-, 2-, 4-, or 8-bytes in length.

The default data size used for a LOGICAL data declaration is LOGICAL(4) (same as LOGICAL(KIND=4)), unless the /integer_size:16 or /integer_size:64 option was specified.

To improve performance on ia64 systems, use LOGICAL(4) (or LOGICAL(8)) rather than LOGICAL(2) or LOGICAL(1).

LOGICAL(KIND=1) values are stored in 1 byte. In addition to having logical values .TRUE. and .FALSE., LOGICAL(1) data can also have values in the range -128 to 127. Logical variables can also be interpreted as integer data.

In addition to LOGICAL(1), logical values can also be stored in 2 (LOGICAL(2)), 4 (LOGICAL(4)), or 8 (LOGICAL(8)) contiguous bytes, starting on an arbitrary byte boundary.

If the /fpscomp:nological compiler option is set (the default), the low-order bit determines whether the logical value is true or false. Specify /fpscomp:logical for Microsoft Fortran PowerStation logical values, where 0 (zero) is false and non-zero values are true.

LOGICAL(1), LOGICAL(2), LOGICAL(4), and LOGICAL(8) data representation (when /fpscomp:nological option was set) appears below.

LOGICAL(1), LOGICAL(2), LOGICAL(4), and LOGICAL(8) Data Representations

LOGICAL(1), LOGICAL(2), LOGICAL(4), and LOGICAL(8) Data Representations


Native IEEE Floating-Point Representations

The REAL(4) (S_floating) and REAL(8) (T_floating) formats are stored in standard little endian IEEE binary floating-point notation. (See IEEE Standard 754 for additional information about IEEE binary floating point notation.) COMPLEX() and COMPLEX() formats use a pair of REAL(KIND=4) or REAL(8) values to denote the real and imaginary parts of the data.

For IEEE S_floating and T_floating formats, fractions are represented in sign-magnitude notation, with the binary radix point to the right of the most-significant bit. Fractions are assumed to be normalized, and therefore the most-significant bit is not stored (this is called "hidden bit normalization"). This bit is assumed to be 1 unless the exponent is 0. If the exponent equals 0, then the value represented is denormalized (subnormal) or plus or minus zero.

The following sections discuss floating-point data:

  • REAL(KIND=4) (REAL) Representation
  • REAL(KIND=8) (DOUBLE PRECISION) Representation
  • COMPLEX(KIND=4) (COMPLEX) Representation
  • COMPLEX(KIND=8) (DOUBLE COMPLEX) Representation

For more information:

  • On using the BitViewer tool, see Viewing Floating-Point Representations with BitViewer.
  • Reading or writing floating-point data other than native IEEE little endian data, see Converting Unformatted Numeric Data.
  • Using floating-point numbers, see The Floating-Point Environment.


REAL(KIND=4) (REAL) Representation

REAL(4) (same as REAL(KIND=4)) data occupies 4 contiguous bytes stored in IEEE S_floating format. Bits are labeled from the right, 0 through 31, as shown below.

REAL(4) Floating-Point Data Representation

REAL(4) Floating-Point Data Representation

The form of REAL(4) data is sign magnitude, with bit 31 the sign bit (0 for positive numbers, 1 for negative numbers), bits 30:23 a binary exponent in excess 127 notation, and bits 22:0 a normalized 24-bit fraction including the redundant most-significant fraction bit not represented.

The value of data is in the approximate range: 1.17549435E-38 (normalized) to 3.40282347E38. The IEEE denormalized (subnormal) limit is 1.40129846E-45. The precision is approximately one part in 2**23; typically 7 decimal digits.


REAL(KIND=8) (DOUBLE PRECISION) Representation

REAL(8) (same as REAL(KIND=8)) data occupies 8 contiguous bytes stored in IEEE T_floating format. Bits are labeled from the right, 0 through 63, as shown below.

REAL(8) Floating-Point Data Representation

REAL(8) Floating-Point Data Representation

The form of REAL(8) data is sign magnitude, with bit 63 the sign bit (0 for positive numbers, 1 for negative numbers), bits 62:52 a binary exponent in excess 1023 notation, and bits 51:0 a normalized 53-bit fraction including the redundant most-significant fraction bit not represented.

The value of data is in the approximate range: 2.2250738585072013D-308 (normalized) to 1.7976931348623158D308. The IEEE denormalized (subnormal) limit is 4.94065645841246544D-324. The precision is approximately one part in 2**52; typically 15 decimal digits.


COMPLEX(KIND=4) (COMPLEX) Representation

COMPLEX(4) (same as COMPLEX(KIND=4) and COMPLEX*8) data is 8 contiguous bytes containing a pair of REAL(4) values stored in IEEE S_floating format. The low-order 4 bytes contain REAL(4) data that represents the real part of the complex number. The high-order 4 bytes contain REAL(4) data that represents the imaginary part of the complex number, as shown below.

COMPLEX(4) Floating-Point Data Representation

COMPLEX(4) Floating-Point Data Representation

The limits and underflow characteristics for REAL(4) apply to the two separate real and imaginary parts of a COMPLEX(4) number. Like REAL(4) numbers, the sign bit representation is 0 (zero) for positive numbers and 1 for negative numbers.


COMPLEX(KIND=8) (DOUBLE COMPLEX) Representation

COMPLEX(8) (same as COMPLEX(KIND=8) and COMPLEX*16) data is 16 contiguous bytes containing a pair of REAL(8) values stored in IEEE T_floating format. The low-order 8 bytes contain REAL(8) data that represents the real part of the complex data. The high-order 8 bytes contain REAL(8) data that represents the imaginary part of the complex data, as shown below.

COMPLEX(8) Floating-Point Data Representation

COMPLEX(8) Floating-Point Data Representation

The limits and underflow characteristics for REAL(8) apply to the two separate real and imaginary parts of a COMPLEX(8) number. Like REAL(8) numbers, the sign bit representation is 0 (zero) for positive numbers and 1 for negative numbers.


Character Representation

A character string is a contiguous sequence of bytes in memory, as shown below.

CHARACTER Data Representation

CHARACTER Data Representation

A character string is specified by two attributes: the address A of the first byte of the string, and the length L of the string in bytes. The length L of a string is in the range 1 through 2,147,483,647 (2**31-1) .


Hollerith Representation

Hollerith constants are stored internally, one character per byte, as shown below.

Hollerith Data Representation

Hollerith Data Representation


Handling Run-Time Errors

This section contains information on the following topics:

  • Default Run-Time Error Processing, which describes the message format and values returned at program termination.
  • Methods of Handling Errors, which describes using the END, EOR, and ERR I/O statement branch specifiers and the IOSTAT specifier.
  • Locating Run-Time Errors, which describes suggested compiler options and information about debugging exceptions.
  • Using Traceback Information, which describes techniques to help you locate the cause of severe run-time errors.
  • Obtaining Traceback Information with TRACEBACKQQ, which explains how to call a routine to obtain traceback information from your application.
  • Run-Time Environment Variables, which describes environment variables that allow program continuation under certain conditions, disable the display of certain dialog boxes under certain conditions, and allow just-in-time debugging.

During execution, your program may encounter errors or exception conditions. These conditions can result from any of the following:

  • Errors that occur during I/O operations
  • Invalid input data
  • Argument errors in calls to the mathematical library
  • Arithmetic errors
  • Other system-detected errors

The Visual Fortran run-time system (Run-Time Library or RTL) generates appropriate messages and takes action to recover from errors whenever possible.

For a description of each Visual Fortran run-time error message, see Run-Time Errors.


Default Run-Time Error Processing

The Visual Fortran run-time system processes a number of errors that can occur during program execution. A default action is defined for each error recognized by the Visual Fortran run-time system. The default actions described throughout this chapter occur unless overridden by explicit error-processing methods.

The way in which the Visual Fortran run-time system actually processes errors depends upon the following factors:

  • The severity of the error. For instance, the program usually continues executing when an error message with a severity level of warning or info (informational) is detected.
  • For certain errors associated with I/O statements, whether or not an I/O error-handling specifier was specified.
  • For certain errors, whether or not the default action of an associated signal was changed.
  • For certain errors related to arithmetic operations (including floating-point exceptions), compilation options can determine whether the error is reported and the severity of the reported error.

How arithmetic exception conditions are reported and handled depends on the cause of the exception and how the program was compiled. Unless the program was compiled to handle exceptions, the exception might not be reported until after the instruction that caused the exception condition.

For more information:

  • About where Visual Fortran run-time message are displayed and their format, see Run-Time Message Display and Format.
  • On the Visual Fortran return values at program termination, see Values Returned at Program Termination.
  • On locating errors and the compiler options related to handling errors and exceptions, see Locating Run-Time Errors and Using Traceback Information.
  • On DF command options and their categories in the visual development environment (Project Settings, Fortran tab), see Categories of Compiler Options.
  • On Compaq Fortran intrinsic data types and their ranges, see Data Representation.
  • On the floating-point environment, see The Floating-Point Environment.
  • On creating exception and termination handlers, see Advanced Exception and Termination Handling Considerations.


Run-Time Message Display and Format

When errors occur during program execution (run time) of a program, the Visual Fortran run-time system issues diagnostic messages. Where Fortran run-time messages are displayed depends upon the Fortran project type:

Project Type | Where Fortran Run-Time Messages Appear
Fortran Console applications | Run-time error messages are displayed on the standard error device (unless redirected).
Fortran QuickWin and Fortran Standard Graphics applications | Run-time error messages are displayed in a separate QuickWin message box.
Fortran Windows applications | Run-time error messages are displayed in a separate message box.

Fortran run-time messages have the following format:

forrtl: severity (number): message-text
where:
  • forrtl
    Identifies the source as the Visual Fortran run-time system (Run-Time Library or RTL).

  • severity
    The severity levels are: severe, error, warning, or info (abbreviation of information).

  • number
    This is the message number, also the IOSTAT value for I/O statements.

  • message-text
    Explains the event that caused the message.

The following table explains the severity levels of run-time messages, in the order of greatest to least severity.

Severity Levels of Run-Time Messages

Severity | Description
severe | Must be corrected. The program's execution is terminated when the error is encountered unless the program's I/O statements use the END, EOR, or ERR branch specifiers to transfer control, perhaps to a routine that uses the IOSTAT specifier (see the section Using the END, EOR, and ERR Branch Specifiers and the section Using the IOSTAT Specifier and Fortran Exit Codes). For severe errors, a hexadecimal dump of the call stack (program counter trace) is displayed after the error message. If the /traceback option was specified, the displayed call stack program counter trace includes the source file name, routine name, and source line number of your Fortran source code.
error | Should be corrected. The program might continue execution, but the output from this execution may be incorrect.
warning | Should be investigated. The program continues execution, but output from this execution may be incorrect.
info | For informational purposes only; the program continues.

For a description of each Visual Fortran run-time error message, see Visual Fortran Run-Time Errors


Values Returned at Program Termination

A Visual Fortran program can terminate in one of several ways:

  • The program runs to normal completion. A value of zero is returned to the shell.
  • The program stops with a STOP statement. A value of zero is returned to the shell.
  • The program stops because of a signal that is caught but does not allow the program to continue. A value of 1 is returned to the shell.
  • The program stops because of a severe run-time error. The error number for that run-time error is returned to the shell. Error numbers are listed in Visual Fortran Run-Time Errors.
  • The program stops with a CALL EXIT statement. The value passed to EXIT is returned to the shell.


Methods of Handling Errors

Whenever possible, the Visual Fortran RTL does certain error handling, such as generating appropriate messages and taking necessary action to recover from errors. You can explicitly supplement or override default actions by using the following methods:

  • To transfer control to error-handling code within the program, use the END, EOR, and ERR branch specifiers in I/O statements, see Using the END, EOR, and ERR Branch Specifiers.
  • To identify Fortran-specific I/O errors based on the value of Visual Fortran RTL error codes, use the I/O status specifier (IOSTAT) in I/O statements (or call the ERRSNS subroutine), see Using the IOSTAT Specifier and Fortran Exit Codes.

These error-processing methods are complementary; you can use any or all of them within the same program to obtain Visual Fortran run-time error codes.


Using the END, EOR, and ERR Branch Specifiers

When a severe error occurs during Visual Fortran program execution, the default action is to display an error message and terminate the program. To override this default action, there are three branch specifiers you can use in I/O statements to transfer control to a specified point in the program:

  • The END branch specifier handles an end-of-file condition.
  • The EOR branch specifier handles an end-of-record condition for nonadvancing reads.
  • The ERR branch specifier handles all error conditions.

If you use the END, EOR, or ERR branch specifiers, no error message is displayed and execution continues at the designated statement, usually an error-handling routine.

You might encounter an unexpected error that the error-handling routine cannot handle. In this case, do one of the following:

  • Modify the error-handling routine to display the error message number.
  • Remove the END, EOR, or ERR branch specifiers from the I/O statement that causes the error.

After you modify the source code, compile, link, and run the program to display the error message. For example:

    READ (8,50,ERR=400)

If any severe error occurs during execution of this statement, the Visual Fortran RTL transfers control to the statement at label 400. Similarly, you can use the END specifier to handle an end-of-file condition that might otherwise be treated as an error. For example:

    READ (12,70,END=550)

When using nonadvancing I/O, use the EOR specifier to handle the end-of-record condition. For example:

150 FORMAT (F10.2, F10.2, I6)
    READ (UNIT=20, FMT=150, SIZE=X, ADVANCE='NO', EOR=700) A, F, I

You can also use ERR as a specifier in an OPEN, CLOSE, or INQUIRE statement. For example:

    OPEN (UNIT=10, FILE='FILNAM', STATUS='OLD', ERR=999)

If an error is detected during execution of this OPEN statement, control transfers to the statement at label 999.


Using the IOSTAT Specifier and Fortran Exit Codes

You can use the IOSTAT specifier to continue program execution after an I/O error and to return information about I/O operations. As described in Visual Fortran Run-Time Errors, certain errors are not returned in IOSTAT.

Although the IOSTAT specifier transfers control, it can only return information returned by the Visual Fortran RTL. For additional error handling capabilities, see the GERROR and PERROR routines.

The IOSTAT specifier can supplement or replace the END, EOR, and ERR branch transfers.

Execution of an I/O statement containing the IOSTAT specifier suppresses the display of an error message and defines the specified integer variable, array element, or scalar field reference as one of the following, which is returned as an exit code if the program terminates:

  • A value of -2 if an end-of-record condition occurs with nonadvancing reads.
  • A value of -1 if an end-of-file condition occurs.
  • A value of 0 for normal completion (not an error condition, end-of-file, or end-of-record condition).
  • A positive integer value if an error condition occurs. (This value is one of the Fortran-specific IOSTAT numbers listed in Visual Fortran Run-Time Errors.)

Following the execution of the I/O statement and assignment of an IOSTAT value, control transfers to the END, EOR, or ERR statement label, if any. If there is no control transfer, normal execution continues. For more information on transfer of control, see Branch Statements.

You can include the iosdef.for file in your program to obtain symbolic definitions for the values of IOSTAT.

The following example uses the IOSTAT specifier and the iosdef.for file to handle an OPEN statement error (in the FILE specifier).

Error Handling OPEN Statement File Name

     CHARACTER(LEN=40) :: FILNM
     INCLUDE 'iosdef.for'

     DO I=1,4
       FILNM = ''
       WRITE (6,*)  'Type file name '
       READ (5,*) FILNM
       OPEN (UNIT=1, FILE=FILNM, STATUS='OLD', IOSTAT=IERR, ERR=100)
       WRITE (6,*) 'Opening file: ', FILNM
!       (process the input file)
       CLOSE (UNIT=1)
       STOP

  100  IF (IERR .EQ. FOR$IOS_FILNOTFOU) THEN
         WRITE (6,*) 'File: ', FILNM, ' does not exist '
       ELSE IF (IERR .EQ. FOR$IOS_FILNAMSPE) THEN
          WRITE (6,*) 'File: ', FILNM, ' was bad, enter new file name'
       ELSE
         PRINT *, 'Unrecoverable error, code =', IERR
         STOP
       END IF
     END DO
     WRITE (6,*) 'File not found. Locate correct file with Explorer and run again'
   END PROGRAM

Within the DO loop, instead of the READ statement that assigns a value to variable FILNM, you could instead call the GetOpenFileName Win32 routine, which requests the file name using a dialog box. For an example of how to call the GetOpenFileName routine, see the Visual Fortran Sample GetOpenFileName in ...Df98\Samples\Advanced\Win32\GetOpenFileName.


Locating Run-Time Errors

This section provides some guidelines for locating the cause of exceptions and run-time errors. Visual Fortran run-time error messages do not usually indicate the exact source location causing the error.

To locate the cause of errors use the various compiler options to isolate programming errors at compile-time and run-time or use the debugger to locate the cause of exceptions:

  • The /[no]warn options control compile-time diagnostic messages, which in some circumstances can help determine the cause of a run-time error. In the Microsoft visual development environment, specify the Warning Level in the General Compiler Option Category or specify individual Warning Options in the Compiler Diagnostics Compiler Option Category.

  • The /check:keyword options generate extra code to catch certain conditions at run-time (see /check or in the visual development environment, specify the Runtime Error Checking items in the Run time Compiler Option Category). For example:

    • The /check:bounds option generates extra code to catch access to data beyond the array or string boundaries.
    • The /check:overflow option generates extra code to catch integer overflow conditions.
    • The /check:noformat, /check:nooutput_conversion, and /check:nopower options reduce the severity level of the associated run-time error to allow program continuation (see /check).
    • The /check:underflow option controls the reporting of floating-point underflow exceptions at run-time.

  • The /traceback option allows program counter to source file line correlation, which simplifies the task of locating the cause of severe run-time errors. Without /traceback, a link map file and source listing are usually needed to locate the cause of the error. Certain traceback-related information accompanies severe run-time errors, as described in Using Traceback Information.

  • The /fpe option controls the handling of floating-point arithmetic exceptions (IEEE arithmetic) at run-time. In the visual development environment, specify the Floating-Point Exception Handling in the Floating Point Compiler Option Category.

    For example, if you specified /fpe:3, exceptions related to exceptional IEEE values are not reported and your application may generate exceptional IEEE values, which later in your application may generate an exception or unexpected values. By recompiling the application at /fpe:0, any exceptional IEEE values generated will cause the program to terminate and report an error message earlier.

    The FOR_GET_FPE and FOR_SET_FPE routines are also available to examine and set the run-time handling of certain arithmetic exceptions.

  • You can use the debugger to help you locate exceptions, as described in Locating Run-Time Errors in the Debugger.


Using Traceback Information

When a Fortran program terminates due to a severe error condition, the Fortran run-time system displays additional diagnostic information after the run-time message.

The Fortran run-time system attempts to walk back up the call chain and produce a report of the calling sequence leading to the error as part of the default diagnostic message report. The minimum information displayed includes:

  • The standard Fortran run-time error message text that explains the error condition.
  • A tabular report that contains one line per call stack frame. This information includes at least the image name and a hexadecimal PC in that image.

The information displayed under the Routine, Line, and Source columns depends upon whether your program was compiled with the /traceback option. In the visual development environment, the default is /traceback in the debug configuration, but must be requested for the release configuration (Run Time category of Project settings).

For example, if /traceback were specified, the displayed information might resemble the following:

 forrtl: severe (24): end-of-file during read, unit 10, file E:\USERS\xxx.dat
 Image             PC        Routine         Line        Source
 DFORRT.dll        1000A3B2  Unknown         Unknown  Unknown
 DFORRT.dll        1000A184  Unknown         Unknown  Unknown
 DFORRT.dll        10009324  Unknown         Unknown  Unknown
 DFORRT.dll        10009596  Unknown         Unknown  Unknown
 DFORRT.dll        10024193  Unknown         Unknown  Unknown
 teof.exe          004011A9  AGAIN                21  teof.for
 teof.exe          004010DD  GO                   15  teof.for
 teof.exe          004010A7  WE                   11  teof.for
 teof.exe          00401071  HERE                  7  teof.for
 teof.exe          00401035  TEOF                  3  teof.for
 teof.exe          004013D9  Unknown         Unknown  Unknown
 teof.exe          004012DF  Unknown         Unknown  Unknown
 KERNEL32.dll      77F1B304  Unknown         Unknown  Unknown

If the same program was not compiled with the /traceback option (/notraceback):

  • The Routine name, Line number, and Source file columns would be reported as "Unknown."
  • A link map file and source listing are usually needed to locate the cause of the error.

The /traceback option provides program counter to source file line correlation information to appear in the displayed error message information, which simplifies the task of locating the cause of severe run-time errors. For Fortran objects generated with /traceback, the compiler generates additional information used by the Fortran run-time system to automatically correlate PC (program counter) values to the routine name in which they occur, Fortran source file, and line number in the source file. This information is displayed in the run-time error diagnostic report.

Automatic PC correlation is only supported for Fortran code. For non-Fortran code, only the hexadecimal PC locations are reported.

The following sections describe traceback-related tools, lists traceback-related environment variables, discuss tradeoffs and restrictions, and provide examples:

  • Tools to Help You Understand Traceback Output
  • Relevant Fortran Run-Time Environment Variables
  • Tradeoffs and Restrictions
  • Example Programs and Traceback Information


Tools to Help You Understand Traceback Output

When an application fails and you need to diagnose the error, there are a few tools and aids that are helpful. Compiler-generated machine code listings and linker-generated map files can help you understand the affects of compiler optimizations and to see how your application is laid out in memory. They may help you interpret the information provided in a stack trace at the time of the error:

To generate a complete listing (.lst) file:

  • When using the Microsoft visual development environment:
    1. Choose Settings from the Project menu
    2. Click the Fortran tab
    3. Select the Listing Files category
    4. Click (check) "Source Listing"
    5. Click "Machine Code"
    6. Click "Include Files"
    7. Make any other changes needed to the Project Settings, then click OK.

  • When compiling from the command line, specify /list with /show:all:
      DF file.f90 /list /show:all

To generate a link map (.map) file:

  • When using the visual development environment:
    1. Choose Settings from the Project menu
    2. Click the Link tab
    3. Select the General or Debug category
    4. Select Generate mapfile
    5. Make any other changes needed to the Project Settings, then click OK.

  • When compiling from the command line, specify /map:
      DF file.f90 /map

To see what sections are defined in an executable image (.exe) file:

  • Specify the /traceback compile option. This requests that the compiler generate PC correlation information to be used at run-time in the event of an error.

  • This information is gathered up by the linker in the executable image in a section named ".trace". To see what sections are in an image, use the command:
      link -dump -summary your_app_name.exe

    To see more detailed information, use the command:

      link -dump -headers your_app_name.exe


Relevant Fortran Run-Time Environment Variables

The Fortran Run-Time library checks certain environment variables that you can use to customize run-time diagnostic error reporting:

  • FOR_DIAGNOSTIC_LOG_FILE

    If set to the name of a file, writes diagnostic output to the specified file. The Fortran run-time system attempts to open that file (append output) and write the error information (ASCII text) to the file. The setting of FOR_DIAGNOSTIC_LOG_FILE is independent of FOR_DISABLE_DIAGNOSTIC_DISPLAY, so you can disable the screen display of information but still capture the error information in a file. The text string you assign for the file name is used literally so you must specify the full name. If the file open fails, no error is reported and the run-time system continues diagnostic processing.

  • FOR_DISABLE_DIAGNOSTIC_DISPLAY

    If set to true, disables the display of all error information. This might be helpful if you just want to test the error status of your program and do not want the Fortran run-time system to display any information about an abnormal program termination.

  • FOR_DISABLE_STACK_TRACE

    If set to true, disables the display of call stack information that follows the displayed severe error message text. The Fortran run-time error message is displayed whether or not FOR_DISABLE_STACK_TRACE is set to true.

  • FOR_ENABLE_VERBOSE_STACK_TRACE

    If set to true, more detailed call stack information is displayed in the event of an error.

    The default brief output is usually sufficient to determine where an error occurred. Brief output includes up to twenty stack frames, reported one line per stack frame. For each frame, the image name containing the PC, the PC, routine name, line number, and source file are given.

    The verbose output, if selected, will provide in addition to the information in brief output, the exception context record if the error was a machine exception (machine register dump), and for each frame, the return address, frame pointer and stack pointer and possible parameters to the routine. This output can be quite long (but limited to 16K bytes) and use of the environment variable FOR_DIAGNOSTIC_LOG_FILE is recommended if you want to capture the output accurately. Most situations should not require the use of verbose output.

  • FOR_FULL_SRC_FILE_SPEC

    By default, the traceback output displays only the file name and extension in the source file field. To display complete file name information including the path, set the environment variable FOR_FULL_SRC_FILE_SPEC to true.


Tradeoffs and Restrictions

The following tradeoffs and restrictions apply to using traceback:

  • Effect on image size using /traceback

    Using the /traceback option to get automatic PC correlation does increase the size of an image. For any application, the developer must decide if the increase in image size is worth the benefit of automatic PC correlation or if manually correlating PC's with a map file is acceptable.

    The approach of providing automatic correlation information in the image was used so that no run-time penalty is incurred by building the information "on the fly" as your application executes. No run-time diagnostic code is invoked unless your application is terminating due to a severe error.

  • The C Compiler Frame Pointer Omission Option (/Oy) on ia32 Systems

    At the heart of the stack walking code is the Win32 routine StackWalk( ) found in imagehlp.dll. In the ia32 systems environment, there are no firm software calling standards documented. Compiler developers are under no constraints to use machine registers in any particular way or to hook up procedures in any particular way. The StackWalk( ) routine therefore, bases its decisions on how to walk the call stack on a set of heuristics. That is, it makes a "best guess" to determine how a program reached a particular point in the call chain. With C code that has been compiled with Visual C++ with the Frame Pointer Omission Option (/Oy) enabled, this "best guess" is not usually the correct one.

    If you are mixing Fortran and C code and you are concerned about stack tracing, consider disabling this option (/Oy-) in your C compiles. Otherwise traceback will most likely not work for you.

  • Linker /incremental:no option

    When incremental linking is enabled, automatic PC correlation does not work. Use of incremental linking always disables automatic PC correlation even if you specify /traceback during compilation.

    When you use incremental linking, the default hexadecimal (hex) PC values will still appear in the output. To correlate from the hexadecimal PC values to routine containing the PC addresses requires use of a linker map file. However, if you request a map file during linking, incremental linking becomes disabled. Thus to allow any PC values generated for a run-time problem to be helpful, incremental linking must be disabled.

    In the visual development environment, you can use the Call stack display, so incremental linking is not a problem.

  • When the Stack Trace Fails For Some Reason

    Programs can fail for a multitude of reasons with unpredictable consequences. Memory corruption by erroneously executing code is always a possibility. Stack memory may be corrupted in such a way that the attempt to trace the call stack will result in access violations or other undesirable consequences. The stack tracing run-time code is guarded with a local exception filter. Should the traceback attempt fail due to a hard detectable condition, the run-time will report this in its diagnostic output message as:

      Stack trace terminated abnormally

    Be forewarned, however, it is also possible for memory to be corrupted in such a way that a stack trace can seem to complete successfully with no hint of a problem. The bit patterns it finds in corrupted memory where the stack used to be, and then uses to access memory, may constitute perfectly valid memory addresses for the program to be accessing. They just do not happen to have any connection to what the stack used to look like. So, if it appears that the stack walk completed normally, but the reported PC's make no sense to you, then consider ignoring the stack trace output in diagnosing your problem.

    You may also see the stack trace fail if the run-time system cannot dynamically load imagehlp.dll or cannot find the routines from that library it needs to do the stack walk. In this case, you would still get the basic run-time diagnostic message. You just will not get any call stack information.

    Another condition that will disable the stack trace process is your program exiting because it has exhausted virtual memory resources.


Example Programs and Traceback Information

The following sections provide example programs that show the use of traceback to locate the cause of the error:

  • Example: End-of-File Condition, Program teof
  • Example: Machine Exception Condition, Program ovf
  • Example: Using Traceback in Mixed Fortran/C Applications, Program FPING and CPONG

Example: End-of-File Condition, Program teof

In the following example, a READ statement creates an End-Of-File error, which the application has not handled:

  program teof
  integer*4 i,res
  i=here( )
  end

  integer*4 function here( )
  here = we( )
  end

  integer*4 function we( )
  we = go( )
  end

  integer*4 function go( )
  go = again( )
  end

  integer*4 function again( )
  integer*4 a
  open(10,file='xxx.dat',form='unformatted',status='unknown')
  read(10) a
  again=a
  end

The diagnostic output that results when this program is built with traceback enabled and linked against the single-threaded, DLL Fortran run-time library on the ia32 platform:

forrtl: severe (24): end-of-file during read, unit 10, file E:\USERS\xxx.dat
Image            PC        Routine         Line     Source
DFORRT.dll       1000A3B2  Unknown         Unknown  Unknown
DFORRT.dll       1000A184  Unknown         Unknown  Unknown
DFORRT.dll       10009324  Unknown         Unknown  Unknown
DFORRT.dll       10009596  Unknown         Unknown  Unknown
DFORRT.dll       10024193  Unknown         Unknown  Unknown
teof.exe         004011A9  AGAIN                21  teof.for
teof.exe         004010DD  GO                   15  teof.for
teof.exe         004010A7  WE                   11  teof.for
teof.exe         00401071  HERE                  7  teof.for
teof.exe         00401035  TEOF                  3  teof.for
teof.exe         004013D9  Unknown         Unknown  Unknown
teof.exe         004012DF  Unknown         Unknown  Unknown
KERNEL32.dll     77F1B304  Unknown         Unknown  Unknown

The first line of the output is the standard Fortran run-time error message. What follows is the result of walking the call stack in reverse order to determine where the error originated. Each line of output represents a call frame on the stack. Since the application was compiled with /traceback, the PC's that fall in Fortran code are correlated to their matching routine name, line number and source module. PC's which are not in Fortran code are not correlated and are reported as "Unknown."

The first five frames show the calls to routines in the Fortran run-time library (in reverse order). Since the application was linked against the single threaded DLL version of the library, the image name reported is DFORRT.dll. These are the run-time routines that were called to do the READ and upon detection of the EOF condition, were invoked to report the error. In the case of an unhandled I/O programming error, there will always be a few frames on the call stack down in run-time code like this.

The stack frame of real interest to the Fortran developer is the first frame in image teof.exe which shows that the error originated in the routine named AGAIN in source module teof.for at line 21. Looking in the source code at line 21, we see the Fortran READ statement that incurred the end-of-file condition.

The next four frames show that completes the trail of calls in the Fortran user code that led to the routine that got the error (TEOF->HERE->WE->GO->AGAIN).

Finally, the bottom three frames are routines which handled the startup and initialization of the program.

If this program had been linked against the single-threaded, static Fortran run-time library, the output would then look like:

forrtl: severe (24): end-of-file during read, unit 10, file E:\USERS\xxx.dat
Image          PC        Routine        Line     Source
teof.exe       004067D2  Unknown        Unknown  Unknown
teof.exe       0040659F  Unknown        Unknown  Unknown
teof.exe       00405754  Unknown        Unknown  Unknown
teof.exe       004059C5  Unknown        Unknown  Unknown
teof.exe       00403543  Unknown        Unknown  Unknown
teof.exe       004011A9  AGAIN               21  teof.for
teof.exe       004010DD  GO                  15  teof.for
teof.exe       004010A7  WE                  11  teof.for
teof.exe       00401071  HERE                 7  teof.for
teof.exe       00401035  TEOF                 3  teof.for
teof.exe       004202F9  Unknown        Unknown  Unknown
teof.exe       00416063  Unknown        Unknown  Unknown
KERNEL32.dll   77F1B304  Unknown        Unknown  Unknown

Notice that the initial five stack frames now show routines in image teof.exe, not DFORRT.DLL. The routines are the same five run-time routines as previously reported for the DLL case but since the application was linked against the static Fortran run-time library (dfor.lib), the object modules containing these routines were linked into the application image (teof.exe). Using the map file, you can determine that the PC reported in the top stack frame, 004067D2, is from routine _for_stack_trace, in module for_diags.obj of library dfor.lib (004067a0 < PC=004067D2 < 004079f0):

 ...
 0001:000057a0       _for_stack_trace           004067a0 f dfor:for_diags.obj
 0001:000069f0       _for__find_trace_info_file 004079f0 f dfor:for_diags.obj
 ...

Now suppose the application was compiled without traceback enabled and once again, linked against the single-threaded, static Fortran library. The diagnostic output would then appear as follows:

forrtl: severe (24): end-of-file during read, unit 10, file E:\USERS\xxx.dat
Image            PC        Routine       Line     Source
teof.exe         00406792  Unknown       Unknown  Unknown
teof.exe         0040655F  Unknown       Unknown  Unknown
teof.exe         00405714  Unknown       Unknown  Unknown
teof.exe         00405985  Unknown       Unknown  Unknown
teof.exe         00403503  Unknown       Unknown  Unknown
teof.exe         00401169  Unknown       Unknown  Unknown
teof.exe         004010A8  Unknown       Unknown  Unknown
teof.exe         00401078  Unknown       Unknown  Unknown
teof.exe         00401048  Unknown       Unknown  Unknown
teof.exe         0040102F  Unknown       Unknown  Unknown
teof.exe         004202B9  Unknown       Unknown  Unknown
teof.exe         00416023  Unknown       Unknown  Unknown
KERNEL32.dll     77F1B304  Unknown       Unknown  Unknown

Without the correlation information in the image that /traceback previously supplied, the Fortran run-time system cannot correlate PC's to routine name, line number, and source file. You can still use the map file to at least determine the routine names and what modules they are in. Look at the beginning of the entry point list in the map file for this image:

  Address         Publics by Value      Rva+Base   Lib:Object

 0001:00000000       _TEOF              00401000 f teof.obj
 0001:00000000       _TEOF@0            00401000 f teof.obj
 0001:00000000       _MAIN__            00401000 f teof.obj
 0001:0000003d       _HERE              0040103d f teof.obj
 0001:0000003d       _HERE@0            0040103d f teof.obj
 0001:0000006d       _WE@0              0040106d f teof.obj
 0001:0000006d       _WE                0040106d f teof.obj
 0001:0000009d       _GO                0040109d f teof.obj
 0001:0000009d       _GO@0              0040109d f teof.obj
 0001:000000cd       _AGAIN             004010cd f teof.obj
 0001:000000cd       _AGAIN@0           004010cd f teof.obj
 0001:00000180       _for_rtl_init_     00401180 f dfor:for_init.obj
 ...

After determining that the first five stack frames fall in run-time code (using portions of the map file not shown here), the sixth frame shows a PC of 00401169. Using the fragment of the map file shown above, it can be seen that this PC is greater than 004010cd but less than 00401180 and is therefore in routine _AGAIN, the first Fortran routine on the call stack. The remaining PC's can be manually correlated in a similar fashion to reconstruct the calling sequence.

Remember that compiling with /traceback increases the size of your application's image because of the extra PC correlation information included in the image. You can see if the extra traceback information is included in an image (checking for the presence of a .trace section) by typing:

  link -dump -summary your_app.exe

For the teof.exe example, the following is displayed:

  Microsoft (R) COFF Binary File Dumper Version x.xx.xxxx
  Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

  Dump of file teof.exe

  File Type: EXECUTABLE IMAGE

     Summary

        1000 .data
        1000 .idata
        1000 .rdata
        1000 .text
        1000 .trace

Check the file size with a simple directory command. Here's the teof.exe example linked against the dynamic Fortran library with traceback:

   03/03/98  01:45p                 5,120 teof.exe
                1 File(s)           5,120 bytes

Without traceback, the following appears:

  03/03/98  01:46p                 4,608 teof.exe
                1 File(s)          4,608 bytes

For this simple example, the traceback correlation information added 512 bytes to the image size. In a real application, this would probably be much larger. For any application, the developer must decide if the increase in image size is worth the benefit of automatic PC correlation or if manually correlating PC's with a map file is acceptable.

For command-line use and in the release configuration in the visual development environment, traceback information is not included by default in Fortran compiles (default is /notraceback). In the visual development environment, the default is /traceback in the debug configuration. For the release configuration, request traceback in the Run Time category of the Project Settings dialog box.

If an error occurs when traceback was requested during compilation, the run-time library will produce the correlated call stack display.

If an error occurs when traceback was disabled during compilation, the run-time library will produce the uncorrelated call stack display.

If you do not want to see the call stack information displayed, you can set the environment variable FOR_DISABLE_STACK_TRACE to true. You will still get the Fortran run-time error message:

 forrtl: severe (24): end-of-file during read, unit 10, file E:\USERS\xxx.dat

Example: Machine Exception Condition, Program ovf

The following program generates a floating-point overflow exception when compiled with /fpe:0:

  program ovf
  real*4 a
  a=1e37
  do i=1,10
     a=hey(a)
  end do
  print *, 'a= ', a
  end

  real*4 function hey(b)
  real*4 b
  hey = watch(b)
  end

  real*4 function watch(b)
  real*4 b
  watch = out(b)
  end

  real*4 function out(b)
  real*4 b
  out = below(b)
  end

  real*4 function below(b)
  real*4 b
  below = b*10.0e0
  end

When this program is compiled on an ia32 system with /traceback, /fpe:0, and /optimization:0, the traceback output appears as follows:

forrtl: error (72): floating overflow
Image              PC        Routine            Line        Source
ovf.exe            00401161  BELOW                      29  ovf.f90
ovf.exe            0040113C  OUT                        24  ovf.f90
ovf.exe            0040111B  WATCH                      19  ovf.f90
ovf.exe            004010FA  HEY                        14  ovf.f90
ovf.exe            0040105B  OVF                         7  ovf.f90
ovf.exe            00432429  Unknown               Unknown  Unknown
ovf.exe            00426C74  Unknown               Unknown  Unknown
KERNEL32.dll       77F1B9EA  Unknown               Unknown  Unknown

Notice that unlike the previous example of an unhandled I/O programming error, the stack walk can begin right at the point of the exception. There are no run-time routines on the call stack to dig through. The overflow occurs in routine BELOW at PC 00401161 which is correlated to line 29 of the source file ovf.f90.

When the program is compiled at a higher optimization level, /optimization:4, with /fpe:0 and /traceback, the traceback output appears as follows:

forrtl: error (72): floating overflow
Image              PC        Routine            Line        Source
ovf.exe            00401070  OVF                        29  ovf.f90
ovf.exe            004323E9  Unknown               Unknown  Unknown
ovf.exe            00426C34  Unknown               Unknown  Unknown
KERNEL32.dll       77F1B9EA  Unknown               Unknown  Unknown

With /optimize:4, the entire program has been inlined. We can see this with a quick look in the listing file:

...
                .CODE
                PUBLIC	_MAIN__
         0000	_MAIN__ PROC
55           0000		push	ebp
EC8B         0001		mov	ebp, esp
30EC83       0003		sub	esp, 48
000000E8     0006		call _for_check_flawed_pentium@0
00
04EC83       000B		sub	esp, 4
0020058D     000E		lea	eax, dword ptr .literal$+32
0000
50           0014		push	eax
000000E8     0015		call	_for_set_fpe_@4
00
001C058D     001A		lea	eax, dword ptr .literal$+28
0000
50           0020		push	eax
000000E8     0021		call	_for_set_reentrancy@4
00
04C483       0026		add	esp, 4
001805D9     0029		fld	dword ptr .literal$+24			; 000029
0000
00000DD8     002F		fmul	dword ptr .literal$
0000
9B           0035		fwait
00000DD8     0036		fmul	dword ptr .literal$
0000
9B           003C		fwait
00000DD8     003D		fmul	dword ptr .literal$
0000
9B           0043		fwait
00000DD8     0044		fmul	dword ptr .literal$
0000
9B           004A		fwait
00000DD8     004B		fmul	dword ptr .literal$
0000
9B           0051		fwait
00000DD8     0052		fmul	dword ptr .literal$
0000
9B           0058		fwait
00000DD8     0059		fmul	dword ptr .literal$
0000
9B           005F		fwait
00000DD8     0060		fmul	dword ptr .literal$
0000
9B           0066		fwait
00000DD8     0067		fmul	dword ptr .literal$
0000
FC5DD9       006D		fstp	dword ptr -4[ebp]
9B           0070		fwait
D233         0071		xor	edx, edx					    ; 000009
0014058D     0073		lea	eax, dword ptr .literal$+20
0000
03D045C7     0079		mov	dword ptr -48[ebp], 3
000000
D44589       0080		mov	dword ptr -44[ebp], eax
000C0D8D     0083		lea	ecx, dword ptr .literal$+12
0000
DC458D       0089		lea	eax, .T1_		; eax, dword ptr -36[ebp]
DC5589       008C		mov	.T1_, edx		; dword ptr -36[ebp], edx
04EC83       008F		sub	esp, 4
D0558D       0092		lea	edx, dword ptr -48[ebp]
52           0095		push	edx
51           0096		push	ecx
84FF0068     0097		push	126156544
07
FFFFFF68     009C		push	-1
FF
50           00A1		push	eax
000000E8     00A2		call	_for_write_seq_lis
00
18C483       00A7		add	esp, 24
FC458B       00AA		mov	eax, dword ptr -4[ebp]
D04589       00AD		mov	dword ptr -48[ebp], eax
04EC83       00B0		sub	esp, 4
D0558D       00B3		lea	edx, dword ptr -48[ebp]
00040D8D     00B6		lea	ecx, dword ptr .literal$+4
0000
DC458D       00BC		lea	eax, .T1_			; eax, dword ptr -36[ebp]
52           00BF		push	edx
51           00C0		push	ecx
50           00C1		push	eax
000000E8     00C2		call	_for_write_seq_lis_xmit
00
10C483       00C7		add	esp, 16
E58B         00CA		mov	esp, ebp					   ; 000010
000001B8     00CC		mov	eax, 1
00
5D           00D1		pop	ebp
C3           00D2		ret
_MAIN__				ENDP

...

The main program, OVF, no longer calls routine HEY. While the output is not quite what one might have expected intuitively, it is still entirely correct. You need to keep in mind the effects of compiler optimization when you interpret the diagnostic information reported for a failure in a release image.

If the same image were executed again but with environment variable FOR_ENABLE_VERBOSE_STACK_TRACE set to true, you would also see a dump of the exception context record at the time of the error. Here is an excerpt of how that would appear on an ia32 system:

forrtl: error (72): floating overflow

Hex Dump Of Exception Record Context Information:

Exception Context:  Processor Control and Status Registers.

EFlags:  00010212
CS:  0000001B  EIP:  00401161  SS:   00000023  ESP:  0012FE38  EBP:  0012FE60

Exception Context:  Processor Integer Registers.

EAX: 00444488  EBX:  00000009  ECX:  00444488  EDX:  00000002
ESI: 0012FBBC  EDI:  F9A70030

Exception Context:  Processor Segment Registers.

DS:  00000023  ES:   00000023  FS:   00000038  GS:   00000000

Exception Context:  Floating Point Control and Status Registers.

ControlWord:  FFFF0262  ErrorOffset:    0040115E  DataOffset:    0012FE5C
StatusWord:   FFFFF8A8  ErrorSelector:  015D001B  DataSelector:  FFFF0023
TagWord:      FFFF3FFF  Cr0NpxState:    00000000

Exception Context:  Floating Point RegisterArea.

RegisterArea[00]:  4080BC143F4000000000  RegisterArea[10]:  F7A0FFFFFFFF77F9D860
RegisterArea[20]:  00131EF0000800060012  RegisterArea[30]:  00000012F7C002080006
RegisterArea[40]:  02080006000000000000  RegisterArea[50]:  0000000000000012F7D0
RegisterArea[60]:  00000000000000300000  RegisterArea[70]:  FBBC000000300137D9EF
...

Example: Using Traceback in Mixed Fortran/C Applications, Program FPING and CPONG

Consider the following example that shows how the traceback output might appear in a mixed Fortran/C application. The main program is a Fortran program named FPING. Program FPING triggers a chain of function calls which are alternately Fortran and C code. Eventually, the C routine named Unlucky is called, which produces a floating divide by zero error.

Source module FPING.FOR contains the Fortran function definitions, each of which calls a C routine from source module CPONG.C. FPING.FOR is compiled with the /fpe:0 /optimize:0 /traceback options enabled, on the ia32 platform. Here's the program traceback output:

forrtl: error (73): floating divide by zero
Image            PC        Routine       Line     Source
fping.exe        00401161  Unknown       Unknown  Unknown
fping.exe        004010DC  DOWN4              58  fping.for
fping.exe        0040118F  Unknown       Unknown  Unknown
fping.exe        004010B6  DOWN3              44  fping.for
fping.exe        00401181  Unknown       Unknown  Unknown
fping.exe        00401094  DOWN2              31  fping.for
fping.exe        00401173  Unknown       Unknown  Unknown
fping.exe        00401072  DOWN1              18  fping.for
fping.exe        0040104B  FPING               5  fping.for
fping.exe        004013B9  Unknown       Unknown  Unknown
fping.exe        004012AF  Unknown       Unknown  Unknown
KERNEL32.dll     77F1B304  Unknown       Unknown  Unknown

Notice that the stack frames contributed by Fortran routines can be correlated to a routine name, line number, and source module but those frames contributed by C routines cannot be correlated. Remember, even though the stack can be walked in reverse, and PC's reported, the information necessary to correlate the PC to a routine name, line number, and so on, is contributed to the image from the objects generated by the Fortran compiler. The C compiler does not have this capability. Also remember that you only get the correlation information if you specify the /traceback option for your Fortran compiles.

The top stack frame cannot be correlated to a routine name because it is in C code. By examining the map file for the application, we can see that the reported PC, 00401161, is greater than the start of routine _Unlucky, but less than the start of routine _down1_C, so we at least know the error occurred in routine _Unlucky. Here is the pertinent section of the map file:

  Address         Publics by Value        Rva+Base   Lib:Object

 0001:00000000       _FPING               00401000 f fping.obj
 0001:00000000       _FPING@0             00401000 f fping.obj
 0001:00000000       _MAIN__              00401000 f fping.obj
 0001:0000005f       _DOWN1               0040105f f fping.obj
 0001:0000005f       _DOWN1@4             0040105f f fping.obj
 0001:00000083       _DOWN2@4             00401083 f fping.obj
 0001:00000083       _DOWN2               00401083 f fping.obj
 0001:000000a5       _DOWN3               004010a5 f fping.obj
 0001:000000a5       _DOWN3@4             004010a5 f fping.obj
 0001:000000c7       _DOWN4@4             004010c7 f fping.obj
 0001:000000c7       _DOWN4               004010c7 f fping.obj
 0001:00000100       _Fact                00401100 f cpong.obj
 0001:00000127       _Pythagoras          00401127 f cpong.obj

******************************************************
The reported PC lies between the start of _Unlucky and
the start of _down1_C...
******************************************************

 0001:0000014d       _Unlucky             0040114d f cpong.obj
 0001:00000167       _down1_C             00401167 f cpong.obj

 0001:00000175       _down2_C             00401175 f cpong.obj
 0001:00000183       _down3_C             00401183 f cpong.obj
 0001:00000192       _for_check_flawed_pentium@0 00401192 f dfordll:DFORRT.dll
 0001:00000198       _for_set_fpe_@4       00401198 f dfordll:DFORRT.dll
 0001:0000019e       _for_set_reentrancy@4 0040119e f dfordll:DFORRT.dll
 etc...

In a similar manner, the other PC's reported as "Unknown" can be correlated to a routine name using the map file.

When examining traceback output (or any type of diagnostic output for that matter), it is always important to keep in mind the affects of compiler optimization. The Fortran source module in the above example was built with optimization turned off, /optimize:0. Look at the output when optimizations are enabled, /optimize:4:

forrtl: error (73): floating divide by zero
Image           PC        Routine     Line     Source
fping.exe       00401111  Unknown     Unknown  Unknown
fping.exe       0040109D  DOWN4            58  fping.for
fping.exe       0040113F  Unknown     Unknown  Unknown
fping.exe       00401082  DOWN3            44  fping.for
fping.exe       00401131  Unknown     Unknown  Unknown
fping.exe       0040106B  DOWN2            31  fping.for
fping.exe       00401123  Unknown     Unknown  Unknown
fping.exe       00401032  FPING            18  fping.for
fping.exe       00401369  Unknown     Unknown  Unknown
fping.exe       0040125F  Unknown     Unknown  Unknown
KERNEL32.dll    77F1B304  Unknown     Unknown  Unknown

From the traceback output, it would appear that routine DOWN1 was never called. In fact, it has not been called. At the higher optimization level, the compiler has inlined function DOWN1 so that the call to routine down1_C is now made from FPING. The correlated line number still points to the correct line in the source code. You can see that DOWN1 was inlined by looking in the listing file, FPING.LST:

                                .CODE
                                PUBLIC  _MAIN__
             0000       _MAIN__ PROC
55           0000               push    ebp
EC8B         0001               mov     ebp, esp
04EC83       0003               sub     esp, 4
53           0006               push    ebx
000000E8     0007               call    _for_check_flawed_pentium@0
00
04EC83       000C               sub     esp, 4
0008058D     000F               lea     eax, dword ptr .literal$+8
0002
50           0015               push    eax
000000E8     0016               call    _for_set_fpe_@4
00
0004058D     001B               lea     eax, dword ptr .literal$+4
0002
50           0021               push    eax
000000E8     0022               call    _for_set_reentrancy@4
00
000035FF     0027               push    dword ptr .literal$           ; 000018
0000
000035FF     0027               push    dword ptr .literal$           ; 000018
0000

*******************************************************************
Call _down1_C from MAIN__ here, no call to DOWN1 Fortran routine...
*******************************************************************

000000E8     002D               call    _down1_C
00
C0DD         0032               ffree   st(0)
F7D9         0034               fincstp
08C483       0036               add     esp, 8
000001B8     0039               mov     eax, 1                        ; 000006
A0
5B           003E               pop     ebx
E58B         003F               mov     esp, ebp
5D           0041               pop     ebp
C3           0042               ret
_MAIN__                        ENDP

Finally, suppose the example Fortran code is redesigned with each of the Fortran routines split into separate source modules. Here is what the traceback output would look like with the redesigned code:

forrtl: error (73): floating divide by zero
Image            PC        Routine      Line     Source
fpingmain.exe    00401171  Unknown      Unknown  Unknown
fpingmain.exe    004010ED  DOWN4             12  fping4.for
fpingmain.exe    0040119F  Unknown      Unknown  Unknown
fpingmain.exe    004010C1  DOWN3             11  fping3.for
fpingmain.exe    00401191  Unknown      Unknown  Unknown
fpingmain.exe    00401099  DOWN2             11  fping2.for
fpingmain.exe    00401183  Unknown      Unknown  Unknown
fpingmain.exe    00401073  DOWN1             11  fping1.for
fpingmain.exe    0040104B  FPING              5  fpingmain.for
fpingmain.exe    004013C9  Unknown      Unknown  Unknown
fpingmain.exe    004012BF  Unknown      Unknown  Unknown
KERNEL32.dll     77F1B304  Unknown      Unknown  Unknown

Notice that the line number and source file correlation information has changed to reflect the new design of the code.

Here are the sources used in the above examples:

************************************
FPING.FOR
************************************
    program fping

    real*4 a,b
    a=-10.0
    b=down1(a)
    end

    real*4 function down1(b)
    real*4 b
!DEC$ IF DEFINED(_X86_)
    INTERFACE TO REAL*4 FUNCTION down1_C [C,ALIAS:'_down1_C'] (n)
!DEC$ ELSE
    INTERFACE TO REAL*4 FUNCTION down1_C [C,ALIAS:'down1_C'] (n)
!DEC$ ENDIF
    REAL*4 n [VALUE]
    END
    real*4 down1_C
    down1 = down1_C(b)
    end

    real*4 function down2(b)
    real*4 b [VALUE]
!DEC$ IF DEFINED(_X86_)
    INTERFACE TO REAL*4 FUNCTION down2_C [C,ALIAS:'_down2_C'] (n)
!DEC$ ELSE
    INTERFACE TO REAL*4 FUNCTION down2_C [C,ALIAS:'down2_C'] (n)
!DEC$ ENDIF
    REAL*4 n [VALUE]
    END
    real*4 down2_C
    down2 = down2_C(b)
    end

    real*4 function down3(b)
    real*4 b [VALUE]
!DEC$ IF DEFINED(_X86_)
    INTERFACE TO REAL*4 FUNCTION down3_C [C,ALIAS:'_down3_C'] (n)
!DEC$ ELSE
    INTERFACE TO REAL*4 FUNCTION down3_C [C,ALIAS:'down3_C'] (n)
!DEC$ ENDIF
    REAL*4 n [VALUE]
    END
    real*4 down3_C
    down3 = down3_C(b)
    end

    real*4 function down4(b)
    real*4 b [VALUE]
!DEC$ IF DEFINED(_X86_)
    INTERFACE TO SUBROUTINE Unlucky [C,ALIAS:'_Unlucky'] (a,c)
!DEC$ ELSE
    INTERFACE TO SUBROUTINE Unlucky [C,ALIAS:'Unlucky'] (a,c)
!DEC$ ENDIF
    REAL*4 a [VALUE]
    REAL*4 c [REFERENCE]
    END
    real*4 a
    call Unlucky(b,a)
    down4 = a
    end

************************************
CPONG.C
************************************
#include <math.h>

extern float __stdcall DOWN2 (float n);
extern float __stdcall DOWN3 (float n);
extern float __stdcall DOWN4 (float n);

int Fact( int n )
{
    if (n > 1)
        return( n * Fact( n - 1 ));
    return 1;
}

void Pythagoras( float a, float b, float *c)
{
    *c = sqrt( a * a + b * b );
}

void Unlucky( float a, float *c)
{
float b=0.0;
    *c = a/b;
}

float down1_C( float a )
{
    return( DOWN2( a ));
}

float down2_C( float a )
{
    return( DOWN3( a ));
}

float down3_C( float a )
{
    return( DOWN4( a ));
}

************************************
FPINGMAIN.FOR
************************************
    program fping

    real*4 a,b
    a=-10.0
    b=down1(a)
    end

************************************
FPING1.FOR
************************************
    real*4 function down1(b)
    real*4 b
!DEC$ IF DEFINED(_X86_)
    INTERFACE TO REAL*4 FUNCTION down1_C [C,ALIAS:'_down1_C'] (n)
!DEC$ ELSE
    INTERFACE TO REAL*4 FUNCTION down1_C [C,ALIAS:'down1_C'] (n)
!DEC$ ENDIF
    REAL*4 n [VALUE]
    END
    real*4 down1_C
    down1 = down1_C(b)
    end

************************************
FPING2.FOR
************************************
    real*4 function down2(b)
    real*4 b [VALUE]
!DEC$ IF DEFINED(_X86_)
    INTERFACE TO REAL*4 FUNCTION down2_C [C,ALIAS:'_down2_C'] (n)
!DEC$ ELSE
    INTERFACE TO REAL*4 FUNCTION down2_C [C,ALIAS:'down2_C'] (n)
!DEC$ ENDIF
    REAL*4 n [VALUE]
    END
    real*4 down2_C
    down2 = down2_C(b)
    end

************************************
FPING3.FOR
************************************
    real*4 function down3(b)
    real*4 b [VALUE]
!DEC$ IF DEFINED(_X86_)
    INTERFACE TO REAL*4 FUNCTION down3_C [C,ALIAS:'_down3_C'] (n)
!DEC$ ELSE
    INTERFACE TO REAL*4 FUNCTION down3_C [C,ALIAS:'down3_C'] (n)
!DEC$ ENDIF
    REAL*4 n [VALUE]
    END
    real*4 down3_C
    down3 = down3_C(b)
    end

************************************
FPING4.FOR
************************************
    real*4 function down4(b)
    real*4 b [VALUE]
!DEC$ IF DEFINED(_X86_)
    INTERFACE TO SUBROUTINE Unlucky [C,ALIAS:'_Unlucky'] (a,c)
!DEC$ ELSE
    INTERFACE TO SUBROUTINE Unlucky [C,ALIAS:'Unlucky'] (a,c)
!DEC$ ENDIF
    REAL*4 a [VALUE]
    REAL*4 c [REFERENCE]
    END
    real*4 a
    call Unlucky(b,a)
    down4 = a
    end


Obtaining Traceback Information with TRACEBACKQQ

You can obtain traceback information in your application by calling the TRACEBACKQQ routine.

TRACEBACKQQ allows an application to initiate a stack trace. You can use this routine to report application detected errors, use it for debugging, and so on. It uses the standard stack trace support in the Visual Fortran run-time system to produce the same output that the run-time system produces for unhandled errors and exceptions (severe error message). The TRACEBACKQQ subroutine generates a stack trace showing the program call stack as it was leading up to the point of the call to TRACEBACKQQ.

The error message string normally included from the run-time support is replaced with the user-supplied message text or omitted if no user string is specified. Traceback output is directed to the target destination appropriate for the application type, just as it is when traceback is initiated internally by the run-time support. See the sections Using Traceback Information and Run-Time Message Display and Format for more information.

In the most simple case, a user can generate a stack trace by coding the call to TRACEBACKQQ with no arguments:

  CALL TRACEBACKQQ()

This call causes the run-time library to generate a traceback report with no leading header message, from wherever the call site is, and terminate execution.

You can specify arguments that generate a stack trace with the user-supplied string as the header and instead of terminating execution, return control to the caller to continue execution of the application. For example:

  CALL TRACEBACKQQ(STRING="Done with pass 1",USER_EXIT_CODE=-1)

By specifying a user exit code of -1, control returns to the calling program. Specifying a user exit code with a positive value requests that specified value be returned to the operating system. The default value is 0, which causes the application to abort execution.

The following example demonstrates the use of the EPTR argument when calling from a user defined exception filter function. The premise of the example is a Fortran DLL containing entry points protected by a C try/except construct, such as:

__declspec(dllexport) void FPE_TEST_WRAPPER ()
{
__try {
      /*
      **  call the Fortran code...
      */
      FPE_TEST() ;
      }
__except ( CHECK_EXCEPTION_INFO ( GetExceptionInformation() ) )
      {
      /*
      **  noncontinuable exception handling here, if any.
      */
      }

The C function shown above is guarding against a floating-point divide-by-zero exception. This function calls the user-supplied FPE_TEST (not shown). The Fortran function CHECK_EXCEPTION_INFO shown below (called in the __except filter expression above) can use TRACEBACKQQ to get a stack trace as follows:

   INTEGER*4 FUNCTION CHECK_EXCEPTION_INFO ( ExceptionInfo )
   !DEC$ ATTRIBUTES DLLEXPORT::CHECK_EXCEPTION_INFO
   USE DFWINTY
   !DEC$ ATTRIBUTES REFERENCE :: ExceptionInfo
   TYPE(T_EXCEPTION_POINTERS) ExceptionInfo

   TYPE(T_EXCEPTION_RECORD) erecptr
   TYPE(T_CONTEXT) ctxptr

   POINTER(eptr,erecptr)
   POINTER(ctxp,ctxptr)

   INTEGER(4) EXIT_CODE,STS
   CHARACTER(LEN=70) MYSTR

! Init the arguments to TRACEBACKQQ appropriately for your needs...

   EXIT_CODE=-1

   eptr = ExceptionInfo.ExceptionRecord
   ctxp = ExceptionInfo.ContextRecord

   IF ( erecptr.ExceptionCode .EQ. STATUS_FLOAT_DIVIDE_BY_ZERO ) THEN
          PRINT *, 'Saw floating divide by zero.'
          PRINT '(1x,a,z8.8)', 'ContextRecord.FloatSave.StatusWord = ', &
                  ctxptr.FloatSave.StatusWord
          MYSTR = "FLTDIV EXCEPTION IN MY APPLICATION"
          CALL TRACEBACKQQ(MYSTR,EXIT_CODE,STS, %LOC(ExceptionInfo))
   END IF
   .
   .
   .
   CHECK_EXCEPTION_INFO = 1
   END

To return a pointer to C run-time exception information pointers within a user-defined handler that was established with SIGNALQQ (or directly with the C signal function), you can call the GETEXCEPTIONPTRSQQ routine.

For an example of how to establish a signal handler with SIGNALQQ (or the C signal() function) and use the TRACEBACKQQ and GETEXCEPTIONPTRSQQ routines to generate a traceback display from the handler, see the Visual Fortran Sample GetEptrs (in ...\Df98\Samples\ExceptionHandling\GetEptrs).


Run-Time Environment Variables

The Visual Fortran run-time system recognizes the following environment variables:

Environment Variable | Description
FOR_ACCEPT | The ACCEPT statement does not include an explicit logical unit number. Instead, it uses an implicit internal logical unit number and the FOR_ACCEPT environment variable. If FOR_ACCEPT is not defined, the code ACCEPT f,iolist reads from CONIN$ (standard input). If FOR_ACCEPT is defined (as a filename optionally containing a path), the specified file would be read.
FORT_BUFFERED | Lets you request that buffered I/O should be used at run-time for output of all Fortran I/O units, except those with output to the terminal. This provides a run-time mechanism to support the /assume:buffered_io compiler option.
FOR_DEFAULT_PRINT_DEVICE | Lets you specify the print device other than the default print device PRN (LPT1) for files closed (CLOSE statement) with the DISPOSE='PRINT' specifier. To specify a different print device for the file associated with the CLOSE statement DISPOSE='PRINT' specifier, set the environment variable FOR_DEFAULT_PRINT_DEVICE to any legal DOS print device before executing the program.
FOR_DIAGNOSTIC_LOG_FILE | If set to the name of a file, writes diagnostic output to the specified file. For information on using stack trace information, see Locating Run-Time Errors and Using Traceback Information.
FOR_DISABLE_DIAGNOSTIC_DISPLAY | If set to true, disables the display of all error information. This might be helpful if you just want to test the error status of your program and do not want the Fortran run-time system to display any information about an abnormal program termination. For information on using stack trace information, see Using Traceback Information.
FOR_DISABLE_STACK_TRACE | If set to true, disables the call stack trace information that follows the displayed severe error message text. For information on locating the cause of run-time errors using stack trace information, see Locating Run-Time Errors and Using Traceback Information.
FOR_ENABLE_VERBOSE_STACK_TRACE | If set to true, displays more detailed call stack information in the event of an error. For information on using stack trace information, see Using Traceback Information.
FOR_FULL_SRC_FILE_SPEC | By default, the traceback output displays only the file name and extension in the source file field. To display complete file name information including the path, set the environment variable FOR_FULL_SRC_FILE_SPEC to true. For more information, see Using Traceback Information.
FOR_GENERATE_DEBUG_EXCEPTION | In Visual Fortran Version 6, you no longer need to set this environment variable for the program to stop in the debugger when a severe error occurs. Regardless of whether this environment variable is set, you can view the Call Stack display. For more information, see Locating Run-Time Errors in the Debugger.
FOR_IGNORE_EXCEPTIONS | If set to true, disables the default run-time exception handling, for example, to allow just-in-time debugging. The run-time system exception handler returns EXCEPTION_CONTINUE_SEARCH to the operating system, which looks for other handlers to service the exception. For information on just-in-time debugging, see Running Fortran Applications and the Visual C++ Development Environment User's Guide.
FOR_NOERROR_DIALOGS | If set to true, disables the display of dialog boxes when certain exceptions or errors occur. This is useful when running many test programs in batch mode to prevent a failure from stopping execution of the entire test stream.
FOR_PRINT | Neither the PRINT statement nor a WRITE statement with an asterisk (*) in place of a unit number includes an explicit logical unit number. Instead, both use an implicit internal logical unit number and the FOR_PRINT environment variable. If FOR_PRINT is not defined, the code PRINT f,iolist or WRITE (*,f) iolist writes to CONOUT$ (standard output). If FOR_PRINT is defined (as a filename optionally containing a path), the specified file would be written to.
FOR_READ | A READ statement that uses an asterisk (*) in place of a unit number does not include an explicit logical unit number. Instead, it uses an implicit internal logical unit number and the FOR_READ environment variable. If FOR_READ is not defined, the code READ (*,f) iolist or READ f,iolist reads from CONIN$ (standard input). If FOR_READ is defined (as a filename optionally containing a path), the specified file would be read.
FOR_RUN_FLAWED_PENTIUM | If set to true, allows the continuation of the executing program when /check:flawed_pentium (default) is in effect and a flawed Pentium chip is detected. For more information, see Intel Pentium Floating-Point Flaw.
FOR_TYPE | The TYPE statement does not include an explicit logical unit number. Instead, it uses an implicit internal logical unit number and the FOR_TYPE environment variable. If FOR_TYPE is not defined, the code TYPE f,iolist writes to CONOUT$ (standard output). If FOR_TYPE is defined (as a filename optionally containing a path), the specified file would be written to.
FORTn | Lets you specify the file name for a particular unit number (n), when a file name is not specified in the OPEN statement or an implicit OPEN is used, and the compiler option /fpscomp:filesfromcmd was not specified. Preconnected files attached to units 0, 5, and 6 are by default associated with system standard I/O files.
FORT_CONVERTn | Lets you specify the data format for an unformatted file associated with a particular unit number (n), as described in Methods of Specifying the Data Format.
FORT_CONVERT.ext FORT_CONVERT_ext | Lets you specify the data format for unformatted files with a particular file extension suffix (ext), as described in Methods of Specifying the Data Format.

On the command line, the SET command lets you:

  • Set an environment variable to a value:
       SET environment-variable=value

    For example:

       SET FOR_GENERATE_DEBUG_EXCEPTION=TRUE
  • To view the current value of an environment variable, use the SET command with only the environment variable name:
      SET FOR_GENERATE_DEBUG_EXCEPTION
  FOR_GENERATE_DEBUG_EXCEPTION=TRUE

From within your program, you can set the appropriate environment variable by calling the SETENVQQ routine:

  program ENVVAR
  use dflib
  LOGICAL(4) res
  ! Add other data declarations here
  ! call SETENVQQ as a function
  res=SETENVQQ("FOR_GENERATE_DEBUG_EXCEPTION=T")
  ...

For a list of environment variables used with the DF command, see Environment Variables Used with the DF Command.


The Floating-Point Environment

This section describes the Visual Fortran numeric environment using IEEE arithmetic. The following topics are covered:

  • Representing Numbers
  • Loss of Precision Errors: Rounding, Special Values, Underflow, and Overflow
  • Setting and Retrieving Floating-Point Status and Control Words (ia32 systems only)
  • Handling Arithmetic Exceptions
  • Intel Pentium Floating-Point Flaw (ia32 systems only)

When the term floating-point unit (FPU) appears, it refers to your math processor. The descriptions in this section minimize hardware-specific terminology.


Representing Numbers

Fortran's numeric environment is flexible, which helps make Fortran a strong language for intensive numerical calculations. The Fortran standard purposely leaves the precision of numeric quantities and the method of rounding numeric results unspecified. This allows Fortran to operate efficiently for diverse applications on diverse systems.

The effect of math computations on integers is straightforward:

  • Integers of KIND=4 consist of a maximum positive integer (2,147,483,647), a minimum negative integer (-2,147,483,648), and all integers between them including zero.
  • Integers of KIND=8 consist of a maximum positive integer (-9,223,372,036,854,775,808), a minimum negative integer (9,223,372,036,854,775,807), and all integers between them including zero.

Operations on integers result in other integers within this range. The only arithmetic rule to remember is that integer division results in truncation (for example, 8/3 evaluates to 2).

Computations on real numbers, however, may not yield what you expect. This happens because the hardware must represent numbers in a finite number of bits.

There are several effects of using finite floating-point numbers. The hardware is not able to represent every real number exactly, but must approximate exact representations by rounding or truncating to finite length. In addition, some numbers lie outside the range of representation of the maximum and minimum exponents and can result in calculations that underflow and overflow. As an example of one consequence, finite precision produces many numbers that, although non-zero, behave in addition as zero.

You can minimize the effects of finite representation with programming techniques; for example, by not using floating-point numbers in LOGICAL comparisons or by giving them a tolerance (for example, IF (x <= 10.001)), and by not attempting to combine or compare numbers that differ by more than the number of significant bits. (For more information on programming methods to reduce the effects of imprecision, see Rounding Errors.)

For further discussion of how floating-point numbers are represented, see:

  • Floating-Point Numbers
  • Retrieving Parameters of Numeric Representations
  • Native IEEE Floating-Point Representations


Floating-Point Numbers

This version of Visual Fortran uses a close approximation to the IEEE floating-point standard (ANSI/IEEE Std 754-1985, IEEE Standard for Binary Floating-Point Arithmetic, 1985). This standard is common to many microcomputer-based systems due to the availability of fast math coprocessors that implement the required characteristics.

You should choose the appropriate setting of the /fpe compiler option to select the type of default floating-point exception handling provided by the Visual Fortran run-time system.

This section outlines the characteristics of the standard and its implementation for Visual Fortran. Except as noted, the description includes both the IEEE standard and the Visual Fortran implementation. The following topics are discussed:

  • Floating-Point Formats
  • Floating-Point Representation
  • Viewing Floating-Point Representations with BitViewer
  • Special Values (Signed Zero, NaN, Signed Infinity)


Floating-Point Formats

The IEEE Standard 754 specifies values and requirements for floating-point representation (such as base 2). The standard outlines requirements for two formats: basic and extended, and for two word-lengths within each format: single and double.

Visual Fortran supports single-precision format (REAL(4)) and double-precision format (REAL(8)) floating-point numbers. Visual Fortran sets the process control word by default to use double-precision run-time intermediate calculations. At some levels of optimization, some single-precision numbers are stored on the floating-point stack (which defaults to double precision) rather than being stored back into memory where they would be truncated to single precision. The compiler option /fltconsistency can control floating-point consistency and request that results be stored in memory rather than on the floating-point stack.


Floating-Point Representation

Floating-point numbers approximate real numbers with a finite number of bits. You can see the bits representing a floating-point number with the BitViewer tool. The bits are calculated as shown in the following formula. The representation is binary, so the base is 2. The bits bn represent binary digits (0 or 1). The precision P is the number of bits in the nonexponential part of the number (the significand), and E is the exponent. With these parameters, binary floating-point numbers approximate real numbers with the values:

( - 1)s b0 . b 1 b2 ... b P-1 x 2E

where s is 0 or 1 (+ or - ), and Emin<= E <= Emax

The following table gives the standard values for these parameters for single, double, and extended-double formats and the resulting bit widths for the sign, the exponent, and the full number.

Parameters for IEEE Floating-Point Formats

Parameter | Single | Double | Extended Double
Sign width in bits | 1 | 1 | 1
P | 24 | 53 | 64
Emax | +127 | +1023 | +16383
Emin | - 126 | - 1022 | - 16382
Exponent bias | +127 | +1023 | +16383
Exponent width in bits | 8 | 11 | 15
Format width in bits | 32 | 64 | 80

The standard requires that the single and double formats be normalized, so b0 is always 1. The actual number of bits needed to represent the precisions 24 and 53 is therefore 23 and 52, respectively, because b0 is chosen to be 1 implicitly.

Extended-double format need not be normalized, so it uses the full 64 bits for precision. A bias is added to all exponents so that only positive integer exponents occur. This expedites comparisons of exponent values. The stored exponent is actually:

e = E + bias

For more information:

  • On the floating-point representation, see Native IEEE Floating-Point Representations.
  • On using the BitViewer tool, see Viewing Floating-Point Representations with BitViewer.
  • On rReading or writing floating-point data other than native IEEE little endian data, see Converting Unformatted Numeric Data.


Viewing Floating-Point Representations with BitViewer

The BitViewer utility lets you view the binary representation of real numbers in single and double format. To access this tool from the command line, type the command BITVIEW. By default, Visual Fortran installs the BitViewer utility in the folder ...\Microsoft Visual Studio\Df98\BIN.

The following figure shows the logical layout of the single and double formats. The figure shows the contents of each field, its width, and the location of the most significant bit (MSB) and the least significant bit (LSB).

Logical Structure of the IEEE Single and Double Formats

To view floating-point numbers in BitViewer, open the Data Type menu, then choose Floating-Point Real (or use the F9 shortcut key). Set the precision by selecting one of the choices in the Bytes box. Four bytes, REAL(4), displays the number in single format (23-bit precision). Eight bytes, REAL(8), displays the number in double format (52-bit precision). The following figures show the BitViewer display of the memory storage for a 4-byte real number and an 8-byte real number, both equal to 12.6. In the double format display, the most significant part is on the bottom and the least significant 32 bits above.

Single Format in BitViewer

Double Format in BitViewer

Note: BitViewer lets you view and manipulate integer and character data as well as floating-point, and to translate between different data types. Refer to the BitViewer online Help file (Help menu) for more information.


Special Values

Special cases of the exponent-significand combination represent four types of special values in addition to the normalized numbers. The following table shows all five types of values.

IEEE Floating-Point Values

Name | Quantity | Exponent | Significand
Signed zero | ± 0 | E = Emin - 1 | sig = 0
Denormalized number | ± 0 . sig x 2Emin | E = Emin - 1 | sig not equal 0
Normalized number | ± 1 . sig x 2E | Emin<= E<= E max | sig
Signed infinity | ± infinity | E = Emax + 1 | sig = 0
Not a Number | NaN | E = Emax + 1 | sig not equal 0

These special values are interpreted as follows:

  • Signed zero

    Visual Fortran treats zero as signed by default. The sign of zero is the same as the sign of a nonzero number. If you use the intrinsic function SIGN with zero as the second argument, the sign of the zero will be transferred. Comparisons, however, consider +0 to be equal to -0. A signed zero is useful in certain numerical analysis algorithms, but in most applications the sign of zero is invisible.

  • Denormalized numbers

    Denormalized numbers (denormals) fill the gap between the smallest positive number and the smallest negative number. Otherwise only (±) 0 occurs in that interval. Denormalized numbers permit gradual underflow for intermediate results calculated internally in extended-double format. A status flag (on ia32 systems, the precision bit in the FPU Status Word exception field) is set when a number loses precision due to denormalization.

  • Signed infinity

    Infinities are the result of arithmetic in the limiting case of operands with arbitrarily large magnitude. They provide a way to continue when an overflow occurs. The sign of an infinity is simply the sign you obtain for a finite number in the same operation as the finite number approaches an infinite value. By retrieving the status flags described in Setting and Retrieving Floating-Point Status and Control Words in this section, you can differentiate between an infinity that results from an overflow and one that results from division by zero. Visual Fortran treats infinity as signed by default. The output value of infinity is Infinity or -Infinity.

  • Not a Number

    Not a Number (NaN) results from an operation involving one or more invalid operands. For instance 0/0 and SQRT(-1) result in NaN. In general, an operation involving a NaN produces another NaN. Because the fraction of a NaN is unspecified, there are many possible NaNs. Visual Fortran treats all NaNs identically, but provide two different types:

    • Signaling NAN, which has an initial fraction bit of 0 (zero).
    • Quiet NaN, which has an initial fraction bit of 1.

    The output value of NaN is NaN.


Retrieving Parameters of Numeric Representations

Visual Fortran includes several intrinsic functions that return details about the numeric representation. These are listed in the following table and described fully in the Language Reference.

Functions that Return Numeric Parameters

Name | Description | Argument/Function Type
DIGITS | DIGITS(x). Returns number of significant digits for data of the same type as x. | x: Integer or Real result: INTEGER(4)
EPSILON | EPSILON(x). Returns the smallest positive number that when added to one produces a number greater than one for data of the same type as x. | x: Real result: same type as x
EXPONENT | EXPONENT(x). Returns the exponent part of the representation of x. | x: Real result: INTEGER(4)
FRACTION | FRACTION(x). Returns the fractional part (significand) of the representation of x. | x: Real result: same type as x
HUGE | HUGE(x). Returns largest number that can be represented by data of type x. | x: Integer or Real result: same type as x
MAXEXPONENT | MAXEXPONENT(x). Returns the largest positive decimal exponent for data of the same type as x. | x: Real result: INTEGER(4)
MINEXPONENT | MINEXPONENT(x). Returns the largest negative decimal exponent for data of the same type as x. | x: Real result: INTEGER(4)
NEAREST | NEAREST(x, s). Returns the nearest different machine representable number to x in the direction of the sign of s. | x: Real s: Real and not zero result: same type as x
PRECISION | PRECISION(x). Returns the number of significant digits for data of the same type as x. | x: Real or Complex result: INTEGER(4)
RADIX | RADIX(x). Returns the base for data of the same type as x. | x: Integer or Real result: INTEGER(4)
RANGE | RANGE(x). Returns the decimal exponent range for data of the same type as x. | x: Integer, Real or Complex result: INTEGER(4)
RRSPACING | RRSPACING(x). Returns the reciprocal of the relative spacing of numbers near x. | x: Real result: same type as x
SCALE | SCALE(x, i). Multiplies x by 2 raised to the power of i. | x: Real i: Integer result: same type as x
SET_EXPONENT | SET_EXPONENT(x,i). Returns a number whose fractional part is x and whose exponential part is i. | x: Real i: Integer result: same type as x
SPACING | SPACING(x). Returns the absolute spacing of numbers near x. | x: Real result: same type as x
TINY | TINY(x). Returns smallest positive number that can be represented by data of type x. | x: Real result: same type as x


Loss of Precision Errors: Rounding, Special Values, Underflow, and Overflow

If a real number is not exactly one of the representable floating-point numbers, then the nearest floating-point number must represent it. The rounding error is the difference between the exact real number and its nearest floating-point representation. The floating-point number representing a rounded real number is called inexact.

Normally, calculations proceed when an inexact value results. Almost any floating-point operation can produce an inexact result. The rounding mode (round up, round down, round nearest, truncate) is determined by the floating-point control word.

If an arithmetic operation does not result in an exact, valid floating-point number, which includes numbers that have been rounded to an exactly representable floating-point number, it results in a special value: signed zero, signed infinity, NaN, or a denormal. Special-value results are a limiting case of the arithmetic operation involved. Special values can propagate through your arithmetic operations without causing your program to fail, and often providing usable results.

If an arithmetic operation results in an exact value, but the value is invalid, the operation causes underflow or overflow:

  • Underflow occurs when an arithmetic result is too small for the math processor to handle. Depending on the setting of the /fpe compiler option, underflows are set to zero (they are usually harmless) or they are left as is (denormalized).
  • Overflow occurs when an arithmetic result is too large for the math processor to handle. Overflows are more serious than underflows, and may indicate an error in the formulation of a problem (for example, unintended exponention of a large number by a large number). Overflows produce an appropriately signed infinity value.

Inexact numbers, special values, underflows, and overflows are floating-point exceptions. You can select how rounding is done and how exceptions are handled by setting the floating-point control word. Setting the control word is described in Setting and Retrieving Floating-Point Status and Control Words (ia32 only) and exception handling in Handling Floating-Point Exceptions (ia32 only).

For a further discussion of rounding errors see:

  • Rounding Errors


Rounding Errors

Although the rounding error for one real number might be acceptably small in your calculations, at least two problems arise because of it. If you test for exact equality between what you consider to be two exact numbers, the rounding error of either or both floating-point representations of those numbers may prevent a successful comparison and produce spurious results. Also, when you calculate with floating-point numbers the rounding errors may accumulate to a meaningful loss of numerical significance.

Carefully consider the numerics of your solution to minimize rounding errors or their effects. You might benefit from using double-precision arithmetic or restructuring your algorithm, or both. For instance, if your calculations involve arrays of linear data items, you might reduce the loss of numerical significance by subtracting the mean value of each array from each array element and by normalizing each element of such an array to the standard deviation of the array elements.

The following code segment can execute differently on different systems and produce different results for n, x, and s. It also produces different results if you use the /fltconsistency (ia32 systems only) or /nofltconsistency compiler options. Rounding error accumulates in x because the floating-point representation of 0.2 is inexact, then accumulates in s, and affects the final value for n:

      INTEGER n
      REAL s, x
      n = 0
      s = 0.
      x = 0.
    1 n = n + 1
      x = x + 0.2
      s = s + x
      IF ( x .LE. 10. ) GOTO 1 ! Will you get 51 cycles?
      WRITE(*,*) 'n = ', n, '; x = ', x, '; s = ', s

This example illustrates a common coding problem: carrying a floating-point variable through many successive cycles and then using it to perform an IF test. This process is common in numerical integration. There are several remedies. You can compute x and s as multiples of an integer index, for example, replacing the statement that increments x with x = n * 0.2 to avoid round-off accumulation. You might test for completion on the integer index, such as IF (n <= 50) GOTO 1, or use a DO loop, such as DO n= 1,51. If you must test on the real variable that is being cycled, use a realistic tolerance, such as IF (x <= 10.001).

Floating-point arithmetic does not always obey the standard rules of algebra exactly. Addition is not precisely associative when round-off errors are considered. You can use parentheses to express the exact evaluation you require to compute a correct, accurate answer. This is recommended when you specify optimization for your generated code, since associativity may otherwise be unpredictable.

The expressions (x + y) + z and x + (y + z) can give unexpected results in some cases, as the Visual Fortran Sample ASSOCN.F90 in the ...\DF98\SAMPLES\TUTORIAL folder shows. This example demonstrates the danger of combining two numbers whose values differ by more than the number of significant digits.

The Sample INTERVAL.F90 in the ...\DF98\SAMPLES\TUTORIAL folder shows how changing the rounding precision and rounding mode in the floating-point control word between calculations affects the calculated result of the following simple expression:

  (q*r + s*t) / (u + v)

The Visual Fortran Sample EPSILON.F90 in the ...\DF98\SAMPLES\TUTORIAL folder illustrates difficulties that rounding errors can cause in expressions like 1.0 + eps, where eps is just significant compared to 1.0.

The compiler uses the default rounding mode (round-to-nearest) during compilation. The compiler performs more compile-time operations that eliminate run-time operations as the optimization level increases. If you set rounding mode to a different setting (other than round-to-nearest), that rounding mode is used only if that computation is performed at run-time. For example, the Sample INTERVAL.F90 is compiled at /optimize:0, which disables certain compile-time optimizations, including constant propagation and inlining.

For more information:

  • ULPs, Relative Error, and Machine Epsilon


ULPs, Relative Error, and Machine Epsilon

Several terms describe the magnitude of rounding error. A floating-point approximation to a real constant or to a computed result may err by as much as 1/2 unit in the last place (the b P-1 bit). The abbreviation ULP represents the measure "unit in the last place." Another measure of the rounding error uses the relative error, which is the difference between the exact number and its approximation divided by the exact number. The relative error that corresponds to 1/2 ULP is bounded by:

1/2 2-P <= 1/2 ULP <= 2 -P.

The upper bound EPS = 2-P, the machine epsilon, is commonly used in discussions of rounding errors because it expresses the smallest floating-point number that you can add to 1.0 with a result that does not round to 1.0.

Additional guard bits are included in floating-point hardware to allow rounding on the order of EPS. The result of any one floating-point operation is therefore tolerably imprecise, but the total error that results from many such operations on propagated numbers accumulates unavoidably.


Setting and Retrieving Floating-Point Status and Control Words (ia32 only)

The FPU (floating-point unit) on ia32 systems contains eight floating-point registers the system uses for numeric calculations, for status and control words, and for error pointers. You normally need to consider only the status and control words, and then only when customizing your floating-point environment.

The FPU status and control words correspond to 16-bit registers whose bits hold the value of a state of the FPU or control its operation. Visual Fortran defines a set of symbolic constants to set and reset the proper bits in the status and control words. For example:

     USE DFLIB
     CALL SETCONTROLFPQQ(FPCW$OVERFLOW .AND. FPCW$CHOP)
     ! set the floating-point control word to allow overflows
     ! and to round by truncation

The status and control symbolic constants (such as FPCW$OVERFLOW and FPCW$CHOP in the preceding example) are defined as INTEGER(2) parameters in the module DFLIB.F90 in the ...\DF98\INCLUDE folder. The status and control words are made of logical combinations (such as with .AND.) of different parameters for different FPU options.

The name of a symbolic constant takes the general form name$option. The prefix name is one of the following:

Prefixes for Parameter Flags

name | Meaning
FPSW | Floating-point status word
FPCW | Floating-point control word
SIG | Signal
FPE | Floating-point exception
MTH | Math function

The suffix option is one of the options available for that name. The parameter name$option corresponds either to a status or control option (for example, FPSW$ZERODIVIDE, a status word parameter that shows whether a zero-divide exception has occurred or not) or name$option corresponds to a mask, which sets all symbolic constants to 1 for all the options of name. You can use the masks in logical functions (such as IAND, IOR, and NOT) to set or to clear all options for the specified name. The following sections define the options and illustrate their use with examples.

You can control the floating-point processor options (on ia32 systems) and find out its status with the run-time library routines GETSTATUSFPQQ (ia32 only), GETCONTROLFPQQ (ia32 only), SETCONTROLFPQQ (ia32 only), and MATHERRQQ (ia32 only). Examples of using these routines also appear in the following sections.

For more information:

  • Floating-Point Status Word (ia32 only)
  • Floating-Point Control Word (ia32 only)


Floating-Point Status Word (ia32 only)

On ia32 systems, the FPU status word includes bits that show the floating-point exception state of the processor. The status word parameters describe six exceptions: invalid result, denormalized result, zero divide, overflow, underflow and inexact precision. These are described in the section, Loss of Precision Errors: Rounding, Special Values, Underflow, and Overflow. When one of the bits is set to 1, it means a past floating-point operation produced that exception type. (Visual Fortran initially clears all status bits. It does not reset the status bits before performing additional floating-point operations after an exception occurs. The status bits accumulate.)

The following table shows the floating-point exception status parameters:

Parameter Name | Value in Hex | Description
FPSW$MSW_EM | #003F | Status Mask (set all bits to 1)
FPSW$INVALID | #0001 | An invalid result occurred
FPSW$DENORMAL | #0002 | A denormal (very small number) occurred
FPSW$ZERODIVIDE | #0004 | A divide by zero occurred
FPSW$OVERFLOW | #0008 | An overflow occurred
FPSW$UNDERFLOW | #0010 | An underflow occurred
FPSW$INEXACT | #0020 | Inexact precision occurred

You can find out which exceptions have occurred by retrieving the status word and comparing it to the exception parameters. For example:

 USE DFLIB
 INTEGER(2) status
 CALL GETSTATUSFPQQ(status)
 IF ((status .AND. FPSW$INEXACT) > 0) THEN
    WRITE (*, *) "Inexact precision has occurred"
 ELSE IF ((status .AND. FPSW$DENORMAL) > 0) THEN
    WRITE (*, *) "Denormal occurred"
 END IF

To clear the status word flags, call the CLEARSTATUSFPQQ (ia32 only) routine.


Floating-Point Control Word (ia32 only)

On ia32 systems, the FPU control word includes bits that control the FPU's precision, rounding mode, and whether exceptions generate signals if they occur. You can read the control word value with GETCONTROLFPQQ (ia32 only) to find out the current control settings, and you can change the control word with SETCONTROLFPQQ (ia32 only).

Each bit in the floating-point control word corresponds to a mode of the floating-point math processor. The DFLIB.F90 module file in the ...\DF98\INCLUDE folder contains the INTEGER(2) parameters defined for the control word, as shown in the following table:

Parameter Name | Value in Hex | Description
FPCW$MCW_IC | #1000 | Infinity control mask
FPCW$AFFINE | #1000 | Affine infinity
FPCW$PROJECTIVE | #0000 | Projective infinity
FPCW$MCW_PC | #0300 | Precision control mask
FPCW$64 | #0300 | 64-bit precision
FPCW$53 | #0200 | 53-bit precision
FPCW$24 | #0000 | 24-bit precision
FPCW$MCW_RC | #0C00 | Rounding control mask
FPCW$CHOP | #0C00 | Truncate
FPCW$UP | #0800 | Round up
FPCW$DOWN | #0400 | Round down
FPCW$NEAR | #0000 | Round to nearest
FPCW$MCW_EM | #003F | Exception mask
FPCW$INVALID | #0001 | Allow invalid numbers
FPCW$DENORMAL | #0002 | Allow denormals (very small numbers)
FPCW$ZERODIVIDE | #0004 | Allow divide by zero
FPCW$OVERFLOW | #0008 | Allow overflow
FPCW$UNDERFLOW | #0010 | Allow underflow
FPCW$INEXACT | #0020 | Allow inexact precision

The control word defaults are:

  • 53-bit precision
  • Round to nearest (rounding mode)
  • The denormal, underflow, overflow, invalid, and inexact precision exceptions are disabled (do not generate an exception). To change exception handling, you can use the /fpe compiler option or the FOR_SET_FPE routine.

For more information:

  • Exception Parameters
  • Precision Parameters
  • Rounding Parameters


Exception Parameters

An exception is disabled if its bit is set to 1 and enabled if its bit is cleared to 0. If an exception is disabled (exceptions can be disabled by setting the flags to 1 with SETCONTROLFPQQ (ia32 only)), it will not generate an interrupt signal if it occurs. The floating-point process will return an appropriate special value (for example, NaN or signed infinity), but the program continues. You can find out which exceptions (if any) occurred by calling GETSTATUSFPQQ (ia32 only).

If errors on floating-point exceptions are enabled (by clearing the flags to 0 with SETCONTROLFPQQ (ia32 only)), the operating system generates an interrupt when the exception occurs. By default these interrupts cause run-time errors, but you can capture the interrupts with SIGNALQQ and branch to your own error-handling routines.

You should remember not to clear all existing settings when changing one. The values you want to change should be combined with the existing control word in an inclusive-OR operation (OR, IOR, .OR.) if you do not want to reset all options. For example:

  USE DFLIB
  INTEGER(2) control, newcontrol
  CALL GETCONTROLFPQQ(control)
  newcontrol = (control .OR. FPCW$INVALID)
  ! Invalid exception set (disabled).
  CALL SETCONTROLFPQQ(newcontrol)


Precision Parameters

On ia32 systems, the precision bits control the precision to which the FPU rounds floating-point numbers. For example:

 USE DFLIB
 INTEGER(2) control, holdcontrol, newcontrol
 CALL GETCONTROLFPQQ(control)
 ! Clear any existing precision flags.
 holdcontrol = (control .AND. (.NOT. FPCW$MCW_PC))
 newcontrol = holdcontrol .OR. FPCW$64
 ! Set precision to 64 bits.
 CALL SETCONTROLFPQQ(newcontrol)

The precision options are mutually exclusive. If you set more than one, you may get an invalid mode or a mode other than the one you want. Therefore, you should clear the precision bits before setting a new precision mode.


Rounding Parameters

On ia32 systems, the rounding flags control the method of rounding that the FPU uses. For example:

 USE DFLIB
 INTEGER(2) control, clearcontrol, newcontrol
 CALL GETCONTROLFPQQ(control)
 ! Clear any existing rounding flags.
 clearcontrol = (control .AND. (.NOT. FPCW$MCW_RC))
 newcontrol = clearcontrol .OR. FPCW$UP
 ! Set rounding mode to round up.
 CALL SETCONTROLFPQQ(newcontrol)

The rounding options are mutually exclusive. If you set more than one, you may get an invalid mode or a mode other than the one you want. Therefore, you should clear the rounding bits before setting a new rounding mode.


Handling Arithmetic Exceptions

Two levels of arithmetic exceptions occur in Visual Fortran. Low-level exceptions result from floating-point exceptions. High-level exceptions result from arithmetic errors that occur during execution of the mathematical functions. You have some flexibility in handling each type of exception.

The following sections describe:

  • Floating-Point Exceptions
  • Handling Run-Time Math Exceptions (ia32 only)


Handling Floating-Point Exceptions

If a floating-point exception is disabled (set to 1), it will not generate an interrupt signal if it occurs. The floating-point process will return an appropriate special value (for example, NaN or signed infinity), and the program will continue. If a floating-point exception is enabled (set to 0), it will generate an interrupt signal (software interrupt) if it occurs. The following table lists the floating-point exception signals:

Parameter Name | Value in Hex | Description
FPE$INVALID | #81 | Invalid result
FPE$DENORMAL | #82 | Denormal operand
FPE$ZERODIVIDE | #83 | Divide by zero
FPE$OVERFLOW | #84 | Overflow
FPE$UNDERFLOW | #85 | Underflow
FPE$INEXACT | #86 | Inexact precision

If a floating-point exception interrupt occurs and you do not have an exception handling routine, the run-time system will respond to the interrupt according to the behavior selected by the compiler options /fpe and /math_library. Remember, interrupts only occur if an exception is enabled (set to 0).

If you do not want the default system exception handling, you need to write your own interrupt handling routine:

  • Write a function that performs whatever special behavior you require on the interrupt.
  • Register that function as the procedure to be called on that interrupt with SIGNALQQ.

Note that your interrupt handling routine must use the ATTRIBUTES C directive.

The drawback of writing your own routine is that your exception-handling routine cannot return to the process that caused the exception. This is because when your exception-handling routine is called, the floating-point processor is in an error condition, and if your routine returns, the processor is in the same state, which will cause a system termination. Your exception-handling routine can therefore either branch to another separate program unit or exit (after saving your program state and printing an appropriate message). You cannot return to a different statement in the program unit that caused the exception-handling routine, because a global GOTO does not exist, and you cannot reset the status word in the floating-point processor.

If you need to know when exceptions occur and also must continue if they do, you must disable exceptions so they do not cause an interrupt, then poll the floating-point status word at intervals with GETSTATUSFPQQ (ia32 only) to see if any exceptions occurred. To clear the status word flags, call the CLEARSTATUSFPQQ (ia32 only) routine.

Obviously, polling the floating-point status word at intervals creates processing overhead for your program. In general, you will want to allow the program to terminate if there is an exception. An example of an exception-handling routine follows. The exception-handling routine hand_fpe and the program that invokes it are both contained in SIGTEST.F90 in the Visual Fortran Samples folder ...\DF98\SAMPLES\TUTORIAL. The comments at the beginning of the SIGTEST.F90 file describe how to compile this example.

 ! SIGTEST.F90
 !Establish the name of the exception handler as the
 ! function to be invoked if an exception happens.
 ! The exception handler hand_fpe is attached below.
   USE DFLIB
      INTERFACE
        FUNCTION hand_fpe (sigid, except)
           !DEC$ ATTRIBUTES C :: hand_fpe
           INTEGER(4) hand_fpe
           INTEGER(2) sigid, except
        END FUNCTION
      END INTERFACE

 INTEGER(4) iret
 REAL(4) r1, r2
 r1 = 0.0
 iret = SIGNALQQ(SIG$FPE, hand_fpe)
 WRITE(*,*) 'Set exception handler. Return = ', iret
 ! Cause divide by zero exception
 r1 = 0.0
 r2 = 3/r1
 END

 ! Exception handler routine hand_fpe
   FUNCTION hand_fpe (signum, excnum)
     !DEC$ ATTRIBUTES C :: hand_fpe
     USE DFLIB
     INTEGER(2) signum, excnum
     WRITE(*,*) 'In signal handler for SIG$FPE'
     WRITE(*,*) 'signum = ', signum
     WRITE(*,*) 'exception = ', excnum
     SELECT CASE(excnum)
       CASE( FPE$INVALID )
         STOP ' Floating point exception: Invalid number'
       CASE( FPE$DENORMAL )
         STOP ' Floating point exception: Denormalized number'
       CASE( FPE$ZERODIVIDE )
         STOP ' Floating point exception: Zero divide'
       CASE( FPE$OVERFLOW )
         STOP ' Floating point exception: Overflow'
       CASE( FPE$UNDERFLOW )
         STOP ' Floating point exception: Underflow'
       CASE( FPE$INEXACT )
         STOP ' Floating point exception: Inexact precision'
       CASE DEFAULT
         STOP ' Floating point exception: Non-IEEE type'
     END SELECT
     hand_fpe = 1
   END


Handling Run-Time Math Exceptions (ia32 only)

On ia32 systems, the run-time subroutine MATHERRQQ (ia32 only) handles floating-point exceptions that occur in the math functions, such as SIN and LOG10.

If you use the default version of MATHERRQQ, which the linker automatically includes in your executable program, then math exceptions result in a standard run-time error (such as forrtl: severe (nnnn): sqrt: domain error). If you want to alter the behavior of one or more math exceptions, you need to provide your own version of MATHERRQQ. You have more flexibility in the way you handle run-time math exceptions than floating-point exceptions, because your error handling routine can return to the program unit that caused the exception.

The module DFLIB.F90 in the ...\DF98\INCLUDE folder contains the definitions of the run-time math exceptions. These are listed in the following table:

Parameter Name | Value | Description
MTH$E_DOMAIN | 1 | Argument domain error
MTH$E_SINGULARITY | 2 | Argument singularity
MTH$E_OVERFLOW | 3 | Overflow range error
MTH$E_UNDERFLOW | 4 | Underflow range error
MTH$E_TLOSS | 5 | Total loss of precision
MTH$E_PLOSS | 6 | Partial loss of precision

A domain error means that an argument is outside the math function's domain, for example, SQRT(-1). A singularity error means that an argument is a singularity value for the math function, and the result is not defined for that value, for example, LOG10(0.0). Overflow and underflow errors are the same as floating-point counterparts, and precision loss the same as floating-point inexact results.

You can write a MATHERRQQ subroutine that resolves errors generated by math functions. Your MATHERRQQ can issue a warning, assign a default value if an error occurs, or take other action. If you do not provide your own MATHERRQQ subroutine, a default MATHERRQQ provided with the floating-point library will terminate the program. The following gives an example of an alternative MATHERRQQ subroutine (in MATHERR.F90 in the .../DF98/SAMPLES/TUTORIAL folder):

 SUBROUTINE MATHERRQQ( name, length, info, retcode)
   USE DFLIB
   INTEGER(2) length, retcode
   CHARACTER(length) name
   RECORD /MTH$E_INFO/ info
   PRINT *, "Entered MATHERRQQ"
   PRINT *, "Failing function is: ", name
   PRINT *, "Error type is: ", info.errcode
   IF ((info.ftype == TY$REAL4 ).OR.(info.ftype == TY$REAL8)) THEN
       PRINT *, "Type: REAL"
       PRINT *, "Enter the desired function result: "
       READ(*,*) info.r8res
       retcode = 1
   ELSE IF ((info.ftype == TY$CMPLX8 ).OR.(info.ftype == TY$CMPLX16)) THEN
       PRINT *, "Type: COMPLEX"
       PRINT *, "Enter the desired function result: "
       READ(*,*) info.c16res
       retcode = 1
   END IF
 END

The following is a Visual Fortran Sample program (MATHTEST.F90 in the .../DF98/SAMPLES/TUTORIAL folder) that causes MATHERQQ to be called:

 REAL(4) r1, r2 /-1.0/
 REAL(8) r3, r4 /-1.0/
 COMPLEX(4) c1, c2 /(0.0, 0.0)/
 r1 = LOG(r2)
 r3 = SQRT(r4)
 c1 = CLOG(c2)

 WRITE(*, *) r1
 WRITE(*, *) r3
 WRITE(*, *) c1
 END


Intel Pentium Floating-Point Flaw (ia32 only)

Certain versions of the Intel (ia32) Pentium 586 processor have a flaw in rare floating-point division operations, which can also manifest itself in floating-point TAN, ATAN, and MOD operations. Since the number of input cases that cause this problem is very small and the associated error in the results is also very small, it is unlikely that you will ever see a problem due to this flaw. It has been estimated that only 1 out of 9 billion operations will produce even the slightest inaccuracy.

To request a check for a flawed Pentium chip, you can use the default compiler option /check:flawed_pentium option on code you suspect demonstrates the Pentium flaw, such as the code shown below. This compiler option generates run-time calls to the run-time routine FOR_CHECK_FLAWED_PENTIUM. The default, /check:flawed_pentium, does issue a run-time error message for this condition and stops program execution. To allow program execution to continue when this condition occurs, set the environment variable FOR_RUN_FLAWED_PENTIUM to true and rerun the program (see Run-Time Environment Variables).

Visual Fortran does not include a software workaround for the flawed Pentium problems, and these operations could produce incorrect results on a flawed Pentium processor.

To determine if you have a flawed Pentium, you can run the following program with the /check:flawed_pentium compiler option:

   PROGRAM go
   REAL(8) op1, op2
   COMMON /divide_check/ op1, op2
   DATA op1 /3145727.0/, op2 /4195835.0/
   IF( op2/op1 > 1.3338 ) THEN
      PRINT *,'This computer always divides correctly.'
   ELSE
      PRINT *,'This computer can have divide problems.'
   ENDIF
   END

If you compile and run this program without any compiler options (the default is /check:flawed_pentium), a run-time error occurs when it is run on a flawed Pentium system.

Your operating system can also work around flawed Pentium processors by using software emulation for floating-point operations. Refer to your operating system documentation for more information. If the operating system has been configured for software emulation, then all floating-point operations in Visual Fortran will always operate correctly, including the above program. Note that the performance cost of an operating system fix can be very high, and if your program is run on another machine without the same operating system fix, it will execute incorrectly.

If you distribute software that is susceptible to the floating-point problems of a flawed Pentium, and want your program to halt if it is run on a system with such a processor, you can check the processor when your application starts. To do this, convert the program above into a simple subroutine, call the subroutine at the start of your application, and use the STOP statement to stop the application before it begins if a flawed Pentium processor is detected. If you distribute your software, you should compile it with the /check:flawed_pentium compiler option.

All the run-time libraries that come with Visual Fortran have been compiled to be safe with respect to the Pentium divide and MOD problems.

For more information on the Intel Pentium flaw, or to request a replacement Pentium processor, you can contact Intel in the United States at 1-800-628-8686.


Advanced Exception and Termination Handling Considerations

This chapter provides a detailed discussion of exception and termination handling issues for those building Visual Fortran applications for ia32 systems. The following topics are discussed:

  • Default Exception Handling, Console Event Handling, and Termination Handling
  • Structure of a Visual Fortran Application
  • When to Provide Your Own Exception/Termination Handler
  • How to Provide Your Own Exception/Termination Handler

To fully appreciate this discussion, you will need knowledge of Windows structured exception handling (SEH). A good reference on this subject is Chapter 16 in the book Advanced Windows (Third Edition) by Jeffrey Richter.

To employ some of the exception handling techniques presented, you will need a C language compiler, such as Microsoft's Visual C++ product (part of Visual Studio), which has support for try-except constructs or some other form of support for structured exception handling.


Default Exception Handling, Console Event Handling, and Termination Handling

The Visual Fortran run-time system provides minimal default support for exception handling, console event handling, and application termination rundown. This section and its subsections describe the default support provided:

  • General Default Exception Handling
  • How the Floating-Point Exception Handling (/fpe) Compiler Option Works
  • Default Console Event Handling
  • General Default Termination Handling


General Default Exception Handling

The default exception handling support provided depends on the type of application (project type) being developed:

  • A default exception handler is included with Fortran Console, Fortran QuickWin, and Fortran Standard Graphics applications.
  • No default exception handler is included with Fortran Windows or Fortran DLL applications.

Most exceptions captured by the Visual Fortran default handler are dealt with as severe errors. When an exception occurs, the Fortran run-time system will display an error message and traceback output as described in Handling Run-Time Errors. A run-time error with a severe status causes the Visual Fortran run-time system to terminate the application. Most I/O programming errors are also severe and will terminate an application.

I/O programming errors are not exceptions and cannot be caught by an exception handler. An unhandled I/O programming error is reported through a different mechanism in the Visual Fortran run-time system. Regardless of the application (project) type, unhandled I/O programming error will generate an error message and traceback output.


How the Floating-Point Exception Handling (/fpe) Compiler Option Works

Whether the default handler treats floating-point exceptions as severe or non-severe depends upon the chosen /fpe and the /check:underflow compiler options. The /fpe option controls more than the behavior of the default exception handler, however.

The /fpe option selects a particular floating-point exception behavior. There are currently two supported behaviors:

  • Using /fpe:3, the default on ia32 systems, implies full IEEE support. There are no floating-point traps in this mode, although floating-point exceptions are detected and recorded in the floating-point status word.
  • The second option, /fpe:0, enables trapping on floating-point exceptions and flushing of underflow results to 0.0.

The full consequences of the /fpe compiler option depend upon the type of application you are building. You only get the full support for the chosen behavior in a Fortran Console or QuickWin/Standard Graphics application, assuming you do not override the default run-time exception handler. The work to achieve the full behavior is done partly by each of the default run-time handler, the Fortran compiler, the math library, the underlying hardware, and the operating system.

The following sections discuss:

  • Floating-Point Exceptions in Fortran Console, Fortran QuickWin, and Fortran Standard Graphics Applications
  • Floating-Point Exceptions in Fortran DLL Applications
  • Floating-Point Exceptions in Fortran Windows Applications

Floating-Point Exceptions in Fortran Console, Fortran QuickWin, and Fortran Standard Graphics Applications

When you build a console application, the compiler generates a few calls at the beginning of your Fortran main program to Fortran run-time routines that initialize the environment, either with default options or in accordance with your selected compile-time options.

  • For floating-point exception handling, /fpe:3 is the default on ia32 platforms. The run-time system initializes the hardware to mask all exceptions. With /fpe:3:
    • The Visual Fortran run-time system does this initialization automatically (no call from the compiled code).
    • The ia32 hardware automatically generates the default IEEE result for exceptional results.
    • Because traps are masked with /fpe:3, there are no traps and you see exceptional values like Nan's, Infinities, and denormalized numbers in your computations.

    Users can poll the floating-point status word with GETSTATUSFPQQ to see if an exception has occurred and can clear the status register with CLEARSTATUSFPQQ.

  • If you specify /fpe:0, the compiler generates a call to a Visual Fortran run-time routine, FOR_SET_FPE, with an argument that unmasks all floating-point traps in the floating-point control word. In this case, the hardware does not supply the default IEEE result. It traps to the operating system, which then looks for a handler.

    In a Fortran console or Fortran QuickWin application, the Visual Fortran run-time system provides a default handler unless you establish your own. For all exceptions except underflow, the run-time system just prints out an error message and aborts the application. For underflow, the run-time system replaces the result with zero. This treatment of denormalized numbers with /fpe:0 is called abrupt underflow to 0 (zero), as opposed to gradual underflow to 0 provided with /fpe:3.

    There are no denormalized numbers with /fpe:0. Further, if you also select /check:underflow with /fpe:0, you get a message at run-time for each of the first two occurrences of a floating-point underflow and a total count of underflows when the application exits. The /check:underflow option is not supported with /fpe:3.

Fixing up underflow results to zero can significantly degrade the performance of your ia32 application. If you are experiencing a large number of underflows, consider changing your code to avoid underflows or consider masking underflow traps and allowing the hardware to operate on denormalized numbers. The ia32 hardware is designed to operate correctly in the denormalized range and doing so is much faster than trapping to fix up a result to zero.

Another important point to understand about selecting the /fpe option is that the generated code must support the trapping mode. When an ia32 floating-point instruction generates an exceptional result, you do not necessarily get a trap. The instruction must be followed by an fwait instruction or another floating-point operate instruction to cause the trap to occur.

The Visual Fortran compiler generates machine code to support these requirements in accordance with your selected /fpe option setting. In other words, the generated code must support the trapping mode. You can see this by compiling a simple test program and look at the machine code listing with /fpe:0 first, then /fpe:3. There are no fwait instructions in the /fpe:3 code. Even if you replace the default run-time exception handler with your own handler, you may still want to compile with /fpe:0 to generate code that supports trapping.

Floating-Point Exceptions in Fortran DLL Applications

In a DLL, there is no main Fortran program (unless you have written your main program in Fortran), so there is no automatic calling of run-time routines to initialize the environment. Even if you select /fpe:0, there is nothing that causes the run-time system to unmask traps in the hardware so you won't see traps. You will continue to see the hardware generated default IEEE results (Nan's, Infinities, and and denormalized numbers in your computations). The generated code will still do its part by supplying the fwait instructions, and so on, but unless the traps are unmasked somehow, no traps will occur. You can use SETCONTROLFPQQ or FOR_SET_FPE to unmask traps in the floating-point control word.

There is also no default exception handling in a DLL. The main application that calls the DLL must provide this, or the code in the DLL must provide something when it is called. Since underflow processing (fixup to 0, and so on) is done by the default Fortran run-time system handler, a DLL won't have that feature automatically.

A typical strategy is to compile with /fpe:0, but only unmask floating divide by zero, floating overflow, and floating invalid traps in the floating-point control word. By leaving floating-point underflow traps masked, the hardware will continue to provide gradual underflow through the denormalized range, but other floating-point exceptions will generate traps, which the user then handles as desired.

Floating-Point Exceptions in Fortran Windows Applications

In a Fortran Windows application, the situation is similar to a Fortran DLL application. You define a WinMain routine in your Fortran code as the main entry point for your application. The Fortran run-time system does not define the main routine as it does in a Fortran console or Fortran QuickWin (or Standard Graphics) application. Your code is not protected by the default handler and the default run-time initialization routines are not called.


Default Console Event Handling

When the Fortran run-time system is initialized, it establishes a default console event handler through the SetConsoleCtrlHandler Win32 API routine. The default handler will respond to the following event types:

  • CTRL_C_EVENT
  • CTRL_BREAK_EVENT
  • CTRL_CLOSE_EVENT

These event types will result in an orderly program abort with an appropriate diagnostic message.

Other console events such as a CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT are not handled by the default handler. The handler is notified of these events but returns FALSE to the operating system. This allows a Visual Fortran application activated as a Windows service to continue execution when a user logs off.


General Default Termination Handling

When a Fortran Console, Fortran QuickWin, or Fortran Standard Graphics application terminates execution, either by normal termination or due to a severe error or exception, the following actions are taken by the Fortran run-time system:

  • If the default exception handler is used and the compiler /check:underflow and /fpe:0 options were selected, a count of the total number of floating point underflows is reported.
  • Any Open files are closed and the requested DISPOSITION operations are performed.
  • With a QuickWin application, any open QuickWin windows are closed.
  • The C run-time exit() routine is called with the status code to return to the operating system. The C run-time exit() routine will call the Win32 routine ExitProcess to terminate the process. (See crt0dat.c in the C run-time sources).

In a Fortran DLL or Fortran Windows application, any unhandled I/O programming errors will cause the following actions:

  • Any Open files are closed and the requested DISPOSITION operations are performed.
  • The C run-time exit() routine is called with the status code to return to the operating system. The C run-time exit() routine will call the Win32 API routine ExitProcess to terminate the process. (See crt0dat.c in the C run-time sources.)

Any unhandled exceptions that occur in a Fortran DLL or Fortran Windows application will have application dependent behavior. Since there is no Fortran default handler present, the behavior depends on what you provide for a handler. If you do not explicitly provide a handler, the default mechanisms provided in your main program will determine the behavior. In a Fortran Windows application, the C run-time system will terminate the application.


Structure of a Visual Fortran Application

To understand how Visual Fortran handlers are incorporated into your application, and how you might incorporate your own handlers, you should understand how each application type is constructed. The following sections describe handlers for the various application (project) types:

  • Fortran Console Applications
  • Fortran QuickWin and Standard Graphics Applications
  • Fortran DLL Applications
  • Fortran Windows Applications

Fortran Console Applications

Fortran Console applications actually look like C applications under the hood, with the Visual Fortran run-time system providing the C main() function.

The entry point for a console application is specified as the C library's mainCRTStartup() routine (see module crt0.c in the C run-time sources). This initializes the C run-time system, wraps the Fortran run-time system main() in a try-except construct using the C run-time's exception filter (_XcptFilter()), and calls the Fortran run-time system main() routine in run-time module for_main.c. In simplified form, it looks like this:

   mainCRTStartup()
  {
     C initialization code here
     __try {
          more initialization code here
          mainret = main()      /* calls Fortran run-time main() */
          exit(mainret)
     } __except ( _XcptFilter() )
            { _exit ( GetExceptionCode() ) }
  }

In the Fortran run-time system, main() initializes the Fortran run-time system (if not already initialized), wraps a try-except construct around MAIN__ (the entry point to the Fortran code) with a filter expression that invokes the Fortran run-time system default handler on exceptions, and calls MAIN__. It also wraps a try-finally construct around all of this so run-time system clean up gets done (with FOR_RTL_FINISH_) when the program exits. In simplified form, it looks like this:

  main()
  {
     __try {
        __try {
              for_rtl_init()
              MAIN__
        } __except ( expression-invoking-fortran-default-handler )
                 { }
     } __finally { for_rtl_finish() }
  }

In the Fortran code, symbol MAIN__ is the entry point called by the run-time system's main() routine. MAIN__ has the code to do any further run-time initialization or checks. For example, if the user compiled with the non-default /fpe:0 option, there would be a call to FOR_SET_FPE to tell the run-time system how to setup/react to floating-point exceptions.

Fortran QuickWin and Standard Graphics Applications

A Fortran QuickWin (including Fortran Standard Graphics) application is a specialized windows application where Visual Fortran provides the WinMain() function.

The entry point for a QuickWin application is specified as the C library WinMainCRTStartup() routine (see module crt0.c in the C run-time sources). This gets the C run-time initialized, wraps the Visual Fortran defined WinMain() in a try-except construct using the C run-time exception filter (_XcptFilter()) and calls the Visual Fortran defined WinMain() routine. In simplified form, it looks like this:

  WinMainCRTStartup()
  {
     C initialization code here
     __try {
           more initialization code here
           mainret = WinMain()      /* calls CVF qwin library WinMain() */
           exit(mainret)
     } __except ( _XcptFilter() )
              { _exit ( GetExceptionCode() ) }
  }

In the QuickWin library, WinMain() performs some initialization specific to QuickWin, creates a new thread which begins execution at QWINForkMain, and then sits in a message loop directing the action. The message loop is wrapped in a try-except-finally construct which invokes the Fortran run-time system default handler if an exception occurs, and calls FOR_RTL_FINISH_ at exit. QWINForkMain() running in the other thread calls the Fortran run-time system main(), which in turn calls MAIN__. In simplified form, it looks like this:

  WinMain()
  {
     Initialization code here
     BeginThreadEx (..., QWINForkMain, ... )
     __try {
        __try {
              the message loop...
              for_rtl_finish()
              return (msg.wParam)
        } __except ( expression-invoking-default-fortran-handler )
                 { }
     } __finally {
           for_rtl_finish()
           return (msg.wParam)
     }
  }

QWINForkMain resembles the following:

  QWINForkMain()
  {
     main()      /* calls the CVF rtl main() which calls MAIN__ */
     cleanup and exit...
  }

The routines main() and MAIN__ are the same as previously described for a Fortran Console application.

Fortran DLL Applications

A Fortran DLL is a collection of one or more routines that you generally call from some other main program. As such, the routines execute in the structure and environment created by the code which calls into the DLL. You can provide DLL initialization through a DllMain() function, but you probably would control general application initialization from the main program.

There are no automatic provisions for any exception handler in a DLL. There is no environment initialization except what you provide. Of course, if your main application is also written in Fortran, you will get the default Fortran handlers provided by that application type.

Fortran Windows Applications

A Fortran Windows application has as its entry point WinMainCRTStartup() and each user writes the code for the WinMain function declaration and interface. Examples are provided to show how to do this in Fortran code. The compiler still generates symbol MAIN__ with the initialization code in place, but nothing calls MAIN__. Also, nothing connects up to the run-time system's main() so there's no try-except construct to hook in the default Visual Fortran handler, and no run-time system initialization or cleanup. In simplified form, it looks like this:

  WinMainCRTStartup()
  {
     C initialization code
     __try {
           more initialization code
           mainret = WinMain()      /* calls the user's WinMain() */
           exit(mainret)
     } __except ( _XcptFilter() )
              { _exit ( GetExceptionCode() ) }
  }

The Fortran code contains:

  integer(4) function WinMain( HANDLE, HANDLE, LPSTR, int )
  ...
   ! whatever Fortran the user codes here...
  ...
  end


When to Provide Your Own Exception/Termination Handler

For Fortran Console, Fortran QuickWin, and Fortran Standard Graphics applications, the default exception and termination handlers are probably sufficient to meet most needs. As described in Structure Of a Visual Fortran Application, Fortran DLL and Fortran Windows applications do not have default handlers.

Whenever the default exception and termination handlers do not meet all your needs, consider providing your own handler. This is really a question you need to answer for each specific application. Some examples:

  • Suppose your application creates some files during the course of its execution and you do not want to leave them on the disk if an unexpected error or exception occurs. The default termination actions only cause the files to be closed if you specifically opened them with DISPOSE='DELETE'. But suppose you do not want them deleted under normal termination. If an unexpected event occurs, you need to get control so you can clean up these files as needed.
  • Perhaps your application can recover from a particular situation, for example, an integer divide-by-zero operation. You want to gain control if that exception occurs and deal with it.
  • Perhaps you just want to output an application-specific error message when an exception occurs.
  • You are building a Fortran DLL to run under a Visual Basic GUI and you do not want the DLL to crash the application if an exception occurs in the DLL.
  • Your code takes a lock on a global resource and you want to be sure and release the resource if an unexpected event occurs.

The list of possibilities is endless and only the application developer can anticipate his or her particular needs.

See How to Provide Your Own Exception/Termination Handler for some ideas on how to deal with unexpected events when implementing a handler for your application.


How to Provide Your Own Exception/Termination Handler

The most general way to establish your own handler is to use Windows structured exception handling capabilities (SEH). For lighter-weight exception handling requirements, you can use SIGNALQQ.

The following sections discuss ways to implement handlers for Fortran applications:

  • Using Windows Structured Exception Handling (SEH)
  • Using SIGNALQQ and How SIGNALQQ Works
  • Suggestions for Console Event Handlers


Using Windows Structured Exception Handling (SEH)

Windows provides a robust exception and termination handling mechanism called Structured Exception Handling (SEH). Structured exception handling requires support in both the operating system and compilers. Unfortunately, Visual Fortran does not include extensions for SEH support, but you can still take advantage of this powerful tool. By introducing a bit of C code in your application, you can use SEH to meet your exception handling needs.

You will need a C compiler with some form of SEH support. In this discussion, the syntax supported by Microsoft Visual C++ is used. Other compilers may provide SEH support, but use a different syntax.

Structured exception handling includes both exception and termination handling. Both mechanisms will be shown and explained through working examples.

The following topics are discussed:

  • Custom Handlers for Fortran Console, Fortran QuickWin, and Fortran Standard Graphics Applications
  • Custom Handlers For Fortran DLL Applications
  • Custom Handlers for Fortran Windows Applications

Custom Handlers for Fortran Console, Fortran QuickWin, and Fortran Standard Graphics Applications

Fortran Console and Fortran QuickWin (and Fortran Standard Graphics) applications have the full benefit of the Fortran default exception and error handling processing facilities. You may, however, want to supplement or replace the default facilities. Two Visual Fortran samples show how you can accomplish this:

  • Sample Program CSLEXCP2
  • Sample Program CSLEXCP4

Sample Program CSLEXCP2

The following discussion refers to the sample program CSLEXCP2 provided with the Visual Fortran kit in the ...\SAMPLES\EXCEPTIONHANDLING folder.

Suppose you have the problem described earlier of deciding what to do about open files your application has created in the event something unexpected occurs during execution of your application. Sample application CSLEXCP2 shows one way you might approach solving the problem.

Looking at CSLEXCP2.F90, there is a main program CSLEXCP2, and three additional routines, MY_CODE, MY_EXCEPTION_FILTER_CODE, and MY_TERMINATION_HANDLER_CODE. Routine MY_CODE is the main body of Fortran code in the application. It opens (OPEN statement) a data file and sits in a loop prompting for two integers, and writes (WRITE statement) the result of dividing the first by the second integer to the data file.

If the user enters the sentinel value of 99 for variable I (and not 0 for J), the application exits normally and the data file is closed (CLOSE statement) by the Fortran run-time system as a result of the call to the EXIT subroutine, but not deleted. If the user enters a 0 (zero) for variable J, an integer divide by zero exception occurs. This is the code we want to protect with a custom exception handler.

Look at the main program, CSLEXCP2:

 PROGRAM CSLEXCP2

 INTERFACE
     SUBROUTINE MY_CODE_WRAPPER()
     !DEC$ IF DEFINED(_X86_)
        !DEC$ATTRIBUTES C, ALIAS:'_MY_CODE_WRAPPER' :: MY_CODE_WRAPPER
     !DEC$ ELSE
        !DEC$ATTRIBUTES C, ALIAS:'MY_CODE_WRAPPER' :: MY_CODE_WRAPPER
     !DEC$ ENDIF
     END SUBROUTINE
 END INTERFACE

 CALL MY_CODE_WRAPPER()

 END

All CSLEXCP2 does is call a routine named MY_CODE_WRAPPER. MY_CODE_WRAPPER is a C routine that implements the custom handler. To see how this is done, look at file wrapper.c. MY_CODE_WRAPPER wraps a try-except construct around a call to the main body of the Fortran application, MY_CODE. It also wraps a try-finally construct around the try-except construct. If an exception occurs during execution of MY_CODE, the operating system will evaluate the except filter expression to see if this handler wishes to handle the event. The except filter expression is just a call to the Fortran routine MY_EXCEPTION_FILTER_CODE.

If MY_EXCEPTION_FILTER_CODE returns EXCEPTION_EXECUTE_HANDLER, the operating system continues execution in the except handler block, which in this case is empty. Execution would then continue in the __finally block which calls the general termination handler for the application, MY_TERMINATION_HANDLER_CODE. Routine MY_EXCEPTION_FILTER_CODE queries the user to see if the data file should be deleted or not. That is all the basic code needed to handle the exception situation. Routine MY_TERMINATION_HANDLER_CODE just prints a message and calls the EXIT subroutine to exit the application.

Note, if MY_EXCEPTION_FILTER_CODE returns EXCEPTION_CONTINUE_SEARCH, the operating system continues searching its list of exception handlers and finds the default Fortran run-time exception filter. The code in the __finally block would never be executed because the default run-time handler will exit the process as part of its default handling of the exception. You can experiment with this when you reply to the handler query "Enter A to exercise the termination handler code path,...or B to pass the exception to the default handler."

There are a couple of points to notice in this example. First, remember that this is a console application and its infrastructure basically looks like a C program. The entry point for the application is mainCRTStartup in the C run-time system. Routine mainCRTStartup() initializes the C run-time system and calls the Fortran run-time system main() routine. The Fortran run-time main() routine initializes the Fortran run-time system and calls entry point _MAIN__ in the Fortran code.

If you build the sample and request a listing with machine code from the Fortran compiler, you can see the bit of prolog code that the Fortran compiler generates which provides further initialization before actually executing your Fortran code. Here is an excerpt of that listing:

                .CODE
                PUBLIC	_MAIN__
         0000	_MAIN__ PROC
55           0000		push	ebp
EC8B         0001		mov	ebp, esp
24EC83       0003		sub	esp, 36
53           0006		push	ebx
000000E8     0007		call	_for_check_flawed_pentium@0
01
04EC83       000C		sub	esp, 4
0004058D     000F		lea	eax, dword ptr .literal$+4
0002
50           0015		push	eax
000000E8     0016		call	_for_set_fpe_@4
01
04C483       001B		add	esp, 4
04EC83       001E		sub	esp, 4
00001D8D     0021		lea	ebx, dword ptr .literal$
0002
53           0027		push	ebx
000000E8     0028		call	_for_set_reentrancy@4
01
04C483       002D		add	esp, 4
000000E8     0030		call	_MY_CODE_WRAPPER

Notice the calls to the Fortran run-time routines _for_check_flawed_pentium@0, _for_set_fpe_@4, and _for_set_reentrancy@4 that occur prior to the call to _MY_CODE_WRAPPER. This code was compiled with /fpe:0 selected, so you can see the call to _for_set_fpe_@4 to set up the non-default floating-point behavior on ia32 systems. This call would not be there with the default /fpe:3 option. The sample does not do any floating-point calculation (the /fpe:0 option was chosen just to illustrate the point). Likewise, if you deselect the check for flawed Pentium run-time option, the call to _for_check_flawed_pentium@0 would not be generated.

This prolog code is only executed as a result of the underlying structure of Fortran Console, Fortran QuickWin, and Fortran Standard Graphics applications. It would not be executed in a Fortran Windows application or Fortran DLL because there would be no Fortran run-time system main() routine present to call MAIN__.

Most of the work of handling the exception is really done in the course of executing the filter expression. The same is true of the Fortran default handler. So, if you allow an exception to be passed to the default run-time system handler, you will not get control again because the default handler will exit the process from within its exception filter in almost all cases. This short circuits any exception unwinding so your termination handler (the __finally construct) will never execute.

The default run-time exception handler plays a role in how an application behaves when exceptions occur while running under the debugger. Normally, the occurrence of an exception while debugging would cause the default handler to do its normal activities except it would not exit the process. Instead, it returns EXCEPTION_CONTINUE_SEARCH so the operating system will give the debugger a second chance at handling the exception and the debugger will stop in your code with the cursor pointing where the unhandled exception happened. If you are more interested in seeing where the exception happened than you are to see your termination handler execute, you can return EXCEPTION_CONTINUE_SEARCH from your exception filter and let the default run-time system handler get the application stopped in the debugger as usual.

In this (CSLEXCP2) example, no traceback output is produced to show where the integer divide by zero happened. This is normally done by the default handler, but we have overridden that handler. The next example shows that you can generate the traceback output in your custom handler using the TRACEBACKQQ routine.

Sample Program CSLEXCP4

The following discussion refers to the sample program CSLEXCP4 provided with the Visual Fortran kit in the ...\SAMPLES\EXCEPTIONHANDLING folder.

Suppose you want to allow the default handler to handle some exceptions, for example, floating-point underflow with /fpe:0. You would like to have the default handler provide the result fix up to zero for this case. Also, suppose you want to turn an exception into a simple program status code which your code can then act upon. Sample CSLEXCP4 will demonstrate a few techniques to accomplish this.

The premise of sample CSLEXCP4 is that a Fortran subroutine is to be called which may generate floating point exceptions. We would like to detect floating point divide by zero exceptions and take some useful action to shut down the application gracefully. The application is to be compiled /fpe:0 and it is desired to have the default Fortran run-time system handler continue handling floating point underflow exceptions.

Looking at the code in CSLEXCP4.F90, the subroutine to be protected is called DIVIDE. In a real application, the protected subroutine could be any complex sequence you like, but in this sample, the subroutine simply does a divide of two input numbers and prints the result. The main Fortran program does not call DIVIDE directly. It makes the call through a C wrapper function called DIVIDE_WRAPPER.

The DIVIDE_WRAPPER function, in file WRAPPER.C, wraps the call to DIVIDE in a try-except construct. In this simple example, it is assumed that if DIVIDE returns without an exception, then all is well and DIVIDE_WRAPPER sets the rtn_sts variable accordingly. If no exception occurs, the except filter expression is never evaluated and the except block is never executed. Execution continues with the return statement just below the except handler block that returns rtn_sts.

If an exception does occur during execution of DIVIDE, the except filter expression is evaluated by the operating system. The filter expression takes two actions:

  1. It captures the exception code related to the event in a local variable, ecode, for use in the exception handler code block. If the exception handler code block is executed, it will examine the exception code to determine a status value to return in rtn_sts.
  2. It calls a Fortran function called CHECK_EXCEPTION_INFO, passing it the value returned from the Win32 routine GetExceptionInformation.

If function CHECK_EXCEPTION_INFO returns EXCEPTION_EXECUTE_HANDLER, the operating system will execute the except handler code block. The handler block will examine the exception code and set rtn_sts to a value indicating a divide by zero occurred or to a value indicating some other exception occurred. Execution then continues with the return statement that returns the value of rtn_sts.

If function CHECK_EXCEPTION_INFO returns EXCEPTION_CONTINUE_SEARCH, the operating system will continue looking back up the list of exception filters looking for one that wants to handle the exception. In this sample, the next exception filter is the default Fortran run-time system exception filter.

The value passed to CHECK_EXCEPTION_INFO is the address of a data structure which contains pointers to an operating system supplied exception record and context record. CHECK_EXCEPTION_INFO uses this information to determine what happened and how to proceed. If this was a floating-point divide by zero, CHECK_EXCEPTION_INFO calls TRACEBACKQQ to produce a stack trace along with an application specific message. It then sets the return value of the function to EXCEPTION_EXECUTE_HANDLER and returns.

If this was a floating-point underflow exception, CHECK_EXCEPTION_INFO calls TRACEBACKQQ again, only so you can see what is happening in the application output. Then, it sets the return value of the function to EXCEPTION_CONTINUE_SEARCH. When the operating system sees this return value, it evaluates the Fortran run-time default except filter expression, which causes the floating underflow result to be fixed up with zero, and execution will continue in the main program at the point of the exception.

The main program initializes two arrays with a set of three values that will demonstrate each path of execution. A DO loop is traversed for three iterations:

  1. The first trip around the loop shows what happens when there are no exceptions.
  2. The second iteration shows a floating underflow being flushed to zero in the default handler.
  3. The third (final) iteration shows a floating divide by zero being processed. The program takes action to shutdown the application with a simple STOP statement and message.

Custom Handlers For Fortran DLL Applications

There are two aspects of creating custom handlers for Fortran DLL applications:

  • Containing Errors and Exceptions in Fortran DLL's
  • Enabling Floating-Point Traps in Fortran DLL's

Containing Errors and Exceptions in Fortran DLL's

If you are building a Fortran DLL and intend to call it from a Visual Basic GUI or a main program written in some other language, you want to be careful that errors and exceptions in the DLL do not crash your main application. Here are a few basic principles to keep in mind if you are building a Fortran DLL:

  • Construct your library routines so that they return a status to the caller and let the caller decide what to do.

    In order to return an expected status to the caller, you need to be defensive in your library code, so consider these other principles:

  • Where it makes sense, have the library code check input arguments passed in from the caller to make sure they are valid for whatever the library routine is going to do with them. For example, suppose the routine implements some numerical algorithm that has a valid domain of inputs it can act on and still produce well defined behavior. You can check the input arguments before you execute the algorithm and avoid unexpected behavior that might otherwise result (like unexpected floating-point exceptions). You might use Fortran intrinsic procedures like ISNAN and FP_CLASS to detect exceptional IEEE numbers. Your DLL code needs to return a status to the caller indicating the problem and let the caller take the appropriate action (gracefully shut down the application, try again with different input, etc.).

  • In your library code, always check the success or failure of calls to I/O routines and dynamic memory allocation/deallocation. In Fortran, the I/O statements have optional ERR, END, EOR, and IOSTAT arguments that you can use to determine if the I/O requested was successful. Dynamic memory ALLOCATE and DEALLOCATE statements have an optional STAT specifier that allows you to obtain the status of the dynamic memory allocation/deallocation and prevent program termination.

    If you do not specify an action to take on an error, the Fortran run-time system has no choice but to deal with the error as an unhandled severe error and terminate the program. For a specific example of using IOSTAT and ERR to deal gracefully with an OPEN statement that gets a file-not-found error, see Using the IOSTAT Specifier and Fortran Exit Codes. You can do the same sort of thing in your code, but just return the status back to your Visual Basic or other non-Fortran main program and let it decide what to do.

  • Try to write your DLL code so unexpected program exceptions cannot occur, but devise a strategy for dealing with unexpected exceptions if they do happen. The most effective alternative for dealing with an exception is to use Win32 Structured Exception Handling support to gain control when an exception happens. Wrap all your DLL routine calls in C try/except constructs and have the except() filter expression call a routine you define which determines how to respond.

Enabling Floating-Point Traps in Fortran DLL's

Before you can worry about how you will handle a floating-point trap condition occurring in a DLL, you have to consider the problem of unmasking those traps so they can occur. If you are compiling /fpe:3 and polling the floating-point status word to check for exceptions, you do not have to worry about the problem of unmasking traps. You do not want traps unmasked in that case.

However, if your strategy is to compile /fpe:0 and allow traps on floating-point exceptions, you need to take action to unmask the traps in the floating-point control word because most other languages mask traps by default.

Recall that a Fortran Console or Fortran QuickWin (or Standard Graphics) application would have unmasked traps for you automatically because the Fortran run-time system provides the main program and calls your MAIN__ which executes some prolog code before the actual application code starts. You do not have that in a Fortran DLL called by some other language. Different languages establish different initial environments. You must provide the desired initial environment yourself. The samples discussed below and in the discussion of Fortran Windows applications give some ideas on how and when to do this.

Sample Program VBVF1

The following discussion refers to the Visual Fortran sample program VBVF1 provided in the ...\SAMPLES\EXCEPTIONHANDLING folder. VBVF1 shows how you might incorporate structured exception handling and standard Fortran I/O error handling techniques to protect a Visual BASIC GUI from exceptions and errors occurring in a Fortran DLL called by the GUI. The error handling techniques are general in nature and could be used in other situations as well. For example, a C main program calling a Fortran DLL could also use the ideas presented here.

Sample application VBVF1 attempts to contain the effects of unexpected errors and exceptions occurring in a Fortran DLL by turning the unexpected events into user defined status conditions which the Visual Basic code can deal with gracefully.

The GUI has six buttons each of which generates a particular error condition in the Fortran DLL. A seventh button allows you to clear the error status displayed in the GUI. There are three text boxes in the GUI. One box displays a message associated with the last error. Another box displays an error number for the last error and the third box displays the Visual Basic source file where the error occurred.

Two of the buttons, "Test Integer Divide By Zero Response" and "Test Floating Point Overflow Response," are coded to show the use of a Visual Basic handler to deal with an error occurring in the Fortran DLL. While Visual Basic error handling works for these two specific cases to some extent, it is not a very robust solution for dealing with the more general case. If you are not familiar with Visual Basic error handling, this simple example should begin to give you an idea of what can be done. Refer to Visual Basic documentation for more complete information.

Each of the four remaining buttons causes a call to routine Fortran_Test in the Fortran DLL. See source file gen_errs.f90. Routine Fortran_Test generates the selected error. The Visual Basic code does not call Fortran_Test directly however. All Visual Basic calls to Fortran_Test go through a wrapper routine, Fortran_Test_Wrapper. Fortran_Test_Wrapper (source file wrappers.c) wraps a C try-except construct around calls into the DLL and acts as a control point for containing exceptions and errors that may unexpectedly occur in the DLL. Fortran_Test_Wrapper always returns a user defined application specific status to the Visual Basic calling routine. The Visual Basic code then reacts to the status value by displaying some appropriate message to the user.

The implementation of this scheme depends on two things:

  1. The solid programming practice of always requesting and checking I/O status in Fortran I/O statements
  2. The use of the try-except construct in the wrapper routine.

In the __try block of the wrapper routine, a call is made to Fortran_Test, which expects a Fortran defined status value to be returned. For the test cases that generate an I/O error, the code in Fortran_Test captures the I/O status and returns it to Fortran_Test_Wrapper. Fortran_Test_Wrapper then calls another DLL routine, TRANSLATE_TO_MY_APP_CODES, which does a table look up to translate the Fortran defined status code to a user defined status code. Execution continues with the return statement following the __except block. The Visual Basic code gets the user defined status value and puts up the appropriate display.

If an exception occurs during the execution of Fortran_Test, control transfers to the operating system. The operating system examines its list of exception handlers and finds the exception filter associated with Fortran_Test_Wrapper. It evaluates the __except expression to see if the exception will be handled here. The __except expression calls another DLL routine, CHECK_EXCEPTION_INFO, passing it the operating system supplied information about the exception. CHECK_EXCEPTION_INFO determines what the exception condition was, generates traceback information with an appropriate message specific to the event and returns EXCEPTION_EXECUTE_HANDLER.

Returning EXCEPTION_EXECUTE_HANDLER tells the operating system to resume execution in the handler block associated with the __except construct in Fortran_Test_Wrapper. The code in the handler block calls TRANSLATE_TO_MY_APP_CODES, which again does a table look up, but to a second table, to translate the Windows defined status code to a user defined status code. Execution continues with the return statement following the __except block. The Visual Basic code gets the user defined status value and puts up the appropriate display.

In this sample, the Fortran code is compiled /fpe:0 and intentionally creates floating point exceptions. It expects traps due to those exceptions. By default, Visual Basic masks all floating point traps so the application must take action to unmask traps. For this sample, two routines are provided in the DLL, Fortran_FP_Trap_Enable and Fortran_FP_Trap_Disable, that are called from the Visual Basic code. In procedure cmdFltOvf_Click, source file frmVBVF1.frm, there is a call to DLL routine Fortran_FP_Trap_Enable to unmask traps before the call to DLL routine Fortran_FltOvf which generates the exception.

Fortran_FP_Trap_Enable uses GETCONTROLFPQQ and SETCONTROLFPQQ to unmask traps in the floating-point control word. In the Visual Basic handler code for this routine at label My_VB_FltOvf_Handler, DLL routine Fortran_FP_Trap_Disable is called to revert to Visual Basic default exception settings. The timing of when and how to unmask or mask floating-point traps is an application design issue. The sample just shows one way you can do it.

Custom Handlers for Fortran Windows Applications

Fortran Windows applications are not hooked up to the Fortran default exception handling processing facilities. Fortran Windows applications are considered to be an area devoted to full customization, and the Fortran run-time system tries to "stay out of the way," so you can do whatever you want in your code.

The following discussion refers to the sample program WINEXCP1 provided with the Visual Fortran kit in the ...\SAMPLES\EXCEPTIONHANDLING folder. WINEXCP1 extends the GENERIC sample to show how you might incorporate structured exception handling and standard I/O error handling techniques to protect a Fortran message processing routine.

If you build and run this application, the main window will be displayed and you will see a menu labeled "Run Error Simulator." On the error simulator menu you can choose from six different error generating test cases. Selecting any one of the test cases sends a specific message which is interpreted in function MainWndProc in source file generic.f90. For each message, MainWndProc effectively calls the message processing routine ERROR_SIMULATOR to generate the selected condition. But MainWndProc does not call ERROR_SIMULATOR directly. Instead, it calls a wrapper routine, ERROR_SIMULATOR_WRAPPER in source file wrapper.c, which wraps a try-except construct around the call to ERROR_SIMULATOR. Also notice that MainWndProc expects to get a status value returned from ERROR_SIMULATOR_WRAPPER. If ERROR_SIMULATOR_WRAPPER returns a zero, all is well. If a non-zero status is returned, MainWndProc displays a message box indicating the error simulator had an error.

The important point to notice is that errors in the simulator routine are contained and turned into status codes that can be acted upon rather than allowing the program to abort when something unexpected occurs. To achieve this behavior, the code must do two things:

  1. The simulator must always ask for and test the completion status on Fortran I/O statements. If the I/O status is not FOR$IOS_SUCCESS, the simulator takes appropriate action and returns the non-zero status to MainWndProc.

  2. Exceptions must be caught and dealt with. The __except construct in ERROR_SIMULATOR_WRAPPER allows this to happen. When an exception occurs in ERROR_SIMULATOR, the operating system will evaluate the __except filter expression to see if we want to handle the exception. The filter expression is a call to CHECK_EXCEPTION_INFO in generic1.f90. A pointer to the operating system supplied exception information is passed to CHECK_EXCEPTION_INFO.

    If CHECK_EXCEPTION_INFO returns EXCEPTION_EXECUTE_HANDLER, the code in the __except handler block is executed. The handler block sets the return status to a non-zero value. Execution then continues with the return statement following the handler block and returns to MainWndProc. CHECK_EXCEPTION_INFO takes whatever error handling action is appropriate for the situation. In this sample program, it will clear the floating point exception status for floating point exceptions and in all cases, it will generate a traceback output with a message specific to the exception which occurred.

If CHECK_EXCEPTION_INFO returns EXCEPTION_CONTINUE_SEARCH, the operating system looks for any other handlers on its handler list. In this case it would find the C run-time system default __except filter which calls the C run-time routine _XcptFilter. _XcptFilter would return EXCEPTION_EXECUTE_HANDLER, which would call the C run-time _exit routine to abort the process.

Finally, recall that the Fortran run-time system does not supply a C main routine for a Fortran Windows application as in a Fortran Console or Fortran QuickWin application. In those cases, main would have called MAIN__, which would have executed a few compiler generated Fortran run-time system calls to do some additional initialization work. This application compiles with the /fpe:0 option so that floating-point traps can be demonstrated. The application must unmask these traps since the Fortran run-time system will not be called to do it automatically. For this sample, the traps are unmasked at the beginning of ERROR_SIMULATOR using GETCONTROLFPQQ and SETCONTROLFPQQ. The traps would have been masked by default.

In some situations, you may want a separate initialization routine to unmask traps for the entire duration of your application. In other cases, you may want to mask or unmask traps at selective points during program execution. If you selectively mask and unmask traps, keep in mind that your code may set floating point exception status bits even through you may have traps masked. The floating-point status bits are "sticky," so before you unmask traps again, you should clear the floating point status bits so you do not generate a false trap later in your code.


Using SIGNALQQ and How SIGNALQQ Works

For light-weight exception handling requirements, a handler established with SIGNALQQ may meet your needs. This section describes how signal handling with SIGNALQQ works in detail and also how GETEXCEPTIONPTRSQQ works.

Reference is made to C run-time sources provided with Microsoft Visual C++. The discussion is worth reviewing even if you do not have Visual C++ available though. The following topics are discussed:

  • C-Style Signal Handling Overview
  • Signal is Really SEH Again
  • How GETEXCEPTIONPTRSQQ Works

C-Style Signal Handling Overview

Many Fortran applications were developed on U*X systems where C-style signal handling was the usual way of dealing with exceptions. When ported to Windows, these applications can continue to use the C signal interface. SIGNALQQ will work with any application type using pure Fortran or mixed Fortran and C code. It does not work well, for example, in a VB-VF application.

SIGNALQQ is just a Fortran jacket to the C run-time signal() function. When you call SIGNALQQ, you are actually registering your signal handler (or action) for a particular signal with the C run-time system. The C run-time system simply stores your handler (or action) in an internal exception action table or variable where it associates your handler with the desired signal. The operating system has no knowledge of this association.

If you have Visual C++ available, you can look at the code for the C run-time signal routine in ...\MICROSOFT VISUAL STUDIO\VC98\CRT\WINSIG.C and see how the table is managed. The table itself is defined and initialized in source file WINXFLTR.C, available in the same folder. When a signal occurs, the C run-time system checks its internal table to see if you have registered a handler for the particular signal. It calls your routine if you have assigned a handler.

Signal is Really SEH Again

Notice that it is the C run-time system that calls your handler when a signal occurs, not the operating system. So how did the C run-time get the exception delivered to it? Recall that the entry point of your image is either mainCRTStartup or WinMainCRTStartup, depending on the application type. Refer back to the section Structure of a Visual Fortran Application and look at these entry points (or look at source file Crt0.c in the C run-time sources). Notice that they wrap a try-except construct around a call to either main() or WinMain() and that the filter expression associated with the __except construct calls a function _XcptFilter. _XcptFilter is passed two arguments which are the operating system supplied exception information.

When an exception occurs, the operating system looks at the list of exception filters and, starting with the inner most nested try-except construct, evaluates except filter expressions until it finds one which does not return EXCEPTION_CONTINUE_SEARCH. If your application type includes main from the Fortran run-time system and thus the except construct associated with main, the Fortran run-time filter will be evaluated before the C run-time filter. The Fortran filter expression will check to see if you have established your own handler with SIGNALQQ. If it finds there is such a handler, or if you have set the environment variable FOR_IGNORE_EXCEPTIONS, it will return EXCEPTION_CONTINUE_SEARCH to allow the C run-time exception filter the opportunity to deal with the exception and find your handler. If you have not established your own handler or set the environment variable, the Fortran run-time will perform its default exception handling processing.

The C filter function, _XcptFilter, compares the exception code from the operating system with its mapping of operating system exceptions to C signal codes. If it finds a match in the table, it uses the exception action entry in the table corresponding to the signal code. This is the same table where your SIGNALQQ handler is recorded as the action for the requested signal code. If you have established a handler, it will be called from _XcptFilter. Before your handler is called, _XcptFilter resets the specified action for the signal to SIG_DFL in the exception action table. If you try to continue from the exception and you want your handler invoked on the next occurrence of the signal, you must call SIGNALQQ again to reestablish your handler as the action for that signal. When your handler routine is finished executing and returns to _XcptFilter, the value EXCEPTION_CONTINUE_EXECUTION is returned to the operating system by _XcptFilter. The operating system will then resume execution at the point of the exception. If you do not want to continue execution, your handler should take appropriate action to shut down the application.

Not every operating system exception code maps to a C signal code. You can see the mapping in source WINXFLTR.C if you have it. Here is the list if you do not have WINXFLTR.C (as of Visual C++ version 6.0):

Operating System Exception Code | C Signal Number
STATUS_ACCESS_VIOLATION | SIGSEGV
STATUS_ILLEGAL_INSTRUCTION | SIGILL
STATUS_PRIVILEGED_INSTRUCTION | SIGILL
STATUS_FLOAT_DENORMAL_OPERAND | SIGFPE
STATUS_FLOAT_DIVIDE_BY_ZERO | SIGFPE
STATUS_FLOAT_INEXACT_RESULT | SIGFPE
STATUS_FLOAT_INVALID_OPERATION | SIGFPE
STATUS_FLOAT_OVERFLOW | SIGFPE
STATUS_FLOAT_STACK_CHECK | SIGFPE
STATUS_FLOAT_UNDERFLOW | SIGFPE

How GETEXCEPTIONPTRSQQ Works

When the C run-time exception filter function _XcptFilter calls your handler that you established with SIGNALQQ, the only argument passed to your handler is the C signal number. The C run-time system also saves a pointer to the exception information supplied by the operating system. This pointer is named _pxcptinfoptrs and you can retrieve it through the Fortran run-time routine GETEXCEPTIONPTRSQQ. See C header file signal.h for the public definition of _pxcptinfoptrs.

The value returned by GETEXCEPTIONPTRSQQ can be used in your handler routine to generate a traceback with TRACEBACKQQ. GETEXCEPTIONPTRSQQ just returns _pxcptinfoptrs. This pointer is only valid while you are executing within the evaluation of the C run-time filter function _XcptFilter because the exception information is on the program stack, so do not use GETEXCEPTIONPTRSQQ in any other context.

See the sample program ...\SAMPLES\EXCEPTIONHANDLING\GETEPTRS for a working example of using GETEXCEPTIONPTRSQQ.


Suggestions for Console Event Handlers

Control-C event handling is basically not reliable due to the threaded nature of processes executing on the Windows operating systems. Depending on what is happening at the instant a user types the Control-C, an event handler may or may not get the opportunity to execute. In any case, there are two ways to establish a handler if you want to do so. You can use the Win32 routine SetConsoleCtrlHandler directly or you can use SIGNALQQ to establish a handler for the C SIGINT or SIGBREAK signals.

The Fortran run-time system establishes a console event handler through a call to SetConsoleCtrlHandler as part of its run-time initialization processing. See the section Default Console Event Handling for a description of this handler's behavior.

If you call SetConsoleCtrlHandler to establish your own event handler, your handler will be called first on console events.

If you establish a handler through SIGNALQQ with SIGINT or SIGBREAK, the C run-time system will establish its own internal handler for console events through a call to SetConsoleCtrlHandler, and it will record your routine as the desired action to take upon occurrence of an event. When an event is delivered to the C run-time handler, it will reset the action for the signal to SIG_DFL and then call your handler routine.

You must call SIGNALQQ again to reset the action to your routine if you want to continue from the control event. Your handler is called with the signal code (either SIGINT or SIGBREAK) as the argument. After your routine returns to the C run-time event handler, the C handler will return the value TRUE to the operating system indicating the event has been handled.


Converting Unformatted Numeric Data

This section describes how you can use Visual Fortran to read and write nonnative unformatted numeric data, including Compaq Fortran for OpenVMS systems numeric data.

The following topics are discussed:

  • Supported Native and Nonnative Numeric Formats
  • Limitations of Numeric Conversion
  • Methods of Specifying the Data Format
  • Environment Variable FORT_CONVERTn Method
  • Environment Variable FORT_CONVERT.xxx or FORT_CONVERT_xxx Method
  • OPEN Statement CONVERT='keyword' Method
  • OPTIONS Statement Method
  • Compiler Option /convert:keyword Method
  • Additional Notes on Nonnative Data


Supported Native and Nonnative Numeric Formats

Visual Fortran supports the following little endian floating-point formats in memory:

Floating-Point Size | Format in Memory
REAL(KIND=4), COMPLEX(KIND=4) | IEEE S_floating
REAL(KIND=8), COMPLEX(KIND=8) | IEEE T_floating

If your program needs to read or write unformatted data files containing a floating-point format that differs from the format in memory for that data size, you can request that the unformatted data be converted.

Data storage in different computers uses a convention of either little endian or big endian storage. The storage convention generally applies to numeric values that span multiple bytes, as follows:

  • Little endian storage occurs when:
    • The least significant bit (LSB) value is in the byte with the lowest address.
    • The most significant bit (MSB) value is in the byte with the highest address.
    • The address of the numeric value is the byte containing the LSB. Subsequent bytes with higher addresses contain more significant bits.

  • Big endian storage occurs when:
    • The least significant bit (LSB) value is in the byte with the highest address.
    • The most significant bit (MSB) value is in the byte with the lowest address.
    • The address of the numeric value is the byte containing the MSB. Subsequent bytes with higher addresses contain less significant bits.

The following figure shows the difference between the two byte-ordering schemes.

Little and Big Endian Storage of an INTEGER Value

Moving unformatted data files between big endian and little endian computers requires that the data be converted.

Visual Fortran provides the capability for programs to read and write unformatted data (originally written using unformatted I/O statements) in several nonnative floating-point formats and in big endian INTEGER or floating-point format. Supported nonnative floating-point formats include Compaq VAX little endian floating-point formats supported by VAX FORTRAN, standard IEEE big endian floating-point format found on most Sun MicrosystemsTM systems and IBM RISC System/6000 systems, IBM floating-point formats (associated with the IBM's System/370 and similar systems), and CRAY floating-point formats.

Converting unformatted data instead of formatted data is generally faster and is less likely to lose precision of floating-point numbers.

The native memory format includes little endian integers and little endian IEEE floating-point formats, S_float for REAL(KIND=4) and COMPLEX(KIND=4) declarations and T_float for REAL(KIND=8) and COMPLEX(KIND=8) declarations.

The keywords for supported nonnative unformatted file formats and their data types are listed in the following table:

Nonnative Numeric Formats, Keywords, and Supported Data Types

Keyword | Description
BIG_ENDIAN | Big endian integer data of the appropriate size (one, two, or four bytes) and big endian IEEE floating-point (REAL(KIND=4), REAL(KIND=8), COMPLEX(KIND=4), COMPLEX(KIND=8)) formats of the appropriate size for either real or complex numbers. INTEGER(KIND=1) data is the same for little endian and big endian.
CRAY | Big endian integer data of the appropriate size (one, two, four, or eight bytes) and big endian CRAY proprietary floating-point format of size REAL(KIND=8) or COMPLEX(KIND=8).
FDX | Little endian integer data of the appropriate size (one, two, four, or eight bytes) and Compaq VAX floating-point data of format F_floating for REAL(KIND=4) or COMPLEX(KIND=4), and D_Floating for REAL(KIND=8) or COMPLEX(KIND=8).
FGX | Little endian integer data of the appropriate size (one, two, four, or eight bytes) and Compaq VAX floating-point data of format F_floating for REAL(KIND=4) or COMPLEX(KIND=4), and G_Floating for REAL(KIND=8) or COMPLEX(KIND=8).
IBM | Big endian integer data of the appropriate size (one, two, or four bytes) and big endian IBM proprietary floating-point format of size REAL(KIND=4) or COMPLEX(KIND=4) or size REAL(KIND=8) or COMPLEX(KIND=8).
LITTLE_ENDIAN | Native little endian integers of the appropriate size (one, two, four, or eight bytes) and native little endian IEEE floating-point data of the appropriate size and type (REAL(KIND=4), REAL(KIND=8), COMPLEX(KIND=4), COMPLEX(KIND=8)). These are the same formats as stored in memory. For additional information on supported ranges for these data types, see Native IEEE Floating-Point Representations.
NATIVE | No conversion occurs between memory and disk. This is the default for unformatted files.
VAXD | Little endian integers of the appropriate size (one, two, four, or eight bytes) and Compaq VAX floating-point format F_floating for size REAL(KIND=4) or COMPLEX(KIND=4), and D_floating for size REAL(KIND=8) or COMPLEX(KIND=8).
VAXG | Little endian integers of the appropriate size (one, two, four, or eight bytes) and Compaq VAX floating-point format F_floating for size REAL(KIND=4) or COMPLEX(KIND=4), and G_floating for size REAL(KIND=8) or COMPLEX(KIND=8).

When reading a nonnative format, the nonnative format on disk is converted to native format in memory. If a converted nonnative value is outside the range of the native data type, a run-time message is displayed.


Limitations of Numeric Conversion

The Visual Fortran floating-point conversion solution is not expected to fulfill all floating-point conversion needs.

For instance, data fields in record structure variables (specified in a STRUCTURE statement) and data components of derived types (TYPE statement) are not converted. When they are later examined as separate fields by the program, they will remain in the binary format they were stored in on disk, unless the program is modified. With EQUIVALENCE statements, the data type of the variable named in the I/O statement is used.

If a program reads an I/O record containing multiple format floating-point fields into a single variable (such as an array) instead of their respective variables, the fields will not be converted. When they are later examined as separate fields by the program, they will remain in the binary format they were stored in on disk, unless the program is modified.

Conversions of the following file structure types are not supported:

  • Binary data (FORM='BINARY')
  • Formatted data (FORM='FORMATTED')
  • Unformatted data (FORM='UNFORMATTED') written by Microsoft Fortran PowerStation or by Visual Fortran with the /fpscomp:ioformat compiler option in effect.


Methods of Specifying the Data Format

There are five methods of specifying a nonnative numeric format for unformatted data. If none of these methods are specified, the native LITTLE_ENDIAN format is assumed (no conversion occurs between disk and memory).

Any keyword listed in Supported Native and Nonnative Numeric Formats can be used with any of these methods.

The five methods you can use to specify the type of nonnative (or native) format are as follows:

  1. Setting an environment variable for a specific unit number before the file is opened. The environment variable is named FORT_CONVERTn, where n is the unit number.
  2. Setting an environment variable for a specific file name extension before the file is opened. The environment variable is named FORT_CONVERT.ext or FORT_CONVERT_ext, where ext is the file name extension (suffix).
  3. Compiling the program with an OPTIONS statement that specifies the /CONVERT=keyword qualifier. This method affects all unit numbers using unformatted data specified by the program.
  4. Specifying the CONVERT keyword in the OPEN statement for a specific unit number.
  5. Compiling the program with the appropriate compiler option (DF command /convert: keyword or visual development environment equivalent), which affects all unit numbers that use unformatted data specified by the program.

If you specify more than one method, the order of precedence when you open a file with unformatted data is to:

  1. Check for an environment variable (FORT_CONVERTn) for the specified unit number (applies to any file opened on a particular unit).
  2. Check for an environment variable (FORT_CONVERT.ext is checked before FORT_CONVERT_ext) for the specified file name extension (applies to all files opened with the specified file name extension).
  3. Check the OPEN statement CONVERT specifier.
  4. Check whether an OPTIONS statement with a /CONVERT=keyword qualifier was present when the program was compiled.
  5. Check whether the compiler option /convert:keyword was present when the program was compiled.

The following sections describe each method:

  • Environment Variable FORT_CONVERTn Method
  • Environment Variable FORT_CONVERT.xxx or FORT_CONVERT_xxx Method
  • OPEN Statement CONVERT= Method
  • OPTIONS Statement Method
  • Compiler Option /convert Method


Environment Variable FORT_CONVERTn Method

You can use this method to specify a non-native numeric format for each specified unit number. You specify the numeric format at run time by setting the appropriate environment variable before an implicit or explicit OPEN to that unit number.

When the appropriate environment variable is set when you open the file, the environment variable is always used because this method takes precedence over the other methods. For instance, you might use this method to specify that a unit number will use a particular format instead of the format specified in the program (perhaps for a one-time file conversion).

For example, assume you have a previously compiled program that reads numeric data from unit 28 and writes it to unit 29 using unformatted I/O statements. You want the program to read nonnative big endian (IEEE floating-point) format from unit 28 and write that data in native little endian format to unit 29. In this case, the data is converted from big endian IEEE format to native little endian IEEE memory format when read from unit 28, and then written without conversion in native little endian IEEE format to unit 29.

Without requiring source code modification or recompilation of this program, the following command sequence sets the appropriate environment variables before running the program (c:\users\leslie\convieee.exe):

set FORT_CONVERT28=BIG_ENDIAN
set FORT_CONVERT29=NATIVE
c:\users\leslie\convieee.exe

The following figure shows the data formats used on disk and in memory when the example file c:\users\leslie\convieee.exe is run after the environment variables are set.

Sample Unformatted File Conversion

This method takes precedence over other methods.


Environment Variable FORT_CONVERT.ext or FORT_CONVERT_ext Method

You can use this method to specify a non-native numeric format for each specified file name extension (suffix). You specify the numeric format at run time by setting the appropriate environment variable before an implicit or explicit OPEN to one or more unformatted files. You can use the format FORT_CONVERT.ext or FORT_CONVERT_ext (where ext is the file extension or suffix). The FORT_CONVERT.ext environment variable is checked before FORT_CONVERT_ext environment variable (if ext is the same).

For example, assume you have a previously compiled program that reads numeric data from one file and writes to another file using unformatted I/O statements. You want the program to read nonnative big endian (IEEE floating-point) format from a file with a .dat file extension extension and write that data in native little endian format to a file with a extension of .data. In this case, the data is converted from big endian IEEE format to native little endian IEEE memory format (S_float and T_float) when read from file.dat, and then written without conversion in native little endian IEEE format to the file with a suffix of .data, assuming that environment variables FORT_CONVERT.DATA and FORT_CONVERTn (for that unit number) are not defined.

Without requiring source code modification or recompilation of this program, the following command sequence sets the appropriate environment variables before running the program (c:\proj2\cvbigend.exe):

   set FORT_CONVERT.DAT=BIG_ENDIAN
   c:\proj2\cvbigend.exe

The FORT_CONVERTn method takes precedence over this method. When the appropriate environment variable is set when you open the file, the FORT_CONVERT.ext or FORT_CONVERT_ext environment variable is used if a FORT_CONVERTn environment variable is not set for the unit number.

The FORT_CONVERTn and the FORT_CONVERT.ext or FORT_CONVERT_ext environment variable methods take precedence over the other methods. For instance, you might use this method to specify that a unit number will use a particular format instead of the format specified in the program (perhaps for a one-time file conversion).

You can set the appropriate environment variable using the format FORT_CONVERT.ext or FORT_CONVERT_ext. If you also use Compaq Fortran on U*X systems, consider using the FORT_CONVERT_ext form, because a dot (.) cannot be used for environment variable names on certain U*X command shells. If you do define both FORT_CONVERT.ext and FORT_CONVERT_ext for the same extension (ext), the file defined by FORT_CONVERT.ext is used.

On Windows systems, the file name extension (suffix) is not case-sensitive. The extension must be part of the file name (not the directory path).


OPEN Statement CONVERT Method

You can use this method to specify a non-native numeric format for each specified unit number. This method requires an explicit file OPEN statement to specify the numeric format of the file for that unit number.

This method takes precedence over the OPTIONS statement and the compiler option /convert:keyword method, but has a lower precedence than the environment variable methods.

For example, the following source code shows how the OPEN statement would be coded to read unformatted VAXD numeric data from unit 15, which might be processed and possibly written in native little endian format to unit 20 (the absence of the CONVERT keyword or environment variables FORT_CONVERT20, FORT_CONVERT.dat, or FORT_CONVERT_dat indicates native little endian data for unit 20):

 OPEN (CONVERT='VAXD', FILE='graph3.dat', FORM='UNFORMATTED', UNIT=15)
   .
   .
   .
 OPEN (FILE='graph3_t.dat', FORM='UNFORMATTED', UNIT=20)

A hard-coded OPEN statement CONVERT keyword value cannot be changed after compile time. However, to allow selection of a particular format at run time, equate the CONVERT keyword to a variable and provide the user with a menu that allows selection of the appropriate format (menu choice sets the variable) before the OPEN occurs. You can also select a particular format at run time for a unit number by using one of the environment variable methods (FORT_CONVERTn, FORT_CONVERT.ext, or FORT_CONVERT_ext), which take precedence over the OPEN statement CONVERT keyword method.


OPTIONS Statement Method

You can only specify one numeric file format for all unformatted file unit numbers using this method unless you also use one of the environment variable methods or OPEN statement CONVERT keyword method.

You specify the numeric format at compile time and must compile all routines under the same OPTIONS statement /CONVERT=keyword qualifier. You could use one source program and compile it using different DF commands to create multiple executable programs that each read a certain format.

The FORT_CONVERTn environment variable method, FORT_CONVERT.ext or FORT_CONVERT_ext environment variable method, and the OPEN statement CONVERT keyword method take precedence over this method. For instance, you might use the FORT_CONVERTn environment variable or OPEN CONVERT keyword method to specify each unit number that will use a format other than that specified using the DF option method. This method takes precedence over the DF /convert:keyword compiler option method.

You can use OPTIONS statements to specify the appropriate floating-point formats (in memory and in unformatted files) instead of using the corresponding DF command qualifiers. For example, to use VAX F_floating and G_floating as the unformatted file format, specify the following OPTIONS statement:

  OPTIONS /CONVERT=VAXG

Because this method affects all unit numbers, you cannot read data in one format and write it in another format, unless you use it in combination with one of the environment variable methods or the OPEN statement CONVERT keyword method to specify a different format for a particular unit number.

For more information, see the OPTIONS statement.


Compiler Option /convert Method

You can only specify one numeric format for all unformatted file unit numbers using the compiler option /convert method unless you also use one (or more) of the previous methods. You specify the numeric format at compile time and must compile all routines under the same /convert:keyword compiler option, which is listed under the Compatibility category in the visual development environment, Fortran tab. You could use the same source program and compile it using different DF commands (or the equivalent in the visual development environment) to create multiple executable programs that each read a certain format.

If you specify other methods, they take precedence over this method. For instance, you might use the environment variable or OPEN statement CONVERT keyword method to specify each unit number that will use a format different than that specified using the DF /convert:keyword compiler option method for all other unit numbers.

For example, the following command compiles program file.for to use VAX D_floating (and F_floating) floating-point data for all unit numbers (unless superseded by one of the other methods). Data is converted between the file format and the little endian memory format (little endian integers, S_float and T_float little endian IEEE floating-point format). The created file, vconvert.exe, can then be run:

  DF file.for /convert:vaxd /link /out:vconvert.exe

Because this method affects all unformatted file unit numbers, you cannot read data in one format and write it in another file format using the /convert:keyword compiler option method alone. You can if you use it in combination with the environment variable methods or the OPEN statement CONVERT keyword method to specify a different format for a particular unit number.


Additional Notes on Nonnative Data

The following notes apply to porting nonnative data:

  • When porting source code along with the unformatted data, vendors might use different units for specifying the record length (RECL specifier) of unformatted files. While formatted files are specified in units of characters (bytes), unformatted files are specified in longword units for Compaq Fortran (default) and some other vendors.

    To allow you to specify the RECL units (bytes or longwords) for unformatted files without source file modification, use the /assume:byterecl compiler option (in the visual development environment, this is available in the Project menu Settings item, Fortran tab, Fortran Data category).

    The Fortran 90 standard (American National Standard Fortran 90, ANSI X3.198-1991, and International Standards Organization standard ISO/IEC 1539:1991), in Section 9.3.4.5, states: "If the file is being connected for unformatted input/output, the length is measured in processor-dependent units."

  • Certain vendors apply different OPEN statement defaults to determine the record type. The default record type (RECORDTYPE) with Compaq Fortran depends on the values for the ACCESS and FORM specifiers for the OPEN statement (also described in the Compaq Fortran Language Reference Manual).
  • Certain vendors use a different identifier for the logical data types, such as hex FF instead of 01 to denote "true."
  • Source code being ported may be coded specifically for big endian use.


Hexadecimal-Binary-Octal-Decimal Conversions

The following table lists hexadecimal, binary, octal, and decimal conversion:

Hexadecimal, Binary, Octal, and Decimal Conversion

Hex Number | Binary Number | Octal Number | Decimal Number
0 | 0000 | 00 | 0
1 | 0001 | 01 | 1
2 | 0010 | 02 | 2
3 | 0011 | 03 | 3
4 | 0100 | 04 | 4
5 | 0101 | 05 | 5
6 | 0110 | 06 | 6
7 | 0111 | 07 | 7
8 | 1000 | 10 | 8
9 | 1001 | 11 | 9
A | 1010 | 12 | 10
B | 1011 | 13 | 11
C | 1100 | 14 | 12
D | 1101 | 15 | 13
E | 1110 | 16 | 14
F | 1111 | 17 | 15


Using the IMSL Mathematical and Statistical Libraries

The Professional and Enterprise Editions of Visual Fortran include the IMSL libraries, a collection of nearly 1,000 mathematical and statistical functions easily accessible from the visual development environment.

The IMSL libraries are installed with Visual Fortran, as described in Compaq Visual Fortran Installation and Getting Started.

You can view the IMSL readme file and online help using the Compaq Visual Fortran program folder. The online documentation included with the IMSL Libraries includes an ASCII readable file and PDF files:

  • README.TXT

    This ASCII readable file contains the Release Notes for the IMSL Libraries. It also includes information on accessing the IMSL libraries.

  • On-line PDF documentation

    The IMSL online Adobe Acrobat PDF documentation lets you quickly find details on the purpose and use of any IMSL Library routine. You can access the following topics through the online IMSL Routines Reference (PDF version):

    • IMSL Mathematical Library Subroutines
    • IMSL Mathematical Library Special Functions
    • IMSL Statistical Library Subroutines, Volumes 1 and 2
    • IMSL Fortran 90 MP Library Subroutines

    Click on any of the libraries to see a submenu of items grouped by subject. Within each category (for example, Linear Systems, Eigensystem Analysis, and so on), click on a routine for more information.

IMSL libraries (and IMSL online documentation files) are included with the Professional and Enterprise Editions of Visual Fortran (not the Standard Edition).

When calling the IMSL library routines from a multi-threaded application, be aware that the IMSL routines are intended only for single-thread use.

This section provides information on the following topics:

  • Using the IMSL Libraries from Visual Fortran
  • Library Naming Conventions
  • Using IMSL Libraries in a Mixed-Language Environment


Using the IMSL Libraries from Visual Fortran

To use the IMSL libraries, you need to:

  1. Set the necessary IMSL environment variables for your development environment by executing the DFVARS.BAT file (see Using the Compiler and Linker from the Command Line). This sets the INCLUDE path and library (linker) search paths.

    Within the Fortran Command Prompt (command-line window) in the Compaq Visual Fortran program folder, the DFVARS.BAT file is already executed. Within the visual development environment, the equivalent of DFVARS.BAT file (as installed by Visual Fortran) is executed. You can view these directory paths within the visual development environment by:

    1. In the Tools menu, click Options.
    2. Click the Directory tab.
    3. In the drop-down list for Show Directories, select Library files and view the library paths.
    4. In the drop-down list for Show Directories, select Include files and view the include file paths.
    5. Click OK if you have changed any information.

  2. The easiest way to pass IMSL libraries to the Linker is to specify the /imsl compiler option.

    Alternatively, if you wish to explicitly include the IMSL libraries, do the following in the visual development environment:

    1. If not already open, open your Project Workspace (File menu, Open Workspace).
    2. In the Project menu, click on Settings.
    3. Click on the Link tab and add the IMSL library names (explained in Library Naming Conventions) to the Project Options box as follows:
      imsl.lib imsls_err.lib imslmpistub.lib
    4. Click OK if you have changed any information.

  3. Make IMSL routines and their interfaces available to your program:

    • When calling Mathematics and Statistical library routines from a Fortran program, you should use the numerical_libraries module to provide interface blocks and parameter definitions for the routines. Including the following USE statement in your calling program will verify the correct usage of the IMSL routines at compile time:
        USE numerical_libraries

      When you add the USE numerical_libraries line to your program, you should not declare the called routines as external with the EXTERNAL statement.

      For more details, see the IMSL readme file in the Visual Fortran program folder.

      When calling Mathematics and Statistical library routines, you do not need to declare the functions or subroutines separately.

    • When also calling Fortran 90 MP library routines, you should instead use the imslf90 module to provide interface blocks and parameter definitions for all the Fortran 90 MP routines and the MATH and STAT library routines. Including the following USE statement in your calling program will verify the correct usage of the IMSL routines at compile time:
         USE IMSLF90
      For more information about calling the Fortran 90 MP routines, see the IMSL Libraries online PDF file.

The free-form Fortran 95/90 example program below invokes the function AMACH and the subroutine UMACH from the IMSL Libraries. The AMACH function retrieves real machine constants that define the computer's real arithmetic. A value for positive machine infinity is returned (Infinity). The subprogram UMACH retrieves the output unit number.

!  This free-form example demonstrates how to call
!  IMSL routines from Visual Fortran.
!
! The module numerical_libraries includes the Math and
! Stat libraries; these contain the type declarations
! and interface statements for the library routines.

  PROGRAM SHOWIMSL

  USE NUMERICAL_LIBRARIES
  INTEGER NOUT
  REAL RINFP

! The AMACH function and UMACH subroutine are
! declared in the numerical_libraries module

  CALL UMACH(2,NOUT)
  RINFP = AMACH(7)
  WRITE(NOUT,*) 'REAL POSITIVE MACHINE INFINITY = ',RINFP
  END PROGRAM

For information on compiling and linking with the visual development environment, see Building Programs and Libraries.

Note: IMSL routines are in general not multithread safe. In a multithread environment, you should take care that no two IMSL routines are active at the same time. To insure this, use multithread control techniques. For further information, see Creating Multithread Applications.


Library Naming Conventions

The IMSL Numerical Libraries use the following library names:

File Name | Library Description
IMSL | IMSL Static Library, contains FORTRAN 77 and Fortran 90 routines
IMSLS_ERR | IMSL Error Handler Library
IMSLMPISTUB | Stub Library for MPI Routines used in IMSL

The IMSL Numerical Libraries are for applications in general applied mathematics and for analyzing and presenting statistical data in scientific and business applications.

For command-line window development, executing the DFVARS.BAT file (see Using the Compiler and Linker from the Command Line) sets environment variables required by Visual Fortran.

For more information on the IMSL libraries, see:

  • The IMSL readme file provided in the Visual Fortran program folder.
  • The IMSL online documentation PDF files provided in the Compaq Visual Fortran program folder for the IMSL Routines Reference.
  • Product information about IMSL at the following Internet URL:
    http://www.vni.com


Using IMSL Libraries in a Mixed-Language Environment

This section explains how to use the IMSL Libraries in a mixed-language development environment with Visual Fortran and Microsoft Visual C++.

Messages that IMSL routines write to standard output or to error output in a mixed-language application or an application for Windows can be awkward if they are written to the screen. You can avoid this by calling UMACH from a Fortran routine to remap the output and error units to a file instead of to the screen. For example, the following free-form program writes the standard output from VHSTP to the file STD.TXT, and the error message from AMACH to the file ERR.TXT:

  PROGRAM fileout
!       This program demonstrates how to use the UMACH routine to
!       redirect the standard output and error output from IMSL
!       routines to files instead of to the screen. The routines
!       AMACH and UMACH are declared in the numerical_libraries module
!
   USE numerical_libraries
   INTEGER STDU, ERRU
   REAL x, frq(10)/3.0,1.0,4.0,1.0,5.0,9.0,2.0,6.0,5.0,3.0/
!
!       Redirect IMSL standard output to STD.TXT at unit 8
!
   CALL umach(-2, STDU)
   OPEN (unit=STDU, file='std.txt')
   CALL vhstp(10,frq,1,'Histogram Plot')
   CLOSE(8)
!
!       Redirect IMSL error output to ERR.TXT at unit 9
!
   CALL umach(-3, ERRU)
   OPEN (unit=ERRU, file='err.txt')
   x = amach(0)   ! Illegal parameter error
   CLOSE(9)
   END

The standard output from IMSL routine VHSTP written to STD.TXT is:

1
           Histogram Plot
 Frequency-------------------------
    9  *            I           *
    8  *            I           *
    7  *            I           *
    6  *            I   I       *
    5  *          I I   I I     *
    4  *      I   I I   I I     *
    3  *  I   I   I I   I I I   *
    2  *  I   I   I I I I I I   *
    1  *  I I I I I I I I I I   *
 ----------------------------------
 Class            5        10

The error output from IMSL routine AMACH written to ERR.TXT is:

 *** TERMINAL ERROR 5 from AMACH. The argument must be between 1 and 8
 ***          inclusive. N = 0

Consider the following simple Fortran example that uses the IMSL library:

  USE numerical_libraries
  real rinfp
  rinfp = AMACH(7)
  write(*,*) 'Real positive machine infinity = ',rinfp
  end

The output is:

 Real positive machine infinity = Infinity

The corresponding C example is:

 /* FILE CSAMP0.C */
 #include <stdio.h>
 #include <stdlib.h>

 extern float _stdcall AMACH(long *);

 main()
 {
    long n;
    float rinfp;

    n = 7;
    rinfp = AMACH(&n);
    printf("Real positive machine infinity = %16E\n", rinfp);

    fflush(stdout);
    _exit(0);
 }

This C language example demonstrates the use of:

  • The _stdcall modifier in the function prototype needed when calling the IMSL libraries.
  • The & address operator passes the address of the variable to the subprogram (IMSL libraries expect arguments passed by reference).

The C example can be compiled by the cl command to create an object file that can be linked using the DF command.

For more information on mixed-language programming, see Programming with Mixed Languages.


Using the Compaq Extended Math Library (CXML)

The Compaq Extended Math Library (CXML, formerly DXML) provides a comprehensive set of mathematical library routines intended to be called from Fortran. CXML contains a set of over 1500 high-performance mathematical subprograms designed for use in many different types of scientific and engineering applications.

CXML subprograms are easily accessible from the Microsoft visual development environment or the command line interface. They are installed with Visual Fortran, using the "Custom" installation option, as described in "Using Setup to Install Visual Fortran and Related Software" in Compaq Visual Fortran Installing and Getting Started.

When you install CXML, you should also install the CXML online documentation, which enables you to quickly find details on the purpose and use of any library routine. You should also view the CXML readme file provided in the Compaq Visual Fortran program folder.

You can access CXML topics in the Compaq Extended Math Library Reference Guide (PDF version) through Adobe Acrobat. Click on any of the topics to see a submenu of items grouped by subject. For example, to view a description of each routine:

  1. Click the topic "CXML Subprogram Reference"
  2. Click a category name
  3. Click a routine name

Further information about CXML is provided in the following sections:

  • CXML Routine Groups
  • Using CXML from Visual Fortran


CXML Routine Groups

CXML covers the areas of Basic Linear Algebra (BLAS), Linear Algebra Routines (LAPACK), sparse linear system solvers, sorting routines, random number generation, and signal processing functions:

Name | Description
Basic Linear Algebra | The Basic Linear Algebra Subprograms (BLAS) library includes the industry-standard Basic Linear Algebra Subprograms for Level 1 (vector-vector, BLAS1), Level 2 (matrix-vector, BLAS2), and Level 3 (matrix-matrix, BLAS3). Also included are subprograms for BLAS Level 1 Extensions, and Sparse BLAS Level 1.
Signal Processing | The Signal Processing library provides a basic set of signal processing functions. Included are one-, two-, and three-dimensional Fast Fourier Transforms (FFT), group FFTs, Cosine/Sine Transforms (FCT/FST), Convolution, Correlation, and Digital Filters.
Sparse Linear System | The Sparse Linear System library provides both direct and iterative sparse linear system solvers. The direct solver package supports both symmetric and nonsymmetric sparse matrices. The iterative solver package contains a basic set of storage schemes, preconditioners, and iterative solvers.
LAPACK | LAPACK is an industry-standard subprogram package offering an extensive set of linear system and eigenproblem solvers. LAPACK uses blocked algorithms that are better suited to most modern architectures, particularly ones with memory hierarchies.
Utility subprograms | Utility subprograms include random number generation, vector math functions, and sorting subprograms.

Where appropriate, each subprogram has a version to support each combination of real or complex and single or double precision arithmetic.

For command-line window development, executing the DFVARS.BAT file (see Using the Compiler and Linker from the Command Line) sets Visual Fortran environment variables as well as CXML environment variables (see Environment Variables Used with the DF Command). If you have problems during linking related to CXML routines, please see the online release notes.

For information on compiling and linking with the visual development environment, see Building Programs and Libraries.

For more information on CXML, refer to:

  • Using CXML from Visual Fortran.
  • The CXML readme file provided in the Compaq Visual Fortran program folder.
  • The CXML Reference Guide, available in PDF format.
  • The CXML Samples, installed in ...\Df98\CXML\Samples.
  • The Compaq Visual Fortran Installing and Getting Started guide.


Using CXML from Visual Fortran

To use CXML, you need to make the CXML routines and their interfaces available to your program. When calling CXML library routines from a Fortran 95/90 program, you include the file CXML_INCLUDE.F90 as the first statement (after the statement that introduces the program unit). Use the following INCLUDE statement:

  INCLUDE 'CXML_INCLUDE.F90'

An example of the INCLUDE statement appears in the following example program.

CXML Program Example

The free-form Fortran example program below invokes the function SAXPY from the BLAS portion of the CXML Libraries. The SAXPY function computes a*x+y.

 PROGRAM example
  !
  ! This free-form example demonstrates how to call
  ! CXML routines from Visual Fortran.
  !
  ! The include file CXML_INCLUDE.F90 contains interface statements for
  ! the CXML library routines and causes the linker to search the CXML
  ! library.  It must be the first statement following the statement
  ! that introduces the program unit.
  !
   INCLUDE 'CXML_INCLUDE.F90'
   REAL(KIND=4) :: a(10)
   REAL(KIND=4) :: b(10)
   REAL(KIND=4) :: alpha
   INTEGER(KIND=4) :: n
   INTEGER(KIND=4) :: incx
   INTEGER(KIND=4) :: incy
   n = 5 ; incx = 1 ; incy = 1 ; alpha = 3.0
   DO i = 1,n
      a(i) = FLOAT(i)
      b(i) = FLOAT(2*i)
   ENDDO
   PRINT 98, (a(i),i=1,n)
   PRINT 98, (b(i),i=1,n)
98 FORMAT(' Input = ',10F7.3)
   CALL saxpy( n, alpha, a, incx, b, incy )
   PRINT 99, (b(i),I=1,n)
99  FORMAT(/,' Result = ',10F7.3)
   STOP
 END PROGRAM example


Compatibility Information

Visual Fortran uses the same Compaq Fortran compiler available on Tru64 UNIX (formerly DIGITAL UNIX) Alpha, Linux Alpha, and OpenVMS Alpha systems. Compaq Visual Fortran supports extensions to the ISO and ANSI standards, including a number of extensions defined by:

  • Compaq Fortran for the various Compaq Fortran Alpha platforms
  • Microsoft Fortran PowerStation 4.0

Many language extensions associated with Microsoft Fortran PowerStation Version 4 have been added to Visual Fortran; most of these extensions have been added to different releases of Compaq Fortran on Alpha platforms.

The following sections describe Visual Fortran compatibility information:

  • Compatibility with Compaq Fortran on Other Platforms
  • Compatibility with Microsoft Fortran PowerStation


Compatibility with Compaq Fortran on Other Platforms

Compaq Visual Fortran supports extensions to the Fortran 95 and 90 ISO and ANSI standards, including a number of extensions defined by:

  • Compaq Fortran (formerly Digital Fortran)

    Compaq Fortran (including Compaq Visual Fortran) provides many of the language extensions provided by Compaq Fortran 77 for OpenVMS VAX Systems (formerly DEC Fortran 77 and VAX FORTRAN).

  • Microsoft Fortran PowerStation 4.0

    For information about Microsoft Fortran PowerStation 4.0, see Compatibility with Microsoft Fortran PowerStation.

This section discusses the following topics:

  • Summary of Language Compatibility
  • Common Language Extensions
  • Major Changes from the FORTRAN 77 to Fortran 95 Standards
  • Platform Porting Notes

Summary of Language Compatibility

Compaq Visual Fortran (CVF) uses the same robust, highly efficient Fortran 95/90 compiler used by Compaq Fortran for the following Alpha operating systems:

  • Compaq Tru64 UNIX Alpha systems
  • Linux Alpha systems
  • Compaq OpenVMS Alpha systems

The following table summarizes the compatibility of Compaq Visual Fortran with Compaq Fortran for Alpha systems and Compaq Fortran 77 (CF77) for OpenVMS VAX systems:

Summary of Language Compatibility

 | Compaq Fortran (CF) OS/Architecture Platform
Language Feature | CVF Windows | CF UNIX Alpha | CF Linux Alpha | CF OpenVMS Alpha | CF77 OpenVMS VAX
Linking against static and shared libraries | X | X | X | X | X
Create code for shared libraries | X | X | X | X | X
Recursive code support | X | X | X | X | X
AUTOMATIC and STATIC statements | X | X | X | X | X
STRUCTURE and RECORD declarations | X | X | X | X | X
INTEGER*1, *2, *4 | X | X | X | X | X
LOGICAL*1, *2, *4 | X | X | X | X | X
INTEGER*8 and LOGICAL*8 | X | X | X | X |
REAL*4, *8 | X | X | X | X | X
REAL*161 |  | X | X | X | X
COMPLEX*8, *16 | X | X | X | X | X
COMPLEX*322 |  | X | X | X |
POINTER (CRAY-style) | X | X | X | X | X
INCLUDE statement | X | X | X | X | X
IMPLICIT NONE statement | X | X | X | X | X
Data initialization in type declarations | X | X | X | X | X
Automatic arrays | X | X | X | X |
VOLATILE statements | X | X | X | X | X
NAMELIST-directed I/O | X | X | X | X | X
31-character names including $ and _ | X | X | X | X | X
Source listing with machine code | X | X | X | X | X
Debug statements in source | X | X | X | X | X
Bit constants to initialize data and use in arithmetic | X | X | X | X | X
DO WHILE and END DO statements | X | X | X | X | X
Built-in functions %LOC, %REF, %VAL | X | X | X | X | X
SELECT CASE construct | X | X | X | X |
EXIT and CYCLE statements | X | X | X | X |
Variable FORMAT expressions (VFEs) | X | X | X | X | X
! marks end-of-line comment | X | X | X | X | X
Optional run-time bounds checking for arrays and substrings | X | X | X | X | X
Binary (unformatted) I/O in IEEE big endian, IEEE little endian, VAX, IBM, and CRAY floating-point formats | X | X | X | X | X
Fortran 95/90 standards checking | X | X | X | X |
FORTRAN-77 standards checking |  |  |  |  | X
IEEE exception handling | X | X | X | X |
VAX floating data type in memory |  |  |  | X | X
IEEE floating data type in memory | X | X | X | X |
CDD/Repository DICTIONARY support |  |  |  |  | X
KEYED access and INDEXED files |  |  |  | X | X
Parallel decomposition | 4 | X3,4 |  | 4 | X
OpenMP parallel directives |  | X |  |  |
Conditional compilation using IF...DEF constructs | X | X | X | X |
Vector code support |  |  |  |  | X
Direct inlining of Basic Linear Algebra Subroutines (BLAS) | 5 | 5 | 5 | 5 | X
DATE_AND_TIME returns 4-digit year | X | X | X | X | X
FORALL statement and construct | X | X | X | X |
Automatic deallocation of ALLOCATABLE arrays | X | X | X | X |
Dim argument to MAXLOC and MINLOC | X | X | X | X |
PURE user-defined subprograms | X | X | X | X |
ELEMENTAL user-defined subprograms | X | X | X | X |
Pointer initialization (initial value) | X | X | X | X |
The NULL intrinsic to nullify a pointer | X | X | X | X |
Derived-type structure initialization | X | X | X | X |
CPU_TIME intrinsic subroutine | X | X | X | X |
Kind argument to CEILING and FLOOR intrinsics | X | X | X | X |
Nested WHERE constructs, masked ELSEWHERE statement, and named WHERE constructs | X | X | X | X |
Comments allowed in namelist input | X | X | X | X |
Generic identifier in END INTERFACE statements | X | X | X | X |
Minimal FORMAT edit descriptor field width | X | X | X | X |
Detection of Obsolescent and/or Deleted features6 | X | X | X | X |

Footnotes to preceding table:

1 | For REAL*16 data, OpenVMS VAX systems use H_float format, and Alpha systems use IEEE style X_float format.
2 | For COMPLEX*32 data, Alpha systems use IEEE style X_float format for both REAL*16 parts.
3 | For parallel processing with Compaq Fortran for Compaq Tru64 UNIX Systems, you can use the OpenMP or Compaq Fortran directives on shared memory multiprocessor systems or MPI software for using High Performance Fortran (HPF) constructs across multiple systems.
4 | For parallel processing, you can use the optional KAP performance preprocessor for a shared memory multiprocessor system.
5 | BLAS and other routines are available with the Compaq Extended Mathematical Library (CXML) software provided with Compaq Visual Fortran and Compaq Fortran for Alpha systems (for download information, see http://www.compaq.com/math).
6 | Compaq Fortran flags these deleted and obsolescent features, but fully supports them.

Common Language Extensions

To simplify porting applications between Compaq Fortran 77 Alpha systems and Compaq Fortran (including Compaq Visual Fortran), Compaq Visual Fortran supports the following Compaq Fortran 77 extensions that are not part of the Fortran 95/90 standards:

  • Record structures (STRUCTURE and RECORD statements)
  • I/O statements, including PRINT, ACCEPT, TYPE, DELETE, and UNLOCK
  • I/O statement specifiers, such as the INQUIRE statement specifiers CARRIAGECONTROL, CONVERT, ORGANIZATION, and RECORDTYPE
  • Multiple INTEGER and REAL kinds
  • Size specifiers for data declaration statements, such as INTEGER*4, in addition to the KIND type parameter
  • IEEE floating-point data types in memory
  • The POINTER statement and its associated data type (integer pointers or CRAY pointers).
  • The typeless PARAMETER statement
  • The VOLATILE statement
  • The AUTOMATIC and STATIC statements
  • Built-in functions used in argument lists, such as %REF, %VAL, and %LOC
  • Hollerith constants
  • Variable-format expressions (VFEs)
  • Certain intrinsic functions
  • The tab source form (a variation of fixed-source form)
  • I/O formatting descriptors
  • USEROPEN routines for user-defined open routines
  • Additional language features, including the DEFINE FILE, ENCODE, DECODE, and VIRTUAL statements

In addition to language extensions, Compaq Visual Fortran also supports the following Compaq Fortran 77 features:

  • Compaq Fortran 77 compilation control statements and directives, including:
    • INCLUDE statement forms using /LIST and /NOLIST (requires compiling with the /vms compiler option )
    • OPTIONS statement to override or set compiler command-line options
    • General cDEC$ directives, including:
      • cDEC$ ALIAS
      • cDEC$ IDENT
      • cDEC$ OPTIONS
      • cDEC$ PSECT
      • cDEC$ TITLE
      • cDEC$ SUBTITLE
  • foriosdef.for symbolic parameter definitions for use with run-time (IOSTAT) error handling.

Compaq Visual Fortran includes the following features and enhancements also found on other Compaq Fortran platforms:

  • Support for linking against static libraries
  • Support for linking against dynamically linked libraries (DLL)
  • Support for creating code to be put into a dynamically linked library (DLL)
  • Support for stack-based storage
  • Support for dynamic memory allocation
  • Support for reading and writing binary data files in nonnative formats, including IEEE (little-endian and big-endian), VAX, IBM System\360, and CRAY integer and floating point formats
  • User control over IEEE floating point exception handling, reporting, and resulting values
  • Control for memory boundary alignment of items in COMMON and fields in structures and warnings for misaligned data
  • Directives to control listing page titles and subtitles, object file identification field, COMMON and record field alignment, and some attributes of COMMON blocks
  • Ability to CALL an external function subprogram
  • 7200 character statement length
  • Free form unlimited line length
  • Composite data declarations using STRUCTURE, END STRUCTURE, and RECORD statements, and access to record components through field references
  • Explicit specification of storage allocation units for data types such as:
    • INTEGER*4
    • LOGICAL*4
    • REAL*4
    • REAL*8
    • COMPLEX*8
  • Support for 64-bit signed integers using INTEGER*8 and LOGICAL*8
  • Support for 128-bit floating-point data using REAL*16 and COMPLEX*32 (on Alpha platforms only)
  • A set of data types:
    • BYTE
    • LOGICAL*1, LOGICAL*2, LOGICAL*4, LOGICAL*8
    • INTEGER*1, INTEGER*2, INTEGER*4, INTEGER*8
    • REAL*4, REAL*8
    • COMPLEX*8, COMPLEX*16, DOUBLE COMPLEX
  • Compaq Fortran POINTER statement (CRAY style)
  • Data statement style initialization in type declaration statements
  • AUTOMATIC and STATIC statements
  • Bit constants to initialize LOGICAL, REAL, and INTEGER values and participate in arithmetic and logical expressions
  • Built-in functions %LOC, %REF, and %VAL
  • VOLATILE statement
  • Bit manipulation functions
  • Binary, hexadecimal, and octal constants and Z and O format edit descriptors applicable to all data types
  • I/O unit numbers that can be any nonnegative INTEGER*4 value
  • Variable amounts of data can be read from and written to "STREAM" files, which contain no record delimiters
  • ENCODE and DECODE statements
  • ACCEPT, TYPE, and REWRITE input/output statements
  • DEFINE FILE, UNLOCK, and DELETE statements
  • USEROPEN subroutine invocation at file OPEN
  • Support for reading nondelimited character strings as input for character NAMELIST items
  • Debug statements in source
  • Generation of a source listing file with optional machine code representation of the executable source
  • Variable format expressions in a FORMAT statement
  • Optional run-time bounds checking of array subscripts and character substrings
  • 31-character identifiers that can include dollar sign ($) and underscore (_)
  • Support for the supercomputer intrinsics POPCNT, POPPAR, LEADZ, and TRAILZ
  • Language elements that support the various extended range and extended precision floating point architectural features:
    • 32-bit IEEE S_floating data type, with an 8-bit exponent and 24-bit mantissa and a precision of typically 7 decimal digits
    • 64-bit IEEE T_floating data type, with an 11-bit exponent and 53-bit mantissa and a precision of typically 15 decimal digits
  • Command line control for:
    • The size of default INTEGER, REAL, and DOUBLE PRECISION data items
    • The levels and types of optimization to be applied to the program
    • The directories to search for INCLUDE and module files
    • Inclusion or suppression of various compile-time warnings
    • Inclusion or suppression of run-time checking for various I/O and computational errors
    • Control over whether compilation terminates after a specific number of errors has been found
    • Choosing whether executing code will be thread-reentrant
    • Internal procedures can be passed as actual arguments to procedures
  • Kind types for all of the hardware-supported data types:
    • For 1-, 2-, 4-, and 8-byte LOGICAL data: LOGICAL (KIND=1), LOGICAL (KIND=2), LOGICAL (KIND=4), LOGICAL (KIND=8)
    • For 1-, 2-, 4-, and 8-byte INTEGER data: INTEGER (KIND=1), INTEGER (KIND=2), INTEGER (KIND=4), INTEGER (KIND=8)
    • For 4- and 8-byte REAL data: REAL (KIND=4), REAL (KIND=8)
    • For single precision and double precision COMPLEX data: COMPLEX (KIND=4), COMPLEX (KIND=8)

Major Changes to the Fortran Language Standards

Major additions and improvements to the FORTRAN 77 standard introduced by the Fortran 90 standard include:

  • Array operations and features
  • Modules
  • Free-form source
  • Improved facilities for numeric computation
  • Parameterized intrinsic data types
  • User-defined (derived) data types and operators
  • Generic user-defined procedures
  • Interface blocks
  • Pointers (Fortran 90 pointers)
  • The concept of language evolution
  • Additional features for source text
  • Optional procedure arguments
  • Additional input/output features
  • Additional control constructs
  • Additional intrinsic procedures
  • Additional specification statements
  • Additional way to specify attributes
  • Scope and Association

In addition, the Fortran 90 standard includes the following industry-accepted extensions to the FORTRAN 77 standard:

  • Support for recursive subprograms
  • IMPLICIT NONE statements
  • INCLUDE statement
  • NAMELIST-directed I/O
  • DO WHILE and ENDDO statements
  • Use of exclamation point (!) for end of line comments
  • Support for automatic arrays
  • Support for the following SELECT CASE – CASE – CASE DEFAULT – END SELECT statements
  • Support for the EXIT and CYCLE statements and for construct names on DO – END DO statements

Major changes and improvements to the Fortran 90 standard introduced by the Fortran 95 standard include:

  • The FORALL statement and construct
  • PURE user-defined procedures
  • ELEMENTAL user-defined procedures
  • CPU_TIME intrinsic subroutine
  • NULL intrinsic function
  • Derived-type structure default initialization
  • Pointer initialization
  • Automatic deallocation of allocatable arrays
  • Enhanced intrinsic functions, including CEILING, FLOOR, MAXLOC, MINLOC, and SIGN
  • Printing of -0.0
  • Enhanced WHERE construct
  • Generic identifier allowed in END INTERFACE statement
  • Minimum-length formats
  • Comments allowed in namelist input

For more information:

  • See Fortran 95 Features
  • See Fortran 90 Features

Platform Porting Notes

When porting code between platforms, be aware that:

  • The use of the /stand option during compilation can help identify source code that uses language extensions during compilation. On U*X Alpha systems, specify the -std option. On OpenVMS systems, specify the /STANDARD qualifier. The online Visual Fortran Language Reference and the printed Compaq Fortran Language Reference Manual identify language extensions with a green-blue color.
  • The use of certain platform-specific procedures (such as library routines) provided by the operating system need to be located and likely changed. Whenever possible, use Fortran standard language calls (such as to intrinsic procedures) instead of platform-specific routines. For example, if you attempt to link source files and the linker returns unresolved references/symbols, be aware that the routine names may be platform-specific:
    • When porting code from a U*X system, identify code that uses system calls (section 2 in reference pages) and certain other library routines not found on Windows systems. Visual Fortran provides the portability library that includes many U*X Fortran library routines (section 3f in reference pages) found on U*X systems. The Compaq Extended Math Library (CXML) routines supported on Alpha systems are provided with Visual Fortran. For more details about the U*X Alpha programming environment, see the appropriate sections in the Compaq Fortran User Manual for Tru64 UNIX and Linux Systems.
    • When porting an application from an OpenVMS system, identify code that calls system services (SYS$ prefix) or RTL routines (such prefixes as LIB$, CVT$, DTK$, MATH$, OTS$, PPL$, SMG$, and STR$). The Compaq Extended Math Library (CXML) routines supported on Alpha systems are provided with Visual Fortran.

      Character arguments on OpenVMS systems may be passed by character descriptors not found on other platforms.

      For more details about the OpenVMS Alpha programming environment, see the appropriate sections in the Compaq Fortran User Manual for OpenVMS Alpha Systems.

    • When porting an application from Visual Fortran to an Alpha system, non-graphical applications are usually easier to port. The nature of Visual Fortran applications is usually defined by the chosen project type (such as Fortran Console applications). For example, applications that use many platform-specific graphical system calls are usually difficult to port to other platforms.

      Certain platform-specific Fortran routine names either have QQ appended at the end of the name or use the Win32 naming conventions (see Calling Win32 Routines). Certain groups of routines require different USE statements. You can use the HTML Help viewer's index and search facility to locate descriptions of Visual Fortran or Win32 routines.

      The online Visual Fortran Language Reference and the printed Compaq Fortran Language Reference Manual identify language elements that are supported only on certain Compaq Fortran platforms.

    • Certain math library routines provided by Visual Fortran are available on other platforms:
      • The IMSL Math and Statistical routines provided with the Visual Fortran Professional or Enterprise Editions are also available for many other platforms (including Compaq Alpha systems) from Visual Numerics, Inc. (see http://www.vni.com).
      • The Compaq Extended Math Library (CXML) routines provided with all Visual Fortran Editions are also provided with Compaq Fortran on Alpha systems. CXML routines are available separately for Compaq Alpha systems (see http://www.compaq.com/math).

  • Certain application code may make assumptions about the numeric data format stored in memory. Compaq Fortran and Visual Fortran store numeric data in memory in little endian format, while some vendors use big endian formats. Also, certain platforms support different sized intrinsic data types.

  • Certain application code may make assumptions about the size of Compaq Fortran (integer) pointers. For example, on an U*X Alpha system, the size of an address is 64 bits. On Windows ia32 systems, the size of an address is 32 bits. On Windows ia64 systems, the size of an address is 64 bits. Whenever possible, use the standard-conforming Fortran 95/90 pointers instead of Compaq Fortran pointers.

  • Certain platforms use different name decoration conventions, such as appending an extra character to symbol names. Use of the appropriate cDEC$ ATTRIBUTES directives can help overcome this problem (see Adjusting Naming Conventions in Mixed-Language Programming.

  • Porting data files used by an application from one platform to another. Consider using ftp for binary file transfers to preserve file integrity. Visual Fortran provides the capability to convert unformatted data files in various formats, including big endian formats (see Supported Native and Nonnative Numeric Formats). It is also important to select compatible cross-platform record types.

    When porting data files between Windows systems running Compaq Visual Fortran and Alpha systems running Compaq Fortran:

    1. For formatted data files, use the stream_LF record type.
    2. For unformatted files, use the segmented record type. Unformatted files ported from Compaq Fortran OpenVMS systems may use a non-IEEE floating-point format. For example, Compaq Fortran for OpenVMS Alpha systems allows the user to specify either IEEE and or VAX formats during compilation (see Supported Native and Nonnative Numeric Formats).

    One suggested way to port an unformatted file from an OpenVMS system follows:

    1. From the OpenVMS system type the following DCL command for the file (file.dat):
       $ SET FILE /ATTR=(RFM=FIX,LRL=512) file.dat
      For information on porting unformatted data files, see the Compaq Fortran Knowledge Base at http://www.compaq.com/fortran/kb. Examples of record type conversion programs are available at http://www.compaq.com/fortran/examples.
    2. Copy the file to your Windows system as a binary (image) copy (perhaps using ftp).
    3. Modify the source code to OPEN the file with RECORDTYPE='SEGMEMTED'.
    4. If the file uses a VAX floating-point format, specify the appropriate VAX format by using one of the methods described in Converting Unformatted Numeric Data.

  • Be aware that Fortran-only programs are usually easier to port than mixed-language programs.

For more information:

  • See the Compatibility appendix and other sections of the appropriate Compaq Fortran for Alpha systems user manual (Compaq Fortran User Manual for Tru64 UNIX and Linux Systems or the Compaq Fortran User Manual for OpenVMS Alpha Systems).


Compatibility with Microsoft Fortran PowerStation

Visual Fortran recognizes the FL32 command and many of the command-line options provided by the Microsoft Fortran PowerStation Version 4 compiler. For more information on command-line compatibility, see Microsoft Fortran PowerStation Command-Line Compatibility.

Visual Fortran supports many of the language extensions to the Fortran 90 Standard supported by Microsoft Fortran PowerStation Version 4. Certain extensions may require the /fpscomp compiler option (also see Categories of Compiler Options). These extensions to the Fortran 90 Standard (and Fortran 95 Standard) include the following:

  • .f, .for, .f90 source file types
  • # Constants – constants using other than base 10
  • C strings – NULL terminated strings
  • MBCS characters in comments
  • MBCS characters in string literals
  • Conditional compilation and metacommand (directive) expressions ($DEFINE, $UNDEFINE, $IF, $ELSEIF, $ELSE, $ENDIF)
  • !MS$ directive form (see Compiler Directives: table)
  • $FREEFORM, $NOFREEFORM, $FIXEDFORM – source file format
  • $OBJCOMMENT – place library-search record in object file
  • $INTEGER, $REAL – selects size
  • $FIXEDFORMLINESIZE – line length for fixed-form source
  • $STRICT, $NOSTRICT – F90 conformance
  • $ATTRIBUTES, identifier attributes (C, STDCALL, REFERENCE, VALUE, DLLIMPORT, DLLEXPORT, EXTERN, ALIAS, VARYING)
  • $PACK – structure packing
  • Kind numbers match bytes – kind parameters
  • AUTOMATIC attribute – automatic storage class
  • Integer Pointers (Cray pointers)
  • VAX Structures equivalent to Fortran 90 sequence derived types
  • Mixing logicals and numerics – logicals used with arithmetic operators and variables
  • Argument matching for procedure calls
  • Mixing integer kinds to intrinsics
  • Byte data type equivalent to INTEGER*1
  • $ATTRIBUTES [ ] Form
  • $ATTRIBUTES ALIAS – external name for a subprogram
  • $ATTRIBUTES C, STDCALL – calling and naming conventions
  • $ATTRIBUTES VALUE, REFERENCE – argument passing calling conventions
  • $ATTRIBUTES DLLIMPORT, DLLEXPORT – import from/export to DLL
  • Character and non-character equivalence
  • Double complex data type
  • .XOR. – exclusive disjunction
  • Integer arguments in logical expressions
  • OPEN statement specifier options:
    • BLOCKSIZE= internal buffer size used in I/O
    • CARRIAGECONTROL= controls the output of formatted files
    • MODE= controls access to files on networked systems
    • TITLE= affects and IOFOCUS= controls QuickWin child windows
    • SHARE= controls simultaneous access to files on networked systems
  • Default carriage control
  • Implicit open – prompt user for filenames
  • Special device names for FILE in OPEN statements
  • FORM=BINARY in INQUIRE/OPEN statements
  • Unformatted sequential file form
  • Q edit descriptor – number of characters remaining in the input record
  • \ descriptor– prevents writing an end-of-record mark
  • $ edit descriptor – suppresses the carriage return at the end of a record
  • X edit descriptor default – 1
  • Ew.dDe and Gw.dDe edit descriptors – similar to Ew.dEe and Gw.dEe
  • Variable Format Expressions (VFEs) – integer expression in FORMAT statement
  • Expanded missing ,'s in FORMAT statements – optional commas
  • Expanded namelist start/end sequences
  • All path names, including driver, compiler, and INCLUDE statements are MBCS enabled [not on Windows 95]
  • UNC pathnames
  • Long filenames
  • 7200 character statement length
  • Free form infinite line length
  • $DECLARE and $NODECLARE like IMPLICIT NONE
  • Logical truth: 0 = false, non-zero = true
  • $ATTRIBUTES EXTERN – variable allocated in another source file
  • $ATTRIBUTES VARYING – variable number of arguments
  • Alternate PARAMETER syntax – no parenthesis
  • $ in identifiers
  • INTERFACE TO – subroutine/function prototype, however global scoping is not supported
  • Argument passing modifiers – %VAL, %REF
  • Argument passing modifiers – %DESCR (treated as %REF)
  • CRAY pointer support for procedure names (for COM/OLE support)
  • $ATTRIBUTES ALLOCATABLE – allocatable array
  • Mixing subroutines/functions in generic interfaces
  • $MESSAGE – output message during compilation
  • Listing directives – $TITLE, $SUBTITLE
  • STATIC attribute – static storage class
  • EOF checks for end of file
  • LOC equivalent to %LOC
  • HFIXconverts to short integer
  • INT1 converts to one byte integer by truncating
  • INT2 converts to two byte integer by truncating
  • INT4 converts to four byte integer by truncating
  • JFIX same as INT4
  • MALLOC allocates a memory block of the specified number of bytes and returns an integer pointer to the block
  • FREE frees the memory block specified by the integer pointer
  • COTAN returns cotangent
  • DCOTAN returns double precision cotangent
  • IMAG returns the imaginary part of complex number
  • IBCHNG reverses value of bit
  • ISHA shifts arithmetically left or right
  • ISHC performs a circular shift
  • ISHL shifts logically left or right

The following known source incompatibilities exist between Microsoft Fortran PowerStation Version 4 and Visual Fortran:

  • DATA statement style initialization in attribute style declaration (not supported)
  • Debug lines (other than D) (not supported)
  • $OPTIMIZE – change optimization options (not supported)
  • Listing directives – $PAGE, $PAGESIZE, $LINESIZE, $[NO]LIST, $INCLUDE (not supported)
  • $DEBUG, $NODEBUG – additional run-time checking (not supported)
  • $LINE = C's #line (not supported)
  • Internal files can be any type (not supported)
  • Negative I/O unit numbers (not supported)
  • Interface blocks using INTERFACE [TO] at the beginning of a source file to provide global scoping for subsequent program units (not supported)
    Visual Fortran uses standard Fortran 90 semantic rules about interface block placement and use.
  • Tab continuation lines that start with characters other than digits 1 through 9 (not supported)


Using Visual Fortran Tools

This section summarizes the available Visual Fortran tools and describes how to use tools from the Console command line:

  • Overview of Visual Fortran Tools
  • Using Tools From the Command Line
  • Setting Up the Command Console
  • Fortran Compiler and Linker
  • MS-DOS Editor
  • Building Projects with NMAKE
  • Resource Compiler Options
  • Managing Libraries with LIB
  • Editing Files with EDITBIN
  • Examining Files with DUMPBIN
  • Editing Format Descriptors with the Format Editor
  • Profiling Code from the Command Line
  • Fortran Tools: FSPLIT and FPR


Overview of Visual Fortran Tools

The following tools are available in Visual Fortran:

Tool | Description
Integrated Tools in the Visual Development Environment
Editor | Provides general editing functionality. It recognizes Fortran syntax and can be customized. For more information, see "Text Editor" in the Visual C++ User's Guide.
Debugger | Provides general debug functionality. For more information, see Debugging Fortran Programs
Format Editor (FRMTEDIT) | Presents format code with resulting data layout. For more information, see Editing Format Descriptors with the Format Editor.
Module Wizard (MODWIZ) | Simplifies the use of Component Object Model (COM) and Automation (OLE Automation) objects with Fortran. For more information, see Using COM and Automation Objects.
Profiler (PROFILE, PLAITS, and PREP) | Determines unexecuted code or indicates where an application is spending most of its time. For more information, see Profiling Code from the Command Line.
Resource Editors | Develops user-interface components for projects; for example, to build a dialog box. For more information, see Using Dialogs and see "Resource Editors" in the Visual C++ User's Guide.
Source Browser (BSCMAKE) | Creates an information file with details about the symbols in your program. The browse window displays this information and lets you move among instances of the symbols in your source code. For more information, see Source Browser Information for a Configuration.
Additional Tools1
Linker (LINK) | Lets you link object files and libraries, creating 32-bit executable images or DLLs. For more information, see Using the Compiler and Linker from the Command Line and Compiler and Linker Options.
Librarian (LIB) | Lets you manage object libraries, create import libraries to reference exported symbol definitions used when you build Dynamic Link Libraries (DLLs), and extract library members. For more information, see Managing Libraries with LIB.
Microsoft Binary File Dumper (DUMPBIN) | Displays various information from .obj, .exe, and .libs files. For more information, see Examining Files with DUMPBIN.
Microsoft Binary File Editor (EDITBIN) | Lets you modify execution characteristics of a program. For more information, see Editing Files with EDITBIN.
BitViewer (BITVIEW) | Lets you view the binary representation of real numbers in single and double format. For more information, see Viewing Floating-Point Representations with BitViewer.
CVTRES | Lets you convert binary resource files (.res) to linkable object (.obj) files. For more information, see CVTRES below.
DDESpy (DDESPY) | Lets you monitor Dynamic Data Exchange (DDE) activity between processes. For more information, see "Windows Utilities" in the Visual C++ User's Guide.
FPP | Lets you preprocess Fortran files; similar to the C preprocessor (CPP). For more information, see /fpp.
FPR | Lets you transform files formatted according to Fortran's carriage control conventions into files formatted according to line printer conventions. For more information, see Fortran Tools: FSPLIT and FPR.
FSPLIT and FSPLIT90 | Lets you split a multi-routine Fortran file into individual files. FSPLIT works on FORTRAN 77 files, while FSPLIT90 works on Fortran 90 files. For more information, see Fortran Tools: FSPLIT and FPR.
Microsoft Program Maintenance Utility (NMAKE) | Lets you build projects based on commands contained in a description (makefile) file. For more information, see Building Projects with NMAKE.
OLE Object Viewer (OLEVIEW) | Lets you browse, configure, test, and activate any COM class on your system; also called the OLEViewer. For more information, see OLE Object Viewer below.
PView (PVIEW) | Lets you examine and modify processes and threads running on your system. For more information, see "Windows Utilities" in the Visual C++ User's Guide.
Resource Compiler (RC) | Compiles various resources so they can be included in an image. For more information, see Resource Compiler Command Line.
Running Object Table Viewer (IROTVIEW) | Lets you view the contents of the OLE Running Object Table. For more information, see Running Object Table Viewer below.
Spy++ (SPYXX) | Lets you monitor windows messages. For more information, see "Windows Utilities" in the Visual C++ User's Guide.
WinDiff (WINDIFF) | Lets you graphically compare the contents of two files or two directories. For more information, see "Windows Utilities" in the Visual C++ User's Guide.
ZoomIn (ZOOMIN) | Lets you capture and enlarge an area of the Windows desktop. For more information, see "Windows Utilities" in the Visual C++ User's Guide.

1 To access these tools from a command window, the Visual Fortran environment must be initialized, as described in "Using the Command-Line Interface" in Compaq Visual Fortran Installing and Getting Started.

Miscellaneous Tool Information

This section briefly describes tools that are not described in detail elsewhere in the documentation.

CVTRES

Binary resource files (.res) cannot be linked. CVTRES lets you convert a binary resource file into a linkable object file (.obj). For example:

  cvtres /out:test.obj test.res

Running Object Table Viewer (IROTVIEW)

The Running Object Table Viewer lets you view the contents of the OLE Running Object Table (ROT). This table contains information about ActiveX and OLE objects currently existing in memory.

OLE Object Viewer (OLEVIEW)

The OLE/COM Object Viewer (OLEViewer) lets you do the following:

  • Browse, in a structured way, all of the Component Object Model (COM) classes installed on your machine.
  • See the registry entries for each class in an easy-to-read format.
  • Configure any COM class (including JavaTM-based classes) on your system. This includes Distributed COM activation and security settings.
  • Configure system-wide COM settings, including enabling or disabling Distributed COM.
  • Test any COM class by double-clicking its name. The list of interfaces that class supports will be displayed. Double-clicking an interface entry allows you to invoke a viewer that will "exercise" that interface.
  • Activate COM classes locally or remotely. Use this to test Distributed COM setups.
  • View type library contents. Use this to figure out what methods, properties, and events an ActiveX Control supports.
  • Copy a properly formatted OBJECT tag to the clipboard for inserting into an HTML document.

The OLEViewer supports plug-in interface viewers. The code for the interface viewers is included in OLEView (in IVIEWERS.DLL).


Using Tools from the Command Line

Although Visual Fortran comes with an integrated Windows-based development environment called Microsoft visual development environment, you can still use many software tools directly from the command line.

If you prefer to use a text-based environment, you can build your programs or libraries in the console (such as the Fortran Command Prompt in the Compaq Visual Fortran program folder), a command-line operating environment similar to MS-DOS provided by your Windows operating system. However, to get the benefit of components that you cannot use from the command line, you may want to do some of your work from the console, and some of it in the visual development environment.

When you run an application for Windows (such as the Format Statement Editor) from the command line, Windows recognizes that the program does not execute within the command window and acts accordingly.

You can tell Windows to run a program with its own resources by using the START command. For example, to run the Library Manager as a separate task, the command is:

START LIB.EXE

Visual Fortran contains an extensive electronic reference you view with the HTML Help Viewer. This includes the Visual Fortran online documentation and a search engine.

To access HTML Help Viewer books from outside the visual development environment, click on the Online Documentation item in the Visual Fortran program folder. If you want to use Visual Fortran from the command line, you can still use the visual development environment to display HTML Help Viewer, and task switch between it and the console.

The following related sections discuss command-line tools:

  • Setting Up the Command Console
  • Fortran Compiler and Linker
  • MS-DOS Editor
  • Building Projects with NMAKE
  • Resource Compiler Options
  • Managing Libraries with LIB
  • Editing Files with EDITBIN
  • Examining Files with DUMPBIN
  • Editing Format Descriptors with the Format Editor
  • Profiling Code from the Command Line
  • Fortran Tools: FSPLIT and FPR

For a summary of all Visual Fortran tools, see Overview of Visual Fortran Tools.


Setting Up the Command Console

Visual Fortran provides a command window with the appropriate environment variables already set for Visual Fortran program development. To start the Visual Fortran command window:

  1. Click Start
  2. Open the Programs submenu
  3. Open the Compaq Visual Fortran program folder
  4. Click Fortran Command Prompt

The console window provides a similar working environment to that provided by running a version of MS-DOS® instead of the Windows operating system. You can use any command recognized by MS-DOS in the Windows NT 4 or Windows 2000 console, plus some additional commands.

Because the command console runs within the context of Windows, you get the additional benefit that you can easily switch between the command console and other applications for Windows. If you want, you can even have multiple instances of the command console open at once.

When you are finished working in a command console window, use the EXIT command to close the window and end the session.

To start the command console window provided by your operating system, open the Start menu and select MS-DOS Prompt from the Programs submenu.

For more information:

  • Configuring the Command Console Window
  • Setting Search Paths in the Console


Configuring the Command Console Window

When you start a session in the command console, a window containing the command interpreter opens. The resources available, as well as the size and behavior of the window, are initially set by the operating system, but you can change these properties, including:

  • Whether the command console takes over the entire screen or is presented in a window
  • The typeface and type size used to display text in the command console
  • The size of the command console text buffer and the position of the command console window if it is presented in a window
  • The colors used to display text in the command console
  • The size of the command history buffer used to store commands that scroll out of view
  • The amount of each type of memory that is available to programs running in the command console
  • Special configuration files to be run when the console session begins

The controls that you use to make these adjustments depend upon which version of Windows you are using. The operating system provides a way to specify configuration settings for all subsequent sessions with the command console.

On Windows NT 4 and Windows 2000 systems, use the Control Panel.

On Windows 98, Windows Me, and Windows 95 systems, use the Properties dialog box to set all of the initial and operating conditions for the command console. With the command window open, do the following:

  1. Click the right mouse button at the top of the window. A pop-up menu appears.
  2. Click Properties.
  3. From the Properties dialog, set up the console display as you like.


Setting Search Paths in the Console

When the command console session begins, the search paths for libraries, module files, and so forth are those set for your user account on the PC. On Windows 98, Windows Me, and Windows 95 systems, these paths are initially specified in the AUTOEXEC.BAT file that is read when the computer is booted.

By default, Windows NT 4 and Windows 2000 systems use a file called AUTOEXEC.NT to perform initialization of console sessions, but you can specify your own initialization file for the command console with the PIF Editor. (See your operating system manual for more details about the PIF Editor.)

You can use the SET command to change these search paths manually within the console session, but your changes will only be in effect during that session. If you need to specify certain path changes each time you begin a console session, you can put the SET commands into a batch file and run it when you begin a session. The Setup program provides a batch file called DFVARS.BAT for this purpose. You can add your SET commands to this file and run it at the start of each session.

You can run DFVARS.BAT:

  • Each time you begin a session on Windows 98 or Windows 95 systems, by specifying it in the Program tab of the Properties dialog box for the console icon.

  • On Windows NT 4 and Windows 2000 systems, you can specify it as the initialization file with the PIF Editor.

The instructions specify the PATH, INCLUDE, and LIB environment variables. For example, the lines in the batch file that sets the INCLUDE environment variable include:

   set LIB=%DFcdrom%\DF98\LIB;%DFcdrom%\VC98\LIB;%LIB%

The batch file inserts the directories used by Visual Fortran at the beginning of the existing paths. Because these directories appear first, they are searched before any directories in the path lists provided by Windows. This is especially important if the existing path includes directories with files having the same names as those needed by Visual Fortran.

As described in "Using the Command-Line Interface" in Compaq Visual Fortran Installing and Getting Started, the Fortran Command Prompt window sets these variables for you automatically. To activate this command window, select the Fortran Command Prompt icon in the Compaq Visual Fortran program folder.


Fortran Compiler and Linker

The DF (or FL32) command is the driver for running the compiler and linker. You can either compile and link your projects in one step with DF, or compile them with DF and then link them with LINK. You can also use LINK to build libraries of object modules. Each of these commands provides syntax instructions at the command line if you request it with the /? or /help option. For more information about the DF and LINK commands, see:

  • Using the Compiler and Linker from the Command Line
  • Compiler and Linker Options


MS-DOS Editor

You can use the MS-DOS Editor (EDIT.EXE) or any text editor to create your source programs, but you will not be able to perform the specialized functions built into the visual development environment such as multi-file searches, and your source code will not be displayed with syntax coloring.

You invoke the MS-DOS Editor by typing EDIT followed by the name of the file you want to edit. For example:

  EDIT test.f90


Building Projects with NMAKE

Some projects require an extensive set of build instructions to ensure that each component is built with the appropriate options. With the Microsoft visual development environment, you can specify build instructions by source file, and you can have separate sets of instructions for the debug and release builds of a project. In the visual development environment, you select these options in a set of dialog boxes. For information on creating (exporting) a makefile from the visual development environment, see The Project Makefile.

When you build projects from the command line, you can put your build instructions into a special build file, and run the build process with NMAKE, the Microsoft Program Maintenance Utility. Other command-line building methods include using indirect command files (see DF Indirect Command File Use) and .BAT files.

The Microsoft Program Maintenance Utility (NMAKE.EXE) is a 32-bit tool that builds projects based on commands contained in a description file. This section discusses the following:

  • Running NMAKE
  • Contents of a Makefile
  • Description Blocks
  • Commands in a Makefile
  • Inline Files in a Makefile
  • Macros and NMAKE
  • NMAKE Inference Rules
  • Dot Directives
  • Makefile Preprocessing


Running NMAKE

The syntax for NMAKE is:

NMAKE [option...] [macros...] [targets...] [@commandfile...]

NMAKE builds only specified targets or, if none is specified, the first target in the makefile is used. The first makefile target can be a pseudotarget (a label used in place of a filename in a dependency line) that builds other targets. NMAKE uses makefiles specified with the /F option. If /F is not specified, it uses the MAKEFILE file in the current directory. If no makefile is specified, it uses inference rules to build command-line targets.

The commandfile text file contains command-line input. Other input can precede or follow @commandfile. A path is permitted. In commandfile, line breaks are treated as spaces. Enclose macro definitions in quotation marks if they contain spaces.

For more information:

  • On targets, see Description Blocks
  • On macros, see Macros and NMAKE
  • On options, see NMAKE Options


NMAKE Options

NMAKE options are described in the following sections. Options are preceded by either a slash ( / ) or a dash ( - ) and are not case sensitive. Use !CMDSWITCHES (described in Makefile Preprocessing Directives) to change option settings in a makefile or in TOOLS.INI.

This section describes the following topics:

  • NMAKE Option Descriptions
  • TOOLS.INI and NMAKE
  • Exit Codes from NMAKE


NMAKE Option Descriptions

Option | Description
/A | Forces build of all evaluated targets, even if not out-of-date with respect to dependents. Does not force build of unrelated targets.
/B | Forces build even if timestamps are equal. Recommended for very fast systems (resolution of two seconds or less).
/C | Suppresses default output, including nonfatal NMAKE errors or warnings, timestamps, and NMAKE copyright message. Suppresses warnings issued by the /K option.
/D | Displays timestamps of each evaluated target and dependent and a message when a target does not exist. Useful with the /P option for debugging a makefile. Use !CMDSWITCHES (described in Makefile Preprocessing Directives) to set or clear the /D option for part of a makefile.
/E | Causes environment variables to override makefile macro definitions.
/F filename | The option /F filename specifies filename as a makefile. Spaces or tabs can precede filename. Specify the /F option once for each makefile. To supply a makefile from standard input, specify a dash (-) for filename. End keyboard input with either F6 or Ctrl+Z.
/HELP, /? | The option /HELP or /? displays a brief summary of NMAKE command-line syntax.
/I | Ignores exit codes from all commands. To set or clear the /I option for part of a makefile, use !CMDSWITCHES (described in Makefile Preprocessing Directives). To ignore exit codes for part of a makefile, use a dash (-) command modifier or .IGNORE. Overrides the /K option if both are specified.
/K | Continues building unrelated dependencies if a command returns an error; also issues a warning and returns an exit code of 1. By default, NMAKE halts if any command returns a nonzero exit code. Warnings from the /K option are suppressed by the /C option; the /I option overrides the /K option if both are specified.
/N | Displays but does not execute commands; preprocessing commands are executed. Does not display commands in recursive NMAKE calls. Useful for debugging makefiles and checking timestamps. To set or clear the /N option for part of a makefile, use !CMDSWITCHES (described in Makefile Preprocessing Directives).
/NOLOGO | Suppresses the NMAKE copyright message.
/P | Displays information (macro definitions, inference rules, targets, .SUFFIXES list) to standard output, then runs the build. If no makefile or command-line target exists, it displays information only. Use with the /D option to debug a makefile.
/Q | Checks timestamps of targets; does not run the build. Returns a zero exit code if all are up-to-date and a nonzero exit code if any target is not. Preprocessing commands are executed. Useful when running NMAKE from a batch file.
/R | Clears the .SUFFIXES list and ignores inference rules and macros that are defined in the TOOLS.INI file or that are predefined.
/S | Suppresses display of executed commands. To suppress display in part of a makefile, use the @ command modifier or .SILENT. To set or clear the /S option for part of a makefile, use !CMDSWITCHES (described in Makefile Preprocessing Directives).
/T | Updates timestamps of command-line targets (or first makefile target) and executes preprocessing commands but does not run the build.
/X filename | The option /X filename sends NMAKE error output to filename instead of standard error. Spaces or tabs can precede filename. To send error output to standard output, specify a dash (-) for filename. Does not affect output from commands to standard error.
/Y | Disables batch-mode inference rules. When this option is selected, all batch-mode inference rules are treated as regular inference rules.


TOOLS.INI and NMAKE

NMAKE reads TOOLS.INI before it reads makefiles, unless the /R option is used. It looks for TOOLS.INI first in the current directory and then in the directory specified by the INIT environment variable. The section for NMAKE settings in the initialization file begins with [NMAKE] and can contain any makefile information. Specify a comment on a separate line beginning with a semicolon (;) or a number sign (#).


Exit Codes from NMAKE

By default, NMAKE halts if any command returns a nonzero exit code. The /I option causes NMAKE to ignore exit codes. Warnings from the /K option are suppressed by the /C option; the /I option overrides the /K option if both are specified. The following table lists the exit codes.

Code | Meaning
0 | No error (possibly a warning)
1 | Incomplete build (issued only when the /K option is used)
2 Program error, possibly due to one of the following:
  • A syntax error in the makefile
  • An error or exit code from a command
  • An interruption by the user
4 | System error – out of memory
255 | Target is not up-to-date (issued only when the /Q option is used)


Contents of a Makefile

A makefile contains:

  • Description blocks
  • Commands
  • Macros
  • Inference Rules
  • Dot Directives
  • Preprocessing Directives

Other features of a makefile include wildcards, long filenames, comments, and special characters.


Wildcards and NMAKE

NMAKE expands filename wildcards (* and ?) in dependency lines. A wildcard specified in a command is passed to the command; NMAKE does not expand it.


Long Filenames in a Makefile

Enclose long filenames in double quotation marks, as follows:

  all : "VeryLongFileName.exe"


Comments in a Makefile

Precede a comment with a number sign (#). NMAKE ignores text from the number sign to the next newline character. The following are examples of comments:

# Comment on line by itself
OPTIONS = /MAP # Comment on macro definition line

all.exe : one.obj two.obj # Comment on dependency line
    link one.obj two.obj
# Comment in commands block
#   copy *.obj \objects # Command turned into comment
    copy one.exe \release

.obj.exe: # Comment on inference rule line
    link $<

 my.exe : my.obj ; link my.obj # Error: cannot comment this
  # Error: # must be the first character
.obj.exe: ; link $< # Error: cannot comment this

To specify a literal number sign, precede it with a caret (^), as follows:

DEF = ^#define #Macro representing a Fortran compiler directive


Special Characters in a Makefile

To use an NMAKE special character as a literal character, place a caret (^) in front of it. NMAKE ignores carets that precede other characters. The special characters are:

: ; # ( ) $ ^ \ { } ! @ -

A caret within a quoted string is treated as a literal caret character. A caret at the end of a line inserts a literal newline character in a string or macro.

In macros, a backslash followed by a newline character is replaced by a space.

In commands, a percent symbol (%) is a file specifier. To represent a percent symbol (%) literally in a command, specify a double percent sign (%%) in place of a single one. In other situations, NMAKE interprets a single % literally, but it always interprets a double %% as a single %. Therefore, to represent a literal %%, specify either three percent signs, %%%, or four percent signs, %%%%.

To use the dollar sign ($) as a literal character in a command, specify two dollar signs ($$); this method can also be used in other situations where ^$ also works.


Description Blocks

A description block is a dependency line optionally followed by a commands block:

targets... : dependents...
       commands...

A dependency line specifies one or more targets and zero or more dependents. A target must be at the start of the line. Separate targets from dependents by a colon (:); spaces or tabs are allowed. To split the line, use a backslash ( \ ) after a target or dependent. If a target does not exist, has an earlier timestamp than a dependent, or is a pseudotarget, NMAKE executes the commands. If a dependent is a target elsewhere and does not exist or is out-of-date with respect to its own dependents, NMAKE updates the dependent before updating the current dependency.

For more information:

  • Targets
  • Pseudotargets
  • Multiple Targets
  • Cumulative Dependencies
  • Targets in Multiple Description Blocks
  • Dependents


Targets

In a dependency line, specify one or more targets, using any valid filename or pseudotarget. Separate multiple targets with one or more spaces or tabs. Targets are not case sensitive. Paths are permitted with filenames. A target cannot exceed 256 characters. If the target preceding the colon is a single character, use a separating space; otherwise, NMAKE interprets the letter-colon combination as a drive specifier.


Pseudotargets

A pseudotarget is a label used in place of a filename in a dependency line. It is interpreted as a file that does not exist and so is out-of-date. NMAKE assumes a pseudotarget's timestamp is the most recent of all its dependents; if it has no dependents, the current time is assumed. If a pseudotarget is used as a target, its commands are always executed.

A pseudotarget used as a dependent must also appear as a target in another dependency; however, that dependency does not need to have a commands block.

Pseudotarget names follow the filename syntax rules for targets. However, if the name does not have an extension (that is, does not contain a period), it can exceed the 8-character limit for filenames and can be up to 256 characters long.


Multiple Targets

NMAKE evaluates multiple targets in a single dependency as if each were specified in a separate description block as follows:

This... ...is evaluated as this

bounce.exe leap.exe :
jump.obj
   echo Building...

bounce.exe : jump.obj
   echo Building...
leap.exe : jump.obj
   echo Building...


Cumulative Dependencies

Dependencies are cumulative in a description block if a target is repeated as follows:

This... ...is evaluated as this

bounce.exe : jump.obj
bounce.exe : up.obj
   echo Building
bounce.exe...

bounce.exe : jump.obj
up.obj
   echo Building
bounce.exe...

Multiple targets in multiple dependency lines in a single description block are evaluated as if each were specified in a separate description block, but targets that are not in the last dependency line do not use the commands block as follows:

This... ...is evaluated as this

bounce.exe leap.exe :
jump.obj
bounce.exe climb.exe :
up.obj
   echo Building...

bounce.exe : jump.obj
up.obj
   echo Building
bounce.exe...
climb.exe : up.obj
   echo Building
climb.exe...
leap.exe : jump.obj
# invokes an inference rule


Targets in Multiple Description Blocks

To update a target in more than one description block using different commands, specify two consecutive colons (::) between targets and dependents. For example:

target.lib :: one.f90 two.f90 three.f90
    df one.f90 two.f90 three.f90
    lib target one.obj two.obj three.obj
target.lib :: four.c five.c
    df /c four.for five.for
    lib target four.obj five.obj

Dependency Side Effects

If a target is specified with a colon (:) in two dependency lines in different locations, and if commands appear after only one of the lines, NMAKE interprets the dependencies as if adjacent or combined. It does not invoke an inference rule for the dependency that has no commands, but instead assumes that the dependencies belong to one description block and executes the commands specified with the other dependency as follows:

This... ...is evaluated as this

bounce.exe : jump.obj
   echo Building
bounce.exe...
bounce.exe : up.obj

bounce.exe : jump.obj
up.obj
   echo Building
bounce.exe...

This effect does not occur if :: is used as follows:

This... ...is evaluated as this

bounce.exe :: jump.obj
   echo Building
bounce.exe...

bounce.exe :: up.obj

bounce.exe : jump.obj
   echo Building
bounce.exe...

bounce.exe : up.obj
# invokes an inference rule


Dependents

In a dependency line, specify zero or more dependents after the colon (:) or double colon (::) using any valid filename or pseudotarget. Separate multiple dependents with one or more spaces or tabs. Dependents are not case sensitive. Paths are permitted with filenames.

Inferred Dependents

An inferred dependent is derived from an inference rule and is evaluated before explicit dependents. If an inferred dependent is out-of-date with respect to its target, NMAKE invokes the commands block for the dependency. If an inferred dependent does not exist or is out-of-date with respect to its own dependents, NMAKE first updates the inferred dependent. For more information, see NMAKE Inference Rules.

Search Paths for Dependents

Each dependent has an optional search path, specified as follows:

{directory[;directory...]}dependent

NMAKE looks for a dependent first in the current directory, and then in directories in the order specified. A macro can specify part or all of a search path. Enclose directory names in braces ({ }); separate multiple directories with a semicolon (;). No spaces or tabs are allowed.


Commands in a Makefile

A description block or inference rule specifies a block of commands to run if the dependency is out-of-date. NMAKE displays each command before running it, unless the /S option, .SILENT, !CMDSWITCHES, or @ is used. NMAKE looks for a matching inference rule if a description block is not followed by a commands block.

A commands block contains one or more commands, each on its own line. No blank line can appear between the dependency or rule and the commands block. However, a line containing only spaces or tabs can appear; this line is interpreted as a null command and no error occurs. Blank lines are permitted between command lines.

A command line begins with one or more spaces or tabs. A backslash ( \ ) followed by a newline character is interpreted as a space in the command; use a backslash at the end of a line to continue a command onto the next line. NMAKE interprets the backslash literally if any other character, including a space or tab, follows the backslash.

A command preceded by a semicolon (;) can appear on a dependency line or inference rule, whether or not a commands block follows:

  project.obj : project.f90 ; df /c project.f90

For more information:

  • Command Modifiers in NMAKE
  • Filename-Parts Syntax in NMAKE


Command Modifiers in NMAKE

You can specify one or more command modifiers preceding a command, optionally separated by spaces or tabs. As with commands, modifiers must be indented. The following table lists the command modifiers:

Modifier | Action
@command | Prevents display of the command. Display by commands is not suppressed. By default, NMAKE echoes all executed commands. Use the /S option to suppress display for the entire makefile; use .SILENT to suppress display for part of the makefile.
-[number] command | Turns off error checking for command. By default, NMAKE halts when a command returns a nonzero exit code. If -number is used, NMAKE stops if the exit code exceeds number. Spaces or tabs cannot appear between the dash and number; at least one space or tab must appear between number and command. Use the /I option to turn off error checking for the entire makefile; use .IGNORE to turn off error checking for part of the makefile.
!command | Executes command for each dependent file if command uses $** (all dependent files in the dependency) or $? (all dependent files in the dependency with a later timestamp than the target).


Filename-Parts Syntax in NMAKE

Filename-parts syntax in commands represents components of the first dependent filename (which may be an implied dependent). Filename components are the file's drive, path, base name, and extension as specified, not as it exists on disk.

Use %s to represent the complete filename.

Use %|[parts]F to represent parts of the filename, where parts can be zero or more of the following letters, in any order:

Letter | Description
No letter | Complete name (same as %s)
d | Drive
p | Path
f | File base name
e | File extension


Inline Files in a Makefile

An inline file contains text you specify in the makefile. Its name can be used in commands as input (for example, a LINK command file), or it can pass commands to the operating system. The file is created on disk when a command that creates the file is run.

For more information:

  • Specifying an Inline File in Makefiles
  • Creating Inline File Text
  • Reusing Inline Files in Makefiles
  • Multiple Inline Files


Specifying an Inline File in Makefiles

The syntax for specifying an inline file in a command is:

<<[filename]

Specify two angle brackets (<<) in the command where the filename is to appear. The angle brackets cannot be a macro expansion. When the command is run, the angle brackets are replaced by filename, if specified, or by a unique NMAKE-generated name. If specified, filename must follow the angle brackets without a space or tab. A path is permitted. No extension is required or assumed.

If filename is specified, the file is created in the current or specified directory, overwriting any existing file by that name; otherwise, it is created in the TMP directory (or the current directory, if the TMP environment variable is not defined). If a previous filename is reused, NMAKE overwrites the previous file.


Creating Inline File Text in Makefiles

The syntax to create the content of an inline file is:

inlinetext
.
.
.
<<[KEEP | NOKEEP]

Specify inlinetext on the first line after the command. Mark the end with double brackets at the beginning of a separate line. The file contains all inlinetext before the delimiting brackets. The inlinetext can have macro expansions and substitutions, but not directives or makefile comments. Spaces, tabs, and newline characters are treated literally.

Inline files are temporary or permanent. A temporary file exists for the duration of the session and can be reused by other commands. Specify KEEP after the closing angle brackets to retain the file after the NMAKE session; an unnamed file is preserved on disk with the generated filename. Specify NOKEEP or nothing for a temporary file. KEEP and NOKEEP are not case sensitive.


Reusing Inline Files in Makefiles

To reuse an inline file, specify <<filename where the file is defined and first used, then reuse filename without the angle brackets (<<) later in the same or another command. The command to create the inline file must run before all commands that use the file.


Multiple Inline Files

A command can create more than one inline file. The syntax to do this is:

command << <<
inlinetext
<<[KEEP | NOKEEP]
inlinetext
<<[KEEP | NOKEEP]

For each file, specify one or more lines of inline text followed by a closing line containing the delimiter. Begin the second file's text on the line following the delimiting line for the first file.


Macros and NMAKE

Macros replace a particular string in the makefile with another string. Using macros, you can create a makefile that can build different projects, specify options for commands, or set environment variables. You can define your own macros or use NMAKE's predefined macros.

For more information:

  • Defining an NMAKE Macro
  • Special Characters in NMAKE Macros
  • Null and Undefined NMAKE Macros
  • Where to Define Macros
  • Precedence in Macro Definitions
  • Using an NMAKE Macro
  • Macro Substitution
  • Special NMAKE Macros


Defining an NMAKE Macro

Use the following syntax to define a macro:

macroname=string

The macroname is a combination of letters, digits, and underscores ( _ ) up to 1024 characters, and is case sensitive. The macroname can contain an invoked macro. If macroname consists entirely of an invoked macro, the macro being invoked cannot be null or undefined.

The string can be any sequence of zero or more characters. A null string contains zero characters or only spaces or tabs. The string can contain a macro invocation.


Special Characters in NMAKE Macros

A number sign (#) after a definition specifies a comment. To specify a literal number sign in a macro, use a caret (^), as in ^#.

A dollar sign ($) specifies a macro invocation. To specify a literal $, use $$.

To extend a definition to a new line, end the line with a backslash (\). When the macro is invoked, the backslash plus newline character is replaced with a space. To specify a literal backslash at the end of the line, precede it with a caret (^), or follow it with a comment specifier (#).

To specify a literal newline character, end the line with a caret (^), as in:

 CMDS = cls^
 dir


Null and Undefined NMAKE Macros

Both null and undefined macros expand to null strings, but a macro defined as a null string is considered defined in preprocessing expressions. To define a macro as a null string, specify no characters except spaces or tabs after the equal sign (=) in a command line or command file, enclose the null string or definition in double quotation marks (" "). To undefine a macro, use !UNDEF.


Where to Define Macros

You can define macros in a makefile command line, or command file.

In a makefile, each macro definition must appear on a separate line and cannot start with a space or tab. Spaces or tabs around the equal sign (=) are ignored. All string characters are literal, including surrounding quotation marks and embedded spaces.

In a command line or command file, spaces and tabs delimit arguments and cannot surround the equal sign. If string has embedded spaces or tabs, enclose either the string itself or the entire macro in double quotation marks (" ").


Precedence in Macro Definitions

If a macro is multiply defined, NMAKE uses the highest-precedence definition. The following list shows the order of precedence, from highest to lowest:

  1. A macro defined on the command line
  2. A macro defined in a makefile or include file
  3. An inherited environment-variable macro
  4. A predefined macro, such as FOR and RC

Use the /E option to cause macros inherited from environment variables to override makefile macros with the same name. Use !UNDEF to override a command line.


Using an NMAKE Macro

To use a macro, enclose its name in parentheses preceded by a dollar sign ($):

$(macroname)

No spaces are allowed. The parentheses are optional if macroname is a single character. The definition string replaces $(macroname); an undefined macro is replaced by a null string.


Macro Substitution

To substitute text within a macro, use the following syntax:

$(macroname:string1=string2)

When macroname is invoked, each occurrence of string1 in its definition string is replaced by string2. Macro substitution is case sensitive and is literal; string1 and string2 cannot invoke macros. Substitution does not modify the original definition. You can substitute text in any predefined macro except $$@.

No spaces or tabs precede the colon; any after the colon are interpreted as literal. If string2 is null, all occurrences of string1 are deleted from the macro's definition string.


Special NMAKE Macros

NMAKE provides several special macros to represent various filenames and commands. One use for some of these macros is in the predefined inference rules. Like all macros, the macros provided by NMAKE are case sensitive.

This section discusses:

  • Filename Macros
  • Recursion Macros
  • Command Macros and Options Macros
  • Environment-Variable Macros

Filename Macros

Filename macros are predefined as filenames specified in the dependency (not full filename specifications on disk). These macros do not need to be enclosed in parentheses when invoked; specify only a $ as shown.

Macro | Meaning
$@ | Current target's full name (path, base name, extension), as currently specified.
$$@ | Current target's full name (path, base name, extension), as currently specified. Valid only as a dependent in a dependency.
$* | Current target's path and base name minus file extension.
$** | All dependents of the current target.
$? | All dependents with a later timestamp than the current target.
$< | Dependent file with a later timestamp than the current target. Valid only in commands in inference rules.

To specify part of a predefined filename macro, append a macro modifier and enclose the modified macro in parentheses.

Modifier | Resulting Filename Part
D | Drive plus directory
B | Base name
F | Base name plus extension
R | Drive plus directory plus base name

Recursion Macros

Use recursion macros to call NMAKE recursively. Recursive sessions inherit command-line and environment-variable macros. They do not inherit makefile-defined inference rules or .SUFFIXES and .PRECIOUS specifications. To pass macros to a recursive NMAKE session, either set an environment variable with the SET command before the recursive call or define a macro in the command for the recursive call.

Macro | Definition
MAKE | Command used originally to invoke NMAKE.
MAKEDIR | Current directory when NMAKE was invoked.
MAKEFLAGS | Options currently in effect. Use as /$(MAKEFLAGS).

Command Macros, Options Macros

Command macros are predefined for Microsoft products. Options macros represent options to these products and are undefined by default. Both are used in predefined inference rules and can be used in description blocks or user-defined inference rules. Command macros can be redefined to represent part or all of a command line, including options. Options macros generate a null string if left undefined.

Product | Command Macro | Defined as: | Options Macro
Macro Assembler | AS | ml | AFLAGS
Basic Compiler | BC | bc | BFLAGS
C Compiler | CC | cl | CFLAGS
COBOL Compiler | COBOL | cobol | COBFLAGS
C++ Compiler | CPP | cl | CPPFLAGS
C++ Compiler | CXX | cl | CXXFLAGS
Compaq Visual Fortran Compiler | FOR | df | FFLAGS
Pascal Compiler | PASCAL | pl | PFLAGS
Resource Compiler | RC | rc | RFLAGS

Environment-Variable Macros

NMAKE inherits macro definitions for environment variables that exist before the start of the session. If a variable was set in the operating-system environment, it is available as an NMAKE macro. Use the /E option to cause macros inherited from environment variables to override any macros with the same name in the makefile.

Environment-variable macros can be redefined in the session, and this changes the corresponding environment variable. You can also change environment variables with the SET command. Using the SET command to change an environment variable in a session does not change the corresponding macro, however.

For example:

PATH=$(PATH);\nonesuch

all:
    echo %PATH%

In this example, changing PATH changes the corresponding environment variable PATH; it appends \nonesuch to your path.

If an environment variable is defined as a string that would be syntactically incorrect in a makefile, no macro is created and no warning is generated. If a variable's value contains a dollar sign ($), NMAKE interprets it as the beginning of a macro invocation. Using the macro can cause unexpected behavior.


NMAKE Inference Rules

Inference rules supply commands to update targets and to infer dependents for targets. Extensions in an inference rule match a single target and dependent that have the same base name. Inference rules are user-defined or predefined; predefined rules can be redefined.

If an out-of-date dependency has no commands and if .SUFFIXES contains the dependent's extension, NMAKE uses a rule whose extensions match the target and an existing file in the current or specified directory. If more than one rule matches existing files, the .SUFFIXES list determines which to use; list priority descends from left to right.

If a dependent file doesn't exist and is not listed as a target in another description block, an inference rule can create the missing dependent from another file with the same base name. If a description block's target has no dependents or commands, an inference rule can update the target. Inference rules can build a command-line target even if no description block exists. NMAKE may invoke a rule for an inferred dependent even if an explicit dependent is specified.

For more information:

  • Defining an Inference Rule in NMAKE
  • Search Paths in Inference Rules
  • Batch-Mode Rules
  • Predefined Inference Rules
  • Inferred Dependents and Rules
  • Precedence in NMAKE Inference Rules


Defining an Inference Rule in NMAKE

To define an inference rule, use the following syntax:

.fromext.toext :
commands

The fromext represents the extension of a dependent file, and toext represents the extension of a target file. Extensions are not case sensitive. Macros can be invoked to represent fromext and toext; the macros are expanded during preprocessing.

The period (.) preceding fromext must appear at the beginning of the line. The colon (:) is preceded by zero or more spaces or tabs; it can be followed only by spaces or tabs, a semicolon (;) to specify a command, a number sign (#) to specify a comment, or a newline character. No other spaces are allowed. Commands are specified as in description blocks.


Search Paths in Inference Rules

An inference rule that specifies paths has the following syntax:

{frompath}.fromext{topath}.toext:
commands

An inference rule applies to a dependency only if paths specified in the dependency exactly match the inference-rule paths. Specify the dependent's directory in frompath and the target's directory in topath; no spaces are allowed. Specify only one path for each extension. A path on one extension requires a path on the other. To specify the current directory, use either a period (.) or empty braces ( { } ). Macros can represent frompath and topath; they are invoked during preprocessing.


Batch-Mode Rules

Batch-mode inference rules provide only one invocation of the inference rule when N commands go through this inference rule. Without batch-mode inference rules, it would require N commands to be invoked. N is the number of dependents that trigger the inference rule.

Makefiles that contain batch-mode inference rules must use NMAKE version 1.62 or higher. To check the NMAKE version, run the _NMAKE_VER macro available with NMAKE version 1.62 or higher. This macro returns an integer representing the NMAKE version. For example, the macro returns 162 for NMAKE version 1.62.

A batch-mode inference rule has the following syntax:

{frompath}.fromext{topath}.toext::
commands

The only syntactical difference from the standard inference rule is that the batch-mode inference rule is terminated with a double colon (::).

Note: The tool being invoked must be able to handle multiple files. The batch-mode inference rule must use $< as the macro to access dependent files.

The batch-mode inference rules can speed up the build process. It is faster to supply files to the compiler in batch, because the compiler driver is invoked only once.


Predefined Inference Rules

Predefined inference rules use NMAKE-supplied command and option macros:

Rule | Command | Default Action
.asm.exe | $(AS) $(AFLAGS) $*.asm | ml $*.asm
.asm.obj | $(AS) $(AFLAGS) /c $*.asm | ml /c $*.asm
.c.exe | $(CC) $(CFLAGS) $*.c | cl $*.c
.c.obj | $(CC) $(CFLAGS) /c $*.c | cl /c $*.c
.cpp.exe | $(CPP) $(CPPFLAGS) $*.cpp | cl $*.cpp
.cpp.obj | $(CPP) $(CPPFLAGS) /c $*.cpp | cl /c $*.cpp
.cxx.exe | $(CXX) $(CXXFLAGS) $*.cxx | cl $*.cxx
.cxx.obj | $(CXX) $(CXXFLAGS) /c $*.cxx | cl /c $*.cxx
.bas.obj | $(BC) $(BFLAGS) $*.bas; | bc $*.bas;
.cbl.exe | $(COBOL) $(COBFLAGS) $*.cbl, $*.exe; | cobol $*.cbl, $*.exe;
.cbl.obj | $(COBOL) $(COBFLAGS) $*.cbl; | cobol $*.cbl;
.for.exe | $(FOR) $(FFLAGS) $*.for | fl32 $*.for
.f90.exe | $(FOR) $(FFLAGS) $*.f90 | fl32 $*.f90
.f.exe | $(FOR) $(FFLAGS) $*.f | fl32 $*.f
.for.obj | $(FOR) /c $(FFLAGS) $*.for | fl32 $*.for /c
.f90.obj | $(FOR) /c $(FFLAGS) $*.f90 | fl32 $*.f90 /c
.f.obj | $(FOR) /c $(FFLAGS) $*.f | fl32 $*.f /c
.pas.exe | $(PASCAL) $(PFLAGS) $*.pas | pl $*.pas
.pas.obj | $(PASCAL) /c $(PFLAGS) $*.pas | pl /c $*.pas
.rc.res | $(RC) $(RFLAGS) /r $* | rc /r $*


Inferred Dependents and Rules

NMAKE assumes an inferred dependent for a target if an applicable inference rule exists. A rule applies if:

  • toext matches the target's extension.
  • fromext matches the extension of a file that has the target's base name and that exists in the current or specified directory.
  • fromext is in .SUFFIXES; no other fromext in a matching rule has a higher .SUFFIXES priority.
  • No explicit dependent has a higher .SUFFIXES priority.

Inferred dependents can cause unexpected side effects. If the target's description block contains commands, NMAKE executes those commands and not the commands in the rule.


Precedence in NMAKE Inference Rules

If an inference rule is multiply defined, the highest-precedence definition. The following list shows the order of precedence from highest to lowest:

  1. An inference rule defined in a makefile; later definitions have precedence.
  2. An inference rule defined in Tools.ini; later definitions have precedence.
  3. A predefined inference rule.


Dot Directives in Makefiles

pecify dot directives outside a description block, at the start of a line. Dot directives begin with a period (.) and are followed by a colon (:). Spaces and tabs are allowed. Dot directive names are case sensitive and are uppercase.

Directive | Action
.IGNORE : | Ignores nonzero exit codes returned by commands, from the place it is specified to the end of the makefile. By default, NMAKE halts if a command returns a nonzero exit code. To restore error checking, use !CMDSWITCHES (described in Makefile Preprocessing Directives). To ignore the exit code for a single command, use the dash modifier. To ignore exit codes for an entire file, use the /I option.
.PRECIOUS : targets | Preserves targets on disk if the commands to update them are halted; has no effect if a command handles an interrupt by deleting the file. Separate the target names with one or more spaces or tabs. By default, NMAKE deletes a target if a build is interrupted by Ctrl+C or Ctrl+BREAK. Each use of .PRECIOUS applies to the entire makefile; multiple specifications are cumulative.
.SILENT : | Suppresses display of executed commands, from the place it is specified to the end of the makefile. By default, NMAKE displays the commands it invokes. To restore echoing, use !CMDSWITCHES. To suppress echoing of a single command, use the @ modifier. To suppress echoing for an entire file, use the /S option.
.SUFFIXES : list | Lists extensions for inference-rule matching; predefined as: .exe .obj .asm .c .cpp .cxx .bas .cbl .for .pas .res .rc

To change the .SUFFIXES list order or to specify a new list, clear the list and specify a new setting. To clear the list, specify no extensions after the colon:

 .SUFFIXES :

To add additional suffixes to the end of the list, specify:

 .SUFFIXES : suffixlist

where suffixlist is a list of the additional suffixes, separated by one or more spaces or tabs. To see the current setting of .SUFFIXES, run NMAKE with the /P option.


Makefile Preprocessing

You can control the NMAKE session by using preprocessing directives and expressions. Preprocessing instructions can be placed in the makefile. Using directives, you can conditionally process your makefile, display error messages, include other makefiles, undefine a macro, and turn certain options on or off.

For more information:

  • Makefile Preprocessing Directives
  • Expressions in Makefile Preprocessing
  • Makefile Preprocessing Operators
  • Executing a Program in Preprocessing


Makefile Preprocessing Directives

Preprocessing directives are not case sensitive. The initial exclamation point (!) must appear at the beginning of the line. Zero or more spaces or tabs can appear after the exclamation point, for indentation. The following are preprocessing directives:

  • !CMDSWITCHES {+ | -}option...

    Turns each option listed on or off. Spaces or tabs must appear before the + or - operator; none can appear between the operator and the option letters. Letters are not case sensitive and are specified without a slash (/). To turn some options on and others off, use separate specifications of !CMDSWITCHES.

    Only /D, /I, /N, and /S can be used in a makefile. In Tools.ini, all options are allowed except /F, /HELP, /NOLOGO, /X, and /?. Changes specified in a description block do not take effect until the next description block. This directive updates the MAKEFLAGS recursion macro; changes are inherited during recursion if MAKEFLAGS is specified.

  • !ERROR text

    Displays text in error U1050, then halts NMAKE, even if /K, /I, .IGNORE, !CMDSWITCHES, or the dash (-) command modifier is used. Spaces or tabs before text are ignored.

  • !MESSAGE text

    Displays text to standard output. Spaces or tabs before text are ignored.

  • !INCLUDE [<]filename[>]

    Reads filename as a makefile, then continues with the current makefile. NMAKE searches for filename first in the specified or current directory, then recursively through directories of any parent makefiles, then, if filename is enclosed by angle brackets (<>), in directories specified by the INCLUDE macro, which is initially set to the INCLUDE environment variable. Useful to pass .SUFFIXES settings, .PRECIOUS, and inference rules to recursive makefiles.

  • !IF constantexpression

    Processes statements between !IF and the next !ELSE or !ENDIF if constantexpression evaluates to a nonzero value.

  • !IFDEF macroname

    Processes statements between !IFDEF and the next !ELSE or !ENDIF if macroname is defined. A null macro is considered to be defined.

  • !IFNDEF macroname

    Processes statements between !IFNDEF and the next !ELSE or !ENDIF if macroname is not defined.

  • !ELSE [IF constantexpression | IFDEF macroname | IFNDEF macroname]

    Processes statements between !ELSE and the next !ENDIF if the prior !IF, !IFDEF, or !IFNDEF statement evaluated to zero. The optional keywords give further control of preprocessing.

  • !ELSEIF

    Synonym for !ELSE IF.

  • !ELSEIFDEF

    Synonym for !ELSE IFDEF.

  • !ELSEIFNDEF

    Synonym for !ELSE IFNDEF.

  • !ENDIF

    Marks the end of an !IF, !IFDEF, or !IFNDEF block. Any text after !ENDIF on the same line is ignored.

  • !UNDEF macroname

    Undefines macroname.


Expressions in Makefile Preprocessing

The !IF or !ELSE IF constantexpression consists of integer constants (in decimal or C-language notation), string constants, or commands. Use parentheses to group expressions. Expressions use C-style signed long integer arithmetic; numbers are in 32-bit two's-complement form in the range -2147483648 to 2147483647.

Expressions can use operators that act on constant values, exit codes from commands, strings, macros, and file-system paths.


Makefile Preprocessing Operators

The DEFINED operator is a logical operator that acts on a macro name. The expression DEFINED (macroname) is true if macroname is defined. DEFINED in combination with !IF or !ELSE IF is equivalent to !IFDEF or !ELSE IFDEF. However, unlike these directives, DEFINED can be used in complex expressions using binary logical operators.

The EXIST operator is a logical operator that acts on a file-system path. EXIST (path) is true if path exists. The result from EXIST can be used in binary expressions. If path contains spaces, enclose it in double quotation marks.

Integer constants can use the unary operators for numerical negation (-), one's complement (~), and logical negation (!).

Constant expressions can use the following binary operators:

Operator | Description | Operator | Description
+ | Addition | || | Logical OR
- | Subtraction | << | Left shift
* | Multiplication | >> | Right shift
/ | Division | == | Equality
% | Modulus | != | Inequality
& | Bitwise AND | < | Less than
| | Bitwise OR | > | Greater than
^ | Bitwise XOR | <= | Less than or equal to
&& | Logical AND | >= | Greater than or equal to

To compare two strings, use the equality (= =) operator and the inequality (!=) operator. Enclose strings in double quotation marks.


Executing a Program in Preprocessing

To use a command's exit code during preprocessing, specify the command, with any arguments, within brackets ( [ ] ). Any macros are expanded before the command is executed. NMAKE replaces the command specification with the command's exit code, which can be used in an expression to control preprocessing.


Resource Compiler Options

With Visual Fortran, you can create dialog boxes for an interactive user interface at run-time. For example, you can provide selection lists and scroll bars and the user will not have to type in text strings or numerical control parameters. You can also create custom icons for your Fortran QuickWin and Fortran Windows applications.

The Microsoft visual development environment includes a special dialog editor for creating dialogs and placing the controls within them, and a graphic editor for drawing or importing icons. You must use the dialog editor and graphic editor in the visual development environment to design dialogs and icons. Once you have created a dialog or icon, you can compile it from the command line using the Resource Compiler (RC).

In the visual development environment, you can view the resources in your project in the ResourceView pane (a tab next to the FileView pane). The resource editor in the Microsoft visual development environment offers easy, time-saving alternatives to the traditional hand-coded scripts used to create resources. Resources are built when you build your project.

These visual tools create and manage your project's script – you do not need to hand-code scripts. For more information on the working with resources in the visual development environment, see the Resource Editors section in the Visual C++ User's Guide.

For information on creating resource-definition script files and using the RC command from the command line, see:

  • Including Resources in an Application
  • Creating a Resource Definition File
  • Resource Compiler Command Line
  • The online Platform SDK sections under "Windows Programming Guidelines," "Platform SDK Tools," such as "Compiling" and "Using the Resource Compiler."


Including Resources in an Application

To include resources in your Win32-based application with RC from the command line, do the following:

  1. Use the visual development environment dialog editor or graphic editor to create a resource for each dialog or icon in your application. (For more information, see "Resources Editors" in the Visual C++ User's Guide.)
  2. Create a resource-definition file (also called a script) that describes all resources used by the application.
  3. Compile the script into a resource (.RES) file with RC.EXE (RC).
  4. Link the compiled resource files into the application's executable file.

You do not use RC to include compiled resources into the executable file or to mark the file as an application. The linker recognizes the compiled resource files and links them to the executable file.


Creating a Resource-Definition File

After creating individual resource files for your application's dialog box and icon resources, you create a resource-definition file, or script. A script is a text file with the extension .RC.

The script lists every resource in your application and describes some types of resources in great detail. For a resource that exists in a separate file, such as an icon or cursor, the script names the resource and the file that contains it. For some resources, such as a menu, the entire definition of the resource exists within the script.

A script file can contain the following information:

  • Comments (single-line comments or block line comments)
  • Predefined macros
  • Preprocessing directives, which instruct RC to perform actions on the script before compiling.
  • Preprocessor operators
  • Resource definition statements, which name and describe resources. Statements can be single-line or multiline statements.
  • Pragmas for changing the code page

The following example shows a script file that defines the resources for an application named Shapes:

#include "SHAPES.H"

ShapesCursor CURSOR SHAPES.CUR
ShapesIcon ICON SHAPES.ICO

    BEGIN
        POPUP "&Shape"
            BEGIN
                MENUITEM "&Clear", ID_CLEAR
                MENUITEM "&Rectangle", ID_RECT
                MENUITEM "&Triangle", ID_TRIANGLE
                MENUITEM "&Star", ID_STAR
                MENUITEM "&Ellipse", ID_ELLIPSE
            END
    END

The CURSOR statement names the application's cursor resource ShapesCursor and specifies the cursor file SHAPES.CUR, which contains the image for that cursor. Custom cursors are not available in Visual Fortran.

The ICON statement names the application's icon resource ShapesIcon and specifies the icon file SHAPES.ICO, which contains the image for that icon.

The MENU statement defines an application menu named ShapesMenu, a pop-up menu with five menu items.

The menu definition, enclosed by the BEGIN and END keywords, specifies each menu item and the menu identifier that is returned when the user selects that item. For example, the first item on the menu, Clear, returns the menu identifier ID_CLEAR when the user selects it. The menu identifiers are defined in the application header file, SHAPES.H.

Once you create the resource-definition script (RC) file, use the Resource Compiler Command Line to create the RES file.

For details about script files, see the online Platform SDK sections under "Windows Programming Guidelines" and "Platform SDK Tools" such as "Using the Resource Compiler."


Resource Compiler Command Line

To start RC, use the following command-line syntax:

RC [options] script-file

The script-file argument specifies the name of the resource-definition script that contains the names, types, filenames, and descriptions of the resources to be compiled.

The options argument can include one or more of the following options:

Option | Description
/? Displays a list of RC command-line options.
/d | Defines a symbol for the preprocessor that you can test with #ifdef.
/fo resname | Uses resname for the name of the .RES file.
/h | Displays a list of RC command-line options.
/i directory | Causes RC to search the specified directory before searching the directories specified by the INCLUDE environment variable.
/lcodepage Specifies default language for compilation. For example, -l409 is equivalent to including the following statement at the top of the resource script file:
LANGUAGE LANG_ENGLISH,SUBLANG_ENGLISH_US

Alternatively, you use #pragma code_page(409) in the .RC file.
/n | Null terminates all strings in the string table.
/r | Ignored. Provided for compatibility with existing makefiles.
/u | Undefines a symbol.
/v | Causes a display of messages that report on the progress of the compiler.
/x | Prevents RC from checking the INCLUDE environment variable when searching for header files or resource files.

Options are not case sensitive and a dash (-) can be used in place of a forward slash (/). You can combine single-letter options if they do not require additional arguments. For example, the following commands are equivalent:

  RC /V /X SAMPLE.RC
  rc -vx sample.rc

For more information on these options and the resource compiler, see the online Platform SDK sections under "Windows Programming Guidelines" and "Platform SDK Tools," such as "Using the Resource Compiler."


Managing Libraries with LIB

You may find it useful to create libraries of Common Object File Format (COFF) object files to organize shared components of multiple projects.

In the Microsoft visual development environment, you create and manage object libraries with a variety of dialogs. From the command line, you can use the Microsoft 32-Bit Library Manager (LIB.EXE) to manage COFF object libraries, create export files and import libraries to reference exported symbol definitions when you build Dynamic Link Libraries (DLLs), and extract library members.

You use the standard libraries, import libraries, and export files LIB creates with LINK when building a 32-bit program. (LINK is described in Using the Compiler and Linker from the Command Line and Compiler and Linker Options.) The three LIB modes -- creating standard (COFF) libraries, creating import libraries and export files, and extracting library members -- are mutually exclusive. You can use LIB in only one mode at a time.

You can use LIB to perform the following library-management tasks:

  • Add objects to a library

    Specify the filename for the existing library and the filenames for the new objects.

  • Combine libraries

    Specify the library filenames. You can add objects and combine libraries in a single LIB command.

  • Replace a library member with a new object

    Specify the library containing the member object to be replaced and the filename for the new object (or the library that contains it). When an object that has the same name exists in more than one input file, LIB puts the last object specified in the LIB command into the output library. When you replace a library member, be sure to specify the new object or library after the library that contains the old object.

  • Delete a member from a library

    Use the /REMOVE option. LIB processes any specifications of /REMOVE after combining all input objects, regardless of command-line order.

Note: You cannot both delete a member and extract it to a file in the same step. You must first extract the member object using /EXTRACT, then run LIB again using /REMOVE.

This section describes the Microsoft 32-Bit Library Manager (LIB.EXE). The following topics are covered:

  • LIB Input/Output
  • Running LIB
  • LIB Options
  • Extracting a Library Member
  • Import Libraries and Export Files


LIB Input/Output

LIB expects types of input files and generates types of output files depending on the mode in which it is used. You can also get information about the resulting library with the /LIST option, and you can examine the contents of the library by using DUMPBIN with the /LINKERMEMBER option.

For more information:

  • LIB Input Files
  • LIB Output Files
  • Other LIB Output
  • Viewing Contents of a Library


LIB Input Files

The input files expected by LIB depend on the mode in which it is used, as follows:

Mode | Input
Default (building or modifying a library) | COFF object (.OBJ) files, COFF libraries (.LIB), 32-bit OMF object (.OBJ) files
Extracting a member with /EXTRACT | COFF library (.LIB)
Building an export file and import library with /DEF | Module-definition (.DEF) file, COFF object (.OBJ) files, COFF libraries (.LIB), 32-bit OMF object (.OBJ) files

Note: Object Model Format (OMF) libraries created by the 16-bit version of LIB cannot be used as input to the 32-bit LIB.


LIB Output Files

The output files produced by LIB depend on the usage mode as follows:

Mode | Output
Default (building or modifying a library) | COFF library (.LIB)
Extracting a member with /EXTRACT | Object (.OBJ) file
Building an export file and import library with /DEF | Import library (.LIB) and export (.EXP) file


Other LIB Output

In the default mode, you can use the /LIST option to display information about the resulting library. You can redirect this output to a file.

LIB displays a copyright and version message and echoes command files unless the /NOLOGO option is used.

When you type lib with no other input, LIB displays a usage statement that summarizes its options.

Error and warning messages issued by LIB have the form LNKnnnn. The LINK, DUMPBIN, and EDITBIN tools also use this range of errors.


Viewing Contents of a Library

A library contains COFF objects. Objects in a library contain functions and data that can be referenced externally by other objects in a program. An object in a library is sometimes referred to as a library member.

You can get additional information about the contents of a library by running the DUMPBIN tool with the /LINKERMEMBER option. For more information, see Examining Files with DUMPBIN.


Running LIB

This section presents information on running LIB in any mode. It describes the LIB command line, discusses the use of command files, and gives general rules for using options.

For more information:

  • LIB Command Line
  • LIB Command Files
  • Using LIB Options


LIB Command Line

To run LIB, type the command LIB followed by the options and filenames for the task you are using LIB to perform. LIB also accepts command-line input in command files. LIB does not use an environment variable.

Note: If you are accustomed to the LINK32.EXE and LIB32.EXE tools provided with the Microsoft Win32 Software Development Kit for Windows NT, you may have been using either the command LINK32 -LIB or the command LIB32 for managing libraries and creating import libraries. Be sure to change your makefiles and batch files to use the LIB command instead.


LIB Command Files

You can pass command-line arguments to LIB in a command file by using the following syntax:

LIB @commandfile

The commandfile is the name of a text file. No space or tab is allowed between the at sign (@) and the filename. There is no default extension; you must specify the full filename, including any extension. Wildcards cannot be used. You can specify an absolute or relative path with the filename.

In the command file, arguments can be separated by spaces or tabs as they can on the command line, and they can also be separated by newline characters. Use a semicolon (;) to mark a comment. LIB ignores all text from the semicolon to the end of the line.

You can specify either all or part of the command line in a command file, and you can use more than one command file in a LIB command. LIB accepts the command-file input as if it were specified in that location on the command line. Command files cannot be nested. LIB echoes the contents of command files unless the /NOLOGO option is used.


Using LIB Options

An option consists of an option specifier, which is either a dash ( - ) or a forward slash ( / ), followed by the name of the option. Option names cannot be abbreviated. Some options take an argument, specified after a colon (:). No spaces or tabs are allowed within an option specification. Use one or more spaces or tabs to separate option specifications on the command line.

Option names and their keyword or filename arguments are not case sensitive, but identifiers used as arguments are case sensitive. LIB processes options in the order specified on the command line and in command files. If an option is repeated with different arguments, the last one to be processed takes precedence.

The following LIB options apply to all modes of LIB:

  • /MACHINE

    Specifies the architecture of the library.

  • /NOLOGO

    Suppresses display of the LIB copyright message and version number and prevents echoing of command files.

  • /VERBOSE

    Displays details about the progress of the session. The information is sent to standard output and can be redirected to a file.

Other options apply only to specific modes of LIB. These options are discussed in the sections describing each mode.


LIB Options

The default mode for LIB is to build or modify a library of COFF objects. LIB runs in this mode when you do not specify /EXTRACT (to copy an object to a file) or /DEF (to build an import library).

To build a library from objects and/or libraries, use the following syntax:

LIB [options...] files...

The options that apply to building and modifying a library are listed in the following table:

Option | Description
/CONVERT | Converts an import library to the previous (Visual C++ version 5.0) format.
/LIBPATH:dir | Overrides the environment library path. For more information, see the linker option /LIBPATH.
/LIST | Displays information about the output library to standard output. The output can be redirected to a file. You can use /LIST to determine the contents of an existing library without modifying it.
/LINK50COMPAT | Generates an import library in the previous (Visual C++ version 5.0) format for backwards compatibility.
/OUT:filename | Overrides the default output filename. By default, the output library has the base name of the first library or object on the command line and the extension .LIB.
/REMOVE:object | Omits the specified object from the output library. LIB creates an output library by first combining all objects (whether in object files or libraries), then deleting any objects specified with /REMOVE.
/SUBSYSTEM | Tells the operating system how to run a program created by linking to the output library. For more information, see the description of the LINK /SUBSYSTEM option in Compiler and Linker Options.

Other LIB options are described in:

  • Building an Import Library and Export File
  • Extracting a Library Member
  • Using LIB Options

The files can be COFF object files, 32-bit OMF object files, and existing COFF libraries. LIB creates one library that contains all objects in the specified files. If an input file is a 32-bit OMF object file, LIB converts it to COFF before building the library. LIB cannot accept a 32-bit OMF object that is in a library created by the 16-bit version of LIB. You must first use the 16-bit LIB to extract the object, then you can use the extracted object file as input to the 32-bit LIB. The 16-bit version of LIB is not provided with Visual Fortran.

By default, LIB names the output file using the base name of the first object or library file and the extension .LIB. If a file already exists with the same name, the output file overwrites the existing file. To preserve an existing library, use the /OUT option to specify a name for the output file.

You can use LIB to perform the following library-management tasks:

  • Add objects to a library

    Specify the filename for the existing library and the filenames for the new objects.

  • Combine libraries

    Specify the library filenames. You can add objects and combine libraries in a single LIB command.

  • Replace a library member with a new object

    Specify the library containing the member object to be replaced and the filename for the new object (or the library that contains it). When an object that has the same name exists in more than one input file, LIB puts the last object specified in the LIB command into the output library. When you replace a library member, be sure to specify the new object or library after the library that contains the old object.

  • Delete a member from a library

    Use the /REMOVE option. LIB processes any specifications of /REMOVE after combining all input objects, regardless of command-line order.

Note: You cannot both delete a member and extract it to a file in the same step. You must first extract the member object using /EXTRACT, then run LIB again using /REMOVE. This behavior differs from that of the 16-bit LIB (for OMF libraries) provided in some Microsoft products.


Extracting a Library Member

You can use LIB to create an object (.OBJ) file that contains a copy of a member of an existing library. To extract a copy of a member, use the following syntax:

LIB library /EXTRACT:member /OUT:objectfile

This command creates an .OBJ file called objectfile that contains a copy of a member of a library. The member name is case sensitive. You can extract only one member in a single command. The /OUT option is required; there is no default output name. If a file called objectfile already exists in the specified directory (or current directory, if no directory is specified with objectfile), the extracted objectfile overwrites the existing file.


Import Libraries and Export Files

You can use LIB with the /DEF option to create an import library and an export file. LINK uses the exports file to build a program that contains exports (usually a DLL), and it uses the import library to resolve references to those exports in other programs.

In most situations, you do not need to use LIB to create your import library. When you link a program (either an executable file or a DLL) that contains exports, LINK automatically creates an import library that describes the exports. Later, when you link a program that references those exports, you specify the import library.

However, when a DLL exports to a program that it also imports from, whether directly or indirectly, you must use LIB to create one of the import libraries. When LIB creates an import library, it also creates an export file. You must use the exports file when linking one of the DLLs.

For more information, see:

  • Building an Import Library and Export File
  • Using an Import Library and Export File


Building an Import Library and Export File

To build an import library and export file, use the following syntax:

LIB /DEF[:deffile] [options] [objfiles] [libraries]

When /DEF is specified, LIB creates the output files from export specifications that are passed in the LIB command. There are three methods for specifying exports, listed in recommended order of use:

  • c DEC$ ATTRIBUTES DLLEXPORT in one of the objfiles or libraries
  • A specification of /EXPORT:name on the LIB command line
  • A definition in an EXPORTS statement in a deffile

These are the same methods you use to specify exports when linking an exporting program. A program can use more than one method. You can specify parts of the LIB command (such as multiple objfiles or /EXPORT specifications) in a command file in the LIB command, just as you can in a LINK command.

The following options apply to building an import library and export file:

  • /DEBUGTYPE:{CV|COFF|BOTH}

    This option sets the format of debugging information. Specify CV for new-style Microsoft Symbolic Debugging Information, required by Visual C++ and Visual Fortran. Specify COFF for Common Object File Format (COFF) debugging information. Specify BOTH for both COFF debugging information and old-style Microsoft debugging information.

  • /OUT:import

    This option overrides the default output filename for the import library being created. When /OUT is not specified, the default name is the base name of the first object file or library in the LIB command and the extension .LIB. The exports file is given the same base name as the import library and the extension .EXP.

  • /EXPORT:entryname[=internalname] [,@ordinal[,NONAME]][,DATA]

    This option exports a function from your program to allow other programs to call the function. You can also export data. Exports are usually defined in a DLL.

    The entryname is the name of the function or data item as it is to be used by the calling program. You can optionally specify the internalname as the function known in the defining program; by default, internalname is the same as entryname. The ordinal specifies an index into the exports table in the range 1 - 65535; if you do not specify ordinal, LIB assigns one. The NONAME keyword exports the function only as an ordinal, without an entryname.

  • /INCLUDE:symbol

    This option adds the specified symbol to the symbol table. This is useful for forcing the use of a library object that otherwise would not be included.


Using an Import Library and Export File

When a program (either an executable file or a DLL) exports to another program that it also imports from, or if more than two programs both export to and import from each other, the commands to link these programs must accommodate the circular exports.

In a situation without circular exports, when you link a program that uses exports from another program, you must specify the import library for the exporting program. The import library for the exporting program is created when you link that exporting program. This requires that you link the exporting program before the importing program. For example, if TWO.DLL imports from ONE.DLL, you must first link ONE.DLL and get the import library ONE.LIB. You then specify ONE.LIB when you link TWO.DLL. When the linker creates TWO.DLL, it also creates its import library, TWO.LIB. You use TWO.LIB when linking programs that import from TWO.DLL.

However, in a circular export situation, it is not possible to link all of the interdependent programs using import libraries from the other programs. In the example discussed earlier, if TWO.DLL also exports to ONE.DLL, the import library for TWO.DLL won't exist yet when ONE.DLL is linked. When circular exports exist, you must use LIB to create an import library and exports file for one of the programs.

To begin, choose one of the programs on which to run LIB. In the LIB command, list all objects and libraries for the program and specify the /DEF option. If the program uses a .DEF file or /EXPORT specifications, specify these as well.

After you create the import library (.LIB) and the export file (.EXP) for the program, you then use the import library when linking the other program or programs. LINK creates an import library for each exporting program it builds. For example, if you ran LIB on the objects and exports for ONE.DLL, you created ONE.LIB and ONE.EXP. You can now use ONE.LIB when linking TWO.DLL; this step also creates the import library TWO.LIB.

Finally, link the program you began with. In the LINK command, specify the objects and libraries for the program, the .EXP file that LIB created for the program, and the import library or libraries for the exports used by the program. In the continuing example, the LINK command for ONE.DLL contains ONE.EXP and TWO.LIB, as well as the objects and libraries that go into ONE.DLL. Do not specify the .DEF file and /EXPORT specifications in the LINK command; these are not needed because the exports definitions are contained in the .EXP file. When you link using an .EXP file, LINK does not create an import library because it assumes that one was created when the .EXP file was created.


Editing files with EDITBIN

You can specify execution characteristics of a program or library by selecting options in the visual development environment. For example, you might need to specify the base address at which a program is loaded by the operating system. If you work from the command line, you can use the Microsoft Binary File Editor (EDITBIN) to set these types of controls.

This section describes the Microsoft COFF Binary File Editor (EDITBIN.EXE). EDITBIN modifies 32-bit Common Object File Format (COFF) binary files. You can use EDITBIN to modify object files, executable files, and dynamic-link libraries (DLLs).

EDITBIN converts the format of an Object Module Format (OMF) input file to COFF before making other changes to the file. You can use EDITBIN to convert the format of a file to COFF by running EDITBIN with no options.

The following topics are covered in this section:

  • EDITBIN Command Line
  • EDITBIN Options


EDITBIN Command Line

To run EDITBIN, use the following syntax:

EDITBIN [options] files...

Specify one or more files for the objects or images to be changed, and one or more options for changing the files.

When you type the command EDITBIN without any other command-line input, EDITBIN displays a usage statement that summarizes its options.


EDITBIN Options

An option consists of an option specifier, which is either a dash (-) or a forward slash (/), followed by the name of the option. Option names cannot be abbreviated. Some options take arguments, specified after a colon (:). No spaces or tabs are allowed within an option specification. Use one or more spaces or tabs to separate option specifications on the command line. Option names and their keyword or filename arguments are not case sensitive.

This section discusses the following EDITBIN options:

  • /BIND
  • /HEAP
  • /LARGEADDRESSAWARE
  • /NOLOGO
  • /REBASE
  • /RELEASE
  • /SECTION
  • /STACK
  • /SUBSYSTEM
  • /SWAPRUN
  • /VERSION
  • /WS


EDITBIN Option /BIND

The /BIND option sets the addresses of the entry points in the import address table for an executable file or DLL. Use this option to reduce load time of a program.

The /BIND option has the following form:

/BIND[:PATH=path]

Specify the program's executable file and DLLs in the files argument on the EDITBIN command line. The optional path argument to the /BIND option specifies the location of the DLLs used by the specified files. Separate multiple directories with semicolons (;). If path is not specified, EDITBIN searches the directories specified in the PATH environment variable. If path is specified, EDITBIN ignores the PATH variable.

By default, the Windows program loader sets the addresses of entry points when it loads a program. The amount of time this takes varies depending on the number of DLLs and the number of entry points referenced in the program.

If a program has been modified with the /BIND option, and if the base addresses for the executable file and its DLLs do not conflict with DLLs that are already loaded, the operating system does not need to set these addresses. In a situation where the files are incorrectly based, the operating system will relocate the program's DLLs and recalculate the entry-point addresses; this adds to the program's load time.


EDITBIN Option /HEAP

The /HEAP option sets the size of the heap in bytes. It has the following form:

/HEAP:reserve[,commit]

The reserve argument specifies the total heap allocation in virtual memory. The default heap size is 1MB. The linker rounds up the specified value to the nearest 4 bytes.

The optional commit argument is subject to interpretation by the operating system. It specifies the amount of physical memory to allocate at a time. Committed virtual memory causes space to be reserved in the paging file. A higher commit value saves time when the application needs more heap space but increases the memory requirements and possibly startup time.

Specify the reserve and commit values in decimal or C-language notation.


EDITBIN Option /LARGEADDRESSAWARE

This option edits the image to indicate that the application can handle addresses larger than 2 gigabytes.


EDITBIN Option /NOLOGO

This option suppresses display of the EDITBIN copyright message and version number.


EDITBIN Option /REBASE

The option /REBASE[:modifiers] sets the base addresses for the specified files. EDITBIN assigns new base addresses in a contiguous address space according to the size of each file rounded up to the nearest 64K.

Specify the program's executable files and DLLs in the files argument on the EDITBIN command line in the order in which they are to be based. You can optionally specify one or more modifiers, each separated by a comma (,):

Modifier | Action
BASE=address | Provides a beginning address for reassigning base addresses to the files. Specify address in decimal or C-language notation. If BASE is not specified, the default starting base address is 0x400000. If DOWN is used, BASE must be specified, and address sets the end of the range of base addresses.
BASEFILE | Creates a file named COFFBASE.TXT, which is a text file in the format expected by LINK's /BASE option.
DOWN | Tells EDITBIN to reassign base addresses downward from an ending address. The files are reassigned in the order specified, with the first file located in the highest possible address below the end of the address range. BASE must be used with DOWN to ensure sufficient address space for basing the files. To determine the address space needed by the specified files, run EDITBIN with the /REBASE option on the files and add 64K to the displayed total size.


EDITBIN Option /RELEASE

This option sets the checksum in the header of an executable file. The operating system requires the checksum for certain files such as device drivers. It is recommended that you set the checksum for release versions of your programs to ensure compatibility with future operating systems.


EDITBIN Option /SECTION

This option changes the properties of a section, overriding the properties that were set when the object file for the section was compiled or linked. It has the following form:

/SECTION:name[=newname][,properties][,alignment]

After the colon ( : ), specify the name of the section. To change the section name, follow name with an equal sign (=) and a newname for the section.

To set or change the section's properties, specify a comma (,) followed by one or more property characters. To negate a property, precede its character with an exclamation point (!). The following characters specify memory properties:

Property | Setting
c | code
d | discardable
e | executable
i | initialized data
k | cached virtual memory
m | link remove
o | link info
p | paged virtual memory
r | read
s | shared
u | uninitialized data
w | write

To control alignment, specify the character "a" followed by a character to set the size of alignment in bytes, as follows:

Character | Alignment Size in Bytes
1 | 1
2 | 2
4 | 4
8 | 8
p | 16
t | 32
s | 64
x | no alignment

Specify the properties and alignment characters as a string with no white space. The characters are not case sensitive.


EDITBIN Option /STACK

This option sets the size of the stack in bytes and takes arguments in decimal or C-language notation. The /STACK option applies only to an executable file. This option takes the following form:

/STACK:reserve[,commit]

The reserve argument specifies the total stack allocation in virtual memory. EDITBIN rounds up the specified value to the nearest 4 bytes. The optional commit argument is subject to interpretation by the operating system. On Windows NT 4 and Windows 2000 systems, commit specifies the amount of physical memory to allocate at a time. Committed virtual memory causes space to be reserved in the paging file. A higher commit value saves time when the application needs more stack space but increases the memory requirements and possibly startup time.


EDITBIN Option /SUBSYSTEM

Edits the image to indicate which subsystem the operating system must invoke for execution.

For more information, see the description of the LINK /SUBSYSTEM option in Compiler and Linker Options.


EDITBIN Option /SWAPRUN

This option edits the image to tell the operating system to copy the image to a swap file and run it from there. Use this option for images that reside on networks or removable media. It has the following form:

/SWAPRUN:{[!]NET|[!]CD}

You can add or remove the NET or CD qualifiers:

  • NET indicates that the image resides on a network.
  • CD indicates that the image resides on a CD-ROM or similar removable medium.

Use !NET and !CD to reverse the effects of NET and CD.


EDITBIN Option /VERSION

This option places a version number into the header of the image. It has the following form:

/VERSION:left[, right]

The whole number part of the version number (the portion to the left of the decimal point) is represented by left. The fractional part of the version number (the portion to the right of the decimal point) is represented by right.


EDITBIN Option /WS

This option adds the WS_AGGRESSIVE property to your application's image. It has the following form:

/WS:AGGRESSIVE

In Windows NT 4 and Windows 2000, the loader recognizes this property and aggressively trims the working set of the process when the process is inactive. This has the same effect as using the following call throughout your application:

   SetProcessWorkingSetSize(hThisProcess, -1, -1)

Use /WS:AGGRESSIVE for applications such as services and screen savers that must have a low impact on the system's memory pool. If the speed of your application matters, do not use /WS:AGGRESSIVE without testing the resulting performance.


Examining Files with DUMPBIN

There are times when you must examine or change OBJ, EXE, and DLL files. In the visual development environment, you can open any file as a Binary rather than as an ASCII text file and work with both hexadecimal and ASCII versions of the contents. From the command line, you can use the Microsoft Binary File Dumper (DUMPBIN) to edit these types of files.

This section describes the Microsoft COFF Binary File Dumper (DUMPBIN.EXE). DUMPBIN displays information about 32-bit Common Object File Format (COFF) binary files. You can use DUMPBIN to examine COFF object files, standard libraries of COFF objects, executable files, and dynamic-link libraries (DLLs).

The following topics are covered in this section:

  • DUMPBIN Command Line
  • DUMPBIN Options


DUMPBIN Command Line

The syntax for DUMPBIN is:

DUMPBIN [options] files...

Specify one or more binary files, along with any options required to control the information. DUMPBIN displays the information to standard output. You can either redirect it to a file or use the /OUT option to specify a filename for the output.

When you run DUMPBIN on a file without specifying an option, DUMPBIN displays the /SUMMARY output.

When you type the command DUMPBIN without any other command-line input, DUMPBIN displays a usage statement that summarizes its options.


DUMPBIN Options

An option consists of an option specifier, which is either a dash (-) or a forward slash (/), followed by the name of the option. Option names cannot be abbreviated. Some options take arguments, specified after a colon (:). No spaces or tabs are allowed within an option specification. Use one or more spaces or tabs to separate option specifications on the command line. Option names and their keyword or filename arguments are not case sensitive. Most options apply to all binary files; a few apply only to certain types of files.

The DUMPBIN options are as follows:

Option | Description
/ALL | Displays all available information except code disassembly. Use the /DISASM option to display disassembly. You can use /RAWDATA:NONE with the /ALL option to omit the raw binary details of the file.
/ARCHIVEMEMBERS | Displays minimal information about member objects in a library.
/ARCH | Dumps the .arch section of an image.
/DEPENDENTS | Dumps the names of the DLLs from which the image imports functions. Does not dump the names of the imported functions.
/DIRECTIVES | Dumps the compiler-generated .drective section of an image.
/DISASM | Displays disassembly of code sections, using symbols if present in the file.
/EXPORTS | Displays all definitions exported from an executable file or DLL.
/FPO | Displays Frame Pointer Optimization (FPO) records.
/HEADERS | Displays coff header information.
/IMPORTS | Displays all definitions imported to an executable file or DLL. Output resembles the /EXPORTS option.
/LINENUMBERS | Displays COFF line numbers. Line numbers exist in an object file if it was compiled with Program Database (/Zi) or Line Numbers Only (/Zd). An executable file or DLL contains COFF line numbers if it was linked with Generate Debug Info (/DEBUG) and COFF Format (/DEBUGTYPE:COFF).
/LINKERMEMBER | The option /LINKERMEMBER[:{1|2}] displays public symbols defined in a library. Specify the 1 argument to display symbols in object order, along with their offsets. Specify the 2 argument to display offsets and index numbers of objects, then list the symbols in alphabetical order along with the object index for each. To get both outputs, specify /LINKERMEMBER without the number argument.
/OUT | The option /OUT:filename specifies a filename for the output. By default, DUMPBIN displays the information to standard output.
/PDATA | dumps the exception tables (.pdata) from an image or object.
/RAWDATA The option /RAWDATA[:{ BYTES | SHORTS | LONGS | NONE }[, number] ] displays the raw contents of each section in the file. The arguments control the format of the display, as follows:
Argument | Result
BYTES | The default. Contents are displayed in hexadecimal bytes, and also as ASCII if they have a printed representation.
SHORTS | Contents are displayed in hexadecimal words.
LONGS | Contents are displayed in hexadecimal longwords.
NONE | Raw data is suppressed. This is useful to control the output of the /ALL option.
number | Displayed lines are set to a width that holds number values per line.
/RELOCATIONS | Displays any relocations in the object or image.
/SECTION | The option /SECTION:section restricts the output to information on the specified section.
/SUMMARY | Displays minimal information about sections, including total size. This option is the default if no other option is specified.
/SYMBOLS | Displays the COFF symbol table. Symbol tables exist in all object files. A COFF symbol table appears in an image file only if it is linked with the Generate Debug Info and COFF Format options under Debug Info on the Debug category for the linker (or the /DEBUG and /DEBUGTYPE:COFF options on the command line).


Editing Format Descriptors with the Format Editor

The Format Editor is an application for Windows® that shows you what data formatted to match your edit descriptors will look like, and lets you edit either the descriptor list or the data. You can interactively create and edit Fortran 90 FORMAT statements and embedded formatting directives.

You can run the Format Editor either from the Edit menu in the visual development environment or from the command line. The Format Editor program is located in the ...\Common\MSDev98\Bin directory, and is called FRMTEDIT.EXE. To use it from the command line, you specify the source code file name, line number and column position in the argument list, and the Format Editor operates on the formatting at the indicated location. For example:

  FRMTEDIT test.f90 5 18

If the line specified by the second parameter is empty, a new format statement is created with the words label FORMAT.

To use the Format Editor on a multi-line format statement, the argument list must specify the first line of the format statement. In-line comments in a multi-line Format statement are lost when the Format Editor writes the updated format statement and generates new continuation marks. Similarly, the part of a formatted I/O statement that follows the formatting directives is lost when the Format Editor writes the updated directive string back to the file.

When you are finished editing the format statement, the Format Editor rewrites the source file with code for the format you have developed. If the file has the extension .F90, the revised code is written with Fortran 90 free-form syntax rules; otherwise, it is written with Fortran 90 fixed-form syntax rules.

The Format Editor is installed on the Edit menu during Visual Fortran installation. If you have removed it for any reason, and need to reinstall it, you can do so by choosing Customize from the Tools menu. The argument list, which passes the current file name, line number and column position to the Format Editor, is $File $Line $Column. For more information about adding programs to the Tools menu, select the Help button in the Customize dialog.


Starting the Format Editor from the Microsoft Visual Development Environment

The Format Editor presents the format code and a sample of the resulting data layout in a window that works like a dialog box. You can edit either the source code or the data layout, and the Format Editor changes the other to match.

To open the Format Editor:

  1. Load a Fortran source file that contains a FORMAT statement or an I/O edit descriptor.
  2. Place the cursor on the first line of the FORMAT statement or on the line containing the edit descriptor.
  3. From the Edit menu, choose Format Editor. The Format Editor dialog box opens.

The Format Editor dialog box consists of the following text boxes and buttons:

  • The edit descriptors in the upper-left text box
  • The sample data display in the lower-left text box
  • The New Field, Remove Field, Change Value, OK, Cancel, and Help buttons along the bottom

When you open the Format editor in a line with an edit descriptor, the editor attempts to parse the first opening quote that precedes the cursor position. When you open the editor in a line containing a FORMAT statement, the editor attempts to parse the edit descriptors in the statement. If the editor is successful, it displays the edit descriptors in the upper-left box and a sample data display in the lower text box. If the editor cannot parse the descriptor string or FORMAT statement, you will get a parse error message.

To insert new I/O edit descriptors into existing formatted I/O statements or FORMAT statements in Microsoft visual development environment:

  1. Place the cursor in the existing descriptor or FORMAT statement.
  2. From the Edit menu, choose Format Editor.
  3. Choose New Field from the Format Editor dialog box.
  4. Choose the descriptor type (Character, Integer, and so on) and choose whether to insert the descriptor before or after the current descriptor.
  5. A default value is used for the descriptor you choose (for example, I5). To change the descriptor value, select the value and type in the new value. (For example, select 5 from I5 and type 8 to get an I8 format.)

To insert a new format statement:

  1. Place the cursor on a blank line.
  2. From the Edit menu, choose Format Editor.

The Format Editor inserts the words label FORMAT into the file at the cursor. You can define the new edit descriptor with the Format Editor.

For a discussion of the features of the Format Editor in Microsoft visual development environment, choose Format Editor from the Edit menu, and click on Help in the Format Editor dialog box.


Profiling Code from the Command Line

The profiler is an analysis tool you can use to examine the run-time behavior of your programs. By profiling, you can find out which sections of your code are working efficiently and which need to be tuned. The profiler can also show areas of code that are not being executed.

Because profiling is a tuning process, you should use the profiler to make your programs run better, not to find bugs. Once your program is fairly stable, you should start profiling to find out where to optimize your code. Use the profiler to determine whether an algorithm is effective, a function is being called frequently (if at all), or if a piece of code is being covered by software testing procedures.

In the Microsoft visual development environment, you can use the Profiler to generate reports that characterize how your program executes. If you work from the command line, you can create a batch command file to run PREP, PROFILE and PLIST, the programs that generate execution profile reports.

If you work from the command line, specify the /profile option to the LINK command to enable profiling. Similarly, when using the visual development environment, you need to enable profiling in the Link tab in the Project Settings dialog box.

For information on using the Profiler from the Microsoft visual development environment and timing your application, see Analyze Program Performance.

This section describes how to use the components of the profiler from the command line. The following topics are covered:

  • Profiler Batch Processing
  • Profiler Batch Files
  • Profiler Command-Line Options
  • Exporting Data From the Profiler


Profiler Batch Processing

Profiling requires three separate programs: PREP, PROFILE, and PLIST. The visual development environment executes all three of these programs for you automatically. To execute them efficiently from the command line, and to customize the output format or specify function and line count profiling, you must write batch files to invoke PREP, PROFILE, and PLIST. You can redirect the output of the batch file to a designated file by using the redirection character (>).

A typical profiler batch file might look like this:

 PREP /OM /FT /EXC nafxcwd.lib %1
 if errorlevel == 1 goto done
 PROFILE %1 %2 %3 %4 %5 %6 %7 %8 %9
 if errorlevel == 1 goto done
 PREP /M %1
 if errorlevel == 1 goto done
 PLIST /SC %1 >%1.lst
  :done

Note that the PREP program is called twice - once before the actual profiling and again afterward. The command-line arguments govern PREP's behavior. Intermediate files with extensions .PBI, .PBO, and .PBT are used to transfer information between profiling steps. The first call to PREP generates a .PBI file which is passed to PROFILER. PROFILER generates a .PBO file which is passed in the second call to PREP. The second call to PREP generates a .PBT file which is passed to PLIST. The profiler data flow is shown in the following figure:

Profiler Data Flow

If the preceding batch file was named FTIME.BAT, and you wanted to profile the program TEST from the command prompt, you would type:

 FTIME C:\Program Files\DF98\MYDIR\TEST.EXE


Profiler Batch Files

Like the linker, all three profiler programs accept response files. The following command line:

  PREP /OM /FT /EXC nafxcwd.lib %1

can be replaced by this line:

 PREP @opts.rsp %1

if you create a file OPTS.RSP that contains this text:

 /OM /FT /EXC nafxcwd.lib # this is a comment

The # character in a response file defines a comment that runs through the end of the line.

Five standard batch files ship with the profiler:

Filename | Description
FTIME.BAT | Function timing
FCOUNT.BAT | Function counting
FCOVER.BAT | Function coverage
LCOUNT.BAT | Line counting
LCOVER.BAT | Line coverage

These batch files contain only the minimum parameters for the initial call to PREP. Use them as prototypes for your own batch files, which should contain selection parameters. If you ran an unmodified LCOVER batch file for a complex Fortran 90 application with a large number of functions, subroutines and modules, the output report could be thousands of lines long.


Profiler Command-Line Options

The following sections describe the command-line options for the three components of the profiler:

  • PREP
  • PROFILE
  • PLIST


PREP

The PREP program runs twice during a normal profiling operation. In Phase I, it reads an .EXE file and then creates .PBI and .PBT files. In Phase II, it reads .PBT and .PBO files and then writes a new .PBT file for PLIST. An 'X' in the following Options table indicates that a PREP command-line option applies to a particular phase.

The syntax for PREP is:

PREP [options] [programname1] [programname2...programname8]

PREP reads the command line from left to right, so the rightmost options override contradictory options to the left. None of the options are case sensitive. You must prefix options with a forward slash ( / ) or a dash ( - ), and options must be separated by spaces.

Parameter | Description
options | Control the kind of profiling, the inclusion and exclusion of code to be profiled, whether to merge profiles, and other profiling features. See the PREP Options table.
programname1 | Filename of primary program to profile (.DBG, .EXE, or .DLL). PROFILE adds the .EXE extension if no extension is given. This parameter must be specified in the first call to PREP and not the second call.
programname2 ... programname8 | Additional programs to profile. These parameters can be specified for the first call to PREP only.

PREP Options

 | Phase
Option | I | II | Description
/AT | X |  | Collects attribution data for function timing and function counting. Function attribution reports which function called another function. See the /STACK switch later in this list.
/CB | X |  | Used with function timing, allows you to set the calibrated overhead of profiler calls in the event that your function timing calls have varied because of varied calibrated overhead values. The calibrated overhead is displayed in default (non-tab-delimited) PLIST output.
/EXC | X |  | Excludes a specified module from the profile (See the Remarks section).
/EXCALL | X |  | Excludes all modules from the profile (See the Remarks section).
/FC | X |  | Selects function count profiling.
/FT | X |  | Selects function timing profiling. This option causes the profiler to generate count information as well.
/FV | X |  | Selects function coverage profiling.
/INC | X |  | Includes in profile (See the Remarks section).
/H[ELP] | X | X | Provides a short summary of PREP options.
/IO filename |  | X | Merges an existing .PBO file (the file generated by PROFILER to be passed in the second call to PREP). Up to eight .PBO files can be merged at a time. The default extension is .PBO.
/IT filename |  | X | Merges an existing .PBT file (the file generated by the second call to PREP to be passed to PLIST). Up to eight .PBT files can be merged at a time. You cannot merge .PBT files from different profiling methods. The default extension is .PBT.
/LC | X |  | Selects line count profiling.
/LV | X |  | Selects line coverage profiling.
/M filename |  | X | Substitutes for /IT, /IO, and /OT options.
/NOLOGO | X | X | Suppresses the PREP copyright message.
/OI filename | X |  | Creates a .PBI file (the file generated by the first call to PREP). The default extension is .PBI. If /OI is not specified, the output .PBI file is programname1.PBI.
/OM | X |  | Creates a self-profiling file with _XE or _LL extension for function timing, function counting, and function coverage. Without this option, the executable code is stored in the .PBI file. This option speeds up profiling.
/OT filename | X | X | Specifies the output .PBT file. The default extension is .PBT. If /OT is not specified, the output .PBT file is programname1.PBT.
/SF function | X |  | Starts profiling with function. The function name must correspond to an entry in the .MAP file.
/STACK dpt | X |  | When using the /AT switch, you can also set the stack depth (dpt) to which functions will have their attribution data recorded.
/? | X | X | Provides a short summary of PREP options.

Environment Variable

The PREP environment variable specifies the default PREP command-line options. If a value for the PREP environment variable is not specified, the default options for PREP are:

  /FT /OI filename /OT filename

where filename is set to the programname1 parameter value.

Remarks

The /INC and /EXC options specify individual .LIB, .OBJ, .FOR and .F90 files. For line counting and line coverage, you can specify line numbers with source files as in:

  /EXCALL /INC TEST.F90(3-41,50-67)

In this example, the /EXCALL option excludes all modules from the profile, and the /INC option supercedes that to include only lines 3 - 41 and lines 50 - 67 from the source file TEST.F90. Note the absence of spaces in the source specification.

To specify all source lines in a particular module, specify the .OBJ file like this:

  /EXCALL /INC TEST.OBJ

or by using the source filename with zero line numbers like this:

  /EXCALL /INC TEST.F90(0-0)

The following statement profiles from line 50 to the end of the file:

  /EXCALL /INC TEST.F90(50-0)


PROFILE

PROFILE profiles an application and generates a .PBO file of the results. Use PROFILE after creating a .PBI file with PREP.

The syntax for PROFILE is:

PROFILE [options] programname [programargs]

PROFILE reads the command line from left to right, so the rightmost options override contradictory options to the left. None of the options are case sensitive. You must prefix options with a forward slash (/) or a dash (-), and options must be separated by spaces.

If you do not specify a .PBO filename on the command line, PROFILE uses the base name of the .PBI file with a .PBO extension. If you do not specify a .PBI or a .PBO file, PROFILE uses the base name of programname with the .PBI and .PBO extensions.

Parameter | Description
options | Control .PBI input, .PBO output, error printing, and other profiler features. (See the PROFILE Options table).
programname | Filename of program to profile. PROFILE adds the .EXE extension if no extension is given. (See the Remarks section.)
programargs | Optional command-line arguments for programname. (See the Remarks section.)

PROFILE Options

Option | Description
/A | Appends any redirected error messages to an existing file. If the /E command-line option is used without the /A option, the file is overwritten. This option is valid only with the /E option.
/E filename | Sends profiler-generated error messages to filename.
/H[ELP] | Provides a short summary of PROFILE options.
/ I filename | Specifies a .PBI file to be read. This file is generated by PREP.
/NOLOGO | Suppresses the PROFILE copyright message.
/O filename | Specifies a .PBO file to be generated. Use the PREP utility to merge with other .PBO files or to create a .PBT file for use with PLIST.
/X | Returns the exit code of the program being profiled.
/? | Provides a short summary of PROFILE options.

Environment Variable

The PROFILE environment variable specifies the default command-line options for PROFILE. If the PROFILE environment variable is not specified, there are no defaults.

Remarks

You must specify the filename of the program to profile on the PROFILE command line. PROFILE assumes the .EXE extension, if no extension is given.

You can follow the program name with command-line arguments; these arguments are passed to the profiled program unchanged.

If you are profiling code in a .DLL file, give the name of an executable file that calls it. For example, if you want to profile SAMPLE.DLL, which is called by CALLER.EXE, you can type:

  PROFILE CALLER.EXE

assuming that CALLER.PBI has SAMPLE.DLL selected for profiling.


PLIST

PLIST converts results from the .PBT file generated by the second call to PREP into a formatted text file.

The syntax for PLIST is:

PLIST [options] inputfile

PLIST reads the command line from left to right, so the rightmost options override contradictory options to the left. None of the options are case sensitive. You must prefix options with a forward slash (/) or a dash (-), and options must be separated by spaces.

PLIST results are sent to STDOUT by default. Use the greater-than (>) redirection

PLIST must be run from the directory in which the profiled program was compiled.

Parameter | Description
options | Control the format and organization of profiler output data. (See the PLIST Options table.)
inputfile | The .PBT file to be converted by PLIST.

PLIST Options

Option | Description
/C count | Specifies the minimum hit count to appear in the listing.
/D directory | Specifies an additional directory for PLIST to search for source files. Use multiple /D command-line options to specify multiple directories. Use this option when PLIST cannot find a source file.
/F | Lists full paths in tab-delimited report.
/FLAT | When using function attribution (see PREP /AT), displays function attribution with no indentation.
/H[ELP] | Provides a short summary of PLIST options.
/INDENT | When using function attribution (see PREP /AT), displays function attribution information in indented format. This is the default display for function attribution if neither /FLAT nor /TAB is selected.
/NOLOGO | Suppresses the PLIST copyright message.
/PL length | Sets page length (in lines) of output. The length must be 0 or 15-255. A length of 0 suppresses page breaks. The default length is 0.
/PW width | Sets page width (in characters) of output. The width must be 1-511. The default width is 511.
/SC | Sorts output by counts, highest first.
/SL | Sorts output in the order that the lines appear in the file. This is the default. This option is available only when profiling by line.
/SLS | Forces line count profile output to be printed in coverage format.
/SN | Sorts output in alphabetical order by function name. This option is available only when profiling by function.
/SNS | Displays function timing or function counting information in function coverage format. Sorts output in alphabetical order by function name.
/ST | Sorts output by time, highest first.
/T | Tab-separated output. Generates a tab-delimited database from the .PBT file for export to other applications. All other options, including sort specifications, are ignored when using this option. For more information, see Exporting Data from the Profiler.
/TAB indent | When using function attribution (see PREP /AT), sets tab width for indentation of function information.
/? | Provides a summary of PLIST options.

Environment Variable

The PLIST environment variable specifies the default command-line options for PLIST. If the PLIST environment variable is not specified, the default options for PLIST depend on the profile type as shown:

Profile Type | Sort Option | Hit Count Option
Function timing | /ST | /C 1
Function counting | /SC | /C 1
Function coverage | /SN | /C 0
Line counting | /SL | /C 0
Line coverage | /SLS | /C 0


Exporting Data from the Profiler

In addition to formatted reports, the PLIST report-generation utility can produce a tab-delimited report of profiler output. The following sections describe the data format of the report, steps for analyzing statistics in the report, and a Microsoft Excel macro that uses this report format:

  • Tab-Delimited Record Format
  • Global Information Records
  • Local Information Records
  • Steps to Analyze Profiler Statistics
  • Processing Profiler Output with Microsoft Excel
  • Generating the Tab-Delimite Report
  • Using the PROFILER.XLM Macro
  • Changing the PROFILER.XLM Selection Criteria

The PLIST /T command-line option causes PLIST to dump the contents of a .PBT file into a tab-delimited format suitable for import into a spreadsheet or database. This format can also be used by user-written programs.

For example, to create a tab-delimited file called MYPROG.TXT from MYPROG.PBT, enter:

  PLIST /T MYPROG > MYPROG.TXT

The ASCII tab-delimited format was designed to be read by other programs; it was not intended for general reporting.


Tab-Delimited Record Format

Every piece of data stored by the Profiler is available through the tab-delimited report. Because not all aspects of the database are recorded by every profiling method, unused fields within a record may be zero. For example, the total time of the program will be zero if the program was profiled for counts only. Also, all included functions will be listed for function counting and timing profiles, even if those functions were not executed.

The tab-delimited format is arranged with one record per line and two to eight fields per record. The following figure shows how a database looks when loaded into Microsoft Excel. The database was produced using the PLIST /T command-line option.

The first item in each record is a format tag number. These tags range from 0 to 7 and indicate the kind of data given in the other fields of the record. The fields in each record are described in:

  • Global Information Records
  • Local Information Records

Tab-delimited reports are generated with global information records first, organized in numerical order by format tag. The local information records, containing information about specific lines or functions, are generated last. Local information records are organized by line number.

If the .PBT file contains information from more than one .EXE or .DLL file, the global information will cover them all. Local information records include the EXE field, which specifies the name of the executable file that each record pertains to.


Global Information Records

The global information records contain information about the entire executable file. The format tag numbers for global information records are 0 through 5. The record formats are as follows:

Profiling Banner
0 Version Banner
Field | Explanation
0 | Format tag number
Version | PLIST version number
Banner | PLIST banner

Profiling Method
1 Method Description
Field | Explanation
1 | Format tag number
Method | Numeric value that indicates the profiling type (see the following table)
Description | ASCII description of the profiling type given by the method field

The profiling types are listed in the following table:

Profiling Types
Method | Description
321 | Profile: Line counting, sorted by line
324 | Profile: Line coverage, sorted by line
521 | Profile: Function counting, sorted by function name
522 | Profile: Function timing, sorted by function name
524 | Profile: Function coverage, sorted by function name

Profiling Time and Depth
2 Total Time Outside Time Call Depth
Field | Explanation
2 | Format tag number
Total Time | Total amount of time used by the program being profiled. This field is zero for counting and coverage profiles
Outside Time | Amount of time spent before the first profiled function (with function profiling) or line (with line profiling) was executed. This field is zero for counting and coverage profiles
Call Depth | Maximum number of nested functions found while profiling. Only profiled functions are counted. This field is zero for line-level profiling

Profiling Hit Counts
3 Total Hits Lines/Funcs Lines/Funcs Hit
Field | Explanation
3 | Format tag number
Total Hits | Total number of times the profiler detected a profiled line or function being executed
Lines/Funcs | Total number of lines or functions marked for profiling
Lines/Funcs Hit | Number of marked lines or functions executed at least once while profiling

Profiling Date/Command Line
4 Date Command Line
Field | Explanation
4 | Format tag number
Date | The date/time the profile was run (ASCII format)
Command Line | The PLIST command-line arguments

Profiling Starting Function Name
5 Starting Function Name
Field | Explanation
5 | Format tag number
Starting Function Name | The decorated name of the starting function identified by the PREP /SF parameter


Local Information Records

The local information records contain information about specific lines or functions that were profiled. The format tag numbers for local information records are 6 and 7. A report can have only one kind of local information record. The record formats are as follows:

Profiling Function Information
6 Exe Source Count Time Child Func
Field | Explanation
6 | Format tag number
Exe | ASCII name of the executable file that contains this function.
Source | ASCII name of the object module (including the .OBJ extension) that contains this function
Count | Number of times this function has been executed
Time | Amount of time spent executing this function in milliseconds. This field is zero with profiling by counting or coverage
Child | Amount of time spent executing the function and any child functions it calls. This field is zero with profiling by counting or coverage
Func | ASCII name of the function

Profiling Line Information
7 Exe Source Line Count
Field | Explanation
7 | Format tag number
Exe | ASCII name of the executable file that contains this function
Source | ASCII name of the source that contains the first line of this function
Line | Line number of this line
Count | Number of times this line has been executed. With coverage, this field is 1 if the line has been executed and 0 otherwise

Profiling Function-Attribution Stacks
8 Number of stacks
Field | Explanation
8 | Format tag number
Number of stacks | Number of stacks for each function call

Profiling Stack Hits and Timing
9 Stack size Hit count Stack time Child time
Field | Explanation
9 | Format tag number
Stack size | Stack size for each function call
Hit count | Hit count for this stack
Stack time | This stack's self-time
Child time | This stack's child-time

Profiling Stack Function Name
10 Function name
Field | Explanation
10 | Format tag number
Function name | Each function's name on the stack. The number of names that appear here will be equal to the stack size field in Profiling Stack Hits and Timing (above).


Steps to Analyze Profiler Statistics

The profiler tab-delimited report format can contain a great deal of information. You can process this data in a spreadsheet, database, or user-written program.

To process the data in the tab-delimited report:

  1. Collect the cumulative data from the global information records. These lines begin with the numbers 0 through 5. Each of these lines appears only once, and always in ascending order.
  2. Determine the type of database by finding the value of the "Method" field. This field is the second field of record type 1.
  3. If the value in the "Method" field is greater than 400, the report comes from function profiling. If it is less than 400, the report comes from line profiling. The type of information in the local information records given later is directly related to this value.
  4. In any one report, the local information records are always of the same type, either line information or function information.
  5. Process data from the local information records. For example, to calculate the percentage of hits on a given function, divide the value of the "Count" field in record type 6 by the total number of hits from the "Total Hits" field of record type 3.
  6. Remember that there can be only one type of local information record (either line or function information) in a report.
  7. Send the results to a file or STDOUT.


Processing Profiler Output with Microsoft Excel

PROFILER.XLM is an example Microsoft ExcelTM macro that processes a tab-delimited profiler report (generated by PLIST) and creates a graph based on the results. You will find this macro in the ..\vc\bin directory.

The PROFILER.XLM macro is composed of four sub-macros. The first two macros, in columns A and B, are helper macros that copy and preprocess the data for use by the second pair of macros in columns C and D. The macro in column C, labeled CreateColumnChart, creates a graph showing the number of times that each function or line was executed. The final macro, in column D, is CreateColumnTimeChart; it works like CreateColumnChart, but operates on timing information.


Generating the Tab-Delimited Report

To generate the tab-delimited report, use the PLIST /T option. This can be done after the normal profile run has been completed; PLIST will read the profile data from the last profiler execution. The output of PLIST /T should be redirected to a file, preferably with the .XLS extension for easy loading into Excel (Excel will interpret the tab-delimited file correctly as a text file even with the .XLS extension).


Using the PROFILER.XLM Macro

To run the macro, follow these steps from within Microsoft Excel:

  1. Open PROFILER.XLM by choosing Open from the File menu.
  2. Open the tab-delimited report that was created by PLIST by choosing Open from the File menu.
  3. If you have several open worksheets, activate the one containing the profiler data by selecting it with the mouse or by choosing its title from the Windows menu.
  4. Run the macro:
    • Press Ctrl+C for a chart based on hit counts.
    • Press Ctrl+T for a chart based on timing.

You cannot get a timing chart if the report contains only counting or coverage information.

The macro typically takes only a few seconds to execute. When it is complete, Microsoft Excel displays a 3-D bar chart based on the results in the report. You can change the chart type by using the Gallery menu.

This macro copies the data in the report to another worksheet before processing it. The original tab-delimited report is left untouched.


Changing the PROFILER.XLM Selection Criteria

The standard PROFILER.XLM macro displays hit counts greater than 0 (for Ctrl+C) and times greater than .01 millisecond (for Ctrl+T). If you need to narrow the selections without analyzing the macro, edit the formulas in cells C10 and D10.


Fortran Tools: FSPLIT and FPR

This section describes the following Fortran command-line tools:

  • FSPLIT (includes FSPLIT90)
  • FPR

FSPLIT and FSPLIT90

The FSPLIT and FSPLIT90 tools split a multi-routine Fortran file into individual files. These tools are useful if you have a large Fortran program.

Use FSPLIT90 when your program uses free-form source or Fortran 95/90 constructs. Use FSPLIT for FORTRAN 77 code. The FSPLIT and FSPLIT90 commands have the same form:

FSPLIT [ options ] [input-file...]

FSPLIT90 [ options ] [input-file...]

options
Is one of the keywords listed in the following table. If more than one option is specified, separate each with a space. The command options are:

Option | Description
-e:name | Processes only the program unit name. You can specify more than one -e name on a command line.
-extend_source | Treats the statement field of each source line as ending in column 132, instead of column 72.
-help, ? | Displays information about the FSPLIT command.
-nologo | Suppresses the copyright notice that is displayed when FSPLIT or FSPLIT90 is run.
-silent | Suppresses display of the name of each file opened (input and output files).
input-file | A Fortran source file to be split. You can specify more than one file by using a list of files. If input-file is omitted the FSPLIT or FSPLIT90 Utility reads from standard input.

input-file
A Fortran source file to be split. You can specify more than one file by using a list of files. If input-file is omitted the FSPLIT or FSPLIT90 Utility reads from standard input.

FSPLIT or FSPLIT90 splits multi-routine Fortran files into separate routine files of the form filename.for, where filename is the name of the program unit (for example: a function, subroutine, block data, or program). The name for unnamed block data subprograms has the form blkdtannn.for, where nnn is a 3-digit code. For unnamed main programs, the name has the form mainnnn.for.

If there is an error in classifying a program unit, or if filename.for already exists, the program unit is put in a file named zzznnn.for, where nnn is a 3-digit code.

Normally each subprogram unit is split into a separate file.

Avoid using the -e option for unnamed main programs and block data subprograms since you must predict the created file name.

If FSPLIT or FSPLIT90 cannot find the names specified by the -e option, an error message is written to standard error device.

The following command example splits the subprogram units readit and doit into separate files:

   FSPLIT -e readit -e doit prog.for

FPR

The FPR tool transforms files formatted according to Fortran's carriage control conventions into files formatted according to line printer conventions. The FPR command has the following form:

FPR [-f record-size] [filename]

record-size
Specifies a fixed-length record as input. The record-size must be a decimal integer.

filename
Specifies the data file to be transformed.

FPR copies the input filename onto itself, replacing the carriage control characters with characters that will produce the intended effects when printed using the PRINT command. The first character of each line determines the vertical spacing as follows:

Character | Vertical Space Before Printing
Blank | One line
0 | Two lines
1 | To first line of next page
+ | No advance
$ or ASCII NUL | One line; no return after printing

FPR interprets the first character of every line of input, even if that character is not a recognizable control character. Control characters that are not recognized are treated as blanks and result in a single line advance.

FPR handles stream and fixed-length files. Input to FPR is assumed to be a stream (Stream_LF) file, unless you specify the -f option.

No diagnostic message is issued when FPR encounters an unrecognized control character.


Introduction to the Language Reference

This manual contains the description of the Compaq Fortran (formerly DIGITAL Fortran) programming language. It contains information on language syntax and semantics, on adherence to various Fortran standards, and on extensions to those standards.

This manual is intended for experienced applications programmers who have a basic understanding of Fortran concepts and the Fortran 95/90 language.

Some familiarity with your operating system is helpful. This manual is not a Fortran or programming tutorial.

This document contains the following major sections:

Section | Description
Overview | Describes language standards, language compatibility, and Fortran 95/90 features.
Program Structure, Characters, and Source Forms | Describes program structure, the Fortran 95/90 character set, and source forms.
Data Types, Constants, and Variables | Describes intrinsic and derived data types, constants, variables (scalars and arrays), and substrings.
Expressions and Assignment Statements | Describes expressions and assignment.
Specification Statements | Describes specification statements, which declare the attributes of data objects.
Dynamic Allocation | Describes dynamic allocation of data objects.
Execution Control | Describes constructs and statements that can transfer control within a program.
Program Units and Procedures | Describes program units (including modules), subroutines and functions, and procedure interfaces.
Intrinsic Procedures | Contains general information on Visual Fortran intrinsic procedures. Each intrinsic is fully described in the A-Z Reference.
Data Transfer I/O Statements | Describes data transfer input/output (I/O) statements.
I/O Formatting | Describes the rules for I/O formatting.
File Operation I/O Statements | Describes auxiliary I/O statements you can use to perform file operations on Windows, Tru64 UNIX, and Linux systems.
Compilation Control Statements | Describes compilation control statements.
Compiler Directives | Describes compiler directives.
Scope and Association | Describes scope and association.
Obsolescent and Deleted Language Features | Describes obsolescent language features in Fortran 95 and Fortran 90.
Additional Language Features | Describes some statements and language features supported for programs written in older versions of Fortran.
Character and Key Code Charts | Describes the Visual Fortran character sets available on Windows systems.
Data Representation Models | Describes data representation models for numeric intrinsic functions.
Run-Time Library Routines on Tru64 UNIX and Linux Systems | Summarizes the library routines available for Tru64 UNIX and Linux systems.
FORTRAN 77 Syntax | Summarizes the syntax for features of the ANSI FORTRAN 77 Standard.
Summary of Language Extensions | Summarizes Compaq Fortran extensions to the Fortran 95 Standard.
A-Z Reference | Organizes the functions, subroutines, and statements available in Visual Fortran by the operations they perform. Also has descriptions of all Visual Fortran statements and intrinsics (arranged in alphabetical order).
Glossary | Contains abbreviated definitions of some commonly used terms in this manual.

Other Sources of Information

This section alphabetically lists some commercially published documents that provide reference or tutorial information on Fortran 95 and Fortran 90:

  • Fortran 90 Explained by M. Metcalf and J. Reid; published by Oxford University Press, ISBN 0-19-853772-7.

  • Fortran 90/95 Explained by M. Metcalf and J. Reid; published by Oxford University Press, ISBN 0-19-851888-9.

  • Fortran 90/95 for Scientists and Engineers by S. Chapman; published by McGraw-Hill, ISBN 0-07-011938-4.

  • Fortran 90 Handbook by J. Adams, W. Brainerd, J. Martin, B. Smith, and J. Wagener; published by Intertext Publications (McGraw-Hill), ISBN 0-07-000406-4.

  • Fortran 90 Programming by T. Ellis, I. Philips, and T. Lahey; published by Addison-Wesley, ISBN 0201-54446-6.

  • Introduction to Fortran 90/95 by Stephen J. Chapman; published by McGraw-Hill, ISBN 0-07-011969-4.

  • Programmer's Guide to Fortran 90, Second Edition by W. Brainerd, C. Goldberg, and J. Adams; published by Unicomp, ISBN 0-07-000248-7.

Compaq does not endorse these books or recommend them over other books on the same subjects.


Language Reference Conventions

This section discusses the following:

  • General Conventions
  • Syntax Conventions
  • Platform Labels

General Conventions

The Language Reference uses the following general conventions. (Note that in most cases, blanks are not significant in Fortran 95/90.)

When you see this | Here is what it means
Extensions to Fortran 95 | This color indicates extensions to the Fortran 95 Standard. These extensions may or may not be implemented by other compilers that conform to the language standard.
OUT.TXT, ANOVA.EXE, COPY,
LINK, FL32 		Uppercase (capital) letters indicate filenames and MS-DOS®-level commands used in the command console. Uppercase is also used for command-line options (unless the application accepts only lowercase).
!  Comment line
WRITE (*,*) 'Hello &
&World'
This kind of type is used for program examples, program output, and error messages within the text. An exclamation point marks the beginning of a comment in sample programs. Continuation lines are indicated by an ampersand ( & ) after the code at the end of a line to be continued and before the code on the following line.
AUTOMATIC, INTRINSIC, WRITE Bold capital letters indicate Fortran 95/90 statements, functions, subroutines, and keywords. Keywords are a required part of statement syntax, unless enclosed in brackets as explained below.
In the sentence, "The following steps occur when a DO WHILE statement is executed," the phrase DO WHILE is a Fortran 95/90 keyword.
other keywords Bold lowercase letters are used for keywords of other languages.
In the sentence, "A Fortran 95/90 subroutine is the equivalent of a function of type void in C," the word void is a keyword of C.
expression | Words in italics indicate placeholders for information that you must supply. A file-name is an example of this kind of information. Italics are also used to introduce new terms.
[optional item] | Items inside single square brackets are optional. In some examples, square brackets are used to show arrays.
{choice1 | choice2} | Braces and a vertical bar indicate a choice among two or more items. You must choose one of the items unless all of the items are also enclosed in square brackets.
s[, s]...
A horizontal ellipsis (three dots) following an item indicates that the item preceding the ellipsis can be repeated. In code examples, a horizontal ellipsis means that not all of the statements are shown.
compiler option | This term refers to Windows® options, OpenVMSTM qualifiers, and Tru64 UNIX® and Linux® options that can be used on the compiler command line.
KEY NAMES Small capital letters are used for the names of keys and key sequences, such as ENTER and CTRL+C.
A plus (+) indicates a combination of keys. For example, CTRL+E means to hold down the CTRL key while pressing the E key.
The carriage-return key, sometimes marked with a bent arrow, is referred to as ENTER.

The cursor arrow keys on the numeric keypad are called DIRECTION keys. Individual DIRECTION keys are referred to by the direction of the arrow on the key top (LEFT ARROW, RIGHT ARROW, UP ARROW, DOWN ARROW) or the name on the key top (PAGE UP, PAGE DOWN).
The key names used in this manual correspond to the names on the IBM® Personal Computer keys. Other machines may use different names.
Compatibility line | The projects or libraries listed are compatible with the language element described.
Fortran | This term refers to language information that is common to ANSI FORTRAN 77, ANSI/ISO Fortran 95 and 90, and Compaq Fortran (formerly DIGITAL Fortran).
Fortran 95/90 | This term refers to language information that is common to ANSI/ISO Fortran 95 and ANSI/ISO Fortran 90.
Fortran 95 | This term refers to language features in ANSI/ISO Fortran 95.
Fortran 90 | This term refers to language features in ANSI/ISO Fortran 90.
Compaq Fortran, DIGITAL Fortran | These terms refer to the same language.
OpenVMS, VMS | These terms refer to the same operating system.
Tru64 UNIX, DIGITAL UNIX | These terms refer to the same operating system.
Windows systems | This term refers to all supported Microsoft® Windows® operating systems. (See labels WNT and W9* in Platform Labels below.)
integer | This term refers to the INTEGER(KIND=1), INTEGER(KIND=2), INTEGER (INTEGER(KIND=4)), and INTEGER(KIND=8) data types as a group.
real | This term refers to the REAL (REAL(KIND=4)), DOUBLE PRECISION (REAL(KIND=8)), and REAL(KIND=16) data types as a group.
complex | This term refers to the COMPLEX (COMPLEX(KIND=4)), DOUBLE COMPLEX (COMPLEX(KIND=8)), and COMPLEX(KIND=16) data types as a group.
logical | This term refers to the LOGICAL(KIND=1), LOGICAL(KIND=2), LOGICAL (LOGICAL(KIND=4)), and LOGICAL(KIND=8) data types as a group.

Syntax Conventions

The Language Reference uses certain conventions for language syntax. For example, consider the following syntax for the PARAMETER statement:

PARAMETER [(] c = expr [, c = expr ] ...[)]

This syntax shows that to use this statement, you must specify the following:

  • The keyword PARAMETER
  • An optional left parenthesis
  • One or more c=expr items, where c is a named constant and expr is a value; note that a comma must appear between c=expr items.
    The three dots following the syntax means you can enter as many c=expr items as you like.
  • An optional terminating right parenthesis

The colored brackets ([ ]) indicate that the optional parentheses are an extension to standard Fortran.

Platform Labels

A platform is a combination of operating system and central processing unit (CPU) that provides a distinct environment in which to use a product (in this case, a language). For example, Microsoft® Windows® 98 on Intel® x86 is a platform.

Information applies to all supported platforms unless it is otherwise labeled for a specific platform (or platforms), as follows:

VMS | Applies to OpenVMSTM on Alpha processors.
U*X | Applies to Tru64 UNIX® and Linux® on Alpha processors.
TU*X | Applies to Tru64 UNIX on Alpha processors.
WNT | Applies to Microsoft Windows 2000 and Windows NT® 4.0 on AMDTM and Intel x86 processors, and 64-bit Windows operating systems on Intel IA-64 processors.
W9* | Applies to Microsoft Windows 98, Windows Millennium Edition (Me), and Windows 95 on AMD and x86 processors.
Alpha | Applies to operating systems on Alpha processors.
ia32 | Applies to 32-bit Windows operating systems on AMD and x86 processors (see System Requirements and Optional Software in Visual Fortran Installing and Getting Started).
ia64 | Applies to 64-bit Windows operating systems on IA-64 processors.


Overview

This chapter discusses Compaq Fortran (formerly DIGITAL Fortran) standards conformance and language compatibility, and provides an overview of Fortran 95, Fortran 90, and High Performance Fortran features.

Graphic Representation of Compaq Fortran

Fortran 95 includes Fortran 90 and most features of FORTRAN 77. Fortran 90 is a superset that includes FORTRAN 77. Compaq Fortran fully supports the Fortran 95, Fortran 90, and FORTRAN 77 Standards.

For more information, see:

  • Language Standards Conformance
  • Language Compatibility
  • Fortran 95 Features
  • Fortran 90 Features


Language Standards Conformance

Compaq Fortran conforms to American National Standard Fortran 95 (ANSI X3J3/96-007)1, American National Standard Fortran 90 (ANSI X3.198-1992)2, and includes support for the High Performance Fortran Language Specification.

The ANSI committee X3J3 is currently answering questions of interpretation of Fortran 95 and Fortran 90 language features. Any answers given by the ANSI committee that are related to features implemented in Compaq Fortran may result in changes in future releases of the Compaq Fortran compiler, even if the changes produce incompatibilities with earlier releases of Compaq Fortran (formerly DIGITAL Fortran).

Compaq Fortran provides a number of extensions to the Fortran 95 Standard. In the language reference, extensions are displayed in this color.

Compaq Fortran also includes support for programs that conform to the previous Fortran standards (ANSI X3.9-1978 and ANSI X3.0-1966), the International Standards Organization standard ISO 1539-1980 (E), the Federal Information Processing Institute standard FIPS 69-1, and the Military Standard 1753 Language Specification.

1This is the same as International Standards Organization standard ISO/IEC 1539-1:1997 (E).
2This is the same as International Standards Organization standard ISO/IEC 1539:1991 (E).


Language Compatibility

Compaq Fortran is highly compatible with Compaq Fortran 77 (formerly DIGITAL Fortran 77) on supported systems, and it is substantially compatible with PDP-11 and VAX FORTRAN 77.


Fortran 95 Features

Fortran 95 includes Fortran 90 and most features of FORTRAN 77.

Some features of FORTRAN 77 have been deleted, but they are fully supported by Compaq Fortran. These features are listed in Deleted Language Features in Fortran 95.

Other features have been identified as obsolescent in Fortran 95. These features are listed in Obsolescent Language Features in Fortran 90.

Fortran 95 features are described in the following sections:

  • New Features
  • Improved Features


New Features

The following Fortran 95 features are new to Fortran:

  • The FORALL statement and construct

    In Fortran 90, you could build array values element-by-element by using array constructors and the RESHAPE and SPREAD intrinsics. The Fortran 95 FORALL statement and construct offer an alternative method.

    FORALL allows array elements, array sections, character substrings, or pointer targets to be explicitly specified as a function of the element subscripts. A FORALL construct allows several array assignments to share the same element subscript control.

    FORALL is a generalization of WHERE. They both allow masked array assignment, but FORALL uses element subscripts, while WHERE uses the whole array.

    Compaq Fortran previously provided the FORALL statement and construct as language extensions.

  • PURE user-defined procedures

    Pure user-defined procedures do not have side effects, such as changing the value of a variable in a common block. To specify a pure procedure, use the PURE prefix in the function or subroutine statement. Pure functions are allowed in specification statements.

    Compaq Fortran previously provided pure procedures as a language extension.

  • ELEMENTAL user-defined procedures

    An elemental user-defined procedure is a restricted form of pure procedure. An elemental procedure can be passed an array, which is acted upon one element at a time. To specify an elemental procedure, use the ELEMENTAL prefix in the function or subroutine statement.

  • CPU_TIME intrinsic subroutine

    This new intrinsic subroutine returns a processor-dependent approximation of processor time.

  • NULL intrinsic function

    In Fortran 90, there was no way to assign a null value to the pointer by using a pointer assignment operation. A Fortran 90 pointer had to be explicitly allocated, nullified, or associated with a target during execution before association status could be determined.

    Fortran 95 provides the NULL intrinsic function that can be used to nullify a pointer.

  • New obsolescent features

    Fortran 95 deletes several language features that were obsolescent in Fortran 90, and identifies new obsolescent features.

    Compaq Fortran fully supports features deleted in Fortran 95.


Improved Features

The following Fortran 95 features improve previous Fortran features:

  • Derived-type structure default initialization

    In derived-type definitions, you can now specify default initial values for derived-type components.

  • Pointer initialization

    In Fortran 90, there was no way to define the initial value of a pointer. You can now specify default initialization for a pointer. See also Derived-Type Definition.

  • Automatic deallocation of allocatable arrays

    Allocatable arrays whose status is allocated upon routine exit are now automatically deallocated. For more information, see Deallocation of Allocatable Arrays.

    Compaq Fortran previously provided this feature.

  • Enhanced CEILING and FLOOR intrinsic functions

    KIND can now be specified for these intrinsic functions.

  • Enhanced MAXLOC and MINLOC intrinsic functions

    DIM can now be specified for these intrinsic functions. Compaq Fortran previously provided this feature as a language extension.

  • Enhanced SIGN intrinsic function

    When compiler option /assume:minus0 is specified, the SIGN function can now distinguish between positive and negative zero if the processor is capable of doing so.

  • Printing of -0.0

    When compiler option /assume:minus0 is specified, a floating-point value of minus zero (-0.0) can now be printed if the processor can represent it.

  • Enhanced WHERE construct

    The WHERE construct has been improved to allow nested WHERE constructs and a masked ELSEWHERE statement. WHERE constructs can now be named.

  • Generic identifier allowed in END INTERFACE statement

    The END INTERFACE statement of an interface block defining a generic routine now can specify a generic identifier.

  • Zero-length formats

    On output, when using I, B, O, Z, and F edit descriptors, the specified value of the field width can be zero. In such cases, the compiler selects the smallest possible positive actual field width that does not result in the field being filled with asterisks (*).

  • Comments allowed in namelist input

    Fortran 95 allows comments (beginning with !) in namelist input data. Compaq Fortran previously provided this feature as a language extension.


Fortran 90 Features

Fortran 90 offers significant enhancements to FORTRAN 77. Some of the features of Fortran 90 were implemented as language extensions in earlier versions of Compaq (formerly DIGITAL) Fortran.

Certain features of FORTRAN 77 have been replaced by more efficient statements and routines in Fortran 90. These features are listed in Obsolescent Features.

Although most FORTRAN 77 functionality remains unchanged in Fortran 90, some features need special handling. For more information on building Fortran programs, refer to Compatibility Information.

Fortran 90 features are described in the following sections:

  • New Features
  • Improved Features


New Features

The following Fortran 90 features are new to Fortran:

  • Free source form

    Fortran 90 provides a new free source form where line positions have no special meaning. There are no reserved columns, trailing comments can appear, and blanks have significance under certain circumstances (for example, P R O G R A M is not allowed as an alternative for PROGRAM).

    For more information, see Free Source Form.

  • Modules

    Fortran 90 provides a new form of program unit called a module, which is more powerful than (and overcomes limitations of) FORTRAN 77 block data program units.

    A module is a set of declarations that are grouped together under a single, global name. Modules let you encapsulate a set of related items such as data, procedures, and procedure interfaces, and make them available to another program unit.

    Module items can be made private to limit accessibility, provide data abstraction, and to create more secure and portable programs.

    For more information, see MODULE PROCEDURE.

  • User-defined (derived) data types and operators

    Fortran 90 lets you define new data types derived from any combination of the intrinsic data types and derived types. The derived-type object can be accessed as a whole, or its individual components can be accessed directly.

    You can extend the intrinsic operators (such as + and *) to user-defined data types, and also define new operators for operands of any type.

    For more information, see Derived Data Types and Defining Generic Operators.

  • Array operations and features

    In Fortran 90, intrinsic operators and intrinsic functions can operate on array-valued operands (whole arrays or array sections).

    New features for arrays include whole, partial, and masked array assignment (including the WHERE statement for selective assignment), and array-valued constants and expressions. You can create user-defined array-valued functions, use array constructors to specify values of a one-dimensional array, and allocate arrays dynamically (using ALLOCATABLE and POINTER attributes).

    New intrinsic procedures create multidimensional arrays, manipulate arrays, perform operations on arrays, and support computations involving arrays (for example, SUM sums the elements of an array).

    For more information, see Arrays and Intrinsic Procedures.

  • Generic user-defined procedures

    In Fortran 90, user-defined procedures can be placed in generic interface blocks. This allows the procedures to be referenced using the generic name of the block.

    Selection of a specific procedure within the block is based on the properties of the argument, the same way as specific intrinsic functions are selected based on the properties of the argument when generic intrinsic function names are used.

    For more information, see Defining Generic Names for Procedures.

  • Pointers

    Fortran 90 pointers are mechanisms that allow dynamic access and processing of data. They allow arrays to be sized dynamically and they allow structures to be linked together.

    A pointer can be of any intrinsic or derived type. When a pointer is associated with a target, it can appear in most expressions and assignments.

    For more information, see POINTER - Fortran 90 and Pointer Assignments.

  • Recursion

    Fortran 90 procedures can be recursive if the keyword RECURSIVE is specified on the FUNCTION or SUBROUTINE statement line.

    For more information, see Program Units and Procedures.

  • Interface blocks

    A Fortran 90 procedure can contain an interface block. Interface blocks can be used to do the following:

    • Describe the characteristics of an external or dummy procedure

    • Define a generic name for a procedure

    • Define a new operator (or extend an intrinsic operator)

    • Define a new form of assignment

    For more information, see Procedure Interfaces.

  • Extensibility and redundancy

    By using user-defined data types, operators, and meanings, you can extend Fortran to suit your needs. These new data types and their operations can be packaged in modules, which can be used by one or more program units to provide data abstraction.

    With the addition of new features and capabilities, some old features become redundant and may eventually be removed from the language. For example, the functionality of the ASSIGN and assigned GO TO statements can be replaced more effectively by internal procedures. The use of certain old features of Fortran can result in less than optimal performance on newer hardware architectures.

    For more information, see your user manual or programmer's guide. See also Obsolescent and Deleted Language Features.


Improved Features

The following Fortran 90 features improve previous Fortran features:

  • Additional features for source text

    Lowercase characters are now allowed in source text. A semicolon can be used to separate multiple statements on a single source line. Additional characters have been added to the Fortran character set, and names can have up to 31 characters (including underscores).

    For more information, see Program Structure, Characters, and Source Forms.

  • Improved facilities for numerical computation

    Intrinsic data types can be specified in a portable way by using a kind type parameter indicating the precision or accuracy required. There are also new intrinsic functions that allow you to specify numeric precision and inquire about precision characteristics available on a processor.

    For more information, see Data Types, Constants, and Variables and Intrinsic Procedures.

  • Optional procedure arguments

    Procedure arguments can be made optional and keywords can be used when calling procedures, allowing arguments to be listed in any order.

    For more information, see Program Units and Procedures.

  • Additional input/output features

    Fortran 90 provides additional keywords for the OPEN and INQUIRE statements. It also permits namelist formatting, and nonadvancing (stream) character-oriented input and output.

    For more information on formatting, see Data Transfer I/O Statements and on OPEN and INQUIRE, see File Operation I/O Statements.

  • Additional control constructs

    Fortran 90 provides a new control construct (CASE) and improves the DO construct. The DO construct can now use CYCLE and EXIT statements, and can have additional (or no) control clauses (for example, WHILE). All control constructs (CASE, DO, and IF) can now be named.

    For more information, see Execution Control.

  • Additional intrinsic procedures

    Fortran 90 provides many more intrinsic procedures than existed in FORTRAN 77. Many of these new intrinsics support mathematical operations on arrays, including the construction and transformation of arrays. New bit manipulation and numerical accuracy intrinsics have been added.

    For more information, see Program Units and Procedures.

  • Additional specification statements

    The following specification statements are new in Fortran 90:

    • The INTENT statement

    • The OPTIONAL statement

    • The Fortran 90 POINTER statement

    • The PUBLIC and PRIVATE statements

    • The TARGET statement

  • Additional way to specify attributes

    Fortran 90 lets you specify attributes (such as PARAMETER, SAVE, and INTRINSIC) in type declaration statements, as well as in specification statements.

    For more information, see Type Declaration Statements.

  • Scope and Association

    These concepts were implicit in FORTRAN 77, but they are explicitly defined in Fortran 90. In FORTRAN 77, the term scoping unit applies to a program unit, but Fortran 90 expands the term to include internal procedures, interface blocks, and derived- type definitions.

    For more information, see Scope and Association.


Program Structure, Characters, and Source Forms

This section contains information on the following topics:

  • An overview of program structure, including general information on statements and names
  • Character sets
  • Source forms


Program Structure

A Fortran program consists of one or more program units. A program unit is usually a sequence of statements that define the data environment and the steps necessary to perform calculations; it is terminated by an END statement.

A program unit can be either a main program, an external subprogram, a module, or a block data program unit. An executable program contains one main program, and, optionally, any number of the other kinds of program units. Program units can be separately compiled.

An external subprogram is a function or subroutine that is not contained within a main program, a module, or another subprogram. It defines a procedure to be performed and can be invoked from other program units of the Fortran program. Modules and block data program units are not executable, so they are not considered to be procedures. (Modules can contain module procedures, though, which are executable.)

Modules contain definitions that can be made accessible to other program units: data and type definitions, definitions of procedures (called module subprograms), and procedure interfaces. Module subprograms can be either functions or subroutines. They can be invoked by other module subprograms in the module, or by other program units that access the module.

A block data program unit specifies initial values for data objects in named common blocks. In Fortran 95/90, this type of program unit can be replaced by a module program unit.

Main programs, external subprograms, and module subprograms can contain internal subprograms. The entity that contains the internal subprogram is its host. Internal subprograms can be invoked only by their host or by other internal subprograms in the same host. Internal subprograms must not contain internal subprograms.

The following sections discuss Statements, Names, and Keywords.


Statements

Program statements are grouped into two general classes: executable and nonexecutable. An executable statement specifies an action to be performed. A nonexecutable statement describes program attributes, such as the arrangement and characteristics of data, as well as editing and data-conversion information.

Order of Statements in a Program Unit

The following figure shows the required order of statements in a Fortran program unit. In this figure, vertical lines separate statement types that can be interspersed. For example, you can intersperse DATA statements with executable constructs.

Horizontal lines indicate statement types that cannot be interspersed. For example, you cannot intersperse DATA statements with CONTAINS statements.
Required Order of Statements
PUBLIC and PRIVATE statements are only allowed in the scoping units of modules. In Fortran 95/90, NAMELIST statements can appear only among specification statements. However, Compaq Fortran allows them to also appear among executable statements.

The following table shows other statements restricted from different types of scoping units.

Statements Restricted in Scoping Units

Scoping Unit | Restricted Statements
Main program | ENTRY and RETURN statements
Module 1 | ENTRY, FORMAT, OPTIONAL, and INTENT statements, statement functions, and executable statements
Block data program unit | CONTAINS, ENTRY, and FORMAT statements, interface blocks, statement functions, and executable statements
Internal subprogram | CONTAINS and ENTRY statements
Interface body | CONTAINS, DATA, ENTRY, SAVE, and FORMAT statements, statement functions, and executable statements
1 The scoping unit of a module does not include any module subprograms that the module contains.


Names

Names identify entities within a Fortran program unit (such as variables, function results, common blocks, named constants, procedures, program units, namelist groups, and dummy arguments). In FORTRAN 77, names were called "symbolic names".

A name can contain letters, digits, underscores ( _ ), and the dollar sign ($) special character. The first character must be a letter or a dollar sign.

In Fortran 95/90, a name can contain up to 31 characters. Compaq Fortran allows names up to 63 characters.

The length of a module name (in MODULE and USE statements) may be restricted by your file system.

Note: Be careful when defining names that contain dollar signs.

On OpenVMS systems, naming conventions reserve names containing dollar signs to those created by Compaq. On Windows, Tru64 UNIX, and Linux systems, a dollar sign can be a symbol for command or symbol substitution in various shell and utility commands.

In an executable program, the names of the following entities are global and must be unique in the entire program:

  • Program units
  • External procedures
  • Common blocks
  • Modules

Examples

The following examples demonstrate valid and invalid names:

Valid |
NUMBER |
FIND_IT |
X |
Invalid | Explanation
5Q | Begins with a numeral.
B.4 | Contains a special character other than _ or $.
_WRONG | Begins with an underscore.

The following are all valid examples of using names:

 INTEGER (SHORT) K       !K names an integer variable
 SUBROUTINE EXAMPLE      !EXAMPLE names the subroutine
 LABEL: DO I = 1,N       !LABEL names the DO block


Keywords

A keyword can either be a part of the syntax of a statement (statement keyword), or it can be the name of a dummy argument (argument keyword). Examples of statement keywords are WRITE, INTEGER, DO, and OPEN. Examples of argument keywords are arguments to the intrinsic functions.

In the intrinsic function UNPACK (VECTOR, MASK, FIELD), for example, VECTOR, MASK, and FIELD are argument keywords. They are dummy argument names, and any variable may be substituted in their place. Dummy argument names and real argument names are discussed in Program Units and Procedures.

Keywords are not reserved. The compiler recognizes keywords by their context. For example, a program can have an array named IF, read, or Goto, even though this is not good programming practice. The only exception is the keyword PARAMETER. If you plan to use variable names beginning with PARAMETER in an assignment statement, you need to use the compiler option /altparam.

Using keyword names for variables makes programs harder to read and understand. For readability, and to reduce the possibility of hard-to-find bugs, avoid using names that look like parts of Fortran statements. Rules that describe the context in which a keyword is recognized are discussed in Program Units and Procedures.

Argument keywords are a feature of Fortran 90 that let you specify dummy argument names when calling intrinsic procedures, or anywhere an interface (either implicit or explicit) is defined. Using argument keywords can make a program more readable and easy to follow. This is described more fully in Program Units and Procedures. The syntax statements in the A-Z Reference show the dummy keywords you can use for each Fortran procedure.


Character Sets

Compaq Fortran supports the following characters:

  • The Fortran 95/90 character set which consists of the following:

    • All uppercase and lowercase letters (A through Z and a through z)
    • The numerals 0 through 9
    • The underscore ( _ )
    • The following special characters:

    Character Name Character Name
    blank or <Tab> Blank (space) or tab : Colon
    = Equal sign ! Exclamation point
    + Plus sign " Quotation mark
    - Minus sign % Percent sign
    * Asterisk & Ampersand
    / Slash ; Semicolon
    ( Left parenthesis < Less than
    ) Right parenthesis > Greater than
    , Comma ? Question mark
    . Period (decimal point) $ Dollar sign (currency symbol)
    ' Apostrophe

  • Other printable characters

    Printable characters include the tab character (09 hex), ASCII characters with codes in the range 20(hex) through 7E(hex), and characters in certain special character sets.

    Printable characters that are not in the Fortran 95/90 character set can only appear in comments, character constants, Hollerith constants, character string edit descriptors, and input/output records.

Uppercase and lowercase letters are treated as equivalent when used to specify program behavior (except in character constants and Hollerith constants).

For more detailed information on character sets and default character types, see Data Types, Constants, and Variables and Using National Language Support Routines. For more information on the ASCII character set, see ASCII and Key Code Charts.


Source Forms

Within a program, source code can be in free, fixed, or tab form. Fixed or tab forms must not be mixed with free form in the same source program, but different source forms can be used in different source programs.

All source forms allow lowercase characters to be used as an alternative to uppercase characters.

Several characters are indicators in source code (unless they appear within a comment or a Hollerith or character constant). The following are rules for indicators in all source forms:

  • Comment indicator

    A comment indicator can precede the first statement of a program unit and appear anywhere within a program unit. If the comment indicator appears within a source line, the comment extends to the end of the line.

    An all blank line is also a comment line.

    Comments have no effect on the interpretation of the program unit.

    For more information, see comment indicators in free source form, or fixed and tab source forms.

  • Statement separator

    More than one statement (or partial statement) can appear on a single source line if a statement separator is placed between the statements. The statement separator is a semicolon character (;).

    Consecutive semicolons (with or without intervening blanks) are considered to be one semicolon.

    If a semicolon is the last character on a line, or the last character before a comment, it is ignored.

  • Continuation indicator

    A statement can be continued for more than one line by placing a continuation indicator on the line. Compaq Fortran allows up to 511 continuation lines in a source program.

    Comments can occur within a continued statement, but comment lines cannot be continued.

    Within a program unit, the END statement cannot be continued, and no other statement in the program unit can have an initial line that appears to be the program unit END statement.

    For more information, see continuation indicators in free source form, or fixed and tab source forms.

The following table summarizes characters used as indicators in source forms.

Indicators in Source Forms

Source Item | Indicator 1 | Source Form | Position
Comment | ! | All forms | Anywhere in source code
Comment line | ! | Free | At the beginning of the source line
 | !, C, or * | Fixed | In column 1
 |  | Tab | In column 1
Continuation line 2 |  | Free | At the end of the source line
 | Any character except zero or blank | Fixed | In column 6
 | Any digit except zero | Tab | After the first tab
Statement separator | ; | All forms | Between statements on the same line
Statement label | 1 to 5 decimal digits | Free | Before a statement
 |  | Fixed | In columns 1 through 5
 |  | Tab | Before the first tab
A debugging statement3 | D | Fixed | In column 1
 |  | Tab | In column 1
1 If the character appears in a Hollerith or character constant, it is not an indicator and is ignored. 2 For all forms, up to 511 continuation lines are allowed. 3 Fixed and tab forms only.

Fixed source form is the default for files with a .FOR extension. You can select free source form in one of three ways:

  • Use the file extension .F90 for your source file.
  • Use the compiler option /free.
  • Use the FREEFORM compiler directive in the source file.

Source form and line length can be changed at any time by using the FREEFORM, NOFREEFORM, or FIXEDFORMLINESIZE directives. The change remains in effect until the end of the file, or until changed again.

Source code can be written so that it is useable for all source forms.

Statement Labels

A statement label (or statement number) identifies a statement so that other statements can refer to it, either to get information or to transfer control. A label can precede any statement that is not part of another statement.

A statement label must be one to five decimal digits long; blanks and leading zeros are ignored. An all-zero statement label is invalid, and a blank statement cannot be labeled.

Labeled FORMAT and labeled executable statements are the only statements that can be referred to by other statements. FORMAT statements are referred to only in the format specifier of an I/O statement or in an ASSIGN statement. Two statements within a scoping unit cannot have the same label.


Free Source Form

In free source form, statements are not limited to specific positions on a source line, and a line can contain from 0 to 132 characters.

Blank characters are significant in free source form. The following are rules for blank characters:

  • Blank characters must not appear in lexical tokens, except within a character context. For example, there can be no blanks between the exponentiation operator **. Blank characters can be used freely between lexical tokens to improve legibility.

  • Blank characters must be used to separate names, constants, or labels from adjacent keywords, names, constants, or labels. For example, consider the following statements:
      INTEGER NUM
  GO TO 40
  20 DO K=1,8

    The blanks are required after INTEGER, TO, 20, and DO.

  • Some adjacent keywords must have one or more blank characters between them. Others do not require any; for example, BLOCK DATA can also be spelled BLOCKDATA. The following list shows which keywords have optional or required blanks:

    Optional Blanks | Required Blanks
    BLOCK DATA | CASE DEFAULT
    DOUBLE COMPLEX | DO WHILE
    DOUBLE PRECISION | IMPLICIT type-specifier
    ELSE IF | IMPLICIT NONE
    END BLOCK DATA | INTERFACE ASSIGNMENT
    END DO | INTERFACE OPERATOR
    END FILE | MODULE PROCEDURE
    END FORALL | RECURSIVE FUNCTION
    END FUNCTION | RECURSIVE SUBROUTINE
    END IF | RECURSIVE type-specifier FUNCTION
    END INTERFACE | type-specifier FUNCTION
    END MODULE | type-specifier RECURSIVE FUNCTION
    END PROGRAM
    END SELECT
    END SUBROUTINE
    END TYPE
    END WHERE
    GO TO
    IN OUT
    SELECT CASE

For information on statement separators (;) in all forms, see Source Forms.

Comment Indicator

In free source form, the exclamation point character (!) indicates a comment if it is within a source line, or a comment line if it is the first character in a source line.

Continuation Indicator

In free source form, the ampersand character (&) indicates a continuation line (unless it appears in a Hollerith or character constant, or within a comment). The continuation line is the first noncomment line following the ampersand. Although Fortran 90 permits up to 39 continuation lines in free-form programs, Compaq Fortran allows up to 511 continuation lines.

The following shows a continued statement:

  TCOSH(Y) = EXP(Y) + &        ! The initial statement line
             EXP(-Y)           ! A continuation line

If the first nonblank character on the next noncomment line is an ampersand, the statement continues at the character following the ampersand. For example, the preceding example can be written as follows:

  TCOSH(Y) = EXP(Y) + &
            & EXP(-Y)

If a lexical token must be continued, the first nonblank character on the next noncomment line must be an ampersand followed immediately by the rest of the token. For example:

    TCOSH(Y) = EXP(Y) + EX&
          &P(-Y)

If you continue a character constant, an ampersand must be the first non-blank character of the continued line; the statement continues with the next character following the ampersand. For example:

  ADVERTISER = "Davis, O'Brien, Chalmers & Peter&
                   &son"
  ARCHITECT  = "O'Connor, Emerson, and Davis&
                 &  Associates"

If the ampersand is omitted on the continued line, the statement continues with the first non-blank character in the continued line. So, in the preceding example, the whitespace before "Associates" would be ignored.

The ampersand cannot be the only nonblank character in a line, or the only nonblank character before a comment; an ampersand in a comment is ignored.

For details on the general rules for all source forms, see Source Forms.


Fixed and Tab Source Forms

In Fortran 95, fixed source form is identified as obsolescent.

In fixed and tab source forms, there are restrictions on where a statement can appear within a line.

By default, a statement can extend to character position 72. In this case, any text following position 72 is ignored and no warning message is printed. You can specify compiler option /extend_source to extend source lines to character position 132.

Except in a character context, blanks are not significant and can be used freely throughout the program for maximum legibility.

Some Fortran compilers use blanks to pad short source lines out to 72 characters. By default, Compaq Fortran does not. If portability is a concern, you can use the concatenation operator to prevent source lines from being padded by other Fortran compilers (see the example in "Continuation Indicator" below) or you can force short source lines to be padded by using the /pad_source compiler option.

Comment Indicator

In fixed and tab source forms, the exclamation point character (!) indicates a comment if it is within a source line. (It must not appear in column 6 of a fixed form line; that column is reserved for a continuation indicator.)

The letter C (or c), an asterisk (*), or an exclamation point (!) indicates a comment line when it appears in column 1 of a source line.

Continuation Indicator

In fixed and tab source forms, a continuation line is indicated by one of the following:

  • For fixed form: Any character (except a zero or blank) in column 6 of a source line

  • For tab form: Any digit (except zero) after the first tab

The compiler considers the characters following the continuation indicator to be part of the previous line. Although Fortran 95/90 permits up to 19 continuation lines in a fixed-form program, Compaq Fortran allows up to 511 continuation lines.

If a zero or blank is used as a continuation indicator, the compiler considers the line to be an initial line of a Fortran statement.

The statement label field of a continuation line must be blank (except in the case of a debugging statement).

When long character or Hollerith constants are continued across lines, portability problems can occur. Use the concatenation operator to avoid such problems. For example:

      PRINT *, 'This is a very long character constant '//
     +         'which is safely continued across lines'

Use this same method when initializing data with long character or Hollerith constants. For example:

      CHARACTER*(*) LONG_CONST
      PARAMETER (LONG_CONST = 'This is a very long '//
     + 'character constant which is safely continued '//
     + 'across lines')
      CHARACTER*100 LONG_VAL
      DATA LONG_VAL /LONG_CONST/

Hollerith constants must be converted to character constants before using the concatenation method of line continuation.

Debugging Statement Indicator

In fixed and tab source forms, the statement label field can contain a statement label, a comment indicator, or a debugging statement indicator.

The letter D indicates a debugging statement when it appears in column 1 of a source line. The initial line of the debugging statement can contain a statement label in the remaining columns of the statement label field.

If a debugging statement is continued onto more than one line, every continuation line must begin with a D and a continuation indicator.

By default, the compiler treats debugging statements as comments. However, you can specify the /d_lines option to force the compiler to treat debugging statements as source text to be compiled.

The following sections discuss Fixed-format lines and Tab-format lines.

For details on the general rules for all source forms, see Source Forms.


Fixed-Format Lines

In fixed source form, a source line has columns divided into fields for statement labels, continuation indicators, statement text, and sequence numbers. Each column represents a single character.

The column positions for each field follow:

Field | Column
Statement label | 1 through 5
Continuation indicator | 6
Statement | 7 through 72 (or 132 with the /extend_source compiler option)
Sequence number | 73 through 80

By default, a sequence number or other identifying information can appear in columns 73 through 80 of any fixed-format line in a Compaq Fortran program. The compiler ignores the characters in this field.

If you extend the statement field to position 132, the sequence number field does not exist.

Note: If you use the sequence number field, do not use tabs anywhere in the source line, or the compiler may interpret the sequence numbers as part of the statement field in your program.

For details on the general rules for all source forms, see Source Forms.

For details on the general rules for fixed and tab source forms, see Fixed and Tab Source Forms.


Tab-Format Lines

In tab source form, you can specify a statement label field, a continuation indicator field, and a statement field, but not a sequence number field.

The following figure shows equivalent source lines coded with tab and fixed source form.

Line Formatting Example

The statement label field precedes the first tab character. The continuation indicator field and statement field follow the first tab character.

The continuation indicator is any nonzero digit. The statement field can contain any Fortran statement. A Fortran statement cannot start with a digit.

If a statement is continued, a continuation indicator must be the first character (following the first tab) on the continuation line.

Many text editors and terminals advance the terminal print carriage to a predefined print position when you press the <Tab> key. However, the Compaq Fortran compiler does not interpret the tab character in this way. It treats the tab character in a statement field the same way it treats a blank character. In the source listing that the compiler produces, the tab causes the character that follows to be printed at the next tab stop (usually located at columns 9, 17, 25, 33, and so on).

Note: If you use the sequence number field, do not use tabs anywhere in the source line, or the compiler may interpret the sequence numbers as part of the statement field in your program.

For details on the general rules for all source forms, see Source Forms.

For details on the general rules for fixed and tab source forms, see Fixed and Tab Source Forms.


Source Code Useable for All Source Forms

To write source code that is useable for all source forms (free, fixed, or tab), follow these rules:

Blanks | Treat as significant (see Free Source Form).
Statement labels | Place in column positions 1 through 5 (or before the first tab character).
Statements | Start in column position 7 (or after the first tab character).
Comment indicator | Use only !. Place anywhere except in column position 6 (or immediately after the first tab character).
Continuation indicator | Use only &. Place in column position 73 of the initial line and each continuation line, and in column 6 of each continuation line (no tab character can precede the ampersand in column 6).

The following example is valid for all source forms:

Column:

12345678...                                                            73
_________________________________________________________________________

! Define the user function MY_SIN

      DOUBLE PRECISION FUNCTION MY_SIN(X)
        MY_SIN = X - X**3/FACTOR(3) + X**5/FACTOR(5)                    &
     &          - X**7/FACTOR(7)
      CONTAINS
        INTEGER FUNCTION FACTOR(N)
         FACTOR = 1
         DO 10 I = N, 1, -1
  10     FACTOR = FACTOR * I
        END FUNCTION FACTOR
      END FUNCTION MY_SIN


Data Types, Constants, and Variables

Each constant, variable, array, expression, or function reference in a Fortran statement has a data type. The data type of these items can be inherent in their construction, implied by convention, or explicitly declared.

Each data type has the following properties:

  • A name

    The names of the intrinsic data types are predefined, while the names of derived types are defined in derived-type definitions. Data objects (constants, variables, or parts of constants or variables) are declared using the name of the data type.

  • A set of associated values

    Each data type has a set of valid values. Integer and real data types have a range of valid values. Complex and derived types have sets of values that are combinations of the values of their individual components.

  • A way to represent constant values for the data type

    A constant is a data object with a fixed value that cannot be changed during program execution. The value of a constant can be a numeric value, a logical value, or a character string.

    A constant that does not have a name is a literal constant. A literal constant must be of intrinsic type and it cannot be array-valued.

    A constant that has a name is a named constant. A named constant can be of any type, including derived type, and it can be array-valued. A named constant has the PARAMETER attribute and is specified in a type declaration statement or PARAMETER statement.

  • A set of operations to manipulate and interpret these values

    The data type of a variable determines the operations that can be used to manipulate it. Besides intrinsic operators and operations, you can also define operators and operations.

This chapter contains information on the following topics:

  • Intrinsic data types and constants
  • Derived data types
  • Binary, octal, hexadecimal, and Hollerith constants
  • Variables, including arrays

For More Information:

  • See Type Declaration Statements.
  • See Defined Operations.
  • See the PARAMETER attribute and statement
  • On valid operations for data types, see Expressions.
  • On ranges for numeric literal constants, see your programmer's guide.
  • On named constants, see PARAMETER.


Intrinsic Data Types

Compaq Fortran provides the following intrinsic data types:

  • INTEGER

    There are four kind parameters for data of type integer:

    • INTEGER([KIND=]1) or INTEGER*1
    • INTEGER([KIND=]2) or INTEGER*2
    • INTEGER([KIND=]4) or INTEGER*4
    • INTEGER([KIND=]8) or INTEGER*8

  • REAL

    There are three kind parameters for data of type real:

    • REAL([KIND=]4) or REAL*4
    • REAL([KIND=]8) or REAL*8
    • REAL([KIND=]16) or REAL*16

      This kind is only available on OpenVMS, Tru64 UNIX, and Linux systems.

  • DOUBLE PRECISION

    No kind parameter is permitted for data declared with type DOUBLE PRECISION. This data type is the same as REAL([KIND=]8).

  • COMPLEX

    There are two kind parameters for data of type complex:

    • COMPLEX([KIND=]4) or COMPLEX*8
    • COMPLEX([KIND=]8) or COMPLEX*16
    • COMPLEX([KIND=]16) or COMPLEX*32

      This kind is only available on OpenVMS, Tru64 UNIX, and Linux systems.

  • DOUBLE COMPLEX

    No kind parameter is permitted for data declared with type DOUBLE COMPLEX. This data type is the same as COMPLEX([KIND=]8).

  • LOGICAL

    There are four kind parameters for data of type logical:

    • LOGICAL([KIND=]1) or LOGICAL*1
    • LOGICAL([KIND=]2) or LOGICAL*2
    • LOGICAL([KIND=]4) or LOGICAL*4
    • LOGICAL([KIND=]8) or LOGICAL*8

  • CHARACTER

    There is one kind parameter for data of type character: CHARACTER([KIND=]1).

  • BYTE

    This is a 1-byte value; the data type is equivalent to INTEGER([KIND=]1).

The intrinsic function KIND can be used to determine the kind type parameter of a representation method.

For more portable programs, you should not use the forms INTEGER([KIND=]n) or REAL([KIND=]n). You should instead define a PARAMETER constant using the SELECTED_INT_KIND or SELECTED_REAL_KIND function, whichever is appropriate. For example, the following statements define a PARAMETER constant for an INTEGER kind that has 9 digits:

  INTEGER, PARAMETER :: MY_INT_KIND = SELECTED_INT_KIND(9)
    ...
  INTEGER(MY_INT_KIND) :: J
    ...

Note that the syntax :: is used in type declaration statements.

The following sections describe the intrinsic data types and forms for literal constants for each type.

For More Information:

  • See the KIND intrinsic function.
  • On declaration statements for intrinsic data types, see Declaration Statements for Noncharacter Types and Declaration Statements for Character Types.
  • On operations for intrinsic data types, see Expressions.
  • On storage requirements for intrinsic data types, see the Data Type Storage Requirements table.


Integer Data Types

Integer data types can be specified as follows:

INTEGER
INTEGER([KIND=]n)
INTEGER*n

n
Is kind 1, 2, 4, or 8.

If a kind parameter is specified, the integer has the kind specified. If a kind parameter is not specified, integer constants are interpreted as follows:

  • If the integer constant is within the default integer kind range, the kind is default integer.

  • If the integer constant is outside the default integer kind range, the kind of the integer constant is the smallest integer kind which holds the constant.

You can change the result of a default specification by using the /integer_size:size compiler option or the INTEGER compiler directive.

The intrinsic inquiry function KIND returns the kind type parameter, if you do not know it. You can use the intrinsic function SELECTED_INT_KIND to find the kind values that provide a given range of integer values. The decimal exponent range is returned by the intrinsic function RANGE.

For more information on the integer data type, see Integer Constants.

Examples

The following examples show ways an integer variable can be declared.
An entity-oriented example is:

 INTEGER, DIMENSION(:), POINTER :: days, hours
 INTEGER(2), POINTER :: k, limit
 INTEGER(1), DIMENSION(10) :: min

An attribute-oriented example is:

 INTEGER days, hours
 INTEGER(2) k, limit
 INTEGER(1) min
 DIMENSION days(:), hours(:), min (10)
 POINTER days, hours, k, limit

An integer can be used in certain cases when a logical value is expected, such as in a logical expression evaluating a condition, as in the following:

 INTEGER I, X
 READ (*,*) I
 IF (I) THEN
   X = 1
 END IF


Integer Constants

An integer constant is a whole number with no decimal point. It can have a leading sign and is interpreted as a decimal number.

Integer constants take the following form:

[s]n[n...][ _k]

s
Is a sign; required if negative (-), optional if positive (+).

n
Is a decimal digit (0 through 9). Any leading zeros are ignored.

k
Is the optional kind parameter: 1 for INTEGER(1), 2 for INTEGER(2), 4 for INTEGER(4), or 8 for INTEGER(8). It must be preceded by an underscore ( _ ).

An unsigned constant is assumed to be nonnegative.

Integer constants are interpreted as decimal values (base 10) by default. To specify a constant that is not in base 10, use the following extension syntax:

[s] [[base] #] nnn...

s
Is an optional plus (+) or minus (-) sign.

base
Is any constant from 2 through 36.

If base is omitted but # is specified, the integer is interpreted in base 16. If both base and # are omitted, the integer is interpreted in base 10.

For bases 11 through 36, the letters A through Z represent numbers greater than 9. For example, for base 36, A represents 10, B represents 11, C represents 12, and so on, through Z, which represents 35. The case of the letters is not significant.

Examples

The following examples show valid and invalid integer (base 10) constants:

Valid |
0 |
-127 |
+32123 |
47_2 |
Invalid | Explanation
9999999999999999999 | Number too large.
3.14 | Decimal point not allowed; this is a valid REAL constant.
32,767 | Comma not allowed.
33_3 | 3 is not a valid kind type for integers.

The following seven integers are all assigned a value equal to 3,994,575 decimal:

 I = 2#1111001111001111001111
 m = 7#45644664
 J = +8#17171717
 K = #3CF3CF
 n = +17#2DE110
 L = 3994575
 index = 36#2DM8F

You can use integer constants to assign values to data. The following table shows assignments to different data and lists the integer and hexadecimal values in the data:

Fortran Assignment    Integer Value in Data    Hexadecimal Value in Data

LOGICAL(1)X
INTEGER(1)X

X = -128                         -128                 Z'80'
X =  127                          127                 Z'7F'
X =  255                           -1                 Z'FF'

LOGICAL(2)X
INTEGER(2)X

X = 255                           255                 Z'FF'
X = -32768                     -32768                 Z'8000'
X = 32767                       32767                 Z'7FFF'
X = 65535                          -1                 Z'FFFF'


Real Data Types

Real data types can be specified as follows:

REAL
REAL([KIND=]n)
REAL*n
DOUBLE PRECISION

n
Is kind 4, 8, or 16. Kind 16 is only available on OpenVMS, Tru64 UNIX, and Linux systems.

If a kind parameter is specified, the real constant has the kind specified. If a kind parameter is not specified, the kind is default real.

DOUBLE PRECISION is REAL(8). No kind parameter is permitted for data declared with type DOUBLE PRECISION.

You can change the result of a default specification by using the /real_size:size compiler option or the REAL compiler directive.

The intrinsic inquiry function KIND returns the kind type parameter. The intrinsic inquiry function RANGE returns the decimal exponent range, and the intrinsic function PRECISION returns the decimal precision. You can use the intrinsic function SELECTED_REAL_KIND to find the kind values that provide a given precision and exponent range.

For more information on real data types, see
General Rules for Real Constants,
REAL(4) Constants,
REAL(8) or DOUBLE PRECISION Constants, and
REAL(16) Constants (VMS, U*X).

Examples

The following examples show how real variables can be declared.
An entity-oriented example is:

 REAL (KIND = high), OPTIONAL :: testval
 REAL, SAVE :: a(10), b(20,30)

An attribute-oriented example is:

 REAL (KIND = high) testval
 REAL a(10), b(20,30)
 OPTIONAL testval
 SAVE a, b


General Rules for Real Constants

A real constant approximates the value of a mathematical real number. The value of the constant can be positive, zero, or negative.

The following is the general form of a real constant with no exponent part:

[s]n[n...][ _k]

A real constant with an exponent part has one of the following forms:

[s]n[n...]E[s]nn...[_k]
[s]n[n...]D[s]nn...
[s]n[n...]Q[s]nn...

s
Is a sign; required if negative (-), optional if positive (+).

n
Is a decimal digit (0 through 9). A decimal point must appear if the real constant has no exponent part.

k
Is the optional kind parameter: 4 for REAL(4), 8 for REAL(8), or 16 for REAL(16) (VMS, U*X). It must be preceded by an underscore ( _ ).

Rules and Behavior

Leading zeros (zeros to the left of the first nonzero digit) are ignored in counting significant digits. For example, in the constant 0.00001234567, all of the nonzero digits, and none of the zeros, are significant. (See the following sections for the number of significant digits each kind type parameter typically has).

The exponent represents a power of 10 by which the preceding real or integer constant is to be multiplied (for example, 1.0E6 represents the value 1.0 * 10**6).

A real constant with no exponent part and no kind type parameter is (by default) a single-precision (REAL(4)) constant. You can change the default behavior by specifying the compiler option /fpconstant.

If the real constant has no exponent part, a decimal point must appear in the string (anywhere before the optional kind parameter). If there is an exponent part, a decimal point is optional in the string preceding the exponent part; the exponent part must not contain a decimal point.

The exponent letter E denotes a single-precision real (REAL(4)) constant, unless the optional kind parameter specifies otherwise. For example, -9.E2_8 is a double-precision constant (which can also be written as -9.D2).

The exponent letter D denotes a double-precision real (REAL(8)) constant.

On OpenVMS, Tru64 UNIX, and Linux systems, the exponent letter Q denotes a quad-precision real (REAL(16)) constant.

A minus sign must appear before a negative real constant; a plus sign is optional before a positive constant. Similarly, a minus sign must appear between the exponent letter (E, D, or Q ) and a negative exponent, whereas a plus sign is optional between the exponent letter and a positive exponent.

If the real constant includes an exponent letter, the exponent field cannot be omitted, but it can be zero.

To specify a real constant using both an exponent letter and a kind parameter, the exponent letter must be E, and the kind parameter must follow the exponent part.


REAL(4) Constants

A single-precision REAL constant occupies four bytes of memory. The number of digits is unlimited, but typically only the leftmost seven digits are significant.

On Tru64 UNIX, Linux, and Windows systems, IEEE® S_floating format is used. On OpenVMS systems, either Compaq VAX F_floating or IEEE S_floating format is used, depending on the compiler option specified.

Examples

The following examples show valid and invalid REAL(4) constants:

Valid |
3.14159 |
3.14159_4 |
621712._4 |
-.00127 |
+5.0E3 |
2E-3_4 |
Invalid | Explanation
1,234,567. | Commas not allowed.
325E-47 | Too small for REAL; this is a valid DOUBLE PRECISION constant.
-47.E47 | Too large for REAL; this is a valid DOUBLE PRECISION constant.
625._6 | 6 is not a valid kind for reals.
100 | Decimal point missing; this is a valid integer constant.
$25.00 | Special character not allowed.

For More Information:

  • See General Rules for Real Constants.
  • On the format and range of REAL(4) data, see your programmer's guide.
  • On compiler options affecting REAL data, see your programmer's guide.


REAL(8) or DOUBLE PRECISION Constants

A REAL(8) or DOUBLE PRECISION constant has more than twice the accuracy of a REAL(4) number, and greater range.

A REAL(8) or DOUBLE PRECISION constant occupies eight bytes of memory. The number of digits that precede the exponent is unlimited, but typically only the leftmost 15 digits are significant.

On Tru64 UNIX, Linux, and Windows systems, IEEE T_floating format is used. On OpenVMS systems, either Compaq VAX D_floating, G_floating, or IEEE T_floating format is used, depending on the compiler option specified.

Examples

The following examples show valid and invalid REAL(8) or DOUBLE PRECISION constants:

Valid |
123456789D+5 |
123456789E+5_8 |
+2.7843D00 |
-.522D-12 |
2E200_8 |
2.3_8 |
3.4E7_8 |
Invalid | Explanation
-.25D0_2 | 2 is not a valid kind for reals.
+2.7182812846182 | No D exponent designator is present; this is a valid single-precision constant.
1234567890D45 | Too large for D_floating format; valid for G_floating and T_floating format.
123456789.D400 | Too large for any double-precision format.
123456789.D-400 | Too small for any double-precision format.

For More Information:

  • See General Rules for Real Constants.
  • On the format and range of DOUBLE PRECISION (REAL(8)) data, see your programmer's guide.
  • On compiler options affecting DOUBLE PRECISION (REAL(8)) data, see your programmer's guide.


REAL(16) Constants (VMS, U*X)

A REAL(16) constant has more than four times the accuracy of a REAL(4) number, and a greater range.

A REAL(16) constant occupies 16 bytes of memory. The number of digits that precede the exponent is unlimited, but typically only the leftmost 33 digits are significant.

Examples

The following examples demonstrate valid and invalid REAL(16) constants:

Valid |
123456789Q4000 |
-1.23Q-400 |
+2.72Q0 |
1.88_16 |
Invalid | Explanation
1.Q5000 | Too large.
1.Q-5000 | Too small.

For More Information:

  • See General Rules for Real Constants.
  • On the format and range of REAL(16) data, see your user manual.


Complex Data Types

Complex data types can be specified as follows:

COMPLEX
COMPLEX([KIND=]n)
COMPLEX*s
DOUBLE COMPLEX

n
Is kind 4, 8, or 16. Kind 16 is only available on OpenVMS, Tru64 UNIX, and Linux systems.

s
Is 8, 16, or 32. COMPLEX(4) is specified as COMPLEX*8; COMPLEX(8) is specified as COMPLEX*16; COMPLEX(16) is specified as COMPLEX*32.

If a kind parameter is specified, the complex constant has the kind specified. If no kind parameter is specified, the kind of both parts is default real, and the constant is of type default complex.

DOUBLE COMPLEX is COMPLEX(8). No kind parameter is permitted for data declared with type DOUBLE COMPLEX.

For more information on complex data types, see General Rules for Complex Constants, COMPLEX(4) Constants, and COMPLEX(8) or DOUBLE COMPLEX Constants.

Examples

The following examples show how complex variables can be declared.
An entity-oriented example is:

 COMPLEX (4), DIMENSION (8) :: cz, cq

An attribute-oriented example is:

 COMPLEX(4) cz, cq
 DIMENSION(8) cz, cq


General Rules for Complex Constants

A complex constant approximates the value of a mathematical complex number. The constant is a pair of real or integer values, separated by a comma, and enclosed in parentheses. The first constant represents the real part of that number; the second constant represents the imaginary part.

The following is the general form of a complex constant:

(c,c)

c
Is as follows:

  • For COMPLEX(4) constants, c is an integer or REAL(4) constant.

  • For COMPLEX(8) constants, c is an integer, REAL(4) constant, or DOUBLE PRECISION (REAL(8)) constant. At least one of the pair must be DOUBLE PRECISION.

  • For COMPLEX(16) constants (VMS, U*X), c is an integer, REAL(4) constant, REAL(8) constant, or REAL(16) constant. At least one of the pair must be a REAL(16) constant.

Note that the comma and parentheses are required.


COMPLEX(4) Constants

A COMPLEX(4) constant is a pair of integer or single-precision real constants that represent a complex number.

A COMPLEX(4) constant occupies eight bytes of memory and is interpreted as a complex number.

If the real and imaginary part of a complex literal constant are both real, the kind parameter value is that of the part with the greater decimal precision.

The rules for REAL(4) constants apply to REAL(4) constants used in COMPLEX constants. (See General Rules for Complex Constants and REAL(4) Constants for the rules on forming REAL(4) constants.)

The REAL(4) constants in a COMPLEX constant have one of the following formats:

  • On Tru64 UNIX, Linux, and Windows systems: IEEE S_floating format
  • On OpenVMS systems: Compaq VAX F_floating or IEEE S_ floating format (depending on the compiler option specified)

Examples

The following examples demonstrate valid and invalid COMPLEX(4) constants:

Valid |
(1.7039,-1.70391) |
(44.36_4,-12.2E16_4) |
(+12739E3,0.) |
(1,2) |
Invalid | Explanation
(1.23,) | Missing second integer or single-precision real constant.
(1.0, 2H12) | Hollerith constant not allowed.

For More Information:

  • See General Rules for Complex Constants.
  • On the format and range of COMPLEX (COMPLEX(4)) data, see your programmer's guide.
  • On compiler options affecting REAL data, see your programmer's guide.


COMPLEX(8) or DOUBLE COMPLEX Constants

A COMPLEX(8) or DOUBLE COMPLEX constant is a pair of constants that represents a complex number. One of the pair must be a double-precision real constant, the other can be an integer, single-precision real, or double-precision real constant.

A COMPLEX(8) or DOUBLE COMPLEX constant occupies 16 bytes of memory and is interpreted as a complex number.

The rules for DOUBLE PRECISION (REAL(8)) constants also apply to the double precision portion of COMPLEX(8) or DOUBLE COMPLEX constants. (See General Rules for Complex Constants and REAL(8) or DOUBLE PRECISION Constants for the rules on forming DOUBLE PRECISION constants.)

The DOUBLE PRECISION constants in a COMPLEX(8) or DOUBLE COMPLEX constant have one of the following formats:

  • On Tru64 UNIX, Linux, and Windows systems: IEEE T_floating format
  • On OpenVMS systems: Compaq VAX D_floating, G_floating, or IEEE T_floating format (depending on the compiler option specified)

Examples

The following examples demonstrate valid and invalid COMPLEX(8) or DOUBLE COMPLEX constants:

Valid |
(1.7039,-1.7039D0) |
(547.3E0_8,-1.44_8) |
(1.7039E0,-1.7039D0) |
(+12739D3,0.D0) |
Invalid | Explanation
(1.23D0,) | Second constant missing.
(1D1,2H12) | Hollerith constants not allowed.
(1,1.2) | Neither constant is DOUBLE PRECISION; this is a valid single-precision constant.

For More Information:

  • See General Rules for Complex Constants.
  • On the format and range of DOUBLE COMPLEX data, see your programmer's guide.
  • On compiler options affecting DOUBLE COMPLEX data, see your programmer's guide.


COMPLEX(16) Constants (VMS, U*X)

A COMPLEX(16) constant is a pair of constants that represents a complex number. One of the pair must be a REAL(16) constant, the other can be an integer, single-precision real, or double-precision real constant.

A COMPLEX(16) constant occupies 32 bytes of memory and is interpreted as a complex number.

The rules for REAL(16) constants apply to REAL(16) constants used in COMPLEX constants. (See General Rules for Complex Constants and REAL(16) Constants for the rules on forming REAL(16) constants.)

The REAL(16) constants in a COMPLEX constant have one of the following formats:

  • On Tru64 UNIX and Linux systems: IEEE X_floating format
  • On OpenVMS systems: Compaq VAX X_floating or IEEE X_ floating format (depending on the compiler option specified)

Examples

The following examples demonstrate valid and invalid COMPLEX(16) constants:

Valid |
(1.7039,-1.7039Q2) |
(547.3E0_16,-1.44) |
(+12739D3,0.Q0) |
Invalid | Explanation
(1.23Q0,) | Second constant missing.
(1D1,2H12) | Hollerith constants not allowed.
(1.7039E0,-1.7039D0) | Neither constant is REAL(16); this is a valid double-precision constant.

For More Information:

  • See General Rules for Complex Constants.
  • On the format and range of COMPLEX(16) data, see your programmer's guide.
  • On compiler options affecting REAL data, see your programmer's guide.


Logical Data Types

Logical data types can be specified as follows:

LOGICAL
LOGICAL([KIND=]n)
LOGICAL*n

n
Is kind 1, 2, 4, or 8.

If a kind parameter is specified, the logical constant has the kind specified. If no kind parameter is specified, the kind of the constant is default logical.

For more information on logical data types, see Logical Constants.

Examples

The following examples show how logical variables can be declared.
An entity-oriented example is:

 LOGICAL, ALLOCATABLE :: flag1, flag2
 LOGICAL (KIND = byte), SAVE :: doit, dont

An attribute-oriented example is:

 LOGICAL flag1, flag2
 LOGICAL (KIND = byte) doit, dont
 ALLOCATABLE flag1, flag2
 SAVE doit, dont


Logical Constants

A logical constant represents only the logical values true or false, and takes one of the following forms:

.TRUE.[_k]
.FALSE.[_k]

k
Is the optional kind parameter: 1 for LOGICAL(1), 2 for LOGICAL(2), 4 for LOGICAL(4), or 8 for LOGICAL(8). It must be preceded by an underscore ( _ ).

Logical data type ranges correspond to their comparable integer data type ranges. For example, the LOGICAL(2) range is the same as the INTEGER(2) range.

For More Information:

For details on integer data type ranges, see your programmer's guide.


Character Data Type

The character data type can be specified as follows:

CHARACTER
CHARACTER([KIND=]n)
CHARACTER([LEN=]len)
CHARACTER([LEN=]len [, [KIND=]n])
CHARACTER(KIND=n [, LEN=len])
CHARACTER*len[,]

n
Is kind 1.

len
Is a string length (not a kind). For more information, see Declaration Statements for Character Types.

If no kind type parameter is specified, the kind of the constant is default character.

Several Multi-Byte Character Set (MBCS) functions are available to manipulate special non-English characters. These are described in Using National Language Support Routines.

For more information on the character data type, see Character Constants, C Strings, and Character Substrings.


Character Constants

A character constant is a character string enclosed in delimiters (apostrophes or quotation marks). It takes one of the following forms:

[k_]'[ch...]' [C]
[k_]"[ch...]" [C]

k
Is the optional kind parameter: 1 (the default). It must be followed by an underscore ( _ ). Note that in character constants, the kind must precede the constant.

ch
Is an ASCII character.

C
Is a C string specifier. C strings can be used to define strings with nonprintable characters. For more information, see C Strings in Character Constants.

Rules and Behavior

The value of a character constant is the string of characters between the delimiters. The value does not include the delimiters, but does include all blanks or tabs within the delimiters.

If a character constant is delimited by apostrophes, use two consecutive apostrophes ('' ) to place an apostrophe character in the character constant.

Similarly, if a character constant is delimited by quotation marks, use two consecutive quotation marks ("") to place a quotation mark character in the character constant.

The length of the character constant is the number of characters between the delimiters, but two consecutive delimiters are counted as one character.

The length of a character constant must be in the range of 0 to 2000. Each character occupies one byte of memory.

If a character constant appears in a numeric context (such as an expression on the right side of an arithmetic assignment statement), it is considered a Hollerith constant.

A zero-length character constant is represented by two consecutive apostrophes or quotation marks.

Examples

The following examples demonstrate valid and invalid character constants:

Valid |
"WHAT KIND TYPE? " |
'TODAY''S DATE IS: ' |
"The average is: " |
'' |
Invalid | Explanation
'HEADINGS | No trailing apostrophe.
'Map Number:" | Beginning delimiter does not match ending delimiter.

For More Information, see Declaration Statements for Character Types.


C Strings in Character Constants

String values in the C language are terminated with null characters (CHAR(0)) and can contain nonprintable characters (such as backspace).

Nonprintable characters are specified by escape sequences. An escape sequence is denoted by using the backslash (\) as an escape character, followed by a single character indicating the nonprintable character desired.

This type of string is specified by using a standard string constant followed by the character C. The standard string constant is then interpreted as a C-language constant. Backslashes are treated as escapes, and a null character is automatically appended to the end of the string (even if the string already ends in a null character).

The following table shows the escape sequences that are allowed in character constants:

C-Style Escape Sequences
Escape Sequence | Represents
\a or \A | A bell
\b or \B | A backspace
\f or \F | A formfeed
\n or \N | A new line
\r or \R | A carriage return
\t or \T | A horizontal tab
\v or \V | A vertical tab
\xhh or \Xhh | A hexadecimal bit pattern
\ooo | An octal bit pattern
\0 | A null character
\\ | A backslash

If a string contains an escape sequence that isn't in this table, the backslash is ignored.

A C string must also be a valid Fortran string. If the string is delimited by apostrophes, apostrophes in the string itself must be represented by two consecutive apostrophes ('' ).

For example, the escape sequence \'string causes a compiler error because Fortran interprets the apostrophe as the end of the string. The correct form is \''string.

If the string is delimited by quotation marks, quotation marks in the string itself must be represented by two consecutive quotation marks ("").

The sequences \ooo and \xhh allow any ASCII character to be given as a one- to three-digit octal or a one- to two-digit hexadecimal character code. Each octal digit must be in the range 0 to 7, and each hexadecimal digit must be in the range 0 to F. For example, the C strings '\010'C and '\x08'C both represent a backspace character followed by a null character.

The C string '\\abcd'C is equivalent to the string '\abcd' with a null character appended. The string ''C represents the ASCII null character.


Character Substrings

A character substring is a contiguous segment of a character string. It takes one of the following forms:

v ([e1]:[e2])
a (s [, s] . . . ) ([e1]:[e2])

v
Is a character scalar constant, or the name of a character scalar variable or character structure component.

e1
Is a scalar integer (or other numeric) expression specifying the leftmost character position of the substring; the starting point.

e2
Is a scalar integer (or other numeric) expression specifying the rightmost character position of the substring; the ending point.

a
Is the name of a character array.

s
Is a subscript expression.

Both e1 and e2 must be within the range 1,2, ..., len, where len is the length of the parent character string. If e1 exceeds e2, the substring has length zero.

Rules and Behavior

Character positions within the parent character string are numbered from left to right, beginning at 1.

If the value of the numeric expression e1 or e2 is not of type integer, it is converted to an integer before use (any fractional parts are truncated).

If e1 is omitted, the default is 1. If e2 is omitted, the default is len. For example, NAMES(1,3)(:7) specifies the substring starting with the first character position and ending with the seventh character position of the character array element NAMES(1,3).

Examples

Consider the following example:

  CHARACTER*8 C, LABEL
  LABEL = 'XVERSUSY'
  C = LABEL(2:7)

LABEL(2:7) specifies the substring starting with the second character position and ending with the seventh character position of the character variable assigned to LABEL, so C has the value 'VERSUS'.

Consider the following example:

  TYPE ORGANIZATION
    INTEGER ID
    CHARACTER*35 NAME
  END TYPE ORGANIZATION

  TYPE(ORGANIZATION) DIRECTOR
  CHARACTER*25 BRANCH, STATE(50)

The following are valid substrings based on this example:

  BRANCH(3:15)           ! parent string is a scalar variable
  STATE(20) (1:3)        ! parent string is an array element
  DIRECTOR%NAME          ! parent string is a structure component

Consider the following example:

  CHARACTER(*), PARAMETER :: MY_BRANCH = "CHAPTER 204"
  CHARACTER(3) BRANCH_CHAP
  BRANCH_CHAP = MY_BRANCH(9:11)  ! parent string is a character constant

BRANCH_CHAP is a character string of length 3 that has the value '204'.

For More Information:

  • See Arrays.
  • See Array Elements.
  • See Structure Components.


Derived Data Types

You can create derived data types from intrinsic data types or previously defined derived types.

A derived type is resolved into "ultimate" components that are either of intrinsic type or are pointers.

The set of values for a specific derived type consists of all possible sequences of component values permitted by the definition of that derived type. Structure constructors are used to specify values of derived types.

Nonintrinsic assignment for derived-type entities must be defined by a subroutine with an ASSIGNMENT interface. Any operation on derived-type entities must be defined by a function with an OPERATOR interface. Arguments and function values can be of any intrinsic or derived type.

The following is also discussed in this section:

  • Derived-Type Definition
  • Default Initialization
  • Structure Components
  • Structure Constructors

For More Information:

  • On OPERATOR interfaces, see Defining Generic Operators.
  • On ASSIGNMENT interfaces, see Defining Generic Assignment.
  • On intrinsic assignment of derived types, see Derived-Type Assignment Statements.
  • On record structures, see Records.


Derived-Type Definition

A derived-type definition specifies the name of a user-defined type and the types of its components. For details on creating derived types, see Derived Type in the A to Z Reference.


Default Initialization

Default initialization occurs if initialization appears in a derived-type component definition. (This is a Fortran 95 feature.)

The specified initialization of the component will apply even if the definition is PRIVATE.

Default initialization applies to dummy arguments with INTENT(OUT). It does not imply the derived-type component has the SAVE attribute.

Explicit initialization in a type declaration statement overrides default initialization.

To specify default initialization of an array component, use a constant expression that includes one of the following:

  • An array constructor
  • A single scalar that becomes the value of each array element

Pointers can have an association status of associated, disassociated, or undefined. If no default initialization status is specified, the status of the pointer is undefined. To specify disassociated status for a pointer component, use =>NULL( ).

Examples

You do not have to specify initialization for each component of a derived type. For example:

  TYPE REPORT
    CHARACTER (LEN=20) REPORT_NAME
    INTEGER DAY
    CHARACTER (LEN=3) MONTH
    INTEGER :: YEAR = 1995        ! Only component with default
  END TYPE REPORT                 !      initialization

Consider the following:

  TYPE (REPORT), PARAMETER :: NOV_REPORT = REPORT ("Sales", 15, "NOV", 1996)

In this case, the explicit initialization in the type declaration statement overrides the YEAR component of NOV_REPORT.

The default initial value of a component can also be overridden by default initialization specified in the type definition. For example:

  TYPE MGR_REPORT
    TYPE (REPORT) :: STATUS = NOV_REPORT
    INTEGER NUM
  END TYPE MGR_REPORT

  TYPE (MGR_REPORT) STARTUP

In this case, the STATUS component of STARTUP gets its initial value from NOV_REPORT, overriding the initialization for the YEAR component.


Structure Components

A reference to a component of a derived-type structure takes the following form:

parent [%component [(s-list)]] ... %component [(s-list)]

parent
Is the name of a scalar or array of derived type. The percent sign (%) is called a component selector.

component
Is the name of a component of the immediately preceding parent or component.

s-list
Is a list of one or more subscripts. If the list contains subscript triplets or vector subscripts, the reference is to an array section.

Each subscript must be a scalar integer (or other numeric) expression with a value that is within the bounds of its dimension.

The number of subscripts in any s-list must equal the rank of the immediately preceding parent or component.

Rules and Behavior

Each parent or component (except the rightmost) must be of derived type.

The parent or one of the components can have nonzero rank (be an array). Any component to the right of a parent or component of nonzero rank must not have the POINTER attribute.

The rank of the structure component is the rank of the part (parent or component) with nonzero rank (if any); otherwise, the rank is zero. The type and type parameters (if any) of a structure component are those of the rightmost part name.

The structure component must not be referenced or defined before the declaration of the parent object.

If the parent object has the INTENT, TARGET, or PARAMETER attribute, the structure component also has the attribute.

Examples

The following example shows a derived-type definition with two components:

  TYPE EMPLOYEE
    INTEGER ID
    CHARACTER(LEN=40) NAME
  END TYPE EMPLOYEE

The following shows how to declare CONTRACT to be of type EMPLOYEE:

  TYPE(EMPLOYEE) :: CONTRACT

Note that both examples started with the keyword TYPE. The first (initial) statement of a derived-type definition is called a derived-type statement, while the statement that declares a derived-type object is called a TYPE statement.

The following example shows how to reference component ID of parent structure CONTRACT:

  CONTRACT%ID

The following example shows a derived type with a component that is a previously defined type:

  TYPE DOT
    REAL X, Y
  END TYPE DOT
  ....
  TYPE SCREEN
    TYPE(DOT) C, D
  END TYPE SCREEN

The following declares a variable of type SCREEN:

  TYPE(SCREEN) M

Variable M has components M%C and M%D (both of type DOT); M%C has components M%C%X and M%C%Y of type REAL.

The following example shows a derived type with a component that is an array:

  TYPE CAR_INFO
    INTEGER YEAR
    CHARACTER(LEN=15), DIMENSION(10) :: MAKER
    CHARACTER(LEN=10) MODEL, BODY_TYPE*8
    REAL PRICE
  END TYPE
  ...
  TYPE(CAR_INFO) MY_CAR

Note that MODEL has a character length of 10, but BODY_TYPE has a character length of 8. You can assign a value to a component of a structure; for example:

  MY_CAR%YEAR = 1985

The following shows an array structure component:

  MY_CAR%MAKER

In the preceding example, if a subscript list (or substring) was appended to MAKER, the reference would not be to an array structure component, but to an array element or section.

Consider the following:

  MY_CAR%MAKER(2) (4:10)

In this case, the component is substring 4 to 10 of the second element of array MAKER.

Consider the following:

  TYPE CHARGE
    INTEGER PARTS(40)
    REAL LABOR
    REAL MILEAGE
  END TYPE CHARGE

  TYPE(CHARGE) MONTH
  TYPE(CHARGE) YEAR(12)

Some valid array references for this type follow:

  MONTH%PARTS(I)           ! An array element
  MONTH%PARTS(I:K)         ! An array section
  YEAR(I)%PARTS            ! An array structure component (a whole array)
  YEAR(J)%PARTS(I)         ! An array element
  YEAR(J)%PARTS(I:K)       ! An array section
  YEAR(J:K)%PARTS(I)       ! An array section
  YEAR%PARTS(I)            ! An array section

The following example shows a derived type with a pointer component that is of the type being defined:

  TYPE NUMBER
    INTEGER NUM

    TYPE(NUMBER), POINTER :: START_NUM => NULL( )
    TYPE(NUMBER), POINTER :: NEXT_NUM => NULL( )

  END TYPE

A type such as this can be used to construct linked lists of objects of type NUMBER. Note that the pointers are given the default initialization status of disassociated.

The following example shows a private type:

  TYPE, PRIVATE :: SYMBOL
    LOGICAL TEST
    CHARACTER(LEN=50) EXPLANATION
  END TYPE SYMBOL

This type is private to the module. The module can be used by another scoping unit, but type SYMBOL is not available.

For More Information

  • On references to array elements, see Array Elements.
  • On references to array sections, see Array Sections.
  • On examples of derived types in modules, see Modules and Module Procedures.


Structure Constructors

A structure constructor lets you specify scalar values of a derived type. It takes the following form:

d-name (expr-list)

d-name
Is the name of the derived type.

expr-list
Is a list of expressions specifying component values. The values must agree in number and order with the components of the derived type. If necessary, values are converted (according to the rules of assignment), to agree with their corresponding components in type and kind parameters.

Rules and Behavior

A structure constructor must not appear before its derived type is defined.

If a component of the derived type is an array, the shape in the expression list must conform to the shape of the component array.

If a component of the derived type is a pointer, the value in the expression list must evaluate to an object that would be a valid target in a pointer assignment statement. (A constant is not a valid target in a pointer assignment statement.)

If all the values in a structure constructor are constant expressions, the constructor is a derived-type constant expression.

Examples

Consider the following derived-type definition:

  TYPE EMPLOYEE
    INTEGER ID
    CHARACTER(LEN=40) NAME
  END TYPE EMPLOYEE

This can be used to produce the following structure constructor:

  EMPLOYEE(3472, "John Doe")

The following example shows a type with a component of derived type:

  TYPE ITEM
    REAL COST
    CHARACTER(LEN=30) SUPPLIER
    CHARACTER(LEN=20) ITEM_NAME
  END TYPE ITEM

  TYPE PRODUCE
    REAL MARKUP
    TYPE(ITEM) FRUIT
  END TYPE PRODUCE

In this case, you must use an embedded structure constructor to specify the values of that component; for example:

  PRODUCE(.70, ITEM (.25, "Daniels", "apple"))

For More Information:

See also Pointer Assignments.


Binary, Octal, Hexadecimal, and Hollerith Constants

Binary, octal, hexadecimal, and Hollerith constants are nondecimal constants. They have no intrinsic data type, but assume a numeric data type depending on their use.

Fortran 95/90 allows unsigned binary, octal, and hexadecimal constants to be used in DATA statements; the constant must correspond to an integer scalar variable.

In Compaq Fortran, binary, octal, hexadecimal, and Hollerith constants can appear wherever numeric constants are allowed.


Binary Constants

A binary constant is an alternative way to represent a numeric constant. A binary constant takes one of the following forms:

B'd[d...]'
B"d[d...]"

d
Is a binary (base 2) digit (0 or 1).

You can specify up to 256 binary digits in a binary constant. Leading zeros are ignored.

Examples

The following examples demonstrate valid and invalid binary constants:

Valid |
B'0101110' |
B"1" |
Invalid | Explanation
B'0112' | The character 2 is invalid.
B10011' | No apostrophe after the B.
"1000001" | No B before the first quotation mark.


Octal Constants

An octal constant is an alternative way to represent numeric constants. An octal constant takes one of the following forms:

O'd[d...]'
O"d[d...]"

d
Is an octal (base 8) digit (0 through 7).

You can specify up to 256 bits in octal (86 octal digits) constants. Leading zeros are ignored.

Examples

The following examples demonstrate valid and invalid octal constants:

Valid |
O'07737' |
O"1" |
Invalid | Explanation
O'7782' | The character 8 is invalid.
O7772' | No apostrophe after the O.
"0737" | No O before the first quotation mark.

For More Information:

See also Alternative Syntax for Octal and Hexadecimal Constants.


Hexadecimal Constants

A hexadecimal constant is an alternative way to represent numeric constants. A hexadecimal constant takes one of the following forms:

Z'd[d...]'
Z"d[d...]"

d
Is a hexadecimal (base 16) digit (0 through 9, or an uppercase or lowercase letter in the range of A to F).

You can specify up to 256 bits in hexadecimal (64 hexadecimal digits) constants. Leading zeros are ignored.

Examples

The following examples demonstrate valid and invalid hexadecimal constants:

Valid |
Z'AF9730' |
Z"FFABC" |
Z'84' |
Invalid | Explanation
Z'999.' | Decimal not allowed.
ZF9" | No quotation mark after the Z.

For More Information:

See also Alternative Syntax for Octal and Hexadecimal Constants.


Hollerith Constants

A Hollerith constant is a string of printable ASCII characters preceded by the letter H. Before the H, there must be an unsigned, nonzero default integer constant stating the number of characters in the string (including blanks and tabs).

Hollerith constants are strings of 1 to 2000 characters. They are stored as byte strings, one character per byte.

Examples

The following examples demonstrate valid and invalid Hollerith constants:

Valid |
16HTODAY'S DATE IS: |
1HB |
4H ABC |
Invalid | Explanation
3HABCD | Wrong number of characters.
0H | Hollerith constants must contain at least one character.


Determining the Data Type of Nondecimal Constants

Binary, octal, hexadecimal, and Hollerith constants have no intrinsic data type. These constants assume a numeric data type depending on their use.

When the constant is used with a binary operator (including the assignment operator), the data type of the constant is the data type of the other operand. For example:

Statement | Data Type of Constant | Length of Constant (in bytes)
INTEGER(2) ICOUNT |  |
INTEGER(4) JCOUNT |  |
INTEGER(4) N |  |
REAL(8) DOUBLE |  |
REAL(4) RAFFIA, RALPHA |  |
RAFFIA = B'1001100111111010011' | REAL(4) | 4
RAFFIA = Z'99AF2' | REAL(4) | 4
RALPHA = 4HABCD | REAL(4) | 4
DOUBLE = B'1111111111100110011010' | REAL(8) | 8
DOUBLE = Z'FFF99A' | REAL(8) | 8
DOUBLE = 8HABCDEFGH | REAL(8) | 8
JCOUNT = ICOUNT + B'011101110111' | INTEGER(2) | 2
JCOUNT = ICOUNT + O'777' | INTEGER(2) | 2
JCOUNT = ICOUNT + 2HXY | INTEGER(2) | 2
IF (N .EQ. B'1010100') GO TO 10 | INTEGER(4) | 4
IF (N .EQ. O'123') GO TO 10 | INTEGER(4) | 4
IF (N. EQ. 1HZ) GO TO 10 | INTEGER(4) | 4

When a specific data type (generally integer) is required, that type is assumed for the constant. For example:

Statement | Data Type of Constant | Length of Constant (in bytes)
Y(IX) = Y(O'15') + 3. | INTEGER(4) | 4
Y(IX) = Y(1HA) + 3. | INTEGER(4) | 4

When a nondecimal constant is used as an actual argument, the following occurs:

  • For binary, octal, and hexadecimal constants, INTEGER(8) is assumed on Alpha and ia64 processors. On ia32 processors, a length of four bytes is used.

  • For Hollerith constants, no data type is assumed.

For example:

Statement | Data Type of Constant | Length of Constant (in bytes)
CALL APAC(Z'34BC2') | INTEGER(4) | 4
CALL APAC(9HABCDEFGHI) | None | 9

When a binary, octal, or hexadecimal constant is used in any other context, the default integer data type is assumed (default integer can be affected by compiler options). In the following examples, default integer is INTEGER(4):

Statement | Data Type of Constant | Length of Constant (in bytes)
IF (Z'AF77') 1,2,3 | INTEGER(4) | 4
IF (2HAB) 1,2,3 | INTEGER(4) | 4
I = O'7777' - Z'A39' 1 | INTEGER(4) | 4
I = 1HC - 1HA | INTEGER(4) | 4
J = .NOT. O'73777' | INTEGER(4) | 4
J = .NOT. 1HB | INTEGER(4) | 4
1 When two typeless constants are used in an operation, they both take default integer type.

When nondecimal constants are not the same length as the length implied by a data type, the following occurs:

  • Binary, octal, and hexadecimal constants

    These constants can specify up to 16 bytes of data. When the length of the constant is less than the length implied by the data type, the leftmost digits have a value of zero.

    When the length of the constant is greater than the length implied by the data type, the constant is truncated on the left. An error results if any nonzero digits are truncated.

    The Data Type Storage Requirements table lists the number of bytes that each data type requires.

  • Hollerith constants

    When the length of the constant is less than the length implied by the data type, blanks are appended to the constant on the right.

    When the length of the constant is greater than the length implied by the data type, the constant is truncated on the right. If any characters other than blank characters are truncated, an error occurs.

    Each Hollerith character occupies one byte of memory.


Variables

A variable is a data object whose value can be changed at any point in a program. A variable can be any of the following:

  • A scalar

    A scalar is a single object that has a single value; it can be of any intrinsic or derived (user-defined) type.

  • An array

    An array is a collection of scalar elements of any intrinsic or derived type. All elements must have the same type and kind parameters.

  • A subobject designator

    A subobject is part of an object. The following are subobjects:

    An array element
    An array section
    A structure component
    A character substring

    For example, B(3) is a subobject (array element) designator for array B. A subobject cannot be a variable if its parent object is a constant.

The name of a variable is associated with a single storage location.

Variables are classified by data type, as constants are. The data type of a variable indicates the type of data it contains, including its precision, and implies its storage requirements. When data of any type is assigned to a variable, it is converted to the data type of the variable (if necessary).

A variable is defined when you give it a value. A variable can be defined before program execution by a DATA statement or a type declaration statement. During program execution, variables can be defined or redefined in assignment statements and input statements, or undefined (for example, if an I/O error occurs). When a variable is undefined, its value is unpredictable.

When a variable becomes undefined, all variables associated by storage association also become undefined.

An object with subobjects, such as an array, can only be defined when all of its subobjects are defined. Conversely, when at least one of its subobjects are undefined, the object itself, such as an array or derived type, is undefined.

This section also discusses the Data Types of Scalar Variables and Arrays.

For More Information:

  • See Type Declaration Statements.
  • See the DATA statement.
  • See Data Type of a Numeric Expressions.
  • On storage association of variables, see Storage Association.


Data Types of Scalar Variables

The data type of a scalar variable can be explicitly declared in a type declaration statement. If no type is declared, the variable has an implicit data type based on predefined typing rules or definitions in an IMPLICIT statement.

An explicit declaration of data type takes precedence over any implicit type. Implicit type specified in an IMPLICIT statement takes precedence over predefined typing rules.

See also Specification of Data Type and Implicit Typing Rules.


Specification of Data Type

Type declaration statements explicitly specify the data type of scalar variables. For example, the following statements associate VAR1 with an 8-byte complex storage location, and VAR2 with an 8-byte double-precision storage location:

  COMPLEX VAR1
  DOUBLE PRECISION VAR2

You can explicitly specify the data type of a scalar variable only once.

If no explicit data type specification appears, any variable with a name that begins with the letter in the range specified in the IMPLICIT statement becomes the data type of the variable.

Character type declaration statements specify that given variables represent character values with the length specified. For example, the following statements associate the variable names INLINE, NAME, and NUMBER with storage locations containing character data of lengths 72, 12, and 9, respectively:

  CHARACTER*72 INLINE
  CHARACTER NAME*12, NUMBER*9

In single subprograms, assumed-length character arguments can be used to process character strings with different lengths. The assumed-length character argument has its length specified with an asterisk, for example:

  CHARACTER*(*) CHARDUMMY

The argument CHARDUMMY assumes the length of the actual argument.

For More Information:

  • See Type declaration statements.
  • See Assumed-length character arguments.
  • See the IMPLICIT statement.
  • On character type declaration statements, see Declaration Statements for Character Types.


Implicit Typing Rules

By default, all scalar variables with names beginning with I, J, K, L, M, or N are assumed to be default integer variables. Scalar variables with names beginning with any other letter are assumed to be default real variables. For example:

Real Variables | Integer Variables
ALPHA | JCOUNT
BETA | ITEM_1
TOTAL_NUM | NTOTAL

Names beginning with a dollar sign ($) are implicitly INTEGER.

You can override the default data type implied in a name by specifying data type in either an IMPLICIT statement or a type declaration statement.

For More Information:

  • See Type declaration statements.
  • See the IMPLICIT statement.


Arrays

An array is a set of scalar elements that have the same type and kind parameters. Any object that is declared with an array specification is an array. Arrays can be declared by using a type declaration statement, or by using a DIMENSION, COMMON, ALLOCATABLE, POINTER, or TARGET statement.

An array can be referenced by element (using subscripts), by section (using a section subscript list), or as a whole. A subscript list (appended to the array name) indicates which array element or array section is being referenced.

A section subscript list consists of subscripts, subscript triplets, or vector subscripts. At least one subscript in the list must be a subscript triplet or vector subscript.

When an array name without any subscripts appears in an intrinsic operation (for example, addition), the operation applies to the whole array (all elements in the array).

An array has the following properties:

  • Data type

    An array can have any intrinsic or derived type. The data type of an array (like any other variable) is specified in a type declaration statement or implied by the first letter of its name. All elements of the array have the same type and kind parameters. If a value assigned to an individual array element is not the same as the type of the array, it is converted to the array's type.

  • Rank

    The rank of an array is the number of dimensions in the array. An array can have up to seven dimensions. A rank-one array represents a column of data (a vector), a rank-two array represents a table of data arranged in columns and rows (a matrix), a rank-three array represents a table of data on multiple pages (or planes), and so forth.

  • Bounds

    Arrays have a lower and upper bound in each dimension. These bounds determine the range of values that can be used as subscripts for the dimension. The value of either bound can be positive, negative, or zero.

    The bounds of a dimension are defined in an array specification.

  • Size

    The size of an array is the total number of elements in the array (the product of the array's extents).

    The extent is the total number of elements in a particular dimension. It is determined as follows: upper bound - lower bound + 1. If the value of any of an array's extents is zero, the array has a size of zero.

  • Shape

    The shape of an array is determined by its rank and extents, and can be represented as a rank-one array (vector) where each element is the extent of the corresponding dimension.

    Two arrays with the same shape are said to be conformable. A scalar is conformable to an array of any shape.

The name and rank of an array must be specified when the array is declared. The extent of each dimension can be constant, but does not need to be. The extents can vary during program execution if the array is a dummy argument array, an automatic array, an array pointer, or an allocatable array.

A whole array is referenced by the array name. Individual elements in a named array are referenced by a scalar subscript or list of scalar subscripts (if there is more than one dimension). A section of a named array is referenced by a section subscript.

This section also discusses:

  • Whole Arrays
  • Array Elements
  • Array Sections
  • Array Constructors

Examples

The following are examples of valid array declarations:

  DIMENSION    A(10, 2, 3)            ! DIMENSION statement
  ALLOCATABLE  B(:, :)                ! ALLOCATABLE statement
  POINTER      C(:, :, :)             ! POINTER statement
  REAL, DIMENSION (2, 5) :: D         ! Type declaration with
                                      !   DIMENSION attribute
Consider the following array declaration:
  INTEGER L(2:11,3)

The properties of array L are as follows:

Data type: | INTEGER
Rank: | 2 (two dimensions)
Bounds: | First dimension: 2 to 11
 | Second dimension: 1 to 3
Size: | 30; the product of the extents: 10 x 3
Shape: | (/10,3/) (or 10 by 3); a vector of the extents 10 and 3

The following example shows other valid ways to declare this array:

DIMENSION L(2:11,3)
INTEGER, DIMENSION(2:11,3) :: L
COMMON L(2:11,3)

The following example shows references to array elements, array sections, and a whole array:

REAL B(10)           ! Declares a rank-one array with 10 elements

INTEGER C(5,8)       ! Declares a rank-two array with 5 elements in
                     !   dimension one and 8 elements in dimension two
...
B(3) = 5.0           ! Reference to an array element
B(2:5) = 1.0         ! Reference to an array section consisting of
                     !   elements: B(2), B(3), B(4), B(5)
...
C(4,8) = I           ! Reference to an array element
C(1:3,3:4) = J       ! Reference to an array section consisting of
                     !   elements:  C(1,3) C(1,4)
                     !              C(2,3) C(2,4)
                     !              C(3,3) C(3,4)
B = 99               ! Reference to a whole array consisting of
                     !   elements: B(1), B(2), B(3), B(4), B(5),
                     !   B(6), B(7), B(8), B(9), and B(10)

For More Information:

  • See the DIMENSION attribute.
  • See Intrinsic data types.
  • See Derived data types.
  • On array specifications, see Declaration Statements for Arrays.
  • On intrinsic functions that perform array operations, see Categories of Intrinsic Functions.
  • On using arrays, see Use Arrays Efficiently.


Whole Arrays

A whole array is a named array; it is either a named constant or a variable. It is referenced by using the array name (without any subscripts).

If a whole array appears in a nonexecutable statement, the statement applies to the entire array. For example:

  INTEGER, DIMENSION(2:11,3) :: L   ! Specifies the type and
                                    !    dimensions of array L

If a whole array appears in an executable statement, the statement applies to all of the elements in the array. For example:

  L = 10             ! The value 10 is assigned to all the
                     !   elements in array L
  WRITE *, L         ! Prints all the elements in array L


Array Elements

An array element is one of the scalar data items that make up an array. A subscript list (appended to the array or array component) determines which element is being referred to. A reference to an array element takes the following form:

array(subscript-list)

array
Is the name of the array.

subscript-list
Is a list of one or more subscripts separated by commas. The number of subscripts must equal the rank of the array.

Each subscript must be a scalar integer (or other numeric) expression with a value that is within the bounds of its dimension.

Rules and Behavior

Each array element inherits the type, kind type parameter, and certain attributes (INTENT, PARAMETER, and TARGET) of the parent array. An array element cannot inherit the POINTER attribute.

If an array element is of type character, it can be followed by a substring range in parentheses; for example:

  ARRAY_D(1,2) (1:3)    ! Elements are substrings of length 3

However, by convention, such an object is considered to be a substring rather than an array element.

The following are some valid array element references for an array declared as REAL B(10,20): B(1,3), B(10,10), and B(5,8).

You can use functions and array elements as subscripts. For example:

  REAL A(3, 3)
  REAL B(3, 3), C(89), R
  B(2, 2) = 4.5                         ! Assigns the value 4.5 to element B(2, 2)
  R = 7.0
  C(INT(R)*2 + 1) = 2.0                 ! Element 15 of C = 2.0
  A(1,2) = B(INT(C(15)), INT(SQRT(R)))  ! Element A(1,2) = element B(2,2) = 4.5
For information on forms for array specifications, see Declaration Statements for Arrays.

Array Element Order

The elements of an array form a sequence known as array element order. The position of an element in this sequence is its subscript order value.

The elements of an array are stored as a linear sequence of values. A one-dimensional array is stored with its first element in the first storage location and its last element in the last storage location of the sequence. A multidimensional array is stored so that the leftmost subscripts vary most rapidly. This is called the order of subscript progression.

The following figure shows array storage in one, two, and three dimensions:

Array Storage

For example, in two-dimensional array BAN, element BAN(1,2) has a subscript order value of 4; in three-dimensional array BOS, element BOS(1,1,1) has a subscript order value of 1.

In an array section, the subscript order of the elements is their order within the section itself. For example, if an array is declared as B(20), the section B(4:19:4) consists of elements B(4), B(8), B(12), and B(16). The subscript order value of B(4) in the array section is 1; the subscript order value of B(12) in the section is 3.

For More Information:

  • See Array association.
  • On substrings, see Character Constants.
  • On arrays as structure components, see Structure Components.
  • On storage sequence association, see Storage Association.


Array Sections

An array section is a portion of an array that is an array itself. It is an array subobject. A section subscript list (appended to the array or array component) determines which portion is being referred to. A reference to an array section takes the following form:

array(sect-subscript-list)

array
Is the name of the array.

sect-subscript-list
Is a list of one or more section subscripts (subscripts, subscript triplets, or vector subscripts) indicating a set of elements along a particular dimension.

At least one of the items in the section subscript list must be a subscript triplet or vector subscript. A subscript triplet specifies array elements in increasing or decreasing order at a given stride. A vector subscript specifies elements in any order.

Each subscript and subscript triplet must be a scalar integer (or other numeric) expression. Each vector subscript must be a rank-one integer expression.

Rules and Behavior

If no section subscript list is specified, the rank and shape of the array section is the same as the parent array.

Otherwise, the rank of the array section is the number of vector subscripts and subscript triplets that appear in the list. Its shape is a rank-one array where each element is the number of integer values in the sequence indicated by the corresponding subscript triplet or vector subscript.

If any of these sequences is empty, the array section has a size of zero. The subscript order of the elements of an array section is that of the array object that the array section represents.

Each array section inherits the type, kind type parameter, and certain attributes (INTENT, PARAMETER, and TARGET) of the parent array. An array section cannot inherit the POINTER attribute.

If an array (or array component) is of type character, it can be followed by a substring range in parentheses. Consider the following declaration:

  CHARACTER(LEN=15) C(10,10)

In this case, an array section referenced as C(:,:) (1:3) is an array of shape (10,10), whose elements are substrings of length 3 of the corresponding elements of C.

The following shows valid references to array sections. Note that the syntax (/.../) denotes an array constructor.

  REAL, DIMENSION(20) :: B
  ...
  PRINT *, B(2:20:5)  ! The section consists of elements
                      !     B(2), B(7), B(12), and B(17)

  K = (/3, 1, 4/)
  B(K) = 0.0      ! Section B(K) is a rank-one array with shape (3) and
                  !  size 3. (0.0 is assigned to B(1), B(3), and B(4).)

For More Information:

  • See the INTENT attribute.
  • See the PARAMETER attribute.
  • See the TARGET attribute.
  • See array sections as Structure components.
  • See Array constructors.
  • On substrings, see Character Substrings.


Subscript Triplets

A subscript triplet is a set of three values representing the lower bound of the array section, the upper bound of the array section, and the increment (stride) between them. It takes the following form:

[first-bound] : [last-bound] [:stride]

first-bound
Is a scalar integer (or other numeric) expression representing the first value in the subscript sequence. If omitted, the declared lower bound of the dimension is used.

last-bound
Is a scalar integer (or other numeric) expression representing the last value in the subscript sequence. If omitted, the declared upper bound of the dimension is used.

When indicating sections of an assumed-size array, this subscript must be specified.

stride
Is a scalar integer (or other numeric) expression representing the increment between successive subscripts in the sequence. It must have a nonzero value. If it is omitted, it is assumed to be 1.

The stride has the following effects:

  • If the stride is positive, the subscript range starts with the first subscript and is incremented by the value of the stride, until the largest value less than or equal to the second subscript is attained.

    For example, if an array has been declared as B(6,3,2), the array section specified as B(2:4,1:2,2) is a rank-two array with shape (3,2) and size 6. It consists of the following six elements:

    B(2,1,2) B(2,2,2)
    B(3,1,2) B(3,2,2)
    B(4,1,2) B(4,2,2)

    If the first subscript is greater than the second subscript, the range is empty.

  • If the stride is negative, the subscript range starts with the value of the first subscript and is decremented by the absolute value of the stride, until the smallest value greater than or equal to the second subscript is attained.

    For example, if an array has been declared as A(15), the array section specified as A(10:3:-2) is a rank-one array with shape (4) and size 4. It consists of the following four elements:

    A(10)
    A(8)
    A(6)
    A(4)

    If the second subscript is greater than the first subscript, the range is empty.

If a range specified by the stride is empty, the array section has a size of zero.

A subscript in a subscript triplet need not be within the declared bounds for that dimension if all values used to select the array elements are within the declared bounds. For example, if an array has been declared as A(15), the array section specified as A(4:16:10) is valid. The section is a rank-one array with shape (2) and size 2. It consists of elements A(4) and A(14).

If the subscript triplet does not specify bounds or stride, but only a colon (:), the entire declared range for the dimension is used.

If you leave out all subscripts, the section defaults to the entire extent in that dimension. For example:

 REAL A(10)
 A(1:5:2) = 3.0   ! Sets elements A(1), A(3), A(5) to 3.0
 A(:5:2) = 3.0    ! Same as the previous statement
                  !   because the lower bound defaults to 1
 A(2::3) = 3.0    ! Sets elements A(2), A(5), A(8) to 3.0
                  ! The upper bound defaults to 10
 A(7:9) = 3.0     ! Sets elements A(7), A(8), A(9) to 3.0
                  ! The stride defaults to 1
 A(:) = 3.0       ! Same as A = 3.0; sets all elements of
                  !   A to 3.0

For More Information:

  • See Array Sections.


Vector Subscripts

A vector subscript is a one-dimensional (rank one) array of integer values (within the declared bounds for the dimension) that selects a section of a whole (parent) array. The elements in the section do not have to be in order and the section can contain duplicate values.

For example, A is a rank-two array of shape (4,6). B and C are rank-one arrays of shape (2) and (3), respectively, with the following values:

  B = (/1,4/)           ! Syntax (/.../) denotes an array constructor
  C = (/2,1,1/)         ! This constructor produces a many-one array section

Array section A(3,B) consists of elements A(3,1) and A(3,4). Array section A(C,1) consists of elements A(2,1), A(1,1), and A(1,1). Array section A(B,C) consists of the following elements:

A(1,2) A(1,1) A(1,1)
A(4,2) A(4,1) A(4,1)

An array section with a vector subscript that has two or more elements with the same value is called a many-one array section. For example:

 REAL A(3, 3), B(4)
 INTEGER K(4)
 ! Vector K has repeated values
 K = (/3, 1, 1, 2/)
 ! Sets all elements of A to 5.0
 A = 5.0
 B = A(3, K)

The array section A(3,K) consists of the elements:

  A(3, 3) A(3, 1) A(3, 1) A(3, 2)

A many-one section must not appear on the left of the equal sign in an assignment statement, or as an input item in a READ statement.

The following assignments to C also show examples of vector subscripts:

  INTEGER A(2), B(2), C(2)
  ...
  B    = (/1,2/)
  C(B) = A(B)
  C    = A((/1,2/))

An array section with a vector subscript must not be any of the following:

  • An internal file

  • An actual argument associated with a dummy array that is defined or redefined (if the INTENT attribute is specified, it must be INTENT(IN))

  • The target in a pointer assignment statement

If the sequence specified by the vector subscript is empty, the array section has a size of zero.

For More Information:

  • See Array Sections.
  • See Array constructors.


Array Constructors

An array constructor can be used to create and assign values to rank-one arrays (and array constants). An array constructor takes the following form:

(/ac-value-list/)

ac-value-list
Is a list of one or more expressions or implied-do loops. Each ac-value must have the same type and kind parameters, and be separated by commas.

An implied-do loop in an array constructor takes the following form:

(ac-value-list, do-variable = expr1, expr2 [,expr3])

do-variable
Is the name of a scalar integer variable. Its scope is that of the implied-do loop.

expr
Is a scalar integer expression. The expr1 and expr2 specify a range of values for the loop; expr3 specifies the stride. The expr3 must be a nonzero value; if it is omitted, it is assumed to be 1.

Rules and Behavior

The array constructed has the same type as the ac-value-list expressions.

If the sequence of values specified by the array constructor is empty (there are no expressions or the implied-do loop produces no values), the rank-one array has a size of zero.

An ac-value is interpreted as follows:

Form of ac-value | Result
A scalar expression | Its value is an element of the new array.
An array expression | The values of the elements in the expression (in array element order) are the corresponding sequence of elements in the new array.
An implied-do loop | It is expanded to form a list of array elements under control of the DO variable (like a DO construct).

The following shows the three forms of an ac-value:

  C1 = (/4,8,7,6/)                  ! A scalar expression
  C2 = (/B(I, 1:5), B(I:J, 7:9)/)   ! An array expression
  C3 = (/(I, I=1, 4)/)              ! An implied-do loop

You can also mix these forms, for example:

  C4 = (/4, A(1:5), (I, I=1, 4), 7/)

If every expression in an array constructor is a constant expression, the array constructor is a constant expression.

If the expressions are of type character, Fortran 95/90 requires each expression to have the same character length.

However, Compaq Fortran allows the character expressions to be of different character lengths. The length of the resultant character array is the maximum of the lengths of the individual character expressions. For example:

print *,len ( (/'a','ab','abc','d'/) )
print *,'++'//(/'a','ab','abc','d'/)//'--'

This causes the following to be displayed:

           3
 ++a  --++ab --++abc--++d  --

If an implied-do loop is contained within another implied-do loop (nested), they cannot have the same DO variable (do-variable).

To define arrays of more than one dimension, use the RESHAPE intrinsic function.

The following are alternative forms for array constructors:

  • Square brackets (instead of parentheses and slashes) to enclose array constructors; for example, the following two array constructors are equivalent:
      INTEGER C(4)
  C = (/4,8,7,6/)
  C = [4,8,7,6]
  • A colon-separated triplet (instead of an implied-do loop) to specify a range of values and a stride; for example, the following two array constructors are equivalent:
      INTEGER D(3)
  D = (/1:5:2/)              ! Triplet form
  D = (/(I, I=1, 5, 2)/)     ! Implied-do loop form

Examples

The following example shows an array constructor using an implied-do loop:

  INTEGER ARRAY_C(10)
  ARRAY_C = (/(I, I=30, 48, 2)/)

The values of ARRAY_C are the even numbers 30 through 48.

Implied-DO expressions and values can be mixed in the value list of an array constructor. For example:

 INTEGER A(10)
 A = (/1, 0, (I, I = -1, -6, -1), -7, -8 /)
 !Mixed values and implied-DO in value list.

This example sets the elements of A to the values, in order, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8.

The following example shows an array constructor of derived type that uses a structure constructor:

TYPE EMPLOYEE
  INTEGER ID
  CHARACTER(LEN=30) NAME
END TYPE EMPLOYEE

TYPE(EMPLOYEE) CC_4T(4)
CC_4T = (/EMPLOYEE(2732,"JONES"), EMPLOYEE(0217,"LEE"),     &
          EMPLOYEE(1889,"RYAN"), EMPLOYEE(4339,"EMERSON")/)

The following example shows how the RESHAPE intrinsic function can be used to create a multidimensional array:

  E = (/2.3, 4.7, 6.6/)
  D = RESHAPE(SOURCE = (/3.5, (/2.0, 1.0/), E/), SHAPE = (/2,3/))

D is a rank-two array with shape (2,3) containing the following elements:

   3.5    1.0    4.7
   2.0    2.3    6.6

The following shows another example:

 INTEGER B(2,3), C(8)
 ! Assign values to a (2,3) array.
 B = RESHAPE((/1, 2, 3, 4, 5, 6/),(/2,3/))
 ! Convert B to a vector before assigning values to
 ! vector C.
 C = (/ 0, RESHAPE(B,(/6/)), 7 /)

For More Information:

  • See the DO construct.
  • See Subscript triplets.
  • See Derived types.
  • See Structure constructors.
  • On array element order, see Array Elements.
  • On another way to assign values to arrays, see Array Assignment Statements.
  • On array specifications, see Declaration Statements for Arrays.


Expressions and Assignment Statements

This chapter contains information on the following topics:

  • Expressions
  • Assignment statements


Expressions

An expression represents either a data reference or a computation, and is formed from operators, operands, and parentheses. The result of an expression is either a scalar value or an array of scalar values.

If the value of an expression is of intrinsic type, it has a kind type parameter. (If the value is of intrinsic type CHARACTER, it also has a length parameter.) If the value of an expression is of derived type, it has no kind type parameter.

An operand is a scalar or array. An operator can be either intrinsic or defined. An intrinsic operator is known to the compiler and is always available to any program unit. A defined operator is described explicitly by a user in a function subprogram and is available to each program unit that uses the subprogram.

The simplest form of an expression (a primary) can be any of the following:

  • A constant; for example, 4.2
  • A subobject of a constant; for example, 'LMNOP' (2:4)
  • A variable; for example, VAR_1
  • A structure constructor; for example, EMPLOYEE(3472, "JOHN DOE")
  • An array constructor; for example, (/12.0,16.0/)
  • A function reference; for example, COS(X)
  • Another expression in parentheses; for example, (I+5)

Any variable or function reference used as an operand in an expression must be defined at the time the reference is executed. If the operand is a pointer, it must be associated with a target object that is defined. An integer operand must be defined with an integer value rather than a statement label value. All of the characters in a character data object reference must be defined.

When a reference to an array or an array section is made, all of the selected elements must be defined. When a structure is referenced, all of the components must be defined.

In an expression that has intrinsic operators with an array as an operand, the operation is performed on each element of the array. In expressions with more than one array operand, the arrays must be conformable (they must have the same shape). The operation is applied to corresponding elements of the arrays, and the result is an array of the same shape (the same rank and extents) as the operands.

In an expression that has intrinsic operators with a pointer as an operand, the operation is performed on the value of the target associated with the pointer.

For defined operators, operations on arrays and pointers are determined by the procedure defining the operation.

A scalar is conformable with any array. If one operand of an expression is an array and another operand is a scalar, it is as if the value of the scalar were replicated to form an array of the same shape as the array operand. The result is an array of the same shape as the array operand.

The following sections describe numeric, character, relational, and logical expressions; defined operations; a summary of operator precedence; and initialization and specification expressions.

For More Information:

  • See Arrays.
  • See Derived data types.
  • On function subprograms that define operators, see Defining Generic Operators.
  • On pointers, see the POINTER statement.


Numeric Expressions

Numeric expressions express numeric computations, and are formed with numeric operands and numeric operators. The evaluation of a numeric operation yields a single numeric value.

The term numeric includes logical data, because logical data is treated as integer data when used in a numeric context. The default for .TRUE. is -1; .FALSE. is 0. Note that on Windows systems, the default can change if compiler option /fpscomp:logicals is used.

Numeric operators specify computations to be performed on the values of numeric operands. The result is a scalar numeric value or an array whose elements are scalar numeric values. The following are numeric operators:

Operator | Function
** | Exponentiation
* | Multiplication
/ | Division
+ | Addition or unary plus (identity)
- | Subtraction or unary minus (negation)

Unary operators operate on a single operand. Binary operators operate on a pair of operands. The plus and minus operators can be unary or binary. When they are unary operators, the plus or minus operators precede a single operand and denote a positive (identity) or negative (negation) value, respectively. The exponentiation, multiplication, and division operators are binary operators.

Valid numeric operations must have results that are defined by the arithmetic used by the processor. For example, raising a negative-valued base to a real power is invalid.

Numeric expressions are evaluated in an order determined by a precedence associated with each operator, as follows (see also Summary of Operator Precedence):

Operator | Precedence
** Highest
* and /
   .
Unary + and -
   .
Binary + and - | Lowest

Operators with equal precedence are evaluated in left-to-right order. However, exponentiation is evaluated from right to left. For example, A**B**C is evaluated as A**(B**C). B**C is evaluated first, then A is raised to the resulting power.

Normally, two operators cannot appear together. However, Compaq Fortran allows two consecutive operators if the second operator is a plus or minus.

Examples

In the following example, the exponentiation operator is evaluated first because it takes precedence over the multiplication operator:

A**B*C is evaluated as (A**B)*C

Ordinarily, the exponentiation operator would be evaluated first in the following example. However, because Compaq Fortran allows the combination of the exponentiation and minus operators, the exponentiation operator is not evaluated until the minus operator is evaluated:

A**-B*C is evaluated as A**(-(B*C))

Note that the multiplication operator is evaluated first, since it takes precedence over the minus operator.

When consecutive operators are used with constants, the unary plus or minus before the constant is treated the same as any other operator. This can produce unexpected results. In the following example, the multiplication operator is evaluated first, since it takes precedence over the minus operator:

X/-15.0*Y is evaluated as X/-(15.0*Y)


Using Parentheses in Numeric Expressions

You can use parentheses to force a particular order of evaluation. When part of an expression is enclosed in parentheses, that part is evaluated first. The resulting value is used in the evaluation of the remainder of the expression.

In the following examples, the numbers below the operators indicate a possible order of evaluation. Alternative evaluation orders are possible in the first three examples because they contain operators of equal precedence that are not enclosed in parentheses. In these cases, the compiler is free to evaluate operators of equal precedence in any order, as long as the result is the same as the result gained by the algebraic left-to-right order of evaluation.

     4 + 3 * 2 - 6/2   = 7
       ^   ^   ^  ^
       2   1   4  3

     (4 + 3) * 2 - 6/2   = 11
        ^    ^   ^  ^
        1    2   4  3

     (4 + 3 * 2 - 6)/2   = 2
        ^   ^   ^   ^
        2   1   3   4

     ((4 + 3) * 2 - 6)/2   = 4
         ^    ^   ^   ^
         1    2   3   4

Expressions within parentheses are evaluated according to the normal order of precedence. In expressions containing nested parentheses, the innermost parentheses are evaluated first.

Nonessential parentheses do not affect expression evaluation, as shown in the following example:

     4 + (3 * 2) - (6/2)

However, using parentheses to specify the evaluation order is often important in high-accuracy numerical computations. In such computations, evaluation orders that are algebraically equivalent may not be computationally equivalent when processed by a computer (because of the way intermediate results are rounded off).

Parentheses can be used in argument lists to force a given argument to be treated as an expression, rather than as the address of a memory item.


Data Type of Numeric Expressions

If every operand in a numeric expression is of the same data type, the result is also of that type.

If operands of different data types are combined in an expression, the evaluation of that expression and the data type of the resulting value depend on the ranking associated with each data type. The following table shows the ranking assigned to each data type:

Data Type | Ranking
LOGICAL(1) and BYTE | Lowest
LOGICAL(2)
  .
LOGICAL(4)
  .
LOGICAL(8)
  .
INTEGER(1)
  .
INTEGER(2)
  .
INTEGER(4)
  .
INTEGER(8)
  .
REAL(4)
  .
REAL(8)1
  .
REAL(16)2
  .
COMPLEX(4)
  .
COMPLEX(8)3
  .
COMPLEX(16)2 | Highest
1 DOUBLE PRECISION
2 VMS, U*X
3 DOUBLE COMPLEX

The data type of the value produced by an operation on two numeric operands of different data types is the data type of the highest-ranking operand in the operation. For example, the value resulting from an operation on an integer and a real operand is of real type. However, an operation involving a COMPLEX(4) or COMPLEX(8) data type and a DOUBLE PRECISION data type produces a COMPLEX(8) result.

The data type of an expression is the data type of the result of the last operation in that expression, and is determined according to the following conventions:

  • Integer operations: Integer operations are performed only on integer operands. (Logical entities used in a numeric context are treated as integers.) In integer arithmetic, any fraction resulting from division is truncated, not rounded. For example, the result of 1/4 + 1/4 + 1/4 + 1/4 is 0, not 1.

  • Real operations: Real operations are performed only on real operands or combinations of real, integer, and logical operands. Any integer operands present are converted to real data type by giving each a fractional part equal to zero. The expression is then evaluated using real arithmetic. However, in the statement Y = (I /J)*X , an integer division operation is performed on I and J, and a real multiplication is performed on that result and X.

    If any operand is a higher-precision real (REAL(8) or REAL(16)) type, all other operands are converted to that higher-precision real type before the expression is evaluated.

    When a single-precision real operand is converted to a double-precision real operand, low-order binary digits are set to zero. This conversion does not increase accuracy; conversion of a decimal number does not produce a succession of decimal zeros. For example, a REAL variable having the value 0.3333333 is converted to approximately 0.3333333134651184D0. It is not converted to either 0.3333333000000000D0 or 0.3333333333333333D0.

  • Complex operations: In operations that contain any complex operands, integer operands are converted to real type, as previously described. The resulting single-precision or double-precision operand is designated as the real part of a complex number and the imaginary part is assigned a value of zero. The expression is then evaluated using complex arithmetic and the resulting value is of complex type. Operations involving a COMPLEX(4) or COMPLEX(8) operand and a DOUBLE PRECISION operand are performed as COMPLEX(8) operations; the DOUBLE PRECISION operand is not rounded.

These rules also generally apply to numeric operations in which one of the operands is a constant. However, if a real or complex constant is used in a higher-precision expression, additional precision will be retained for the constant. The effect is as if a DOUBLE PRECISION (REAL(8)) or REAL(16) (VMS, U*X) representation of the constant were given. For example, the expression 1.0D0 + 0.3333333 is treated as if it is 1.0D0 + 0.3333333000000000D0.


Character Expressions

A character expression consists of a character operator (//) that concatenates two operands of type character. The evaluation of a character expression produces a single value of that type.

The result of a character expression is a character string whose value is the value of the left character operand concatenated to the value of the right operand. The length of a character expression is the sum of the lengths of the values of the operands. For example, the value of the character expression 'AB'//'CDE' is 'ABCDE', which has a length of five.

Parentheses do not affect the evaluation of a character expression; for example, the following character expressions are equivalent:

  ('ABC'//'DE')//'F'
  'ABC'//('DE'//'F')
  'ABC'//'DE'//'F'

Each of these expressions has the value ' ABCDEF'.

If a character operand in a character expression contains blanks, the blanks are included in the value of the character expression. For example, 'ABC '//'D E'//'F ' has a value of 'ABC D EF '.


Relational Expressions

A relational expression consists of two or more expressions whose values are compared to determine whether the relationship stated by the relational operator is satisfied. The following are relational operators:

Operator | Relationship
.LT. or < | Less than
.LE. or <= | Less than or equal to
.EQ. or = = | Equal to
.NE. or /= | Not equal to
.GT. or > | Greater than
.GE. or >= | Greater than or equal to

The result of the relational expression is .TRUE. if the relation specified by the operator is satisfied; the result is .FALSE. if the relation specified by the operator is not satisfied.

Relational operators are of equal precedence. Numeric operators and the character operator // have a higher precedence than relational operators.

In a numeric relational expression, the operands are numeric expressions. Consider the following example:

  APPLE+PEACH > PEAR+ORANGE

This expression states that the sum of APPLE and PEACH is greater than the sum of PEAR and ORANGE. If this relationship is valid, the value of the expression is .TRUE.; if not, the value is .FALSE.

Operands of type complex can only be compared using the equal operator (= = or .EQ.) or the not equal operator (/= or .NE.). Complex entities are equal if their corresponding real and imaginary parts are both equal.

In a character relational expression, the operands are character expressions. In character relational expressions, less than (< or .LT.) means the character value precedes in the ASCII collating sequence, and greater than (> or .GT.) means the character value follows in the ASCII collating sequence. For example:

  'AB'//'ZZZ' .LT. 'CCCCC'

This expression states that 'ABZZZ' is less than 'CCCCC'. In this case, the relation specified by the operator is satisfied, so the result is .TRUE..

Character operands are compared one character at a time, in order, starting with the first character of each operand. If the two character operands are not the same length, the shorter one is padded on the right with blanks until the lengths are equal; for example:

  'ABC' .EQ. 'ABC  '

  'AB' .LT. 'C'

The first relational expression has the value .TRUE. even though the lengths of the expressions are not equal, and the second has the value .TRUE. even though 'AB' is longer than 'C'.

A relational expression can compare two numeric expressions of different data types. In this case, the value of the expression with the lower-ranking data type is converted to the higher-ranking data type before the comparison is made.

For More Information:

For details on the ranking of data types, see Data Type of Numeric Expressions.


Logical Expressions

A logical expression consists of one or more logical operators and logical, numeric, or relational operands. The following are logical operators:

Operator | Example | Meaning
.AND. | A .AND. B | Logical conjunction: the expression is true if both A and B are true.
.OR. | A .OR. B | Logical disjunction (inclusive OR): the expression is true if either A, B, or both, are true.
.NEQV. | A .NEQV. B | Logical inequivalence (exclusive OR): the expression is true if either A or B is true, but false if both are true.
.XOR. | A .XOR. B | Same as .NEQV.
.EQV. | A .EQV. B | Logical equivalence: the expression is true if both A and B are true, or both are false.
.NOT.1 | .NOT. A | Logical negation: the expression is true if A is false and false if A is true.
1 .NOT. is a unary operator.

Periods cannot appear consecutively except when the second operator is .NOT. For example, the following logical expression is valid:

  A+B/(A-1) .AND. .NOT. D+B/(D-1)

Data Types Resulting from Logical Operations

Logical operations on logical operands produce single logical values (.TRUE. or .FALSE.) of logical type.

Logical operations on integers produce single values of integer type. The operation is carried out bit-by-bit on corresponding bits of the internal (binary) representation of the integer operands.

Logical operations on a combination of integer and logical values also produce single values of integer type. The operation first converts logical values to integers, then operates as it does with integers.

Logical operations cannot be performed on other data types.

Evaluation of Logical Expressions

Logical expressions are evaluated according to the precedence of their operators. Consider the following expression:

  A*B+C*ABC == X*Y+DM/ZZ .AND. .NOT. K*B > TT

This expression is evaluated in the following sequence:

  (((A*B)+(C*ABC)) == ((X*Y)+(DM/ZZ))) .AND. (.NOT. ((K*B) > TT))

As with numeric expressions, you can use parentheses to alter the sequence of evaluation.

When operators have equal precedence, the compiler can evaluate them in any order, as long as the result is the same as the result gained by the algebraic left-to-right order of evaluation (except for exponentiation, which is evaluated from right to left).

You should not write logical expressions whose results might depend on the evaluation order of subexpressions. The compiler is free to evaluate subexpressions in any order. In the following example, either (A(I)+1.0) or B(I)*2.0 could be evaluated first:

  (A(I)+1.0) .GT. B(I)*2.0

Some subexpressions might not be evaluated if the compiler can determine the result by testing other subexpressions in the logical expression. Consider the following expression:

  A .AND. (F(X,Y) .GT. 2.0) .AND. B

If the compiler evaluates A first, and A is false, the compiler might determine that the expression is false and might not call the subprogram F(X,Y).

For More Information:

For details on the precedence of numeric, relational, and logical operators, see Summary of Operator Precedence.


Defined Operations

When operators are defined for functions, the functions can then be referenced as defined operations.

The operators are defined by using a generic interface block specifying OPERATOR, followed by the defined operator (in parentheses).

A defined operation is not an intrinsic operation. However, you can use a defined operation to extend the meaning of an intrinsic operator.

For defined unary operations, the function must contain one argument. For defined binary operations, the function must contain two arguments.

Interpretation of the operation is provided by the function that defines the operation.

A Fortran 95/90 defined operator can contain up to 31 letters, and is enclosed in periods (.). Its name cannot be the same name as any of the following:

  • The intrinsic operators (.NOT., .AND., .OR., .XOR., .EQV., .NEQV., .EQ., .NE., .GT., .GE., .LT., and .LE.)
  • The logical literal constants (.TRUE. or .FALSE.)

An intrinsic operator can be followed by a defined unary operator.

The result of a defined operation can have any type. The type of the result (and its value) must be specified by the defining function.

Examples

The following examples show expressions containing defined operators:

  .COMPLEMENT. A
  X .PLUS. Y .PLUS. Z
  M * .MINUS. N

For More Information:

  • On defining generic operators, see Defining Generic Operators.
  • On operator precedence, see Summary of Operator Precedence.


Summary of Operator Precedence

The following table shows the precedence of all intrinsic and defined operators:

Precedence of Expression Operators

Category | Operator | Precedence
Defined Unary Operators | Highest
Numeric **
   .
Numeric * or /
   .
Numeric Unary + or -
   .
Numeric Binary + or -
   .
Character //
   .
Relational .EQ., .NE., .LT., .LE., .GT., .GE.
= =, /=, <, <=, >, >=
   .
Logical .NOT.
   .
Logical .AND.
   .
Logical .OR.
   .
Logical .XOR., .EQV., .NEQV.
   .
Defined Binary Operators | Lowest


Initialization and Specification Expressions

A constant expression contains intrinsic operations and parts that are all constants. An initialization expression is a constant expression that is evaluated when a program is compiled. A specification expression is a scalar, integer expression that is restricted to declarations of array bounds and character lengths.

Initialization and specification expressions can appear in specification statements, with some restrictions.


Initialization Expressions

An initialization expression must evaluate at compile time to a constant. It is used to specify an initial value for an entity.

In an initialization expression, each operation is intrinsic and each operand is one of the following:

  • A constant or subobject of a constant

  • An array constructor where each element and the bounds and strides of each implied-do, are expressions whose primaries are initialization expressions

  • A structure constructor whose components are initialization expressions

  • An elemental intrinsic function reference of type integer or character, whose arguments are initialization expressions of type integer or character

  • A reference to one of the following inquiry functions:

    BIT_SIZE | MINEXPONENT
    DIGITS | PRECISION
    EPSILON | RADIX
    HUGE | RANGE
    ILEN | SHAPE
    KIND | SIZE
    LBOUND | TINY
    LEN | UBOUND
    MAXEXPONENT

    Each function argument must be one of the following:

    • An initialization expression

    • A variable whose kind type parameter and bounds are not assumed or defined by an ALLOCATE statement, pointer assignment, or an expression that is not an initialization expression

  • A reference to one of the following transformational functions (each argument must be an initialization expression):

    REPEAT | SELECTED_REAL_KIND
    RESHAPE | TRANSFER
    SELECTED_INT_KIND | TRIM

  • A reference to the transformational function NULL

  • An implied-do variable within an array constructor where the bounds and strides of the corresponding implied-do are initialization expressions

  • Another initialization expression enclosed in parentheses

Each subscript, section subscript, and substring starting and ending point must be an initialization expression.

In an initialization expression, the exponential operator (**) must have a power of type integer.

If an initialization expression invokes an inquiry function for a type parameter or an array bound of an object, the type parameter or array bound must be specified in a prior specification statement (or to the left of the inquiry function in the same statement).

Examples

The following examples show valid and invalid initialization (constant) expressions:

Valid |
-1 + 3 |
SIZE(B) | ! B is a named constant
7_2 |
INT(J, 4) | ! J is a named constant
SELECTED_INT_KIND (2) |
Invalid | Explanation
SUM(A) | Not an allowed function.
A/4.1 - K**1.2 | Exponential does not have integer power (A and K are named constants).
HUGE(4.0) | Argument is not an integer.

For More Information:

  • See Array constructors.
  • See Structure constructors.
  • See Intrinsic procedures.


Specification Expressions

A specification expression is a restricted expression that is of type integer and has a scalar value. This type of expression appears only in the declaration of array bounds and character lengths.

In a restricted expression, each operation is intrinsic and each operand is one of the following:

  • A constant or subobject of a constant

  • A variable that is one of the following:

    • A dummy argument that does not have the OPTIONAL or INTENT (OUT) attribute (or the subobject of such a variable)

    • In a common block (or the subobject of such a variable)

    • Made accessible by use or host association (or the subobject of such a variable)

  • A structure constructor whose components are restricted expressions

  • An implied-do variable within an array constructor, where the bounds and strides of the corresponding implied-do are restricted expressions

  • A reference to one of the following inquiry functions:

    BIT_SIZE | NWORKERS
    DIGITS | PRECISION
    EPSILON | PROCESSORS_SHAPE
    HUGE | RADIX
    ILEN | RANGE
    KIND | SHAPE
    LBOUND | SIZE
    LEN | SIZEOF
    MAXEXPONENT | TINY
    MINEXPONENT | UBOUND
    NUMBER_OF_PROCESSORS

    Each function argument must be one of the following:

    • A restricted expression

    • A variable whose properties inquired about are not dependent on the upper bound of the last dimension of an assumed-size array, are not defined by an expression that is not a restricted expression, or are not definable by an ALLOCATE or pointer assignment statement.

  • A reference to any other intrinsic function where each argument is a restricted expression.

  • A reference to a specification function where each argument is a restricted expression

  • An array constructor where each element and the bounds and strides of each implied-do, are expressions whose primaries are restricted expressions

  • Another restricted expression enclosed in parentheses

Each subscript, section subscript, and substring starting and ending point must be a restricted expression.

Specification functions can be used in specification expressions to indicate the attributes of data objects. A specification function is a pure function. It cannot have a dummy procedure argument or be any of the following:

  • An intrinsic function
  • An internal function
  • A statement function
  • Defined as RECURSIVE

A variable in a specification expression must have its type and type parameters (if any) specified in one of the following ways:

  • By a previous declaration in the same scoping unit

  • By the implicit typing rules currently in effect for the scoping unit

  • By host or use association

If a variable in a specification expression is typed by the implicit typing rules, its appearance in any subsequent type declaration statement must confirm the implied type and type parameters.

If a specification expression invokes an inquiry function for a type parameter or an array bound of an object, the type parameter or array bound must be specified in a prior specification statement (or to the left of the inquiry function in the same statement).

In a specification expression, the number of arguments for a function reference is limited to 255.

Examples

The following shows valid specification expressions:

  MAX(I) + J          ! I and J are scalar integer variables
  UBOUND(ARRAY_B,20)  ! ARRAY_B is an assumed-shape dummy array

For More Information:

  • See Array constructors.
  • See Structure constructors.
  • See Intrinsic procedures.
  • See Implicit typing rules.
  • See Use and host association.
  • See PURE procedures.


Assignment Statements

An assignment statement causes variables to be defined or redefined. This section describes the following kinds of assignment statements: intrinsic, defined, pointer, masked array (WHERE), and element array (FORALL).

The ASSIGN statement assigns a label to an integer variable. It is discussed elsewhere.


Intrinsic Assignments

Intrinsic assignment is used to assign a value to a nonpointer variable. In the case of pointers, intrinsic assignment is used to assign a value to the target associated with the pointer variable. The value assigned to the variable (or target) is determined by evaluation of the expression to the right of the equal sign.

An intrinsic assignment statement takes the following form:

variable = expression

variable
Is the name of a scalar or array of intrinsic or derived type (with no defined assignment). The array cannot be an assumed-size array, and neither the scalar nor the array can be declared with the PARAMETER or INTENT(IN) attribute.

expression
Is of intrinsic type or the same derived type as variable. Its shape must conform with variable. If necessary, it is converted to the same type and kind as variable.

Rules and Behavior

Before a value is assigned to the variable, the expression part of the assignment statement and any expressions within the variable are evaluated. No definition of expressions in the variable can affect or be affected by the evaluation of the expression part of the assignment statement.

Note: When the run-time system assigns a value to a scalar integer or character variable and the variable is shorter than the value being assigned, the assigned value may be truncated and significant bits (or characters) lost. This truncation can occur without warning, and can cause the run- time system to pass incorrect information back to the program.

If the variable is a pointer, it must be associated with a definable target. The shape of the target and expression must conform and their type and kind parameters must match.

The following sections discuss numeric, logical, character, derived- type, and array intrinsic assignment.

For More Information:

  • See Arrays.
  • See Pointers.
  • See Derived data types.
  • On subroutine subprograms that define assignment, see Defining Generic Assignment.


Numeric Assignment Statements

For numeric assignment statements, the variable and expression must be numeric type.

The expression must yield a value that conforms to the range requirements of the variable. For example, a real expression that produces a value greater than 32767 is invalid if the entity on the left of the equal sign is an INTEGER(2) variable.

Significance can be lost if an INTEGER(4) value, which can exactly represent values of approximately the range -2*10**9 to +2*10**9, is converted to REAL(4) (including the real part of a complex constant), which is accurate to only about seven digits.

If the variable has the same data type as that of the expression on the right, the statement assigns the value directly. If the data types are different, the value of the expression is converted to the data type of the variable before it is assigned.

The following table summarizes the data conversion rules for numeric assignment statements. REAL(16) and COMPLEX(16) are only available on OpenVMS, Tru64 UNIX, and Linux systems.

Conversion Rules for Numeric Assignment Statements
Scalar Memory Reference (V) | Expression (E)
 | Integer, Logical or Real | Complex
Integer or Logical | V=INT(E) | V=INT(REAL(E)) Imaginary part of E is not used.
REAL (KIND=4) | V=REAL(E) | V=REAL(REAL(E)) Imaginary part of E is not used.
REAL (KIND=8) | V=DBLE(E) | V=DBLE(REAL(E)) Imaginary part of E is not used.
REAL (KIND=16) | V=QEXT(E) | V=QEXT(REAL(E)) Imaginary part of E is not used.
COMPLEX (KIND=4) | V=CMPLX(REAL(E), 0.0) | V=CMPLX(REAL(REAL(E)), REAL(AIMAG(E)))
COMPLEX (KIND=8) | V=CMPLX(DBLE(E), 0.0) | V=CMPLX(DBLE(REAL(E)), DBLE(AIMAG(E)))
COMPLEX (KIND=16) | V=CMPLX(QEXT(E), 0.0) | V=CMPLX(QEXT(REAL(E)), QEXT(AIMAG(E)))

For more information, see INT, REAL, DBLE, QEXT, CMPLX, and AIMAG.

Examples

The following examples demonstrate valid and invalid numeric assignment statements:

Valid
BETA = -1./(2.*X)+A*A /(4.*(X*X))
PI = 3.14159 |
SUM = SUM + 1. |
ARRAY_A = ARRAY_B + ARRAY_C + SCALAR_I | ! Valid if all arrays conform in shape
Invalid | Explanation
3.14 = A - B | Entity on the left must be a variable.
ICOUNT = A//B(3:7) | Implicitly typed data types do not match.
SCALAR_I = ARRAY_A(:) | Shapes do not match.


Logical Assignment Statements

For logical assignment statements, the variable must be of logical type and the expression can be of logical or numeric type.

If necessary, the expression is converted to the same type and kind as the variable.

Examples

The following examples demonstrate valid logical assignment statements:

PAGEND = .FALSE.

PRNTOK = LINE .LE. 132 .AND. .NOT. PAGEND

ABIG = A.GT.B .AND. A.GT.C .AND. A.GT.D

LOGICAL_VAR = 123      ! Moves binary value of 123 to LOGICAL_VAR


Character Assignment Statements

For character assignment statements, the variable and expression must be of character type and have the same kind parameter.

The variable and expression can have different lengths. If the length of the expression is greater than the length of the variable, the character expression is truncated on the right. If the length of the expression is less than the length of the variable, the character expression is filled on the right with blank characters.

If you assign a value to a character substring, you do not affect character positions in any part of the character scalar variable not included in the substring. If a character position outside of the substring has a value previously assigned, it remains unchanged. If the character position is undefined, it remains undefined.

Examples

The following examples demonstrate valid and invalid character assignment statements. (In the valid examples, all variables are of type character.)

Valid |
FILE = 'PROG2' |
REVOL(1) = 'MAR'//'CIA' |
LOCA(3:8) = 'PLANT5' |
TEXT(I,J+1)(2:N-1) = NAME/ /X
Invalid | Explanation
'ABC' = CHARS | Left element must be a character variable, array element, or substring reference.
CHARS = 25 | Expression does not have a character data type.
STRING = 5HBEGIN | Expression does not have a character data type. (Hollerith constants are numeric, not character.)


Derived-Type Assignment Statements

In derived-type assignment statements, the variable and expression must be of the same derived type. There must be no accessible interface block with defined assignment for objects of this derived type.

The derived-type assignment is performed as if each component of the expression is assigned to the corresponding component of the variable. Pointer assignment is performed for pointer components, and intrinsic assignment is performed for nonpointer components.

Examples

The following example demonstrates derived-type assignment:

TYPE DATE
  LOGICAL(1) DAY, MONTH
  INTEGER(2) YEAR
END TYPE DATE

TYPE(DATE) TODAY, THIS_WEEK(7)

TYPE APPOINTMENT
...
  TYPE(DATE) APP_DATE
END TYPE

TYPE(APPOINTMENT) MEETING

DO I = 1,7
  CALL GET_DATE(TODAY)
  THIS_WEEK(I) = TODAY
END DO
MEETING%APP_DATE = TODAY

For More Information:

  • See Derived types.
  • See Pointer assignments.


Array Assignment Statements

Array assignment is permitted when the array expression on the right has the same shape as the array variable on the left, or the expression on the right is a scalar.

If the expression is a scalar, and the variable is an array, the scalar value is assigned to every element of the array.

If the expression is an array, the variable must also be an array. The array element values of the expression are assigned (element by element) to corresponding elements of the array variable.

A many-one array section is a vector-valued subscript that has two or more elements with the same value. In intrinsic assignment, the variable cannot be a many-one array section because the result of the assignment is undefined.

Examples

In the following example, X and Y are arrays of the same shape:

  X = Y

The corresponding elements of Y are assigned to those of X element by element; the first element of Y is assigned to the first element of X, and so forth. The processor can perform the element-by-element assignment in any order.

The following example shows a scalar assigned to an array:

  B(C+1:N, C) = 0

This sets the elements B (C+1,C), B (C+2,C),...B (N,C) to zero.

The following example causes the values of the elements of array A to be reversed:

  REAL A(20)
  ...
  A(1:20) = A(20:1:-1)

For More Information:

  • See Arrays.
  • See Array constructors.
  • On masked array assignment, see WHERE.
  • On element array assignment, see FORALL.


Defined Assignments

Defined assignment specifies an assignment operation. It is defined by a subroutine subprogram containing a generic interface block with the specifier ASSIGNMENT(=). The subroutine is specified by a SUBROUTINE or ENTRY statement that has two nonoptional dummy arguments.

Defined elemental assignment is indicated by specifying ELEMENTAL in the SUBROUTINE statement.

The dummy arguments represent the variable and expression, in that order. The rank (and shape, if either or both are arrays), type, and kind parameters of the variable and expression in the assignment statement must match those of the corresponding dummy arguments.

The dummy arguments must not both be numeric, or of type logical or character with the same kind parameter.

If the variable in an elemental assignment is an array, the defined assignment is performed element-by-element, in any order, on corresponding elements of the variable and expression. If the expression is scalar, it is treated as if it were an array of the same shape as the variable with every element of the array equal to the scalar value of the expression.

For More Information:

  • See Subroutines.
  • See Derived data types.
  • On subroutine subprograms that define assignment, see Defining Generic Assignment.
  • On intrinsic operations, see Numeric Expressions and Character Expressions.


Pointer Assignments

In ordinary assignment involving pointers, the pointer is an alias for its target. In pointer assignment, the pointer is associated with a target. If the target is undefined or disassociated, the pointer acquires the same status as the target. The pointer assignment statement has the following form:

pointer-object => target

pointer-object
Is a variable name or structure component declared with the POINTER attribute.

target
Is a variable or expression. Its type and kind parameters, and rank must be the same as pointer-object. It cannot be an array section with a vector subscript.

Rules and Behavior

If the target is a variable, it must have the POINTER or TARGET attribute, or be a subobject whose parent object has the TARGET attribute.

If the target is an expression, the result must be a pointer.

If the target is not a pointer (it has the TARGET attribute), the pointer object is associated with the target.

If the target is a pointer (it has the POINTER attribute), its status determines the status of the pointer object, as follows:

  • If the pointer is associated, the pointer object is associated with the same object as the target

  • If the pointer is disassociated, the pointer object becomes disassociated

  • If the pointer is undefined, the pointer object becomes undefined

A pointer must not be referenced or defined unless it is associated with a target that can be referenced or defined.

When pointer assignment occurs, any previous association between the pointer object and a target is terminated.

Pointers can also be assigned for a pointer structure component by execution of a derived-type intrinsic assignment statement or a defined assignment statement.

Pointers can also become associated by using the ALLOCATE statement to allocate the pointer.

Pointers can become disassociated by deallocation, nullification of the pointer (using the DEALLOCATE or NULLIFY statements), or by reference to the NULL intrinsic function.

Examples

The following are examples of pointer assignments:

  HOUR => MINUTES(1:60)         ! target is an array
  M_YEAR => MY_CAR%YEAR         ! target is a structure component
  NEW_ROW%RIGHT => CURRENT_ROW  ! pointer object is a structure component
  PTR => M                      ! target is a variable
  POINTER_C => NULL ()          ! reference to NULL intrinsic

The following example shows a target as a pointer:

  INTEGER, POINTER :: P, N
  INTEGER, TARGET :: M
  INTEGER S
  M = 14
  N => M                         ! N is associated with M
  P => N                         ! P is associated with M through N
  S = P + 5

The value assigned to S is 19 (14 + 5).

You can use the intrinsic function ASSOCIATED to find out if a pointer is associated with a target or if two pointers are associated with the same target. For example:

  REAL C (:), D(:), E(5)
  POINTER C, D
  TARGET E
  LOGICAL STATUS
  ! Pointer assignment.
  C => E
  ! Pointer assignment.
  D => E
  ! Returns TRUE; C is associated.
  STATUS = ASSOCIATED (C)
  ! Returns TRUE; C is associated with E.
  STATUS = ASSOCIATED (C, E)
  ! Returns TRUE; C and D are associated with the
  ! same target.
  STATUS = ASSOCIATED (C, D)

For More Information:

  • See Arrays.
  • See ALLOCATE.
  • See ASSOCIATED.
  • See DEALLOCATE.
  • See NULLIFY.
  • See NULL.
  • See POINTER.
  • See Defined assignments.
  • On derived-type intrinsic assignments, see Intrinsic Assignments.


WHERE Statement and Construct

You can perform an array operation on selected elements by using masked array assignment. For more information, see WHERE.

See also FORALL.


FORALL Statement and Constructs

FORALL Statement and Construct

The FORALL statement and construct is a generalization of the Fortran 95/90 masked array assignment. It allows more general array shapes to be assigned, especially in construct form. For more information, see FORALL.

See also WHERE.


Specification Statements

A specification statement is a nonexecutable statement that declares the attributes of data objects. In Fortran 95/90, many of the attributes that can be defined in specification statements can also be optionally specified in type declaration statements.

The following are specification statements:

  • Type declaration statement

    Explicitly specifies the properties (for example: data type, rank, and extent) of data objects.

  • ALLOCATABLE attribute and statement

    Specifies a list of array names that are allocatable (have a deferred-shape).

  • AUTOMATIC and STATIC attributes and statements

    Control the storage allocation of variables in subprograms.

  • COMMON statement

    Defines one or more contiguous areas, or blocks, of physical storage (called common blocks).

  • DATA statement

    Assigns initial values to variables before program execution.

  • DIMENSION attribute and statement

    Specifies that an object is an array, and defines the shape of the array.

  • EQUIVALENCE statement

    Specifies that a storage area is shared by two or more objects in a program unit.

  • EXTERNAL attribute and statement

    Allows external (user-supplied) procedures to be used as arguments to other subprograms.

  • IMPLICIT statement

    Overrides the implicit data type of names.

  • INTENT attribute and statement

    Specifies the intended use of a dummy argument.

  • INTRINSIC attribute and statement

    Allows intrinsic procedures to be used as arguments to subprograms.

  • NAMELIST statement

    Associates a name with a list of variables. This group name can be referenced in some input/output operations.

  • OPTIONAL attribute and statement

    Allows a procedure reference to omit arguments.

  • PARAMETER attribute and statement

    Defines a named constant.

  • POINTER attribute and statement

    Specifies that an object is a pointer.

  • PUBLIC and PRIVATE attributes and statements

    Declare the accessibility of entities in a module.

  • SAVE attribute and statement

    Causes the definition and status of objects to be retained after the subprogram in which they are declared completes execution.

  • TARGET attribute and statement

    Specifies a pointer target.

  • VOLATILE attribute and statement

    Prevents optimizations from being performed on specified objects.

For More Information:

  • See BLOCK DATA.
  • See PROGRAM.


Type Declaration Statements

A type declaration statement explicitly specifies the properties of data objects or functions. For more information, see Type Declarations in the A to Z Reference.

This section also discusses:

  • Declaration Statements for Noncharacter Types
  • Declaration Statements for Character Types
  • Declaration Statements for Derived Types
  • Declaration Statements for Arrays

For More Information:

  • See Derived data types.
  • See the DATA statement.
  • See Initialization expressions.
  • On specific kind parameters of intrinsic data types, see Intrinsic Data Types.
  • On implicit typing, see Implicit Typing Rules.
  • On explicit typing, see Specification of Data Type.


Declaration Statements for Noncharacter Types

The following table shows the data types that can appear in noncharacter type declaration statements.

Noncharacter Data Types
BYTE1
LOGICAL2
LOGICAL([KIND=]1) (or LOGICAL*1)
LOGICAL([KIND=]2) (or LOGICAL*2)
LOGICAL([KIND=]4) (or LOGICAL*4)
LOGICAL([KIND=]8) (or LOGICAL*8)
INTEGER3
INTEGER([KIND=]1) (or INTEGER*1)
INTEGER([KIND=]2) (or INTEGER*2)
INTEGER([KIND=]4) (or INTEGER*4)
INTEGER([KIND=]8) (or INTEGER*8)
REAL4
REAL([KIND=]4) (or REAL*4)
DOUBLE PRECISION (REAL([KIND=]8) or REAL*8)
REAL([KIND=]16) (or REAL*16)5
COMPLEX6
COMPLEX([KIND=]4) (or COMPLEX*8)
DOUBLE COMPLEX (COMPLEX([KIND=]8) or COMPLEX*16)
COMPLEX([KIND=]16) (or COMPLEX*32)5
1 Same as INTEGER(1).
2 This is treated as default logical.
3 This is treated as default integer.
4 This is treated as default real.
5 VMS, U*X.
6 This is treated as default complex.

In noncharacter type declaration statements, you can optionally specify the name of the data object or function as v*n, where n is the length (in bytes) of v. The length specified overrides the length implied by the data type.

The value for n must be a valid length for the type of v. The type specifiers BYTE, DOUBLE PRECISION, and DOUBLE COMPLEX have one valid length, so the n specifier is invalid for them.

For an array specification, the n must be placed immediately following the array name; for example, in an INTEGER declaration statement, IVEC*2(10) is an INTEGER(2) array of 10 elements.

Examples

In a noncharacter type declaration statement, a subsequent kind parameter overrides any initial kind parameter. For example, consider the following statements:

  INTEGER(KIND=2) I, J, K, M12*4, Q, IVEC*4(10)
  REAL(KIND=8) WX1, WXZ, WX3*4, WX5, WX6*4
  REAL(KIND=8) PI/3.14159E0/, E/2.72E0/, QARRAY(10)/5*0.0,5*1.0/

In the first statement, M12*4 and IVEC*4 override the KIND=2 specification. In the second statement, WX3*4 and WX6*4 override the KIND=8 specification. In the third statement, QARRAY is initialized with implicit conversion of the REAL(4) constants to a REAL(8) data type.

For More Information:

  • On compiler options that can affect the defaults for numeric and logical data types, see your programmer's guide.
  • On the general form and rules for type declaration statements, see Type Declarations.


Declaration Statements for Character Types

A CHARACTER type specifier can be immediately followed by the length of the character object or function. It takes one of the following forms:

Keyword Forms

CHARACTER [([LEN=]len)]
CHARACTER [([LEN=]len [, [KIND=]n])]
CHARACTER [(KIND=n [, LEN=len])]

Nonkeyword Form

CHARACTER*len[,]

len
Is one of the following:

  • In keyword forms

    The len is a specification expression or an asterisk (*). If no length is specified, the default length is 1.

    If the length evaluates to a negative value, the length of the character entity is zero.

  • In nonkeyword form

    The len is a specification expression or an asterisk enclosed in parentheses, or a scalar integer literal constant (with no kind parameter). The comma is permitted only if no double colon (::) appears in the type declaration statement.

    This form can also (optionally) be specified following the name of the data object or function (v*len). In this case, the length specified overrides any length following the CHARACTER type specifier.

The largest valid value for len in both forms is 2147483647 (2**31-1) for Tru64 UNIX, Linux, and Windows systems; 65535 for OpenVMS systems. Negative values are treated as zero.

n
Is a scalar integer initialization expression specifying a valid kind parameter. Currently the only kind available is 1.

Rules and Behavior

An automatic object can appear in a character declaration. The object cannot be a dummy argument, and its length must be declared with a specification expression that is not a constant expression.

The length specified for a character-valued statement function or statement function dummy argument of type character must be an integer constant expression.

When an asterisk length specification *(*) is used for a function name or dummy argument, it assumes the length of the corresponding function reference or actual argument. Similarly, when an asterisk length specification is used for a named constant, the name assumes the length of the actual constant it represents. For example, STRING assumes a 9-byte length in the following statements:

  CHARACTER*(*) STRING
  PARAMETER (STRING = 'VALUE IS:')

A function name must not be declared with a * length, if the function is an internal or module function, or if it is array-valued, pointer-valued, recursive, or pure.

The form CHARACTER*(*) is an obsolescent feature in Fortran 95.

Examples

In the following example, the character string last_name is given a length of 20:

  CHARACTER (LEN=20) last_name

In the following example, stri is given a length of 12, while the other two variables retain a length of 8.

  CHARACTER *8 strg, strh, stri*12

In the following example, as a dummy argument strh is given the length of an assigned string when it is assigned, while the other two variables retain a length of 8:

  CHARACTER *8 strg, strh(*), stri

The following examples show ways to specify strings of known length:

  CHARACTER*32 string
  CHARACTER string*32

The following examples show ways to specify strings of unknown length:

  CHARACTER string*(*)
  CHARACTER*(*) string

The following example declares an array NAMES containing 100 32-character elements, an array SOCSEC containing 100 9-character elements, and a variable NAMETY that is 10 characters long and has an initial value of 'ABCDEFGHIJ'.

  CHARACTER*32 NAMES(100),SOCSEC(100)*9,NAMETY*10 /'ABCDEFGHIJ'/

The following example includes a CHARACTER statement declaring two 8-character variables, LAST and FIRST.

  INTEGER, PARAMETER :: LENGTH=4
  CHARACTER*(4+LENGTH) LAST, FIRST

The following example shows a CHARACTER statement declaring an array LETTER containing 26 one-character elements. It also declares a dummy argument BUBBLE that has a passed length defined by the calling program.

  CHARACTER LETTER(26), BUBBLE*(*)

In the following example, NAME2 is an automatic object:

  SUBROUTINE AUTO_NAME(NAME1)
    CHARACTER(LEN = *) NAME1
    CHARACTER(LEN = LEN(NAME1)) NAME2

For More Information:

  • See Obsolescent features in Fortran 95.
  • On asterisk length specifications, see Data Types of Scalar Variables and Assumed-Length Character Arguments.
  • On the general form and rules for type declaration statements, see Type Declarations.


Declaration Statements for Derived Types

The derived-type (TYPE) declaration statement specifies the properties of objects and functions of derived (user-defined) type.

The derived type must be defined before you can specify objects of that type in a TYPE type declaration statement.

An object of derived type must not have the PUBLIC attribute if its type is PRIVATE.

A structure constructor specifies values for derived-type objects.

Examples

The following are examples of derived-type declaration statements:

  TYPE(EMPLOYEE) CONTRACT
  ...
  TYPE(SETS), DIMENSION(:,:), ALLOCATABLE :: SUBSET_1

The following example shows a public type with private components:

  TYPE LIST_ITEMS
    PRIVATE
    ...
    TYPE(LIST_ITEMS), POINTER :: NEXT, PREVIOUS
  END TYPE LIST_ITEMS

For More Information:

  • See the TYPE statement.
  • See Use and host association.
  • See the PUBLIC and PRIVATE attributes.
  • See Structure constructors.
  • On the general form and rules for type declaration statements, see Type Declarations.


Declaration Statements for Arrays

An array declaration (or array declarator) declares the shape of an array. It takes the following form:

(a-spec)

a-spec
Is one of the following array specifications:

  • Explicit-shape
  • Assumed-shape
  • Assumed-size
  • Deferred-shape

The array specification can be appended to the name of the array when the array is declared.

Examples

The following examples show array declarations:

SUBROUTINE SUB(N, C, D, Z)
  REAL, DIMENSION(N, 15) :: IARRY       ! An explicit-shape array
  REAL C(:), D(0:)                      ! An assumed-shape array
  REAL, POINTER :: B(:,:)               ! A deferred-shape array pointer
  REAL, ALLOCATABLE, DIMENSION(:) :: K  ! A deferred-shape allocatable array
  REAL :: Z(N,*)                        ! An assumed-size array

For More Information:

For details on the general form and rules for type declaration statements, see Type Declarations in the A to Z Reference.


Explicit-Shape Specifications

An explicit-shape array is declared with explicit values for the bounds in each dimension of the array. An explicit-shape specification takes the following form:

([dl:] du[, [dl:] du] ...)

dl
Is a specification expression indicating the lower bound of the dimension. The expression can have a positive, negative, or zero value. If necessary, the value is converted to integer type.

If the lower bound is not specified, it is assumed to be 1.

du
Is a specification expression indicating the upper bound of the dimension. The expression can have a positive, negative, or zero value. If necessary, the value is converted to integer type.

The bounds can be specified as constant or nonconstant expressions, as follows:

  • If the bounds are constant expressions, the subscript range of the array in a dimension is the set of integer values between and including the lower and upper bounds. If the lower bound is greater than the upper bound, the range is empty, the extent in that dimension is zero, and the array has a size of zero.

  • If the bounds are nonconstant expressions, the array must be declared in a procedure. The bounds can have different values each time the procedure is executed, since they are determined when the procedure is entered.

    The bounds are not affected by any redefinition or undefinition of the variables in the specification expression that occurs while the procedure is executing.

    The following explicit-shape arrays can specify nonconstant bounds:

    • An automatic array (the array is a local variable)
    • An adjustable array (the array is a dummy argument to a subprogram)

The following are examples of explicit-shape specifications:

INTEGER I(3:8, -2:5)         ! Rank-two array; range of dimension one is
...                          ! 3 to 8, range of dimension two is -2 to 5
SUBROUTINE SUB(A, B, C)
  INTEGER :: B, C
  REAL, DIMENSION(B:C) :: A  ! Rank-one array; range is B to C

Consider the following:

 INTEGER M(10, 10, 10)
 INTEGER K(-3:6, 4:13, 0:9)

M and K are both explicit-shape arrays with a rank of 3, a size of 1000, and the same shape (10,10,10). Array M uses the default lower bound of 1 for each of its dimensions. So, when it is declared only the upper bound needs to be specified. Each of the dimensions of array K has a lower bound other than the default, and the lower bounds as well as the upper bounds are declared.

Automatic Arrays

An automatic array is an explicit-shape array that is a local variable. Automatic arrays are only allowed in function and subroutine subprograms, and are declared in the specification part of the subprogram. At least one bound of an automatic array must be a nonconstant specification expression. The bounds are determined when the subprogram is called.

The following example shows automatic arrays:

SUBROUTINE SUB1 (A, B)
  INTEGER A, B, LOWER
  COMMON /BOUND/ LOWER
  ...
  INTEGER AUTO_ARRAY1(B)
  ...
  INTEGER AUTO_ARRAY2(LOWER:B)
  ...
  INTEGER AUTO_ARRAY3(20, B*A/2)
END SUBROUTINE

Consider the following:

 SUBROUTINE EXAMPLE (N, R1, R2)
   DIMENSION A (N, 5), B(10*N)
   ...
   N = IFIX(R1) + IFIX(R2)

When the subroutine is called, the arrays A and B are dimensioned on entry into the subroutine with the value of the passed variable N. Later changes to the value of N have no effect on the dimensions of array A or B.

Adjustable Arrays

An adjustable array is an explicit-shape array that is a dummy argument to a subprogram. At least one bound of an adjustable array must be a nonconstant specification expression. The bounds are determined when the subprogram is called.

The array specification can contain integer variables that are either dummy arguments or variables in a common block.

When the subprogram is entered, each dummy argument specified in the bounds must be associated with an actual argument. If the specification includes a variable in a common block, the variable must have a defined value. The array specification is evaluated using the values of the actual arguments, as well as any constants or common block variables that appear in the specification.

The size of the adjustable array must be less than or equal to the size of the array that is its corresponding actual argument.

To avoid possible errors in subscript evaluation, make sure that the bounds expressions used to declare multidimensional adjustable arrays match the bounds as declared by the caller.

In the following example, the function computes the sum of the elements of a rank-two array. Notice how the dummy arguments M and N control the iteration:

  FUNCTION THE_SUM(A, M, N)
    DIMENSION A(M, N)
    SUMX = 0.0
    DO J = 1, N
      DO I = 1, M
        SUMX = SUMX + A(I, J)
      END DO
    END DO
    THE_SUM = SUMX
  END FUNCTION

The following are examples of calls on THE_SUM:

DIMENSION A1(10,35), A2(3,56)
SUM1 = THE_SUM(A1,10,35)
SUM2 = THE_SUM(A2,3,56)

The following example shows how the array bounds determined when the procedure is entered do not change during execution:

DIMENSION ARRAY(9,5)
L = 9
M = 5
CALL SUB(ARRAY,L,M)
END

SUBROUTINE SUB(X,I,J)
  DIMENSION X(-I/2:I/2,J)
  X(I/2,J) = 999
  J = 1
  I = 2
END

The assignments to I and J do not affect the declaration of adjustable array X as X(-4:4,5) on entry to subroutine SUB.

For More Information:

See also Specification expressions.


Assumed-Shape Specifications

An assumed-shape array is a dummy argument array that assumes the shape of its associated actual argument array. An assumed-shape specification takes the following form:

([dl]:[, [dl]:] ...)

dl
Is a specification expression indicating the lower bound of the dimension. The expression can have a positive, negative, or zero value. If necessary, the value is converted to integer type.

If the lower bound is not specified, it is assumed to be 1.

The rank of the array is the number of colons (:) specified.

The value of the upper bound is the extent of the corresponding dimension of the associated actual argument array + lower-bound - 1.

Examples

The following is an example of an assumed-shape specification:

INTERFACE
  SUBROUTINE SUB(M)
    INTEGER M(:, 1:, 5:)
  END SUBROUTINE
END INTERFACE
INTEGER L(20, 5:25, 10)
CALL SUB(L)

SUBROUTINE SUB(M)
  INTEGER M(:, 1:, 5:)
END SUBROUTINE

Array M has the same extents as array L, but array M has bounds (1:20, 1:21, 5:14).

Note that an explicit interface is required when calling a routine that expects an assumed-shape or pointer array.

Consider the following:

 SUBROUTINE ASSUMED(A)
   REAL A(:, :, :)

The array A has rank 3, indicated by the three colons (:) separated by commas (,). However, the extent of each dimension is unspecified. When the subroutine is called, A takes its shape from the array passed to it. For example, consider the following:

 REAL X (4, 7, 9)
 ...
 CALL ASSUMED(X)

This gives A the dimensions (4, 7, 9). The actual array and the assumed-shape array must have the same rank.

Consider the following:

 SUBROUTINE ASSUMED(A)
   REAL A(3:, 0:, -2:)
 ...

If the subroutine is called with the same actual array X(4, 7, 9), as in the previous example, the lower and upper bounds of A would be:

A(3:6, 0:6, -2:6)


Assumed-Size Specifications

An assumed-size array is a dummy argument array that assumes the size (only) of its associated actual argument array; the rank and extents can differ for the actual and dummy arrays. An assumed-size specification takes the following form:

([expli-shape-spec,] [expli-shape-spec,] ... [dl:] *)

expli-shape-spec
Is an explicit-shape specification.

dl
Is a specification expression indicating the lower bound of the dimension. The expression can have a positive, negative, or zero value. If necessary, the value is converted to integer type.

If the lower bound is not specified, it is assumed to be 1.

*
Is the upper bound of the last dimension.

The rank of the array is the number of explicit-shape specifications plus 1.

The size of the array is assumed from the actual argument associated with the assumed-size dummy array as follows:

  • If the actual argument is an array of type other than default character, the size of the dummy array is the size of the actual array.
  • If the actual argument is an array element of type other than default character, the size of the dummy array is a + 1 - s , where s is the subscript order value and a is the size of the actual array.
  • If the actual argument is a default character array, array element, or array element substring, and it begins at character storage unit b of an array with n character storage units, the size of the dummy array is as follows:
              MAX(INT((n + 1 - b)/y), 0)
    The y is the length of an element of the dummy array.

An assumed-size array can only be used as a whole array reference in the following cases:

  • When it is an actual argument in a procedure reference that does not require the shape
  • In the intrinsic function LBOUND

Because the actual size of an assumed-size array is unknown, an assumed-size array cannot be used as any of the following in an I/O statement:

  • An array name in the I/O list
  • A unit identifier for an internal file
  • A run-time format specifier

Examples

The following is an example of an assumed-size specification:

  SUBROUTINE SUB(A, N)
    REAL A, N
    DIMENSION A(1:N, *)
    ...

The following example shows that you can specify lower bounds for any of the dimensions of an assumed-size array, including the last:

  SUBROUTINE ASSUME(A)
    REAL A(-4:-2, 4:6, 3:*)

For More Information:

For details on array element order, see Array Elements.


Deferred-Shape Specifications

A deferred-shape array is an array pointer or an allocatable array.

The array specification contains a colon (:) for each dimension of the array. No bounds are specified. The bounds (and shape) of allocatable arrays and array pointers are determined when space is allocated for the array during program execution.

An array pointer is an array declared with the POINTER attribute. Its bounds and shape are determined when it is associated with a target by pointer assignment, or when the pointer is allocated by execution of an ALLOCATE statement.

In pointer assignment, the lower bound of each dimension of the array pointer is the result of the LBOUND intrinsic function applied to the corresponding dimension of the target. The upper bound of each dimension is the result of the UBOUND intrinsic function applied to the corresponding dimension of the target.

A pointer dummy argument can be associated only with a pointer actual argument. An actual argument that is a pointer can be associated with a nonpointer dummy argument.

A function result can be declared to have the pointer attribute.

An allocatable array is declared with the ALLOCATABLE attribute. Its bounds and shape are determined when the array is allocated by execution of an ALLOCATE statement.

Examples

The following are examples of deferred-shape specifications:

 REAL, ALLOCATABLE :: A(:,:)       ! Allocatable array
 REAL, POINTER :: C(:), D (:,:,:)  ! Array pointers

If a deferred-shape array is declared in a DIMENSION or TARGET statement, it must be given the ALLOCATABLE or POINTER attribute in another statement. For example:

  DIMENSION P(:, :, :)
  POINTER P

  TARGET B(:,:)
  ALLOCATABLE B

If the deferred-shape array is an array of pointers, its size, shape, and bounds are set in an ALLOCATE statement or in the pointer assignment statement when the pointer is associated with an allocated target. A pointer and its target must have the same rank.

For example:

  REAL, POINTER :: A(:,:), B(:), C(:,:)
  INTEGER, ALLOCATABLE :: I(:)
  REAL, ALLOCATABLE, TARGET :: D(:, :), E(:)
        ...
  ALLOCATE (A(2, 3), I(5), D(SIZE(I), 12), E(98) )
  C => D              ! Pointer assignment statement
  B => E(25:56)       ! Pointer assignment to a section
                      !   of a target

For More Information:

  • See the POINTER attribute.
  • See the ALLOCATABLE attribute.
  • See the ALLOCATE statement.
  • See Pointer assignment.
  • See the LBOUND intrinsic function.
  • See the UBOUND intrinsic function.


ALLOCATABLE Attribute and Statement

The ALLOCATABLE attribute specifies that an array is an allocatable array with a deferred shape. The shape of an allocatable array is determined when an ALLOCATE statement is executed, dynamically allocating space for the array. For more information, see ALLOCATABLE in the A to Z Reference.


AUTOMATIC and STATIC Attributes and Statements

The AUTOMATIC and STATIC attributes control the storage allocation of variables in subprograms. For more information, see AUTOMATIC and STATIC in the A to Z Reference.


COMMON Statement

A COMMON statement defines one or more contiguous areas, or blocks, of physical storage (called common blocks) that can be accessed by any of the scoping units in an executable program. COMMON statements also define the order in which variables and arrays are stored in each common block, which can prevent misaligned data items. For more information, see COMMON in the A to Z Reference.


DATA Statement

The DATA statement assigns initial values to variables before program execution. For more information, see DATA in the A to Z Reference.


DIMENSION Attribute and Statement

The DIMENSION attribute specifies that an object is an array, and defines the shape of the array. For more information, see DIMENSION in the A to Z Reference.


EQUIVALENCE Statement

The EQUIVALENCE statement specifies that a storage area is shared by two or more objects in a program unit. This causes total or partial storage association of the objects that share the storage area. For more information, see EQUIVALENCE in the A to Z Reference.

This section also discusses the following:

  • Making Arrays Equivalent
  • Making Substrings Equivalent
  • EQUIVALENCE and COMMON Interaction


Making Arrays Equivalent

When you make an element of one array equivalent to an element of another array, the EQUIVALENCE statement also sets equivalences between the other elements of the two arrays. Thus, if the first elements of two equal-sized arrays are made equivalent, both arrays share the same storage. If the third element of a 7-element array is made equivalent to the first element of another array, the last five elements of the first array overlap the first five elements of the second array.

Two or more elements of the same array should not be associated with each other in one or more EQUIVALENCE statements. For example, you cannot use an EQUIVALENCE statement to associate the first element of one array with the first element of another array, and then attempt to associate the fourth element of the first array with the seventh element of the other array.

Consider the following example:

  DIMENSION TABLE (2,2), TRIPLE (2,2,2)
  EQUIVALENCE(TABLE(2,2), TRIPLE(1,2,2))

These statements cause the entire array TABLE to share part of the storage allocated to TRIPLE. The following table shows how these statements align the arrays:

Equivalence of Array Storage

Array TRIPLE | Array TABLE
Array Element | Element Number | Array Element | Element Number
TRIPLE(1,1,1) | 1
TRIPLE(2,1,1) | 2
TRIPLE(1,2,1) | 3
TRIPLE(2,2,1) | 4 | TABLE(1,1) | 1
TRIPLE(1,1,2) | 5 | TABLE(2,1) | 2
TRIPLE(2,1,2) | 6 | TABLE(1,2) | 3
TRIPLE(1,2,2) | 7 | TABLE(2,2) | 4
TRIPLE(2,2,2) | 8

Each of the following statements also aligns the two arrays as shown in the above table:

  EQUIVALENCE(TABLE, TRIPLE(2,2,1))
  EQUIVALENCE(TRIPLE(1,1,2), TABLE(2,1))

You can also make arrays equivalent with nonunity lower bounds. For example, an array defined as A(2:3,4) is a sequence of eight values. A reference to A(2,2) refers to the third element in the sequence. To make array A(2:3,4) share storage with array B(2:4,4), you can use the following statement:

  EQUIVALENCE(A(3,4), B(2,4))

The entire array A shares part of the storage allocated to array B. The following table shows how these statements align the arrays. The arrays can also be aligned by the following statements:

EQUIVALENCE(A, B(4,1))
EQUIVALENCE(B(3,2), A(2,2))

Equivalence of Arrays with Nonunity Lower Bounds

Array B | Array A
Array Element | Element Number | Array Element | Element Number
B(2,1) | 1
B(3,1) | 2
B(4,1) | 3 | A(2,1) | 1
B(2,2) | 4 | A(3,1) | 2
B(3,2) | 5 | A(2,2) | 3
B(4,2) | 6 | A(3,2) | 4
B(2,3) | 7 | A(2,3) | 5
B(3,3) | 8 | A(3,3) | 6
B(4,3) | 9 | A(2,4) | 7
B(2,4) | 10 | A(3,4) | 8
B(3,4) | 11
B(4,4) | 12

Only in the EQUIVALENCE statement can you identify an array element with a single subscript (the linear element number), even though the array was defined as multidimensional. For example, the following statements align the two arrays as shown in the above table:

  DIMENSION B(2:4,1:4), A(2:3,1:4)
  EQUIVALENCE(B(6), A(4))


Making Substrings Equivalent

When you make one character substring equivalent to another character substring, the EQUIVALENCE statement also sets associations between the other corresponding characters in the character entities; for example:

  CHARACTER NAME*16, ID*9
  EQUIVALENCE(NAME(10:13), ID(2:5))

These statements cause character variables NAME and ID to share space (see the following figure). The arrays can also be aligned by the following statement:

  EQUIVALENCE(NAME(9:9), ID(1:1))

Equivalence of Substrings

If the character substring references are array elements, the EQUIVALENCE statement sets associations between the other corresponding characters in the complete arrays.

Character elements of arrays can overlap at any character position. For example, the following statements cause character arrays FIELDS and STAR to share storage (see the following figure).

  CHARACTER FIELDS(100)*4, STAR(5)*5
  EQUIVALENCE(FIELDS(1)(2:4), STAR(2)(3:5))

Equivalence of Character Arrays

The EQUIVALENCE statement cannot assign the same storage location to two or more substrings that start at different character positions in the same character variable or character array. The EQUIVALENCE statement also cannot assign memory locations in a way that is inconsistent with the normal linear storage of character variables and arrays.


EQUIVALENCE and COMMON Interaction

A common block can extend beyond its original boundaries if variables or arrays are associated with entities stored in the common block. However, a common block can only extend beyond its last element; the extended portion cannot precede the first element in the block.

Examples

The following two figures demonstrate valid and invalid extensions of the common block, respectively.

A Valid Extension of a Common Block

An Invalid Extension of a Common Block

The second example is invalid because the extended portion, B(1), precedes the first element of the common block.

The following example shows a valid EQUIVALENCE statement and an invalid EQUIVALENCE statement in the context of a common block.

  COMMON A, B, C
  DIMENSION D(3)
  EQUIVALENCE(B, D(1))      ! Valid, because common block is extended
                            ! from the end.

  COMMON A, B, C
  DIMENSION D(3)
  EQUIVALENCE(B, D(3))      ! Invalid, because D(1) would extend common
                            ! block to precede A's location.


EXTERNAL Attribute and Statement

The EXTERNAL attribute allows an external or dummy procedure to be used as an actual argument. For more information, see EXTERNAL in the A to Z Reference.


IMPLICIT Statement

The IMPLICIT statement overrides the default implicit typing rules for names. For more information, see IMPLICIT in the A to Z Reference.


INTENT Attribute and Statement

The INTENT attribute specifies the intended use of one or more dummy arguments. For more information, see INTENT in the A to Z Reference.


INTRINSIC Attribute and Statement

The INTRINSIC attribute allows the specific name of an intrinsic procedure to be used as an actual argument. Certain specific function names cannot be used; these are indicated in Functions Not Allowed as Actual Arguments in the A to Z Reference.

For more information, see INTRINSIC in the A to Z Reference.


NAMELIST Statement

The NAMELIST statement associates a name with a list of variables. This group name can be referenced in some input/output operations. For more information, see NAMELIST in the A to Z Reference.


OPTIONAL Attribute and Statement

The OPTIONAL attribute permits dummy arguments to be omitted in a procedure reference. For more information, see OPTIONAL in the A to Z Reference.


PARAMETER Attribute and Statement

The PARAMETER attribute defines a named constant. For more information, see PARAMETER in the A to Z Reference.


POINTER Attribute and Statement

The POINTER attribute specifies that an object is a pointer (a dynamic variable). For more information, see POINTER in the A to Z Reference.


PUBLIC and PRIVATE Attributes and Statements

The PRIVATE and PUBLIC attributes specify the accessibility of entities in a module. (These attributes are also called accessibility attributes.) For more information, see PUBLIC and PRIVATE in the A to Z Reference.


SAVE Attribute and Statement

The SAVE attribute causes the values and definition of objects to be retained after execution of a RETURN or END statement in a subprogram. For more information, see SAVE in the A to Z Reference.


TARGET Attribute and Statement

The TARGET attribute specifies that an object can become the target of a pointer. For more information, see TARGET in the A to Z Reference.


VOLATILE Attribute and Statement

The VOLATILE attribute specifies that the value of an object is entirely unpredictable, based on information local to the current program unit. For more information, see VOLATILE in the A to Z Reference.


Dynamic Allocation

Data objects can be static or dynamic. If a data object is static, a fixed amount of memory storage is created for it at compile time and is not freed until the program exits. If a data object is dynamic, memory storage for the object can be created (allocated), altered, or freed (deallocated) as a program executes.

In Fortran 95/90, pointers, allocatable arrays, and automatic arrays are dynamic data objects.

No storage space is created for a pointer until it is allocated with an ALLOCATE statement or until it is assigned to a allocated target. A pointer can be dynamically disassociated from a target by using a NULLIFY statement.

An ALLOCATE statement can also be used to create storage for an allocatable array. A DEALLOCATE statement is used to free the storage space reserved in a previous ALLOCATE statement.

Automatic arrays differ from allocatable arrays in that they are automatically allocated and deallocated whenever you enter or leave a procedure, respectively.

Note: Dynamic memory allocation is limited by several factors, including swap file size and memory requirements of other applications that are running. Dynamic allocations that are too large or otherwise attempt to use the protected memory of other applications result in General Protection Fault errors. If you encounter an unexpectedly low limit, you might need to reset your virtual memory size through the Control Panel or redefine the swap file size.

Some programming techniques can help minimize memory requirements, such as using one large array instead of two or more individual arrays. Allocated arrays that are no longer needed should be deallocated.

This chapter contains information on the following topics:

  • The ALLOCATE Statement
  • The DEALLOCATE Statement
  • The NULLIFY Statement

For More Information:

  • See Pointer Assignments.
  • See Automatic arrays.
  • See the NULL intrinsic function, which can also be used to disassociate a pointer.


ALLOCATE Statement

The ALLOCATE statement dynamically creates storage for allocatable arrays and pointer targets. The storage space allocated is uninitialized. For more information, see ALLOCATE in the A to Z Reference.

This section also discusses the following:

  • Allocation of Allocatable Arrays
  • Allocation of Pointer Targets


Allocation of Allocatable Arrays

The bounds (and shape) of an allocatable array are determined when it is allocated. Subsequent redefinition or undefinition of any entities in the bound expressions does not affect the array specification.

If the lower bound is greater than the upper bound, that dimension has an extent of zero, and the array has a size of zero. If the lower bound is omitted, it is assumed to be 1.

When an array is allocated, it is definable. If you try to allocate a currently allocated allocatable array, an error occurs.

The intrinsic function ALLOCATED can be used to determine whether an allocatable array is currently allocated; for example:

  REAL, ALLOCATABLE :: E(:,:)
  ...
  IF (.NOT. ALLOCATED(E)) ALLOCATE(E(2:4,7))

Allocation Status

During program execution, the allocation status of an allocatable array is one of the following:

  • Not currently allocated

    The array was never allocated or the last operation on it was a deallocation. Such an array must not be referenced or defined.

  • Currently allocated

    The array was allocated by an ALLOCATE statement. Such an array can be referenced, defined, or deallocated.

If an allocatable array has the SAVE attribute, it has an initial status of "not currently allocated". If the array is then allocated, its status changes to "currently allocated". It keeps that status until the array is deallocated.

If an allocatable array does not have the SAVE attribute, it has the status of "not currently allocated" at the beginning of each invocation of the procedure. If the array's status changes to "currently allocated", it is deallocated if the procedure is terminated by execution of a RETURN or END statement.

Examples

The following example shows a program that performs virtual memory allocation. This program uses Fortran 95/90 standard-conforming statements instead of calling an operating system memory allocation routine.

Allocating Virtual Memory

! Program accepts an integer and displays square root values

  INTEGER(4) :: N
  READ (5,*) N                         ! Reads an integer value
  CALL MAT(N)
  END

! Subroutine MAT uses the typed integer value to display the square
! root values of numbers from 1 to N (the number read)

  SUBROUTINE MAT(N)
  REAL(4), ALLOCATABLE :: SQR(:)       ! Declares SQR as a one-dimensional
                                       !          allocatable array
  ALLOCATE (SQR(N))                    ! Allocates array SQR

  DO J=1,N
     SQR(J) = SQRT(FLOATJ(J))          ! FLOATJ converts integer to REAL
  ENDDO

  WRITE (6,*) SQR                      ! Displays calculated values
  DEALLOCATE (SQR)                     ! Deallocates array SQR
  END SUBROUTINE MAT

For More Information:

  • See ALLOCATED.
  • See ALLOCATE.


Allocation of Pointer Targets

When a pointer is allocated, the pointer is associated with a target and can be used to reference or define the target. (The target can be an array or a scalar, depending on how the pointer was declared.)

Other pointers can become associated with the pointer target (or part of the pointer target) by pointer assignment.

In contrast to allocatable arrays, a pointer can be allocated a new target even if it is currently associated with a target. The previous association is broken and the pointer is then associated with the new target.

If the previous target was created by allocation, it becomes inaccessible unless it can still be referred to by other pointers that are currently associated with it.

The intrinsic function ASSOCIATED can be used to determine whether a pointer is currently associated with a target. (The association status of the pointer must be defined.) For example:

  REAL, TARGET  :: TAR(0:50)
  REAL, POINTER :: PTR(:)
  PTR => TAR
  ...
  IF (ASSOCIATED(PTR,TAR))...

For More Information:

  • See POINTER.
  • See Pointer assignments.
  • See ASSOCIATED.


DEALLOCATE Statement

The DEALLOCATE statement frees the storage allocated for allocatable arrays and pointer targets (and causes the pointers to become disassociated). For more information, see DEALLOCATE in the A to Z Reference.

This section also discusses the following:

  • Deallocation of Allocatable Arrays
  • Deallocation of Pointer Targets


Deallocation of Allocatable Arrays

If the DEALLOCATE statement specifies an array that is not currently allocated, an error occurs.

If an allocatable array with the TARGET attribute is deallocated, the association status of any pointer associated with it becomes undefined.

If a RETURN or END statement terminates a procedure, an allocatable array has one of the following allocation statuses:

  • It keeps its previous allocation and association status if the following is true:

    • It has the SAVE attribute.

    • It is in the scoping unit of a module that is accessed by another scoping unit which is currently executing.

    • It is accessible by host association.

  • It remains allocated if it is accessed by use association.

  • Otherwise, its allocation status is deallocated.

The intrinsic function ALLOCATED can be used to determine whether an allocatable array is currently allocated; for example:

SUBROUTINE TEST
  REAL, ALLOCATABLE, SAVE :: F(:,:)

  REAL, ALLOCATABLE :: E(:,:,:)
  ...
  IF (.NOT. ALLOCATED(E)) ALLOCATE(E(2:4,7,14))
END SUBROUTINE TEST

Note that when subroutine TEST is exited, the allocation status of F is maintained because F has the SAVE attribute. Since E does not have the SAVE attribute, it is deallocated. On the next invocation of TEST, E will have the status of "not currently allocated".

For More Information:

  • See Host association.
  • See TARGET.
  • See RETURN.
  • See END.
  • See SAVE.


Deallocation of Pointer Targets

A pointer must not be deallocated unless it has a defined association status. If the DEALLOCATE statement specifies a pointer that has undefined association status, or a pointer whose target was not created by allocation, an error occurs.

A pointer must not be deallocated if it is associated with an allocatable array, or it is associated with a portion of an object (such as an array element or an array section).

If a pointer is deallocated, the association status of any other pointer associated with the target (or portion of the target) becomes undefined.

Execution of a RETURN or END statement in a subprogram causes the pointer association status of any pointer declared (or accessed) in the procedure to become undefined, unless any of the following applies to the pointer:

  • It has the SAVE attribute.

  • It is in the scoping unit of a module that is accessed by another scoping unit which is currently executing.

  • It is accessible by host association.

  • It is in blank common.

  • It is in a named common block that appears in another scoping unit that is currently executing.

  • It is the return value of a function declared with the POINTER attribute.

If the association status of a pointer becomes undefined, it cannot subsequently be referenced or defined.

Examples

The following example shows deallocation of a pointer:

  INTEGER ERR
  REAL, POINTER :: PTR_A(:)
  ...
  ALLOCATE (PTR_A(10), STAT=ERR)
  ...
  DEALLOCATE(PTR_A)

For More Information:

  • See POINTER.
  • See COMMON.
  • See NULL.
  • See Host association.
  • See TARGET.
  • See RETURN.
  • See END.
  • See SAVE.


NULLIFY Statement

The NULLIFY statement disassociates a pointer from its target. For more information, see NULLIFY in the A to Z Reference.


Execution Control

A program normally executes statements in the order in which they are written. Executable control constructs and statements modify this normal execution by transferring control to another statement in the program, or by selecting blocks (groups) of constructs and statements for execution or repetition.

In Fortran 95/90, control constructs (CASE, DO, and IF) can be named. The name must be a unique identifier in the scoping unit, and must appear on the initial line and terminal line of the construct. On the initial line, the name is separated from the statement keyword by a colon (:).

A block can contain any executable Fortran statement except an END statement. You can transfer control out of a block, but you cannot transfer control into another block.

DO loops cannot partially overlap blocks. The DO statement and its terminal statement must appear together in a statement block.

This chapter contains information on the following topics:

  • Branch statements
  • The CALL statement
  • The CASE construct
  • The CONTINUE statement
  • The DO construct
  • The END statement
  • The IF construct and statement
  • The PAUSE statement
  • The RETURN statement
  • The STOP statement


Branch Statements

Branching affects the normal execution sequence by transferring control to a labeled statement in the same scoping unit. The transfer statement is called the branch statement, while the statement to which the transfer is made is called the branch target statement.

Any executable statement can be a branch target statement, except for the following:

  • CASE statement
  • ELSE statement
  • ELSE IF statement

Certain restrictions apply to the following statements:

Statement | Restriction
DO terminal statement | The branch must be taken from within its nonblock DO construct1.
END DO | The branch must be taken from within its block DO construct.
END IF | The branch should be taken from within its IF construct2.
END SELECT | The branch must be taken from within its CASE construct.
1 If the terminal statement is shared by more than one nonblock DO construct, the branch can only be taken from within the innermost DO construct 2 You can branch to an END IF statement from outside the IF construct; this is a deleted feature in Fortran 95. Compaq Fortran fully supports features deleted in Fortran 95.

The following branch statements are described in this section:

  • Unconditional GO TO
  • Computed GO TO
  • Assigned GO TO (the ASSIGN statement is also described here)
  • Arithmetic IF

For More Information:

  • See IF constructs.
  • See CASE constructs.
  • See DO constructs.


Unconditional GO TO Statement

The unconditional GO TO statement transfers control to the same branch target statement every time it executes. For more information, see GOTO - Unconditional in the A to Z Reference.


Computed GO TO Statement

The computed GO TO statement transfers control to one of a set of labeled branch target statements based on the value of an expression. For more information, see GOTO - Computed in the A to Z Reference.


The ASSIGN and Assigned GO TO Statements

The ASSIGN statement assigns a label to an integer variable. Subsequently, this variable can be used as a branch target statement by an assigned GO TO statement or as a format specifier in a formatted input/output statement.

The ASSIGN and assigned GO TO statements are deleted features in Fortran 95; they were obsolescent features in Fortran 90. Compaq Fortran fully supports features deleted in Fortran 95.

For more information, see ASSIGN and GOTO - Assigned in the A to Z Reference.


Arithmetic IF Statement

The arithmetic IF statement conditionally transfers control to one of three statements, based on the value of an arithmetic expression. For more information, see IF - Arithmetic in the A to Z Reference.


CALL Statement

The CALL statement transfers control to a subroutine subprogram. For more information, see CALL in the A to Z Reference.


CASE Constructs

The CASE construct conditionally executes one block of constructs or statements depending on the value of a scalar expression in a SELECT CASE statement. For more information, see CASE in the A to Z Reference.


CONTINUE Statement

The CONTINUE statement is primarily used to terminate a labeled DO construct when the construct would otherwise end improperly with either a GO TO, arithmetic IF, or other prohibited control statement. For more information, see CONTINUE in the A to Z Reference.


DO Constructs

The DO construct controls the repeated execution of a block of statements or constructs. For more information, see DO in the A to Z Reference.

This section also discusses the following topics:

  • Forms for DO Constructs
  • Execution of DO Constructs
  • DO WHILE Statement
  • CYCLE Statement
  • EXIT Statement


Forms for DO Constructs

A DO construct can be in block or nonblock form. For more information, see DO in the A to Z Reference.


Execution of DO Constructs

The range of a DO construct includes all the statements and constructs that follow the DO statement, up to and including the terminal statement. If the DO construct contains another construct, the inner (nested) construct must be entirely contained within the DO construct.

Execution of a DO construct differs depending on how the loop is controlled, as follows:

  • For simple DO constructs, there is no loop control. Statements in the DO range are repeated until the DO statement is terminated explicitly by a statement within the range.

  • For iterative DO statements, loop control is specified as do-var = expr1, expr2 [,expr3]. An iteration count specifies the number of times the DO range is executed. (For more information, see Iteration Loop Control.)

  • For DO WHILE statements, loop control is specified as a DO range. The DO range is repeated as long as a specified condition remains true. Once the condition is evaluated as false, the DO construct terminates. (For more information, see the DO WHILE statement.)

This section also discusses the following topics:

  • Nested DO Constructs
  • Extended Range


Iteration Loop Control

DO iteration loop control takes the following form:

do-var = expr1, expr2 [, expr3]

do-var
Is the name of a scalar variable of type integer or real. It cannot be the name of an array element or structure component.

expr
Is a scalar numeric expression of type integer or real. If it is not the same type as do-var, it is converted to that type.

Rules and Behavior

A DO variable or expression of type real is a deleted feature in Fortran 95; it was obsolescent in Fortran 90. Compaq Fortran fully supports features deleted in Fortran 95.

The following steps are performed in iteration loop control:

  1. The expressions expr1, expr2, and expr3 are evaluated to respectively determine the initial, terminal, and increment parameters.

    The increment parameter (expr3) is optional and must not be zero. If an increment parameter is not specified, it is assumed to be of type default integer with a value of 1.

  2. The DO variable (do-var) becomes defined with the value of the initial parameter (expr1).

  3. The iteration count is determined as follows:
          MAX(INT((expr2 - expr1 + expr3)/expr3), 0)
    The iteration count is zero if either of the following is true:
          expr1 > expr2 and expr3 > 0
      expr1 < expr2 and expr3 < 0
  4. The iteration count is tested. If the iteration count is zero, the loop terminates and the DO construct becomes inactive. (The compiler option /f66 can affect this.) If the iteration count is nonzero, the range of the loop is executed.

  5. The iteration count is decremented by one, and the DO variable is incremented by the value of the increment parameter, if any.

After termination, the DO variable retains its last value (the one it had when the iteration count was tested and found to be zero).

The DO variable must not be redefined or become undefined during execution of the DO range.

If you change variables in the initial, terminal, or increment expressions during execution of the DO construct, it does not affect the iteration count. The iteration count is fixed each time the DO construct is entered.

Examples

The following example specifies 25 iterations:

  DO 100 K=1,50,2

K=49 during the final iteration, K=51 after the loop.

The following example specifies 27 iterations:

  DO 350 J=50,-2,-2

J=-2 during the final iteration, J=-4 after the loop.

The following example specifies 9 iterations:

  DO NUMBER=5,40,4

NUMBER=37 during the final iteration, NUMBER=41 after the loop. The terminating statement of this DO loop must be END DO.

For More Information:

For details on obsolescent features in Fortran 95 and Fortran 90, as well as features deleted in Fortran 95, see Obsolescent and Deleted Language Features.


Nested DO Constructs

A DO construct can contain one or more complete DO constructs (loops). The range of an inner nested DO construct must lie completely within the range of the next outer DO construct. Nested nonblock DO constructs can share a labeled terminal statement.

The following figure shows correctly and incorrectly nested DO constructs:

Nested DO Constructs

In a nested DO construct, you can transfer control from an inner construct to an outer construct. However, you cannot transfer control from an outer construct to an inner construct.

If two or more nested DO constructs share the same terminal statement, you can transfer control to that statement only from within the range of the innermost construct. Any other transfer to that statement constitutes a transfer from an outer construct to an inner construct, because the shared statement is part of the range of the innermost construct.


Extended Range

A DO construct has an extended range if both of the following are true:

  • The DO construct contains a control statement that transfers control out of the construct.

  • Another control statement returns control back into the construct after execution of one or more statements.

The range of the construct is extended to include all executable statements between the destination statement of the first transfer and the statement that returns control to the construct.

The following rules apply to a DO construct with extended range:

  • A transfer into the range of a DO statement is permitted only if the transfer is made from the extended range of that DO statement.

  • The extended range of a DO statement must not change the control variable of the DO statement.

The following figure shows valid and invalid extended range control transfers:

Control Transfers and Extended Range


DO WHILE Statement

The DO WHILE statement executes the range of a DO construct while a specified condition remains true. For more information, see DO WHILE in the A to Z Reference.


CYCLE Statement

The CYCLE statement interrupts the current execution cycle of the innermost (or named) DO construct. For more information, see CYCLE in the A to Z Reference.


EXIT Statement

The EXIT statement terminates execution of a DO construct. For more information, see EXIT in the A to Z Reference.


END Statement

The END statement marks the end of a program unit. For more information, see END in the A to Z Reference.


IF Construct and Statement

The IF construct conditionally executes one block of statements or constructs.

The IF statement conditionally executes one statement.

The decision to transfer control or to execute the statement or block is based on the evaluation of a logical expression within the IF statement or construct.

For More Information:

See Arithmetic IF Statement.


IF Construct

The IF construct conditionally executes one block of constructs or statements depending on the evaluation of a logical expression. For more information, see IF construct in the A to Z Reference.


IF Statement

The IF statement conditionally executes one statement based on the value of a logical expression. For more information, see IF - Logical in the A to Z Reference.


PAUSE Statement

The PAUSE statement temporarily suspends program execution until the user or system resumes execution. For more information, see PAUSE in the A to Z Reference.

The PAUSE statement is a deleted feature in Fortran 95; it was an obsolescent feature in Fortran 90. Compaq Fortran fully supports features deleted in Fortran 95.

For alternate methods of pausing while reading from and writing to a device, see READ and WRITE in the A to Z Reference.


RETURN Statement

The RETURN statement transfers control from a subprogram to the calling program unit. For more information, see RETURN in the A to Z Reference.


STOP Statement

The STOP statement terminates program execution before the end of the program unit. For more information, see STOP in the A to Z Reference.


Program Units and Procedures

A Fortran 95/90 program consists of one or more program units. There are four types of program units:

  • Main program

    The program unit that denotes the beginning of execution. It may or may not have a PROGRAM statement as its first statement.

  • External procedures

    Program units that are either user-written functions or subroutines.

  • Modules

    Program units that contain declarations, type definitions, procedures, or interfaces that can be shared by other program units.

  • Block data program units

    Program units that provide initial values for variables in named common blocks.

A program unit does not have to contain executable statements; for example, it can be a module containing interface blocks for subroutines.

A procedure can be invoked during program execution to perform a specific task. There are several kinds of procedures, as follows:

Kind of Procedure | Description
External Procedure | A procedure that is not part of any other program unit.
Module Procedure | A procedure defined within a module
Internal Procedure1 | A procedure (other than a statement function) contained within a main program, function, or subroutine
Intrinsic Procedure | A procedure defined by the Fortran language
Dummy Procedure | A dummy argument specified as a procedure or appearing in a procedure reference
Statement function | A computing procedure defined by a single statement
1 The program unit that contains an internal procedure is called its host.

A function is invoked in an expression using the name of the function or a defined operator. It returns a a single value (function result) that is used to evaluate the expression.

A subroutine is invoked in a CALL statement or by a defined assignment statement. It does not directly return a value, but values can be passed back to the calling program unit through arguments (or variables) known to the calling program.

Recursion (direct or indirect) is permitted for functions and subroutines.

A procedure interface refers to the properties of a procedure that interact with or are of concern to the calling program. A procedure interface can be explicitly defined in interface blocks. All program units, except block data program units, can contain interface blocks.

This chapter contains information on the following topics:

  • Main program
  • Modules and module procedures
  • Block data program units
  • Functions, subroutines, and statement functions
  • External procedures
  • Internal procedures
  • Argument association
  • Procedure interfaces
  • The CONTAINS statement
  • The ENTRY statement

For More Information:

  • See Program structure.
  • See Intrinsic procedures.
  • See Scope.
  • See RECURSIVE.


Main Program

A main program is a program unit whose first statement is not a SUBROUTINE, FUNCTION, MODULE, or BLOCK DATA statement. Program execution always begins with the first executable statement in the main program, so there must be exactly one main program unit in every executable program. For more information, see PROGRAM in the A to Z Reference.


Modules and Module Procedures

A module program unit contains specifications and definitions that can be made accessible to other program units. For the module to be accessible, the other program units must reference its name in a USE statement, and the module entities must be public. For more information, see MODULE in the A to Z Reference.

A module procedure is a procedure declared and defined in a module, between its CONTAINS and END statements. For more information, see MODULE PROCEDURE in the A to Z Reference.

This section also discusses:

  • Module References
  • USE Statement


Module References

A program unit references a module in a USE statement. This module reference lets the program unit access the public definitions, specifications, and procedures in the module.

Entities in a module are public by default, unless the USE statement specifies otherwise or the PRIVATE attribute is specified for the module entities.

A module reference causes use association between the using program unit and the entities in the module.

For More Information:

  • See the USE statement.
  • See the PRIVATE and PUBLIC attributes.
  • See Use association.


USE Statement

The USE statement gives a program unit accessibility to public entities in a module. For more information, see USE in the A to Z Reference.

Examples

Entities in modules can be accessed either through their given name, or through aliases declared in the USE statement of the main program unit. For example:

  USE MODULE_LIB, XTABS => CROSSTABS

This statement accesses the routine called CROSSTABS in MODULE_LIB by the name XTABS. This way, if two modules have routines called CROSSTABS, one program can use them both simultaneously by assigning a local name in its USE statement.

When a program or subprogram renames a module entity, the local name (XTABS, in the preceding example) is accessible throughout the scope of the program unit that names it.

The ONLY option also allows public variables to be renamed. Consider the following:

  USE MODULE_A, ONLY: VARIABLE_A => VAR_A

In this case, the host program accesses only VAR_A from module A, and refers to it by the name VARIABLE_A.

Consider the following example:

  MODULE FOO
     integer foos_integer
   PRIVATE
     integer foos_secret_integer
  END MODULE FOO

PRIVATE, in this case, makes the PRIVATE attribute the default for the entire module FOO. To make foos_integer accessible to other program units, add the line:

  PUBLIC :: foos_integer

Alternatively, to make only foos_secret_integer inaccessible outside the module, rewrite the module as follows:

  MODULE FOO
    integer foos_integer
    integer, private::foos_secret_integer
  END MODULE FOO


Block Data Program Units

A block data program unit provides initial values for nonpointer variables in named common blocks. For more information, see BLOCK DATA in the A to Z Reference.

Examples

An example of a block data program unit follows:

  BLOCK DATA WORK
     COMMON /WRKCOM/ A, B, C (10,10)
     DATA A /1.0/, B /2.0/, C /100*0.0/
  END BLOCK DATA WORK


Functions, Subroutines, and Statement Functions

Functions, subroutines, and statement functions are user-written subprograms that perform computing procedures. The computing procedure can be either a series of arithmetic operations or a series of Fortran statements. A single subprogram can perform a computing procedure in several places in a program, to avoid duplicating a series of operations or statements in each place.

The following table shows the statements that define these subprograms, and how control is transferred to the subprogram:

Subprogram | Defining Statements | Control Transfer Method
Function | FUNCTION or ENTRY | Function reference1
Subroutine | SUBROUTINE or ENTRY | CALL statement2
Statement function | Statement function definition | Function reference
1 A function can also be invoked by a defined operation (see Defining Generic Operators). 2 A subroutine can also be invoked by a defined assignment (see Defining Generic Assignment).

A function reference is used in an expression to invoke a function; it consists of the function name and its actual arguments. The function reference returns a value to the calling expression that is used to evaluate the expression.

The following topics are discussed in this section:

  • General rules for function and subroutine subprograms
  • Functions
  • Subroutines
  • Statement functions

For More Information:

  • See the ENTRY statement.
  • See the CALL statement.


General Rules for Function and Subroutine Subprograms

A subprogram can be an external, module, or internal subprogram. The END statement for an internal or module subprogram must be END SUBROUTINE [name] for a subroutine, or END FUNCTION [name] for a function. In an external subprogram, the SUBROUTINE and FUNCTION keywords are optional.

If a subprogram name appears after the END statement, it must be the same as the name specified in the SUBROUTINE or FUNCTION statement.

Function and subroutine subprograms can change the values of their arguments, and the calling program can use the changed values.

A SUBROUTINE or FUNCTION statement can be optionally preceded by an OPTIONS statement.

Dummy arguments (except for dummy pointers or dummy procedures) can be specified with an intent and can be made optional.

For More Information:

  • See RECURSIVE procedures.
  • See PURE procedures.
  • See user-defined ELEMENTAL procedures.
  • See Module procedures.
  • See Internal procedures.
  • See External procedures.
  • See Optional arguments.
  • See INTENT.


Recursive Procedures

A recursive procedure is a function or subroutine that references itself, either directly or indirectly. For more information, see RECURSIVE in the A to Z Reference.


Pure Procedures

A pure procedure is a user-defined procedure that has no side effects. Pure procedures are a feature of Fortran 95. For more information, see PURE in the A to Z Reference.


Elemental Procedures

An elemental procedure is a user-defined procedure that is a restricted form of pure procedure. For more information, see PURE and ELEMENTAL in the A to Z Reference.


Functions

A function subprogram is invoked in an expression and returns a single value (a function result) that is used to evaluate the expression. For more information, see FUNCTION in the A to Z Reference.

This section also discusses the following:

  • The RESULT Keyword
  • Function References


RESULT Keyword

If you use the RESULT keyword in a FUNCTION statement, you can specify a local variable name for the function result. For more information, see RESULT in the A to Z Reference.


Function References

Functions are invoked by a function reference in an expression or by a defined operation.

A function reference takes the following form:

fun ([a-arg [, a-arg] ...])

fun
Is the name of the function subprogram.

a-arg
Is an actual argument optionally preceded by [keyword=], where keyword is the name of a dummy argument in the explicit interface for the function. The keyword is assigned a value when the procedure is invoked.

Each actual argument must be a variable, an expression, or the name of a procedure. (It must not be the name of an internal procedure, statement function, or the generic name of a procedure.)

Rules and Behavior

When a function is referenced, each actual argument is associated with the corresponding dummy argument by its position in the argument list or by the name of its keyword. The arguments must agree in type and kind parameters.

Execution of the function produces a result that is assigned to the function name or to the result name, depending on whether the RESULT keyword was specified.

The program unit uses the result value to complete the evaluation of the expression containing the function reference.

If positional arguments and argument keywords are specified, the argument keywords must appear last in the actual argument list.

If a dummy argument is optional, the actual argument can be omitted.

If a dummy argument is specified with the INTENT attribute, its use may be limited. A dummy argument whose intent is not specified is subject to the limitations of its associated actual argument.

An actual argument associated with a dummy procedure must be the specific name of a procedure, or be another dummy procedure. Certain specific intrinsic function names must not be used as actual arguments (see Functions Not Allowed as Actual Arguments).

Examples

Consider the following example:

  X = 2.0
  NEW_COS = COS(X)        ! A function reference

Intrinsic function COS calculates the cosine of 2.0. The value -0.4161468 is returned (in place of COS(X)) and assigned to NEW_COS.

For More Information:

  • See the INTENT attribute.
  • See Defining Generic Operators.
  • See Dummy Procedure Arguments.
  • See Intrinsic Procedures.
  • See Optional arguments.
  • See the RESULT keyword.
  • See the FUNCTION statement.
  • On procedure arguments, see Argument Association.


Subroutines

A subroutine subprogram is invoked in a CALL statement or by a defined assignment statement, and does not return a particular value. For more information, see SUBROUTINE in the A to Z Reference.


Statement Functions

A statement function is a procedure defined by a single statement in the same program unit in which the procedure is referenced. For more information, see Statement Function in the A to Z Reference.


External Procedures

External procedures are user-written functions or subroutines. They are located outside of the main program and can't be part of any other program unit.

External procedures can be invoked by the main program or any procedure of an executable program.

In Fortran 95/90, external procedures can include internal subprograms (defining internal procedures). An internal subprogram begins with a CONTAINS statement.

An external procedure can reference itself (directly or indirectly).

The interface of an external procedure is implicit unless an interface block is supplied for the procedure.

For More Information:

  • See Functions, Subroutines, and Statement Functions.
  • See Procedure Interfaces.
  • On passing arguments, see your programmer's guide.


Internal Procedures

Internal procedures are functions or subroutines that follow a CONTAINS statement in a program unit. The program unit in which the internal procedure appears is called its host.

Internal procedures can appear in the main program, in an external subprogram, or in a module subprogram.

An internal procedure takes the following form:

CONTAINS
internal-subprogram
[internal-subprogram] ...

internal-subprogram
Is a function or subroutine subprogram that defines the procedure. An internal subprogram must not contain any other internal subprograms.

Rules and Behavior

Internal procedures are the same as external procedures, except for the following:

  • Only the host program unit can use an internal procedure.

  • An internal procedure has access to host entities by host association; that is, names declared in the host program unit are useable within the internal procedure.

  • In Fortran 95/90, the name of an internal procedure must not be passed as an argument to another procedure. However, Compaq Fortran allows an internal procedure name to be passed as an actual argument to another procedure.

  • An internal procedure must not contain an ENTRY statement.

An internal procedure can reference itself (directly or indirectly); it can be referenced in the execution part of its host and in the execution part of any internal procedure contained in the same host (including itself).

The interface of an internal procedure is always explicit.

Examples

The following example shows an internal procedure:

PROGRAM COLOR_GUIDE
...
CONTAINS
  FUNCTION HUE(BLUE)   ! An internal procedure
  ...
  END FUNCTION HUE
END PROGRAM

The following example program contains an internal subroutine find, which performs calculations that the main program then prints. The variables a, b, and c declared in the host program are also known to the internal subroutine.

 program INTERNAL
 ! shows use of internal subroutine and CONTAINS statement
    real a,b,c
    call find
    print *, c
 contains
    subroutine find
     read *, a,b
     c = sqrt(a**2 + b**2)
    end subroutine find
 end

For More Information:

  • See Functions, Subroutines, and Statement Functions.
  • See Host association.
  • See Procedure Interfaces.
  • See CONTAINS.


Argument Association

Procedure arguments provide a way for different program units to access the same data.

When a procedure is referenced in an executable program, the program unit invoking the procedure can use one or more actual arguments to pass values to the procedure's dummy arguments. The dummy arguments are associated with their corresponding actual arguments when control passes to the subprogram.

In general, when control is returned to the calling program unit, the last value assigned to a dummy argument is assigned to the corresponding actual argument.

An actual argument can be a variable, expression, or procedure name. The type and kind parameters, and rank of the actual argument must match those of its associated dummy argument.

A dummy argument is either a dummy data object, a dummy procedure, or an alternate return specifier (*). Except for alternate return specifiers, dummy arguments can be optional.

If argument keywords are not used, argument association is positional. The first dummy argument becomes associated with the first actual argument, and so on. If argument keywords are used, arguments are associated by the keyword name, so actual arguments can be in a different order than dummy arguments.

A keyword is required for an argument only if a preceding optional argument is omitted or if the argument sequence is changed.

A scalar dummy argument can be associated with only a scalar actual argument.

If a dummy argument is an array, it must be no larger than the array that is the actual argument. You can use adjustable arrays to process arrays of different sizes in a single subprogram.

A dummy argument referenced as a subprogram must be associated with an actual argument that has been declared EXTERNAL or INTRINSIC in the calling routine.

If a scalar dummy argument is of type character, its length must not be greater than the length of its associated actual argument.

If the character dummy argument's length is specified as *(*) (assumed length), it uses the length of the associated actual argument.

Once an actual argument has been associated with a dummy argument, no action can be taken that affects the value or availability of the actual argument, except indirectly through the dummy argument. For example, if the following statement is specified:

  CALL SUB_A (B(2:6), B(4:10))

B(4:6) must not be defined, redefined, or become undefined through either dummy argument, since it is associated with both arguments. However, B(2:3) is definable through the first argument, and B(7:10) is definable through the second argument.

Similarly, if any part of the actual argument is defined through a dummy argument, the actual argument can only be referenced through that dummy argument during execution of the procedure. For example, if the following statements are specified:

  MODULE MOD_A
    REAL :: A, B, C, D
  END MODULE MOD_A

  PROGRAM TEST
    USE MOD_A
    CALL SUB_1 (B)
    ...
  END PROGRAM TEST

  SUBROUTINE SUB_1 (F)
    USE MOD_A
    ...
    WRITE (*,*) F
  END SUBROUTINE SUB_1

Variable B must not be directly referenced during the execution of SUB_1 because it is being defined through dummy argument F. However, B can be indirectly referenced through F (and directly referenced when SUB_1 completes execution).

The following sections provide more details on arguments:

  • Optional arguments

  • The different kinds of arguments:

    • Array arguments

    • Pointer arguments

    • Assumed-length character arguments

    • Character constant and Hollerith arguments

    • Alternate return arguments

    • Dummy procedure arguments

  • References to generic procedures

  • References to non-Fortran procedures (%DESCR %REF, %VAL, and %LOC)

For More Information:

  • On argument keywords in subroutine references, see CALL.
  • On argument keywords in function references, see Function References.


Optional Arguments

Dummy arguments can be made optional if they are declared with the OPTIONAL attribute. In this case, an actual argument does not have to be supplied for it in a procedure reference.

If argument keywords are not used, argument association is positional. The first dummy argument becomes associated with the first actual argument, and so on. If argument keywords are used, arguments are associated by the keyword name, so actual arguments can be in a different order than dummy arguments. A keyword is required for an argument only if a preceding optional argument is omitted or if the argument sequence is changed.

Positional arguments (if any) must appear first in an actual argument list, followed by keyword arguments (if any). If an optional argument is the last positional argument, it can simply be omitted if desired.

However, if the optional argument is to be omitted but it is not the last positional argument, keyword arguments must be used for any subsequent arguments in the list.

Optional arguments must have explicit procedure interfaces so that appropriate argument associations can be made.

The PRESENT intrinsic function can be used to determine if an actual argument is associated with an optional dummy argument in a particular reference.

The following example shows optional arguments:

  PROGRAM RESULT
  TEST_RESULT = LGFUNC(A, B=D)
  ...
  CONTAINS
    FUNCTION LGFUNC(G, H, B)
      OPTIONAL H, B
      ...
    END FUNCTION
  END

In the function reference, A is a positional argument associated with required dummy argument G. The second actual argument D is associated with optional dummy argument B by its keyword name (B). No actual argument is associated with optional argument H.

The following shows another example:

   ! Arguments can be passed out of order, but must be
   !  associated with the correct dummy argument.
   CALL EXT1 (Z=C, X=A, Y=B)
   . . .
   END

   SUBROUTINE EXT1(X,Y,Z)
      REAL X, Y
      REAL, OPTIONAL :: Z
      . . .
   END SUBROUTINE

In this case, argument A is associated with dummy argument X by explicit assignment. Once EXT1 executes and returns, A is no longer associated with X, B is no longer associated with Y, and C is no longer associated with Z.

For More Information:

  • See the OPTIONAL attribute.
  • See the PRESENT intrinsic function.
  • On general rules for procedure argument association, see Argument association.
  • On argument keywords in subroutine references, see CALL.
  • On argument keywords in function references, see Function References.


Array Arguments

Arrays are sequences of elements. Each element of an actual array is associated with the element of the dummy array that has the same position in array element order.

If the dummy argument is an explicit-shape or assumed-size array, the size of the dummy argument array must not exceed the size of the actual argument array.

The type and kind parameters of an explicit-shape or assumed-size dummy argument must match the type and kind parameters of the actual argument, but their ranks need not match.

If the dummy argument is an assumed-shape array, the size of the dummy argument array is equal to the size of the actual argument array. The associated actual argument must not be an assumed-size array or a scalar (including a designator for an array element or an array element substring).

If the actual argument is an array section with a vector subscript, the associated dummy argument must not be defined.

The declaration of an array used as a dummy argument can specify the lower bound of the array.

Although most types of arrays can be used as dummy arguments, allocatable arrays cannot be dummy arguments. Allocatable arrays can be used as actual arguments.

Dummy argument arrays declared as assumed-shape, deferred-shape, or pointer arrays require an explicit interface visible to the caller.

For More Information:

  • See Arrays.
  • See Array association.
  • On general rules for procedure argument association, see Argument association.
  • On array element order, see Array Elements.
  • On explicit-shape arrays, see Explicit-Shape Specifications.
  • On assumed-shape arrays, see Assumed-Shape Specifications.
  • On assumed-size arrays, see Assumed-Size Specifications.


Pointer Arguments

An argument is a pointer if it is declared with the POINTER attribute.

When a procedure is invoked, the dummy argument pointer receives the pointer association status of the actual argument. If the actual argument is currently associated, the dummy argument becomes associated with the same target.

The pointer association status of the dummy argument can change during the execution of the procedure, and any such changes are reflected in the actual argument.

If both the dummy and actual arguments are pointers, an explicit interface is required.

A dummy argument that is a pointer can be associated only with an actual argument that is a pointer. However, an actual argument that is a pointer can be associated with a nonpointer dummy argument. In this case, the actual argument is associated with a target and the dummy argument, through argument association, also becomes associated with that target.

If the dummy argument does not have the TARGET or POINTER attribute, any pointers associated with the actual argument do not become associated with the corresponding dummy argument when the procedure is invoked.

If the dummy argument has the TARGET attribute, and is either a scalar or assumed-shape array, and the corresponding actual argument has the TARGET attribute but is not an array section with a vector subscript, the following occurs:

  • Any pointer associated with the actual argument becomes associated with the corresponding dummy argument when the procedure is invoked.
  • Any pointers associated with the dummy argument remain associated with the actual argument when execution of the procedure completes.

If the dummy argument has the TARGET attribute, and is an explicit-shape or assumed-size array, and the corresponding actual argument has the TARGET attribute but is not an array section with a vector subscript, association of actual and corresponding dummy arguments when the procedure is invoked or when execution is completed is processor dependent.

If the dummy argument has the TARGET attribute and the corresponding actual argument does not have that attribute or is an array section with a vector subscript, any pointer associated with the dummy argument becomes undefined when execution of the procedure completes.

For More Information:

  • See POINTER.
  • See Pointer assignments.
  • See the TARGET attribute.
  • On general rules for procedure argument association, see Argument association.


Assumed-Length Character Arguments

An assumed-length character argument is a dummy argument that assumes the length attribute of its corresponding actual argument. An asterisk (*) specifies the length of the dummy character argument.

A character array dummy argument can also have an assumed length. The length of each element in the dummy argument is the length of the elements in the actual argument. The assumed length and the array declarator together determine the size of the assumed-length character array.

The following example shows an assumed-length character argument:

  INTEGER FUNCTION ICMAX(CVAR)
    CHARACTER*(*) CVAR
    ICMAX = 1
    DO I=2,LEN(CVAR)
      IF (CVAR(I:I) .GT. CVAR(ICMAX:ICMAX)) ICMAX=I
    END DO
    RETURN
  END

The function ICMAX finds the position of the character with the highest ASCII code value. It uses the length of the assumed-length character argument to control the iteration. Intrinsic function LEN determines the length of the argument.

The length of the dummy argument is determined each time control transfers to the function. The length of the actual argument can be the length of a character variable, array element, substring, or expression. Each of the following function references specifies a different length for the dummy argument:

  CHARACTER VAR*10, CARRAY(3,5)*20
  ...
  I1 = ICMAX(VAR)
  I2 = ICMAX(CARRAY(2,2))
  I3 = ICMAX(VAR(3:8))
  I4 = ICMAX(CARRAY(1,3)(5:15))
  I5 = ICMAX(VAR(3:4)//CARRAY(3,5))

For More Information:

  • See the LEN intrinsic function.
  • On general rules for procedure argument association, see Argument association.


Character Constant and Hollerith Arguments

If an actual argument is a character constant (for example, 'ABCD'), the corresponding dummy argument must be of type character. If an actual argument is a Hollerith constant (for example, 4HABCD), the corresponding dummy argument must have a numeric data type.

The following example shows character and Hollerith constants being used as actual arguments:

  SUBROUTINE S(CHARSUB, HOLLSUB, A, B)
  EXTERNAL CHARSUB, HOLLSUB
  ...
  CALL CHARSUB(A, 'STRING')
  CALL HOLLSUB(B, 6HSTRING)

The subroutines CHARSUB and HOLLSUB are themselves dummy arguments of the subroutine S. Therefore, the actual argument 'STRING' in the call to CHARSUB must correspond to a character dummy argument, and the actual argument 6HSTRING in the call to HOLLSUB must correspond to a numeric dummy argument.

For More Information:

For details on general rules for procedure argument association, see Argument association.


Alternate Return Arguments

Alternate return (dummy) arguments can appear in a subroutine argument list. They cause execution to transfer to a labeled statement rather than to the statement immediately following the statement that called the routine. The alternate return is indicated by an asterisk (*). (An alternate return is an obsolescent feature in Fortran 90 and Fortran 95.)

There can be any number of alternate returns in a subroutine argument list, and they can be in any position in the list.

An actual argument associated with an alternate return dummy argument is called an alternate return specifier; it is indicated by an asterisk (*), or ampersand (&) followed by the label of an executable branch target statement in the same scoping unit as the CALL statement.

Alternate returns cannot be declared optional.

In Fortran 90, you can also use the RETURN statement to specify alternate returns.

The following example shows alternate return actual and dummy arguments:

  CALL MINN(X, Y, *300, *250, Z)
  ....
  SUBROUTINE MINN(A, B, *, *, C)

For More Information:

  • On general rules for procedure argument association, see Argument association.
  • See the SUBROUTINE statement.
  • See the CALL statement.
  • See the RETURN statement.
  • On obsolescent features in Fortran 90 and Fortran 95, see Obsolescent and Deleted Language Features.


Dummy Procedure Arguments

If an actual argument is a procedure, its corresponding dummy argument is a dummy procedure. Dummy procedures can appear in function or subroutine subprograms.

The actual argument must be the specific name of an external, module, intrinsic, or another dummy procedure. If the specific name is also a generic name, only the specific name is associated with the dummy argument. Not all specific intrinsic procedures can appear as actual arguments. (For more information, see Functions Not Allowed as Actual Arguments.)

The actual argument and corresponding dummy procedure must both be subroutines or both be functions.

If the interface of the dummy procedure is explicit, the type and kind parameters, and rank of the associated actual procedure must be the same as that of the dummy procedure.

If the interface of the dummy procedure is implicit and the procedure is referenced as a subroutine, the actual argument must be a subroutine or a dummy procedure.

If the interface of the dummy procedure is implicit and the procedure is referenced as a function or is explicitly typed, the actual argument must be a function or a dummy procedure.

Dummy procedures can be declared optional, but they must not be declared with an intent.

The following is an example of a procedure used as an argument:

  REAL FUNCTION LGFUNC(BAR)
    INTERFACE
      REAL FUNCTION BAR(Y)
        REAL, INTENT(IN) :: Y
      END
    END INTERFACE
    ...
    LGFUNC = BAR(2.0)
    ...
  END FUNCTION LGFUNC

For More Information:

For details on general rules for procedure argument association, see Argument association.


References to Generic Procedures

Generic procedures are procedures with different specific names that can be accessed under one generic (common) name. In FORTRAN 77, generic procedures were limited to intrinsic procedures. In Fortran 90, you can use generic interface blocks to specify generic properties for intrinsic and user-defined procedures.

If you refer to a procedure by using its generic name, the selection of the specific routine is based on the number of arguments and the type and kind parameters, and rank of each argument.

All procedures given the same generic name must be subroutines, or all must be functions. Any two must differ enough so that any invocation of the procedure is unambiguous.

The following sections describe references to generic intrinsic functions and show an example of using intrinsic function names.

For More Information:

  • See Unambiguous Generic Procedure References.
  • See Intrinsic procedures.
  • On the rules for resolving ambiguous procedure references, see Resolving Procedure References.
  • On user-defined generic procedures, see Defining Generic Names for Procedures.


References to Generic Intrinsic Functions

The generic intrinsic function name COS lists six specific intrinsic functions that calculate cosines: COS, DCOS, QCOS, CCOS, CDCOS, and CQCOS. These functions return different values: REAL(4), REAL(8), REAL(16) (VMS, U*X), COMPLEX(4), COMPLEX(8), and COMPLEX(16) (VMS, U*X) respectively.

If you invoke the cosine function by using the generic name COS, the compiler selects the appropriate routine based on the arguments that you specify. For example, if the argument is REAL(4), COS is selected; if it is REAL(8), DCOS is selected; and if it is COMPLEX(4), CCOS is selected.

You can also explicitly refer to a particular routine. For example, you can invoke the double-precision cosine function by specifying DCOS.

Procedure selection occurs independently for each generic reference, so you can use a generic reference repeatedly in the same program unit to access different intrinsic procedures.

You cannot use generic function names to select intrinsic procedures if you use them as follows:

  • The name of a statement function
  • A dummy argument name, a common block name, or a variable or array name

When an intrinsic function is passed as an actual argument to a procedure, its specific name must be used, and when called, its arguments must be scalar. Not all specific intrinsic functions can appear as actual arguments. (For more information, see Functions Not Allowed as Actual Arguments.)

Generic procedure names are local to the program unit that refers to them, so they can be used for other purposes in other program units.

Normally, an intrinsic procedure name refers to the Fortran 90 library procedure with that name. However, the name can refer to a user-defined procedure when the name appears in an EXTERNAL statement.

Note: If you call an intrinsic procedure by using the wrong number of arguments or an incorrect argument type, the compiler assumes you are referring to an external procedure. For example, intrinsic procedure SIN requires one argument; if you specify two arguments, such as SIN(10,4), the compiler assumes SIN is external and not intrinsic.

Except when used in an EXTERNAL statement, intrinsic procedure names are local to the program unit that refers to them, so they can be used for other purposes in other program units. The data type of an intrinsic procedure does not change if you use an IMPLICIT statement to change the implied data type rules.

Intrinsic and user-defined procedures cannot have the same name if they appear in the same program unit.

Examples

The following example shows the local and global properties of an intrinsic function name. It uses intrinsic function SIN as follows:

  • The name of a statement function
  • The generic name of an intrinsic function
  • The specific name of an intrinsic function
  • The name of a user-defined function

Using and Redefining an Intrinsic Function Name

    !    Compare ways of computing sine

         PROGRAM SINES
           DOUBLE PRECISION X, PI
           PARAMETER (PI=3.141592653589793238D0)
           COMMON V(3)

    !    Define SIN as a statement function

           SIN(X) = COS(PI/2-X)
           DO X = -PI, PI, 2*PI/100

    !    Reference the statement function SIN

             WRITE (6,100) X, V, SIN(X)
           END DO
           CALL COMPUT(X)
   100     FORMAT (5F10.7)
         END

         SUBROUTINE COMPUT(Y)
           DOUBLE PRECISION Y

    !    Use intrinsic function SIN as an actual argument

           INTRINSIC SIN
           COMMON V(3)

    !    Define generic reference to double-precision sine

           V(1) = SIN(Y)

    !    Use intrinsic function SIN as an actual argument

           CALL SUB(REAL(Y),SIN)
         END

         SUBROUTINE SUB(A,S)

    !    Declare SIN as name of a user function

           EXTERNAL SIN

    !    Declare SIN as type DOUBLE PRECISION

           DOUBLE PRECISION SIN
           COMMON V(3)

    !    Evaluate intrinsic function SIN

           V(2) = S(A)

    !    Evaluate user-defined SIN function

           V(3) = SIN(A)
         END

   !     Define the user SIN function

         DOUBLE PRECISION FUNCTION SIN(X)
           INTEGER FACTOR
           SIN = X - X**3/FACTOR(3) + X**5/FACTOR(5)     &
               - X**7/FACTOR(7)
         END

         INTEGER FUNCTION FACTOR(N)
           FACTOR = 1
           DO I=N,1,-1
             FACTOR = FACTOR * I
           END DO
         END

The statement function named SIN is defined in terms of the generic function name COS. Because the argument of COS is double precision, the double-precision cosine function is evaluated. The statement function SIN is itself single precision.

The statement function SIN is called.

The name SIN is declared intrinsic so that the single-precision intrinsic sine function can be passed as an actual argument at 5.

The generic function name SIN is used to refer to the double-precision sine function.

The single-precision intrinsic sine function is used as an actual argument.

The name SIN is declared a user-defined function name.

The type of SIN is declared double precision.

The single-precision sine function passed at 5 is evaluated.

The user-defined SIN function is evaluated.

The user-defined SIN function is defined as a simple Taylor series using a user-defined function FACTOR to compute the factorial function.

For More Information:

  • See the EXTERNAL attribute.
  • See the INTRINSIC attribute.
  • See Intrinsic procedures.
  • On the scope of names, see Names.


References to Elemental Intrinsic Procedures

An elemental intrinsic procedure has scalar dummy arguments that can be called with scalar or array actual arguments. If actual arguments are array-valued, they must have the same shape. There are many elemental intrinsic functions, but only one elemental intrinsic subroutine (MVBITS).

If the actual arguments are scalar, the result is scalar. If the actual arguments are array-valued, the scalar-valued procedure is applied element-by-element to the actual argument, resulting in an array that has the same shape as the actual argument.

The values of the elements of the resulting array are the same as if the scalar-valued procedure had been applied separately to the corresponding elements of each argument.

For example, if A and B are arrays of shape (5,6), MAX(A, 0.0, B) is an array expression of shape (5,6) whose elements have the value MAX(A (i, j), 0.0, B (i, j)), where i = 1, 2,..., 5, and j = 1, 2,..., 6.

A reference to an elemental intrinsic procedure is an elemental reference if one or more actual arguments are arrays and all array arguments have the same shape.

Examples

Consider the following:

   REAL, DIMENSION (2) :: a, b
   a(1) = 4; a(2) = 9
   b = SQRT(a)                ! sets b(1) = SQRT(a(1)), and b(2) = SQRT(a(2))

For More Information:

  • See Arrays.
  • On elemental procedures, see Intrinsic Procedures.


References to Non-Fortran Procedures

To facilitate references to non-Fortran procedures, Compaq Fortran provides the following built-in functions:

  • To pass actual arguments:

    • %REF
    • %VAL
    • %DESCR (VMS only)

  • To compute the internal address of a storage item

    • %LOC


Procedure Interfaces

Every procedure has an interface, which consists of the name and characteristics of a procedure, the name and characteristics of each dummy argument, and the generic identifier (if any) by which the procedure can be referenced. The characteristics of a procedure are fixed, but the remainder of the interface can change in different scoping units.

If these properties are all known within the scope of the calling program, the procedure interface is explicit; otherwise it is implicit (deduced from its reference and declaration). The following table shows which procedures have implicit or explicit interfaces:

Kind of Procedure | Interface
External procedure | Implicit 1
Module Procedure | Explicit
Internal Procedure | Explicit
Intrinsic Procedure | Explicit
Dummy Procedure | Implicit 1
Statement function | Implicit
1 Unless an interface block is supplied for the procedure.

The interface of a recursive subroutine or function is explicit within the subprogram that defines it.

An explicit interface can appear in a procedure's definition, in an interface block, or both. (Internal procedures must not appear in an interface block.)

The following sections describe when explicit interfaces are required, how to define explicit interfaces, and how to define generic names, operators, and assignment.

Examples

An example of an interface block follows:

 INTERFACE
   SUBROUTINE Ext1 (x, y, z)
   REAL, DIMENSION (100,100) :: x, y, z
   END SUBROUTINE Ext1

   SUBROUTINE Ext2 (x, z)
   REAL x
   COMPLEX (KIND = 2) z (2000)
   END SUBROUTINE Ext2

   FUNCTION Ext3 (p, q)
   LOGICAL Ext3
   INTEGER p (1000)
   LOGICAL q (1000)
   END FUNCTION Ext3
 END INTERFACE


Determining When Procedures Require Explicit Interfaces

A procedure must have an explicit interface in the following cases:

  • If the procedure has any of the following:

    • An optional dummy argument

    • A dummy argument that is an assumed-shape array, a pointer, or a target

    • A result that is array-valued or a pointer (functions only)

    • A result whose length is neither assumed nor a constant (character functions only)

  • If a reference to the procedure appears as follows:

    • With an argument keyword

    • As a reference by its generic name

    • As a defined assignment (subroutines only)

    • In an expression as a defined operator (functions only)

    • In a context that requires it to be pure

  • If the procedure is elemental

For More Information:

  • See Optional arguments.
  • See Array arguments.
  • See Pointer arguments.
  • On argument keywords in subroutine references, see CALL.
  • On argument keywords in function references, see Function references.
  • See Pure procedures.
  • See Elemental procedures.
  • On user-defined generic procedures, see Defining Generic Names for Procedures.
  • On defined operators, see Defining Generic Operators.
  • On defined assignment, see Defining Generic Assignment.


Defining Explicit Interfaces

Interface blocks define explicit interfaces for external or dummy procedures. They can also be used to define a generic name for procedures, a new operator for functions, and a new form of assignment for subroutines.

For more information on interface blocks, see INTERFACE in the A to Z Reference.


Defining Generic Names for Procedures

An interface block can be used to specify a generic name to reference all of the procedures within the interface block.

The initial line for such an interface block takes the following form:

INTERFACE generic-name

generic-name
Is the generic name. It can be the same as any of the procedure names in the interface block, or the same as any accessible generic name (including a generic intrinsic name).

This kind of interface block can be used to extend or redefine a generic intrinsic procedure.

The procedures that are given the generic name must be the same kind of subprogram: all must be functions, or all must be subroutines.

Any procedure reference involving a generic procedure name must be resolvable to one specific procedure; it must be unambiguous. For more information, see Unambiguous Generic Procedure References.

The following is an example of a procedure interface block defining a generic name:

INTERFACE GROUP_SUBS
  SUBROUTINE INTEGER_SUB (A, B)
    INTEGER, INTENT(INOUT) :: A, B
  END SUBROUTINE INTEGER_SUB

  SUBROUTINE REAL_SUB (A, B)
    REAL, INTENT(INOUT) :: A, B
  END SUBROUTINE REAL_SUB

  SUBROUTINE COMPLEX_SUB (A, B)
    COMPLEX, INTENT(INOUT) :: A, B
  END SUBROUTINE COMPLEX_SUB
END INTERFACE

The three subroutines can be referenced by their individual specific names or by the group name GROUP_SUBS.

The following example shows a reference to INTEGER_SUB:

INTEGER V1, V2
CALL GROUP_SUBS (V1, V2)

Consider the following:

 INTERFACE LINE_EQUATION

   SUBROUTINE REAL_LINE_EQ(X1,Y1,X2,Y2,M,B)
     REAL,INTENT(IN) :: X1,Y1,X2,Y2
     REAL,INTENT(OUT) :: M,B
   END SUBROUTINE REAL_LINE_EQ

   SUBROUTINE INT_LINE_EQ(X1,Y1,X2,Y2,M,B)
     INTEGER,INTENT(IN) :: X1,Y1,X2,Y2
     INTEGER,INTENT(OUT) :: M,B
   END SUBROUTINE INT_LINE_EQ

 END INTERFACE

In this example, LINE_EQUATION is the generic name which can be used for either REAL_LINE_EQ or INT_LINE_EQ. Fortran selects the appropriate subroutine according to the nature of the arguments passed to LINE_EQUATION. Even when a generic name exists, you can always invoke a procedure by its specific name. In the previous example, you can call REAL_LINE_EQ by its specific name (REAL_LINE_EQ), or its generic name LINE_EQUATION.

For More Information:

For details on interface blocks, see INTERFACE.


Defining Generic Operators

An interface block can be used to define a generic operator. The only procedures allowed in the interface block are functions that can be referenced as defined operations.

The initial line for such an interface block takes the following form:

INTERFACE OPERATOR (op)

op
Is one of the following:

  • A defined unary operator (one argument)
  • A defined binary operator (two arguments)
  • An extended intrinsic operator (number of arguments must be consistent with the intrinsic uses of that operator)

The functions within the interface block must have one or two nonoptional arguments with intent IN, and the function result must not be of type character with assumed length. A defined operation is treated as a reference to the function.

The following shows the form (and an example) of a defined unary and defined binary operation:

Operation | Form | Example
Defined Unary | .defined-operator. operand1 | .MINUS. C
Defined Binary | operand2 .defined-operator. operand3 | B .MINUS. C
1 The operand corresponds to the function's dummy argument. 2 The left operand corresponds to the first dummy argument of the function. 3 The right operand corresponds to the second argument.

For intrinsic operator symbols, the generic properties include the intrinsic operations they represent. Both forms of each relational operator have the same interpretation, so extending one form (such as >=) defines both forms (>= and .GE.).

The following is an example of a procedure interface block defining a new operator:

  INTERFACE OPERATOR(.BAR.)
    FUNCTION BAR(A_1)
      INTEGER, INTENT(IN) :: A_1
      INTEGER :: BAR
    END FUNCTION BAR
  END INTERFACE

The following example shows a way to reference function BAR by using the new operator:

  INTEGER B
  I = 4 + (.BAR. B)

The following is an example of a procedure interface block with a defined operator extending an existing operator:

  INTERFACE OPERATOR(+)
    FUNCTION LGFUNC (A, B)
      LOGICAL, INTENT(IN) :: A(:), B(SIZE(A))
      LOGICAL :: LGFUNC(SIZE(A))
    END FUNCTION LGFUNC
  END INTERFACE

The following example shows two equivalent ways to reference function LGFUNC:

  LOGICAL, DIMENSION(1:10) :: C, D, E
  N = 10
  E = LGFUNC(C(1:N), D(1:N))
  E = C(1:N) + D(1:N)

For More Information:

  • See INTENT.
  • On interface blocks, see INTERFACE.
  • On intrinsic operators, see Expressions.
  • On defined operators and operations, see Defined Operations.


Defining Generic Assignment

An interface block can be used to define generic assignment. The only procedures allowed in the interface block are subroutines that can be referenced as defined assignments.

The initial line for such an interface block takes the following form:

INTERFACE ASSIGNMENT (=)

The subroutines within the interface block must have two nonoptional arguments, the first with intent OUT or INOUT, and the second with intent IN.

A defined assignment is treated as a reference to a subroutine. The left side of the assignment corresponds to the first dummy argument of the subroutine; the right side of the assignment corresponds to the second argument.

The ASSIGNMENT keyword extends or redefines an assignment operation if both sides of the equal sign are of the same derived type.

Defined elemental assignment is indicated by specifying ELEMENTAL in the SUBROUTINE statement.

Any procedure reference involving generic assignment must be resolvable to one specific procedure; it must be unambiguous. For more information, see Unambiguous Generic Procedure References.

The following is an example of a procedure interface block defining assignment:

  INTERFACE ASSIGNMENT (=)
    SUBROUTINE BIT_TO_NUMERIC (NUM, BIT)
      INTEGER, INTENT(OUT) :: NUM
      LOGICAL, INTENT(IN)  :: BIT(:)
    END SUBROUTINE BIT_TO_NUMERIC

    SUBROUTINE CHAR_TO_STRING (STR, CHAR)
      USE STRING_MODULE                    ! Contains definition of type STRING
      TYPE(STRING), INTENT(OUT) :: STR     ! A variable-length string
      CHARACTER(*), INTENT(IN)  :: CHAR
    END SUBROUTINE  CHAR_TO_STRING
  END  INTERFACE

The following example shows two equivalent ways to reference subroutine BIT_TO_NUMERIC:

  CALL BIT_TO_NUMERIC(X, (NUM(I:J)))
  X = NUM(I:J)

The following example shows two equivalent ways to reference subroutine CHAR_TO_STRING:

  CALL CHAR_TO_STRING(CH, '432C')
  CH = '432C'

For More Information:

  • See Defined Assignments.
  • See INTENT.
  • On interface blocks, see INTERFACE.


CONTAINS Statement

For information on the CONTAINS statement, see CONTAINS in the A to Z Reference.


ENTRY Statement

The ENTRY statement provides multiple entry points within a subprogram. It is not executable and must precede any CONTAINS statement (if any) within the subprogram. For more information, see ENTRY in the A to Z Reference.

This section also discusses:

  • ENTRY Statements in Function Subprograms
  • ENTRY Statements in Subroutine Subprograms


ENTRY Statements in Function Subprograms

If the ENTRY statement is contained in a function subprogram, it defines an additional function. The name of the function is the name specified in the ENTRY statement, and its result variable is the entry name or the name specified by RESULT (if any).

If the entry result variable has the same characteristics as the FUNCTION statement's result variable, their result variables identify the same variable, even if they have different names. Otherwise, the result variables are storage associated and must all be nonpointer scalars of intrinsic type, in one of the following groups:

Group 1 | Type default integer, default real, double precision real, default complex, double complex, or default logical
Group 2 | Type REAL(16) (VMS, U*X) and COMPLEX(16) (VMS, U*X)
Group 3 | Type default character (with identical lengths)

All entry names within a function subprogram are associated with the name of the function subprogram. Therefore, defining any entry name or the name of the function subprogram defines all the associated names with the same data type. All associated names with different data types become undefined.

If RESULT is specified in the ENTRY statement and RECURSIVE is specified in the FUNCTION statement, the interface of the function defined by the ENTRY statement is explicit within the function subprogram.

Examples

The following example shows a function subprogram that computes the hyperbolic functions SINH, COSH, and TANH:

REAL FUNCTION TANH(X)
  TSINH(Y) = EXP(Y) - EXP(-Y)
  TCOSH(Y) = EXP(Y) + EXP(-Y)

  TANH = TSINH(X)/TCOSH(X)
  RETURN

  ENTRY SINH(X)
  SINH = TSINH(X)/2.0
  RETURN

  ENTRY COSH(X)
  COSH = TCOSH(X)/2.0
  RETURN
END

For More Information:

See the RESULT keyword.


ENTRY Statements in Subroutine Subprograms

If the ENTRY statement is contained in a subroutine subprogram, it defines an additional subroutine. The name of the subroutine is the name specified in the ENTRY statement.

If RECURSIVE is specified on the SUBROUTINE statement, the interface of the subroutine defined by the ENTRY statement is explicit within the subroutine subprogram.

Examples

The following example shows a main program calling a subroutine containing an ENTRY statement:

PROGRAM TEST
  ...
  CALL SUBA(A, B, C)       ! A, B, and C are actual arguments
  ...                      !    passed to entry point SUBA
END
SUBROUTINE SUB(X, Y, Z)
  ...
  ENTRY SUBA(Q, R, S)      ! Q, R, and S are dummy arguments
  ...                      ! Execution starts with this statement
END SUBROUTINE

The following example shows an ENTRY statement specifying alternate returns:

CALL SUBC(M, N, *100, *200, P)
...
SUBROUTINE SUB(K, *, *)
  ...
  ENTRY SUBC(J, K, *, *, X)
  ...
  RETURN 1
  RETURN 2
END

Note that the CALL statement for entry point SUBC includes actual alternate return arguments. The RETURN 1 statement transfers control to statement label 100 and the RETURN 2 statement transfers control to statement label 200 in the calling program.


Intrinsic Procedures

Intrinsic procedures are functions and subroutines that are included in the Fortran 95/90 library. There are four classes of these intrinsic procedures, as follows:

  • Elemental procedures

    These procedures have scalar dummy arguments that can be called with scalar or array actual arguments. There are many elemental intrinsic functions and one elemental intrinsic subroutine (MVBITS).

    If the arguments are all scalar, the result is scalar. If an actual argument is array-valued, the intrinsic procedure is applied to each element of the actual argument, resulting in an array that has the same shape as the actual argument.

    If there is more than one array-valued argument, they must all have the same shape.

    Many algorithms involving arrays can now be written conveniently as a series of computations with whole arrays. For example, consider the following:

      a = b + c
  ...               ! a, b, c, and s are all arrays of similar shape
  s = sum(a)

    The above statements can replace entire DO loops.

    Consider the following:

      real, dimension (5,5) x,y
  . . .      !Assign values to x.
  y = sin(x) !Pass the entire array as an argument.

    In this example, since the SIN(X) function is an elemental procedure, it operates element-by-element on the array x when you pass it the name of the whole array.

  • Inquiry functions

    These functions have results that depend on the properties of their principal argument, not the value of the argument (the argument value can be undefined).

  • Transformational functions

    These functions have one or more array-valued dummy or actual arguments, an array result, or both. The intrinsic function is not applied elementally to an array-valued actual argument; instead it changes (transforms) the argument array into another array.

  • Nonelemental procedures

    These procedures must be called with only scalar arguments; they return scalar results. All subroutines (except MVBITS) are nonelemental.

Intrinsic procedures are invoked the same way as other procedures, and follow the same rules of argument association.

The intrinsic procedures have generic (or common) names, and many of the intrinsic functions have specific names. (Some intrinsic functions are both generic and specific.)

In general, generic functions accept arguments of more than one data type; the data type of the result is the same as that of the arguments in the function reference. For elemental functions with more than one argument, all arguments must be of the same type (except for the function MERGE).

When an intrinsic function is passed as an actual argument to a procedure, its specific name must be used, and when called, its arguments must be scalar. Some specific intrinsic functions are not allowed as actual arguments in all circumstances. Functions Not Allowed as Actual Arguments lists specific functions that cannot be passed as actual arguments.

This chapter also contains information on the following topics:

  • Argument keywords in intrinsic procedures
  • Overview of intrinsic procedures

The A to Z Reference contains the descriptions of all intrinsics listed in alphabetical order. Each reference entry indicates whether the procedure is inquiry, elemental, transformational, or nonelemental, and whether it is a function or a subroutine.

For More Information:

  • See Argument association.
  • See the MERGE intrinsic function.
  • See Optional arguments.
  • See Language Summary Tables.
  • See Data representation models.
  • On generic intrinsic procedures, see References to Generic Intrinsic Functions.
  • On elemental references to intrinsic procedures, see References to Elemental Intrinsic Procedures.


Argument Keywords in Intrinsic Procedures

For all intrinsic procedures, the arguments shown are the names you must use as keywords when using the keyword form for actual arguments. For example, a reference to function CMPLX(X, Y, KIND) can be written as follows:

Using positional arguments: | CMPLX(F, G, L)
Using argument keywords: 1 | CMPLX(KIND=L, Y=G, X=F)
1 Note that argument keywords can be written in any order.

Some argument keywords are optional (denoted by square brackets). The following describes some of the most commonly used optional arguments:

BACK | Specifies that a string scan is to be in reverse order (right to left).
DIM | Specifies a selected dimension of an array argument.
KIND | Specifies the kind type parameter of the function result.
MASK | Specifies that a mask can be applied to the elements of the argument array to exclude the elements that are not to be involved in an operation.

Examples:

The syntax for the DATE_AND_TIME intrinsic subroutine shows four optional positional arguments: DATE, TIME, ZONE, and VALUES. The following shows some valid ways to specify these arguments:

  ! Keyword example
  CALL DATE_AND_TIME (ZONE=Z)

  ! The following two positional examples are equivalent:
  CALL DATE_AND_TIME (DATE, TIME, ZONE)
  CALL DATE_AND_TIME (, , ZONE)

For More Information:

  • On argument keywords in subroutine references, see CALL.
  • On argument keywords in function references, see Function references.
  • See Argument Association.


Overview of Intrinsic Procedures

This section describes the categories of generic intrinsic functions (including a summarizing table), lists the intrinsic subroutines, and provides general information on bit functions.

Intrinsic procedures are fully described (in alphabetical order) in the A to Z Reference.


Categories of Intrinsic Functions

Generic intrinsic functions can be divided into categories, as shown in the following table:

Categories of Intrinsic Functions

Category | Subcategory | Description
Numeric | Computation | Elemental functions that perform type conversions or simple numeric operations: ABS, AIMAG, AINT, AMAX0, AMIN0, ANINT, CEILING, CMPLX, CONJG, DBLE, DCMPLX, DFLOAT, DIM, DPROD, DREAL, FLOAT, FLOOR, IFIX, IMAG, INT, MAX, MAX1, MIN, MIN1, MOD, MODULO, NINT, QCMPLX, QEXT, QFLOAT, QREAL, RAN, REAL, SIGN, SNGL, ZEXT
Manipulation1 | Elemental functions that return values related to the components of the model values associated with the actual value of the argument: EXPONENT, FRACTION, NEAREST, RRSPACING, SCALE, SET_EXPONENT, SPACING
Inquiry1 | Functions that return scalar values from the models associated with the type and kind parameters of their arguments2: DIGITS, EPSILON, HUGE, ILEN, MAXEXPONENT, MINEXPONENT, PRECISION, RADIX, RANGE, SIZEOF, TINY
Transformational | Functions that perform vector and matrix multiplication: DOT_PRODUCT, MATMUL
System | Functions that return information about a process or processor: PROCESSORS_SHAPE, NWORKERS, NUMBER_OF_PROCESSORS, SECNDS
Kind type | Functions that return kind type parameters: KIND, SELECTED_INT_KIND, SELECTED_REAL_KIND
Mathematical | Functions that perform mathematical operations: ACOS, ACOSD, ASIN, ASIND, ATAN, ATAND, ATAN2, ATAN2D, COS, COSD, COSH, COTAN, COTAND, EXP, LOG, LOG10, SIN, SIND, SINH, SQRT, TAN, TAND, TANH
Bit | Manipulation | Elemental functions that perform single-bit processing, and logical and shift operations; and allow bit subfields to be referenced: AND, BTEST, IAND, IBCHNG, IBCLR, IBITS, IBSET, IEOR, IOR, ISHA, ISHC, ISHFT, ISHFTC, ISHL, LSHIFT, NOT, OR, RSHIFT, XOR
Inquiry | Function that lets you determine parameter s (the bit size) in the bit model4: BIT_SIZE
Representation | Functions that return information on bit representation of integers: LEADZ, POPCNT, POPPAR, TRAILZ
Character | Comparison | Elemental functions that make a lexical comparison of the character-string arguments and return a default logical result: LGE, LGT, LLE, LLT
Conversion | Elemental functions that take character arguments and return integer, ASCII, or character values3: ACHAR, CHAR, IACHAR, ICHAR
String handling | Functions that perform operations on character strings, return lengths of arguments, and search for certain arguments: ADJUSTL, ADJUSTR, INDEX, LEN_TRIM, REPEAT, SCAN, TRIM, VERIFY
Inquiry | Function that returns length of argument: LEN
Array | Construction | Functions that construct new arrays from the elements of existing array: MERGE, PACK, SPREAD, UNPACK
Inquiry | Functions that let you determine if an array argument is allocated, and return the size or shape of an array, and the lower and upper bounds of subscripts along each dimension: ALLOCATED, LBOUND, SHAPE, SIZE, UBOUND
Location | Transformational functions that find the geometric locations of the maximum and minimum values of an array: MAXLOC, MINLOC
Manipulation | Transformational functions that shift an array, transpose an array, or change the shape of an array: CSHIFT, EOSHIFT, RESHAPE, TRANSPOSE
Reduction | Transformational functions that perform operations on arrays. The functions "reduce" elements of a whole array to produce a scalar result, or they can be applied to a specific dimension of an array to produce a result array with a rank reduced by one: ALL, ANY, COUNT, MAXVAL, MINVAL, PRODUCT
Miscellaneous Functions that do the following:
  • Let you use assembler instructions in an executable program (ASM)
  • Check for pointer association (ASSOCIATED)
  • Check for end-of-file (EOF)
  • Return the class of a floating-point argument (FP_CLASS)
  • Count actual arguments passed to a routine (IARGCOUNT)
  • Return a pointer to an actual argument list for a routine (IARGPTR)
  • Return the INTEGER KIND that will hold an address (INT_PTR_KIND)
  • Test for Not-a-Number values (ISNAN)
  • Return the internal address of a storage item (LOC)
  • Return a logical value of an argument (LOGICAL)
  • Allocate memory (MALLOC)
  • Return the upper 64 bits of a 128-bit unsigned result (MULT_HIGH)
  • Return a disassociated pointer (NULL)
  • Check for argument presence (PRESENT)
  • Convert a bit pattern (TRANSFER)
1 All of the numeric manipulation, and many of the numeric inquiry functions are defined by the model sets for integers and reals.
2 The value of the argument does not have to be defined.
3 The Compaq Fortran processor character set is ASCII, so ACHAR = CHAR and IACHAR = ICHAR.
4 For more information on bit functions, see Bit functions.

The following table summarizes the generic intrinsic functions and indicates whether they are elemental, inquiry, or transformational functions, if applicable. Optional arguments are shown within square brackets.

Summary of Generic Intrinsic Functions

Generic Function | Class | Value Returned
ABS (A) | E | The absolute value of an argument
ACHAR (I) | E | The character in the specified position of the ASCII character set
ACOS (X) | E | The arc cosine (in radians) of the argument
ACOSD (X) | E | The arc cosine (in degrees) of the argument
ADJUSTL (STRING) | E | The specified string with leading blanks removed and placed at the end of the string
ADJUSTR (STRING) | E | The specified string with trailing blanks removed and placed at the beginning of the string
AIMAG (Z) | E | The imaginary part of a complex argument
AINT (A [,KIND]) | E | A real value truncated to a whole number
ALL (MASK [,DIM]) | T | .TRUE. if all elements of the masked array are true
ALLOCATED (ARRAY) | I | The allocation status of the argument array
AMAX0 (A1, A2 [, A3,...]) | E | The maximum value in a list of integers (returned as a real value)
AMIN0 (A1, A2 [, A3,...]) | E | The minimum value in a list of integers (returned as a real value)
AND (I, J) | E | See IAND
ANINT (A [, KIND]) | E | A real value rounded to a whole number
ANY (MASK [,DIM]) | T | .TRUE. if any elements of the masked array are true
ASIN (X) | E | The arc sine (in radians) of the argument
ASIND (X) | E | The arc sine (in degrees) of the argument
ASM (STRING [,A,...) 1 | N | A value stored in the appropriate register by the user
ASSOCIATED (POINTER [,TARGET]) | I | .TRUE. if the pointer argument is associated or the pointer is associated with the specified target
ATAN (X) | E | The arc tangent (in radians) of the argument
ATAND (X) | E | The arc tangent (in degrees) of the argument
ATAN2 (Y, X) | E | The inverse arc tangent (in radians) of the arguments
ATAN2D (Y, X) | E | The inverse arc tangent (in degrees) of the arguments
BIT_SIZE (I) | I | Returns the number of bits (s) in the bit model
BTEST (I, POS) | E | .TRUE. if the specified position of argument I is one
CEILING (A [,KIND]) | E | The smallest integer greater than or equal to the argument value
CHAR (I [,KIND]) | E | The character in the specified position of the processor character set
CMPLX (X [,Y] [,KIND]) | E | The corresponding complex value of the argument
CONJG (Z) | E | The conjugate of a complex number
COS (X) | E | The cosine of the argument, which is in radians
COSD (X) | E | The cosine of the argument, which is in degrees
COSH (X) | E | The hyperbolic cosine of the argument
COTAN (X) | E | The cotangent of the argument, which is in radians
COTAND (X) | E | The cotangent of the argument, which is in degrees
COUNT (MASK [,DIM] [,KIND]) | T | The number of .TRUE. elements in the argument array
CSHIFT (ARRAY, SHIFT [,DIM]) | T | An array that has the elements of the argument array circularly shifted
DBLE (A) | E | The corresponding double precision value of the argument
DCMPLX (X, Y) | E | The corresponding double complex value of the argument
DFLOAT (A) | E | The corresponding double precision value of the integer argument
DIGITS (X) | I | The number of significant digits in the model for the argument
DIM (X, Y) | E | The positive difference between the two arguments
DOT_PRODUCT (VECTOR_A, VECTOR_B) | T | The dot product of two rank-one arrays (also called a vector multiply function)
DREAL (A) | E | The corresponding double-precision value of the double complex argument
EOF (A) | I | .TRUE. or .FALSE. depending on whether a file is beyond the end-of-file record
EOSHIFT (ARRAY, SHIFT [,BOUNDARY] [,DIM]) | T | An array that has the elements of the argument array end-off shifted
EPSILON (X) | I | The number that is almost negligible when compared to one
EXP (X) | E | The exponential value for the argument
EXPONENT (X) | E | The value of the exponent part of a real argument
FLOAT (X) | E | The corresponding real value of the integer argument
FLOOR (A [,KIND]) | E | The largest integer less than or equal to the argument value
FP_CLASS (X) | E | The class of the IEEE floating-point argument
FRACTION (X) | E | The fractional part of a real argument
HUGE (X) | I | The largest number in the model for the argument
IACHAR (C) | E | The position of the specified character in the ASCII character set
IAND (I, J) | E | The logical AND of the two arguments
IBCLR (I, POS) | E | The specified position of argument I cleared (set to zero)
IBCHNG (I, POS) | E | The reversed value of a specified bit
IBITS (I, POS, LEN) | E | The specified substring of bits of argument I
IBSET (I, POS) | E | The specified bit in argument I set to one
ICHAR (C) | E | The position of the specified character in the processor character set
IEOR (I, J) | E | The logical exclusive OR of the corresponding bit arguments
IFIX (X) | E | The corresponding integer value of the real argument rounded as if it were an implied conversion in an assignment
ILEN (I) | I | The length (in bits) in the two's complement representation of an integer
IMAG (Z) | E | See AIMAG
INDEX (STRING, SUBSTRING [,BACK]) | E | The position of the specified substring in a character expression
INT (A [,KIND]) | E | The corresponding integer value (truncated) of the argument
IOR (I, J) | E | The logical inclusive OR of the corresponding bit arguments
ISHA (I, SHIFT) | E | Argument I shifted left or right by a specified number of bits
ISHC (I, SHIFT) | E | Argument I rotated left or right by a specified number of bits
ISHFT (I, SHIFT) | E | The logical end-off shift of the bits in argument I
ISHFTC (I, SHIFT [,SIZE]) | E | The logical circular shift of the bits in argument I
ISHL (I, SHIFT) | E | Argument I logically shifted left or right by a specified number of bits
ISNAN (X) | E | Tests for Not-a-Number (NaN) values
KIND (X) | I | The kind type parameter of the argument
LBOUND (ARRAY [,DIM] [,KIND]) | I | The lower bounds of an array (or one of its dimensions)
LEADZ (I) | E | The number of leading zero bits in an integer
LEN (STRING [,KIND]) | I | The length (number of characters) of the argument character string
LEN_TRIM (STRING) | E | The length of the specified string without trailing blanks
LGE (STRING_A, STRING_B) | E | A logical value determined by a > or = comparison of the arguments
LGT (STRING_A, STRING_ B) | E | A logical value determined by a > comparison of the arguments
LLE (STRING_A, STRING_B) | E | A logical value determined by a < or = comparison of the arguments
LLT (STRING_A, STRING_B) | E | A logical value determined by a < comparison of the arguments
LOC (A) | I | The internal address of the argument.
LOG (X) | E | The natural logarithm of the argument
LOG10 (X) | E | The common logarithm (base 10) of the argument
LOGICAL (L [,KIND]) | E | The logical value of the argument converted to a logical of type KIND
LSHIFT (I, POSITIVE_SHIFT) | E | See ISHFT
MATMUL (MATRIX_A, MATRIX_B) | T | The result of matrix multiplication (also called a matrix multiply function)
MAX (A1, A2 [, A3,...]) | E | The maximum value in the set of arguments
MAX1 (A1, A2 [, A3,...]) | E | The maximum value in the set of real arguments (returned as an integer)
MAXEXPONENT (X) | I | The maximum exponent in the model for the argument
MAXLOC (ARRAY [,DIM] [,MASK]) | T | The rank-one array that has the location of the maximum element in the argument array
MAXVAL (ARRAY [,DIM] [,MASK]) | T | The maximum value of the elements in the argument array
MERGE (TSOURCE, FSOURCE, MASK) | E | An array that is the combination of two conformable arrays (under a mask)
MIN (A1, A2 [, A3,...]) | E | The minimum value in the set of arguments
MIN1 (A1, A2 [, A3,...]) | E | The minimum value in the set of real arguments (returned as an integer)
MINEXPONENT (X) | I | The minimum exponent in the model for the argument
MINLOC (ARRAY [,DIM] [,MASK]) | T | The rank-one array that has the location of the minimum element in the argument array
MINVAL (ARRAY [,DIM] [,MASK]) | T | The minimum value of the elements in the argument array
MOD (A, P) | E | The remainder of the arguments (has the sign of the first argument)
MODULO (A, P) | E | The modulo of the arguments (has the sign of the second argument)
NEAREST (X, S) | E | The nearest different machine-representable number in a given direction
NINT (A [,KIND]) | E | A real value rounded to the nearest integer
NOT (I) | E | The logical complement of the argument
NULL ([MOLD]) | T | A disassociated pointer
OR (I, J) | E | See IOR
PACK (ARRAY, MASK [,VECTOR]) | T | A packed array of rank one (under a mask)
POPCNT (I) | E | The number of 1 bits in an integer
POPPAR (I) | E | The parity of an integer
PRECISION (X) | I | The decimal precision (real or complex) of the argument
PRESENT (A) | I | .TRUE. if an actual argument has been provided for an optional dummy argument
PRODUCT (ARRAY [,DIM] [,MASK]) | T | The product of the elements of the argument array
QCMPLX (X, Y)2 | E | The corresponding COMPLEX(16) value of the argument
QEXT (A)2 | E | The corresponding REAL(16) precision value of the argument
QFLOAT (A)2 | E | The corresponding REAL(16) precision value of the integer argument
QREAL (A)2 | E | The corresponding REAL(16) value of the real part of a COMPLEX(16) argument
RADIX (X) | I | The base of the model for the argument
RANGE (X) | I | The decimal exponent range of the model for the argument
REAL (A [,KIND]) | E | The corresponding real value of the argument
REPEAT (STRING, NCOPIES) | T | The concatenation of zero or more copies of the specified string
RESHAPE (SOURCE, SHAPE [,PAD] [,ORDER]) | T | An array that has a different shape than the argument array, but the same elements
RRSPACING (X) | E | The reciprocal of the relative spacing near the argument
RSHIFT (I, NEGATIVE_SHIFT) | E | See ISHFT
SCALE (X, I) | E | The value of the exponent part (of the model for the argument) changed by a specified value
SCAN (STRING, SET [,BACK]) | E | The position of the specified character (or set of characters) within a string
SELECTED_INT_KIND (R) | T | The integer kind parameter of the argument
SELECTED_REAL_KIND ([P] [,R]) | T | The real kind parameter of the argument; one of the optional arguments must be specified
SET_EXPONENT (X, I) | E | The value of the exponent part (of the model for the argument) set to a specified value
SHAPE (SOURCE [,KIND]) | I | The shape (rank and extents) of an array or scalar
SIGN (A, B) | E | A value with the sign transferred from its second argument
SIN (X) | E | The sine of the argument, which is in radians
SIND (X) | E | The sine of the argument, which is in degreess
SINH (X) | E | The hyperbolic sine of the argument
SIZE (ARRAY [,DIM] [,KIND]) | I | The size (total number of elements) of the argument array (or one of its dimensions)
SNGL (X) | E | The corresponding real value of the argument
SPACING (X) | E | The value of the absolute spacing of model numbers near the argument
SPREAD (SOURCE, DIM, NCOPIES) | T | A replicated array that has an added dimension
SQRT (X) | E | The square root of the argument
SUM (ARRAY [,DIM] [,MASK]) | T | The sum of the elements of the argument array
TAN (X) | E | The tangent of the argument, which is in radians
TAND (X) | E | The tangent of the argument, which is in degrees
TANH (X) | E | The hyperbolic tangent of the argument
TINY (X) | I | The smallest positive number in the model for the argument
TRAILZ (I) | E | The number of trailing zero bits in an integer
TRANSFER (SOURCE, MOLD [,SIZE]) | T | The bit pattern of SOURCE converted to the type and kind parameters of MOLD
TRANSPOSE (MATRIX) | T | The matrix transpose for the rank-two argument array
TRIM (STRING) | T | The argument with trailing blanks removed
UBOUND (ARRAY [,DIM] [,KIND]) | I | The upper bounds of an array (or one of its dimensions)
UNPACK (VECTOR, MASK, FIELD) | T | An array (under a mask) unpacked from a rank-one array
VERIFY (STRING, SET [,BACK]) | E | The position of the first character in a string that does not appear in the given set of characters
XOR (I, J) | E | See IEOR
ZEXT (X [,KIND]) | E | A zero-extended value of the argument
1 Alpha only
2 VMS, U*X
Key to Classes
E-Elemental
I-Inquiry
T-Transformational
N-Nonelemental

The following table lists specific functions that have no generic function associated with them:

Specific Functions with No Generic Association

Generic Function | Class | Value Returned
DPROD (X, Y) | E | The double-precision product of two real arguments
DREAL (A) | E | The corresponding double-precision value of the double-complex argument
MALLOC (I) | E | The starting address for the block of memory allocated
MULT_HIGH (I, J) 1 | E | The upper (leftmost) 64 bits of the 128-bit unsigned result
NUMBER_OF_PROCESSORS ( ) | I | The total number of processors (peers) available to the program
NWORKERS ( ) 2 | I | The number of executing processes
PROCESSORS_SHAPE ( ) | I | The shape of an implementation-dependent hardware processor array
RAN (I) | N | The next number from a sequence of pseudorandom numbers (uniformly distributed in the range 0 to 1)
SECNDS (X) | E | The system time of day (or elapsed time) as a floating-point value in seconds
SIZEOF (X) | I | The bytes of storage used by the argument
1 Alpha only
2 Included for compatibility with older versions of Compaq Fortran 77.
Key to Classes
E-Elemental
I-Inquiry
N-Nonelemental


Intrinsic Subroutines

The following table lists the intrinsic subroutines. All these subroutines are nonelemental except for MVBITS.

Intrinsic Subroutines

Subroutine | Value Returned
CPU_TIME (TIME) | The processor time in seconds
DATE (BUF) | The ASCII representation of the current date (in dd-mmm-yy form)
DATE_AND_TIME ([DATE] [,TIME] [,ZONE] [,VALUES]) | Date and time information from the real-time clock
ERRSNS ([IO_ERR] [,SYS_ERR] [,STAT] [,UNIT] [,COND]) | Information about the most recently detected error condition
EXIT ([STATUS]) | Image exit status is optionally returned; the program is terminated, all files closed, and control is returned to the operating system
FREE (A) | Frees memory that is currently allocated
IDATE (I, J, K) | Three integer values representing the current month, day, and year
MVBITS (FROM, FROMPOS, LEN, TO, TOPOS)1 | A sequence of bits (bit field) is copied from one location to another
RANDOM_NUMBER (HARVEST) | A pseudorandom number taken from a sequence of pseudorandom numbers uniformly distributed within the range 0 <= x < 1
RANDOM_SEED ([SIZE] [,PUT] [,GET]) | The initialization or retrieval of the pseudorandom number generator seed value
RANDU (I1, I2, X) | A pseudorandom number as a single- precision value (within the range 0.0 to 1.0)
SYSTEM_CLOCK ([COUNT] [,COUNT_RATE] [,COUNT_MAX]) | Data from the processors real-time clock
TIME (BUF) | The ASCII representation of the current time (in hh:mm:ss form)
1 An elemental subroutine


Bit Functions

Integer data types are represented internally in binary twos complement notation. Bit positions in the binary representation are numbered from right (least significant bit) to left (most significant bit); the rightmost bit position is numbered 0.

The intrinsic functions IAND, IOR, IEOR, and NOT operate on all of the bits of their argument (or arguments). Bit 0 of the result comes from applying the specified logical operation to bit 0 of the argument. Bit 1 of the result comes from applying the specified logical operation to bit 1 of the argument, and so on for all of the bits of the result.

The functions ISHFT and ISHFTC shift binary patterns.

The functions IBSET, IBCLR, BTEST, and IBITS and the subroutine MVBITS operate on bit fields.

A bit field is a contiguous group of bits within a binary pattern. Bit fields are specified by a starting bit position and a length. A bit field must be entirely contained in its source operand.

For example, the integer 47 is represented by the following:

Binary pattern: | 0...0101111
Bit position: | n...6543210
 | Where n is the number of bit positions in the numeric storage unit.

You can refer to the bit field contained in bits 3 through 6 by specifying a starting position of 3 and a length of 4.

Negative integers are represented in twos complement notation. For example, the integer -47 is represented by the following:

Binary pattern: | 1...1010001
Bit position: | n...6543210
 | Where n is the number of bit positions in the numeric storage unit.

The value of bit position n is as follows:

   1 for a negative number
   0 for a non-negative number

All the high-order bits in the pattern from the last significant bit of the value up to bit n are the same as bit n.

IBITS and MVBITS operate on general bit fields. Both the starting position of a bit field and its length are arguments to these intrinsics. IBSET, IBCLR, and BTEST operate on 1-bit fields. They do not require a length argument.

For IBSET, IBCLR, and BTEST, the bit position range is as follows:

  • 0 to 63 for INTEGER(8) and LOGICAL(8)
  • 0 to 31 for INTEGER(4) and LOGICAL(4)
  • 0 to 15 for INTEGER(2) and LOGICAL(2)
  • 0 to 7 for BYTE, INTEGER(1), and LOGICAL(1)

For IBITS, the bit position can be any number. The length range is 0 to 63 on Alpha and ia64 processors; 0 to 31 on ia32 processors.

The following example demonstrates IBSET, IBCLR, and BTEST:

  I = 4
  J = IBSET (I,5)
  PRINT *, 'J = ',J
  K = IBCLR (J,2)
  PRINT *, 'K = ',K
  PRINT *, 'Bit 2 of K is ',BTEST(K,2)
  END

The results are: J = 36, K = 32, and Bit 2 of K is F.

For optimum selection of performance and memory requirements, Compaq Fortran provides the following integer data types:

Data Type | Storage Required (in bytes)
INTEGER(1) | 1
INTEGER(2) | 2
INTEGER(4) | 4
INTEGER(8)1 | 8

The bit manipulation functions each have a generic form that operates on all of these integer types and a specific form for each type.

When you specify the intrinsic functions that refer to bit positions or that shift binary patterns within a storage unit, be careful that you do not create a value that is outside the range of integers representable by the data type. If you shift by an amount greater than or equal to the size of the object you're shifting, the result is 0.

Consider the following:

  INTEGER(2) I,J
  I = 1
  J = 17
  I = ISHFT(I,J)

The variables I and J have INTEGER(2) type. Therefore, the generic function ISHFT maps to the specific function IISHFT, which returns an INTEGER(2) result. INTEGER(2) results must be in the range -32768 to 32767, but the value 1, shifted left 17 positions, yields the binary pattern 1 followed by 17 zeros, which represents the integer 131072. In this case, the result in I is 0.

The previous example would be valid if I was INTEGER(4), because ISHFT would then map to the specific function JISHFT, which returns an INTEGER(4) value.

If ISHFT is called with a constant first argument, the result will either be the default integer size or the smallest integer size that can contain the first argument, whichever is larger.


Data Transfer I/O Statements

Input/Output (I/O) statements can be used for data transfer, file connection, file inquiry, and file positioning.

This section discusses data transfer and contains information on the following topics:

  • An overview of records and files

  • Components of data transfer statements

  • Data transfer input statements:
    • READ statement
    • ACCEPT statement

  • Data transfer output statements:
    • WRITE statement
    • PRINT and TYPE statements
    • REWRITE statement

File connection, file inquiry, and file positioning I/O statements are discussed in File Operation I/O Statements (WNT, W95, and U*X).

See also Improve Overall I/O Performance in the Programmer's Guide.


Records and Files

A record is a sequence of values or a sequence of characters. There are three kinds of Fortran records, as follows:

  • Formatted

    A record containing formatted data that requires translation from internal to external form. Formatted I/O statements have explicit format specifiers (which can specify list-directed formatting) or namelist specifiers (for namelist formatting). Only formatted I/O statements can read formatted data.

  • Unformatted

    A record containing unformatted data that is not translated from internal form. An unformatted record can also contain no data. The internal representation of unformatted data is processor- dependent. Only unformatted I/O statements can read unformatted data.

  • Endfile

    The last record of a file. An endfile record can be explicitly written to a sequential file by an ENDFILE statement.

A file is a sequence of records. There are two types of Fortran files, as follows:

  • External

    A file that exists in a medium (such as computer disks or terminals) external to the executable program.

    Records in an external file must be either all formatted or all unformatted. There are three ways to access records in external files: sequential, keyed access (VMS only), and direct access.

    In sequential access, records are processed in the order in which they appear in the file. In direct access, records are selected by record number, so they can be processed in any order. In keyed access, records are processed by key-field value.

  • Internal

    Memory (internal storage) that behaves like a file. This type of file provides a way to transfer and convert data in memory from one format to another. The contents of these files are stored as scalar character variables.

For More Information:

For details on formatted and unformatted data transfers and external file access methods, see your programmer's guide.


Components of Data Transfer Statements

Data transfer statements take one of the following forms:

io-keyword (io-control-list) [io-list]
io-keyword format [, io-list]

io-keyword
Is one of the following: ACCEPT, PRINT (or TYPE), READ, REWRITE, or WRITE.

io-control-list
Is one or more of the following input/output (I/O) control specifiers:

[UNIT=]io-unit | ADVANCE | ERR | KEYID (VMS only)
[FMT=]format | END | IOSTAT | REC
[NML=]group | EOR | KEY[con] (VMS only) | SIZE

io-list
Is an I/O list, which can contain variables (except for assumed-size arrays) or implied-do lists. Output statements can contain constants or expressions.

format
Is the nonkeyword form of a control-list format specifier (no FMT=).

If a format specifier ([FMT=]format) or namelist specifier ([NML=]group) is present, the data transfer statement is called a formatted I/O statement; otherwise, it is an unformatted I/O statement.

If a record specifier (REC=) is present, the data transfer statement is a direct-access I/O statement; otherwise, it is a sequential-access I/O statement.

If an error, end-of-record, or end-of-file condition occurs during data transfer, file positioning and execution are affected, and certain control-list specifiers (if present) become defined. (For more information, see Branch Specifiers.)

Following sections describe the I/O control list and I/O lists.


I/O Control List

The I/O control list specifies one or more of the following:

  • The I/O unit to act upon ([UNIT=]io-unit)

    This specifier must be present; the rest are optional.

  • The format (explicit or list-directed) to use for data editing; if explicit, the keyword form must appear ([FMT=]
  • The namelist group name to act upon ([NML=]group)
  • The number of a record to access (REC)
  • The name of a variable that contains the completion status of an I/O operation (IOSTAT)
  • The label of the statement that receives control if an error (ERR), end-of-file (END), or end-of-record (EOR) condition occurs
  • The key field (KEY[con]) and key of reference (KEYID) to access a keyed-access record (VMS only)
  • Whether you want to use advancing or nonadvancing I/O (ADVANCE)
  • The number of characters read from a record (SIZE) by a nonadvancing READ statement

No control specifier can appear more than once, and the list must not contain both a format specifier and namelist group name specifier.

Control specifiers can take any of the following forms:

  • Keyword form

    When the keyword form (for example, UNIT=io-unit) is used for all control-list specifiers in an I/O statement, the specifiers can appear in any order.

  • Nonkeyword form

    When the nonkeyword form (for example, io-unit) is used for all control-list specifiers in an I/O statement, the io-unit specifier must be the first item in the control list. If a format specifier or namelist group name specifier is used, it must immediately follow the io-unit specifier.

  • Mixed form

    When a mix of keyword and nonkeyword forms is used for control-list specifiers in an I/O statement, the nonkeyword values must appear first. Once a keyword form of a specifier is used, all specifiers to the right must also be keyword forms.

The following sections describe the control-list specifiers in detail:

  • Unit Specifier
  • Format Specifier
  • Namelist Specifier
  • Record Specifier
  • I/O Status Specifier
  • Branch Specifiers
  • Advance Specifier
  • Character Count Specifier


Unit Specifier

The unit specifier identifies the I/O unit to be accessed. It takes the following form:

[UNIT=]io-unit

io-unit
For external files, it identifies a logical unit and is one of the following:

  • A scalar integer expression that refers to a specific file, I/O device, or pipe. If necessary, the value is converted to integer data type before use. The integer is in the range 0 through 2**31-1.

    Units 5 and 6 are associated with preconnected units. In addition, unit 0 is also associated with a preconnected unit on Tru64 UNIX, Linux, and Windows systems.

  • An asterisk (*). This is the default (or implicit) external unit, which is preconnected for formatted sequential access.

For internal files, io-unit identifies a scalar or array character variable that is an internal file. An internal file is designated internal storage space (a variable buffer) that is used with formatted (including list-directed) sequential READ and WRITE statements.

The io-unit must be specified in a control list. If the keyword UNIT is omitted, the io-unit must be first in the control list.

A unit number is assigned either explicitly through an OPEN statement or implicitly by the system. If a READ statement implicitly opens a file, the file's status is STATUS='OLD'. If a WRITE statement implicitly opens a file, the file's status is as follows:

  • On OpenVMS systems: STATUS='NEW'
  • On Tru64 UNIX, Linux, and Windows systems: STATUS='UNKNOWN'

If the internal file is a scalar character variable, the file has only one record; its length is equal to that of the variable.

If the internal file is an array character variable, the file has a record for each element in the array; each record's length is equal to one array element.

An internal file can be read only if the variable has been defined and a value assigned to each record in the file. If the variable representing the internal file is a pointer, it must be associated; if the variable is an allocatable array, it must be currently allocated.

Before data transfer, an internal file is always positioned at the beginning of the first character of the first record.

For More Information:

  • See the OPEN statement.
  • On implicit logical assignments, see your programmer's guide.
  • On preconnected units, see your programmer's guide.
  • On using internal files, see your programmer's guide.


Format Specifier

The format specifier indicates the format to use for data editing. It takes the following form:

[FMT=]format

format
Is one of the following:

  • The statement label of a FORMAT statement

    The FORMAT statement must be in the same scoping unit as the data transfer statement.

  • An asterisk (*), indicating list-directed formatting

  • A scalar default integer variable that has been assigned the label of a FORMAT statement (through an ASSIGN statement)

    The FORMAT statement must be in the same scoping unit as the data transfer statement.

  • A character expression (which can be an array or character constant) containing the run-time format

    A default character expression must evaluate to a valid format specification. If the expression is an array, it is treated as if all the elements of the array were specified in array element order and were concatenated.

  • The name of a numeric array (or array element) containing the format

If the keyword FMT is omitted, the format specifier must be the second specifier in the control list; the io-unit specifier must be first.

If a format specifier appears in a control list, a namelist group specifier must not appear.

For More Information:

  • See the FORMAT statement.
  • See the interaction between FORMAT statements and I/O lists.
  • On list-directed input, see Rules for List-Directed Sequential READ Statements; output, see Rules for List-Directed Sequential WRITE Statements.


Namelist Specifier

The namelist specifier indicates namelist formatting and identifies the namelist group for data transfer. It takes the following form:

[NML=]group

group
Is the name of a namelist group previously declared in a NAMELIST statement.

If the keyword NML is omitted, the namelist specifier must be the second specifier in the control list; the io-unit specifier must be first.

If a namelist specifier appears in a control list, a format specifier must not appear.

For More Information:

For details on namelist input, see Rules for Namelist Sequential READ Statements; output, see Rules for Namelist Sequential WRITE Statements.


Record Specifier

The record specifier identifies the number of the record for data transfer in a file connected for direct access. It takes the following form:

REC=r

r
Is a scalar numeric expression indicating the record number. The value of the expression must be greater than or equal to 1, and less than or equal to the maximum number of records allowed in the file.

If necessary, the value is converted to integer data type before use.

If REC is present, no END specifier, * format specifier, or namelist group name can appear in the same control list.

For More Information:

See Alternative Syntax for a Record Specifier.


Key-Field-Value Specifier (VMS only)

The key-field-value specifier identifies the key field of a record that you want to access in an indexed file. The key-field value is equal to the contents of a key field. The key field can be used to access records in indexed files because it determines their location.

A key field has attributes, such as the number, direction, length, byte offset, and type of the field. The attributes of the key field are specified at file creation. Records in an indexed file have the same attributes for their key fields.

A key-field-value specifier takes the following form:

KEY[con]=val

con
Is a selection condition keyword specifying how to compare val with key-field values. The keyword can be any of the following:

In Ascending-Key Files:
Keyword | Meaning
EQ | The key-field value must be equal to val. KEYEQ is the same as specifying KEY without the optional con.
GE | The key-field value must be greater than or equal to val.
GT | The key-field value must be greater than val.
NXT | The key-field value must be the next value of the key equal to or greater than val.
NXTNE | The key-field value must be the next value of the key strictly greater than val.
In Descending-Key Files:
Keyword | Meaning
EQ | The key-field value must be equal to val. KEYEQ is the same as specifying KEY without the optional con.
LE | The key-field value must be less than or equal to val.
LT | The key-field value must be less than val.
NXT | The key-field value must be the next value of the key equal to or less than val.
NXTNE | The key-field value must be the next value of the key that is strictly less than val.

val
Is an integer or character expression. The expression must match the type of key defined for the file. For an integer key, you must pass an integer expression; it cannot contain real or complex data. For a character key, you can pass either a CHARACTER expression or a BYTE array that contains CHARACTER data.

The specifiers KEY, KEYEQ, KEYNXT, and KEYNXTNE are interchangeable between ascending-key files and descending-key files. However, KEYNXT and KEYNXTNE are interpreted differently depending on the direction of the keys in the file, as follows:

 | In Ascending-Key Files | In Descending-Key Files
Specifier: | Is Equivalent to Specifier:
KEYNXT | KEYGE | KEYLE
KEYNXTNE | KEYGT | KEYLT

The specifiers KEYGE and KEYGT can only be used with ascending-key files, while the specifiers KEYLE and KEYLT can only be used with descending-key files. Any other use of these key specifiers causes a run-time error to occur.

When a program must be able to use either ascending-key or descending-key files, you should use KEYNXT and KEYNXTNE.

The Selection Process

To select key-field integer values, the process compares values using the signed integers themselves.

To select key-field character values, the process compares values by using the ASCII collating sequence. 1 The comparative length of val and a key-field value, as well as any specified selection condition, determine the kind of selection that occurs. The selection can be exact, generic, or approximate-generic, as follows:

  • Exact selections occur when the expression in val is equal in length to the expression in the key field of the currently accessed record, and the con keyword specifies a unique selection condition.

  • Generic selections occur when the expression in val is shorter than the expression in the key field of the currently accessed record, and the con keyword specifies a unique selection condition.

    The process compares all the characters in val, from left to right, with the same amount of characters in the key field (also from left to right). Remaining key-field characters are ignored.

    For example, consider that a record's key field is 10 characters long and the following statement is entered:

      READ (3, KEYEQ = 'ABCD')

    In this case, the process can select a record with a key-field value 'ABCDEFGHIJ'.

  • An approximate-generic selection occurs when the expression in val is shorter than the expression in the key field, and the con keyword does not specify a unique selection condition.

    As with generic selections, the process uses only the leftmost characters in the key field to compare values. It selects the first key field that satisfies the generic selection criterion.

    For example, consider that a record's key field is 5 characters long and the following statement is entered:

      READ (3, KEYGT = 'ABCD')

    In this case, the process can select the key-field value 'ABCEx' (and not the key-field value 'ABCDA').

If val is longer than the key-field value, no selection is made and a run-time error occurs.

1 Other collating sequences are available. For more information, see the Guide to OpenVMS File Applications.


Key-of-Reference Specifier (VMS only)

The key-of-reference specifier can optionally accompany the key-field-value specifier. The key-of-reference specifier indicates the key-field index that is searched to find the designated key-field value. It takes the following form:

KEYID=kn

kn
Is an integer expression indicating the key-field index. This expression is called the key of reference. Its value must be in the range 0 to 254.

A value of zero indicates the primary key, a value of 1 indicates the first alternate key, a value of 2 indicates the second alternate key, and so forth.

If no kn is indicated, the default number is the last specification given in a keyed I/O statement for that I/O unit.

For More Information:

See the key-field-value specifier.


I/O Status Specifier

The I/O status specifier designates a variable to store a value indicating the status of a data transfer operation. It takes the following form:

IOSTAT=i-var

i-var
Is a scalar integer variable. When a data transfer statement is executed, i-var is set to one of the following values:

A positive integer | Indicating an error condition occurred.
A negative integer | Indicating an end-of-file or end-of-record condition occurred. The negative integers differ depending on which condition occurred.
Zero | Indicating no error, end-of-file, or end-of-record condition occurred.

Execution continues with the statement following the data transfer statement, or the statement identified by a branch specifier (if any).

An end-of-file condition occurs only during execution of a sequential READ statement; an end-of-record condition occurs only during execution of a nonadvancing READ statement.

For More Information:

For details on the error numbers returned by IOSTAT, see your programmer's guide.


Branch Specifiers

A branch specifier identifies a branch target statement that receives control if an error, end-of-file, or end-of-record condition occurs. There are three branch specifiers, taking the following forms:

ERR=label
END=label
EOR=label

label
Is the label of the branch target statement that receives control when the specified condition occurs.

The branch target statement must be in the same scoping unit as the data transfer statement.

The following rules apply to these specifiers:

  • ERR

    The error specifier can appear in a sequential access READ or WRITE statement, a direct-access READ statement, an indexed READ statement (VMS only), or a REWRITE statement.

    If an error condition occurs, the position of the file is indeterminate, and execution of the statement terminates.

    If IOSTAT was specified, the IOSTAT variable becomes defined as a positive integer value. If SIZE was specified (in a nonadvancing READ statement), the SIZE variable becomes defined as an integer value. If a label was specified, execution continues with the labeled statement.

  • END

    The end-of-file specifier can appear only in a sequential access READ statement.

    An end-of-file condition occurs when no more records exist in a file during a sequential read, or when an end-of-file record produced by the ENDFILE statement is encountered. End-of-file conditions do not occur in indexed (VMS only) or direct-access READ statements.

    If an end-of-file condition occurs, the file is positioned after the end-of-file record, and execution of the statement terminates.

    If IOSTAT was specified, the IOSTAT variable becomes defined as a negative integer value. If a label was specified, execution continues with the labeled statement.

  • EOR

    The end-of-record specifier can appear only in a formatted, sequential access READ statement that has the specifier ADVANCE='NO'(nonadvancing input).

    An end-of-record condition occurs when a nonadvancing READ statement tries to transfer data from a position after the end of a record.

    If an end-of-record condition occurs, the file is positioned after the current record, and execution of the statement terminates.

    If IOSTAT was specified, the IOSTAT variable becomes defined as a negative integer value. If PAD='YES' was specified for file connection, the record is padded with blanks (as necessary) to satisfy the input item list and the corresponding data edit descriptor. If SIZE was specified, the SIZE variable becomes defined as an integer value. If a label was specified, execution continues with the labeled statement.

If one of the conditions occurs, no branch specifier appears in the control list, but an IOSTAT specifier appears, execution continues with the statement following the I/O statement. If neither a branch specifier nor an IOSTAT specifier appears, the program terminates.

For More Information:

  • On the IOSTAT specifier, see I/O Status Specifier and Using the IOSTAT Specifier and Fortran Exit Codes.
  • On branch target statements, see Branch Statements and Using the END, EOR, and ERR Branch Specifiers.
  • On error processing, see your programmer's guide.


Advance Specifier

The advance specifier determines whether nonadvancing I/O occurs for a data transfer statement. It takes the following form:

ADVANCE=c-expr

c-expr
Is a scalar character expression that evaluates to 'YES' for advancing I/O or 'NO' for nonadvancing I/O. The default value is 'YES'.

Trailing blanks in the expression are ignored.

The ADVANCE specifier can appear only in a formatted, sequential data transfer statement that specifies an external unit. It must not be specified for list-directed or namelist data transfer.

Advancing I/O always positions a file at the end of a record, unless an error condition occurs. Nonadvancing I/O can position a file at a character position within the current record.

For More Information:

For details on advancing and nonadvancing I/O, see your programmer's guide.


Character Count Specifier

The character count specifier defines a variable to contain the count of how many characters are read when a nonadvancing READ statement terminates. It takes the following form:

SIZE=i-var

i-var
Is a scalar integer variable.

If PAD='YES' was specified for file connection, blanks inserted as padding are not counted.

The SIZE specifier can appear only in a formatted, sequential READ statement that has the specifier ADVANCE='NO' (nonadvancing input). It must not be specified for list-directed or namelist data transfer.


I/O Lists

In a data transfer statement, the I/O list specifies the entities whose values will be transferred. The I/O list is either an implied- do list or a simple list of variables (except for assumed-size arrays).

In input statements, the I/O list cannot contain constants and expressions because these do not specify named memory locations that can be referenced later in the program.

However, constants and expressions can appear in the I/O lists for output statements because the compiler can use temporary memory locations to hold these values during the execution of the I/O statement.

If an input item is a pointer, it must be currently associated with a definable target; data is transferred from the file to the associated target. If an output item is a pointer, it must be currently associated with a target; data is transferred from the target to the file.

If an input or output item is an array, it is treated as if the elements (if any) were specified in array element order. For example, if ARRAY_A is an array of shape (2,1), the following input statements are equivalent:

  READ *, ARRAY_A
  READ *, ARRAY_A(1,1), ARRAY_A(2,1)

However, no element of that array can affect the value of any expression in the input list, nor can any element appear more than once in an input list. For example, the following input statements are invalid:

  INTEGER  B(50)
  ...
  READ *, B(B)
  READ *, B(B(1):B(10))

If an input or output item is an allocatable array, it must be currently allocated.

If an input or output item is a derived type, the following rules apply:

  • Any derived-type component must be in the scoping unit containing the I/O statement.
  • The derived type must not have a pointer component.
  • In a formatted I/O statement, a derived type is treated as if all of the components of the structure were specified in the same order as in the derived-type definition.
  • In an unformatted I/O statement, a derived type is treated as a single object.

The following sections describe simple list items in I/O lists, and implied-do lists in I/O lists.


Simple List Items in I/O Lists

In a data transfer statement, a simple list of items takes the following form:

item [, item] ...

item
Is one of the following:

  • For input statements: a variable name

    The variable must not be an assumed-size array, unless one of the following appears in the last dimension: a subscript, a vector subscript, or a section subscript specifying an upper bound.

  • For output statements: a variable name, expression, or constant

    Any expression must not attempt further I/O operations on the same logical unit. For example, it must not refer to a function subprogram that performs I/O on the same logical unit.

The data transfer statement assigns values to (or transfers values from) the list items in the order in which the items appear, from left to right.

When multiple array names are used in the I/O list of an unformatted input or output statement, only one record is read or written, regardless of how many array name references appear in the list.

Examples

The following example shows a simple I/O list:

  WRITE (6,10) J, K(3), 4, (L+4)/2, N

When you use an array name reference in an I/O list, an input statement reads enough data to fill every item of the array. An output statement writes all of the values in the array.

Data transfer begins with the initial item of the array and proceeds in the order of subscript progression, with the leftmost subscript varying most rapidly. The following statement defines a two-dimensional array:

  DIMENSION ARRAY(3,3)

If the name ARRAY appears with no subscripts in a READ statement, that statement assigns values from the input record(s) to ARRAY(1,1), ARRAY(2,1), ARRAY(3,1), ARRAY(1,2), and so on through ARRAY(3,3).

An input record contains the following values:

  1,3,721.73

The following example shows how variables in the I/O list can be used in array subscripts later in the list:

  DIMENSION ARRAY(3,3)
  ...
  READ (1,30) J, K, ARRAY(J,K)

When the READ statement is executed, the first input value is assigned to J and the second to K, establishing the subscript values for ARRAY(J,K). The value 721.73 is then assigned to ARRAY(1,3). Note that the variables must appear before their use as array subscripts.

Consider the following derived-type definition and structure declaration:

  TYPE EMPLOYEE
    INTEGER ID
    CHARACTER(LEN=40) NAME
  END TYPE EMPLOYEE
  ...
  TYPE(EMPLOYEE) :: CONTRACT   ! A structure of type EMPLOYEE

The following statements are equivalent:

  READ *, CONTRACT

  READ *, CONTRACT%ID, CONTRACT%NAME

The following shows more examples:

 !  A variable and array element in iolist:
       REAL b(99)
       READ (*, 300) n, b(n) ! n and b(n) are the iolist
 300   FORMAT (I2, F10.5) ! FORMAT statement telling what form the input data has

 !  A derived type and type element in iolist:
       TYPE YOUR_DATA
         REAL a
         CHARACTER(30) info
         COMPLEX cx
       END TYPE YOUR_DATA
       TYPE (YOUR_DATA) yd1, yd2
       yd1.a = 2.3
       yd1.info = "This is a type demo."
       yd1.cx = (3.0, 4.0)
       yd2.cx = (4.5, 6.7)
 !  The iolist follows the WRITE (*,500).
       WRITE (*, 500) yd1, yd2.cx
 !  The format statement tells how the iolist will be output.
 500   FORMAT (F5.3, A21, F5.2, ',', F5.2, ' yd2.cx = (', F5.2,
        ',',F5.2, ' )')
 !  The output looks like:
 !  2.300This is a type demo 3.00, 4.00 yd2.cx = ( 4.50, 6.70 )

The following example uses an array and an array section:

 !  An array in the iolist:
       INTEGER handle(5)
       DATA handle / 5*0 /
       WRITE (*, 99) handle
 99    FORMAT (5I5)
 !  An array section in the iolist.
       WRITE (*, 100) handle(2:3)
 100   FORMAT (2I5)

The following shows another example:

 PRINT *,'(I5)', 2*3   ! The iolist is the expression 2*3.

The following example uses a namelist:

 ! Namelist I/O:
      INTEGER int1
      LOGICAL log1
      REAL r1
      CHARACTER (20) char20
      NAMELIST /mylist/ int1, log1, r1, char20
      int1 = 1
      log1 = .TRUE.
      r1 = 1.0
      char20 = 'NAMELIST demo'
      OPEN (UNIT = 4, FILE = 'MYFILE.DAT', DELIM = 'APOSTROPHE')
      WRITE (UNIT = 4, NML = mylist)
 ! Writes the following:
 ! &MYLIST
 ! INT1 = 1,
 ! LOG1 = T,
 ! R1 = 1.000000    ,
 ! CHAR20 = 'NAMELIST demo '
 ! /
      REWIND(4)
      READ (4, mylist)

For More Information:

For details on the general rules for I/O lists, see I/O Lists.


Implied-Do Lists in I/O Lists

In a data transfer statement, an implied-do list acts as though it were a part of an I/O statement within a DO loop. It takes the following form:

(list, do-var = expr1, expr2 [,expr3])

list
Is a list of variables, expressions, or constants (see Simple List Items in I/O Lists).

do-var
Is the name of a scalar integer or real variable. The variable must not be one of the input items in list.

expr
Are scalar numeric expressions of type integer or real. They do not all have to be the same type, or the same type as the DO variable.

The implied-do loop is initiated, executed, and terminated in the same way as a DO construct.

The list is the range of the implied-do loop. Items in that list can refer to do-var, but they must not change the value of do-var.

Two nested implied-do lists must not have the same (or an associated) DO variable.

Use an implied-do list to do the following:

  • Specify iteration of part of an I/O list
  • Transfer part of an array
  • Transfer array items in a sequence different from the order of subscript progression

If the I/O statement containing an implied-do list terminates abnormally (with an END, EOR, or ERR branch or with an IOSTAT value other than zero), the DO variable becomes undefined.

Examples

The following two output statements are equivalent:

  WRITE (3,200) (A,B,C, I=1,3)            ! An implied-do list

  WRITE (3,200) A,B,C,A,B,C,A,B,C         ! A simple item list

The following example shows nested implied-do lists. Execution of the innermost list is repeated most often:

  WRITE (6,150) ((FORM(K,L), L=1,10), K=1,10,2)

The inner DO loop is executed 10 times for each iteration of the outer loop; the second subscript (L) advances from 1 through 10 for each increment of the first subscript (K). This is the reverse of the normal array element order. Note that K is incremented by 2, so only the odd-numbered rows of the array are output.

In the following example, the entire list of the implied-do list (P(1), Q(1,1), Q(1,2)...,Q(1,10)) are read before I is incremented to 2:

  READ (5,999) (P(I), (Q(I,J), J=1,10), I=1,5)

The following example uses fixed subscripts and subscripts that vary according to the implied-do list:

  READ (3,5555) (BOX(1,J), J=1,10)

Input values are assigned to BOX(1,1) through BOX(1,10), but other elements of the array are not affected.

The following example shows how a DO variable can be output directly:

  WRITE (6,1111) (I, I=1,20)

Integers 1 through 20 are written.

Consider the following:

        INTEGER mydata(25)
        READ (10, 9000) (mydata(I), I=6,10,1)
  9000  FORMAT (5I3)

In this example, the iolist specifies to put the input data into elements 6 through 10 of the array called mydata. The third value in the implied-DO loop, the increment, is optional. If you leave it out, the increment value defaults to 1.

For More Information:

  • See DO constructs.
  • On the general rules for I/O lists, see I/O Lists.


READ Statements

The READ statement is a data transfer input statement. Data can be input from external sequential, keyed-access (VMS only) or direct-access records, or from internal records. (For more information, see READ in the A to Z Reference.)

This section discusses the following topics:

  • Forms for Sequential READ Statements
  • Forms for Direct-Access READ Statements
  • Forms and Rules for Internal READ Statements


Forms for Sequential READ Statements

Sequential READ statements transfer input data from external sequential-access records. The statements can be formatted with format specifiers (which can use list-directed formatting) or namelist specifiers (for namelist formatting), or they can be unformatted.

A sequential READ statement takes one of the following forms:

Formatted:

READ (eunit, format [, advance] [, size] [, iostat] [, err] [, end] [, eor]) [io-list]
READ form [, io-list]

Formatted - List-Directed:

READ (eunit, * [, iostat] [, err] [, end]) [io-list]
READ * [, io-list]

Formatted - Namelist:

READ (eunit, nml-group [, iostat] [, err] [, end])
READ nml

Unformatted:

READ (eunit [, iostat] [, err] [, end]) [io-list]

For more information, see READ in the A to Z Reference.

This section discusses the following topics:

  • Rules for Formatted Sequential READ Statements
  • Rules for List-Directed Sequential READ Statements
  • Rules for Namelist Sequential READ Statements
  • Rules for Unformatted Sequential READ Statements

For More Information:

  • See I/O control-list specifiers.
  • See I/O lists.


Rules for Formatted Sequential READ Statements

Formatted, sequential READ statements translate data from character to binary form by using format specifications for editing (if any). The translated data is assigned to the entities in the I/O list in the order in which the entities appear, from left to right.

Values can be transferred to objects of intrinsic or derived types. For derived types, values of intrinsic types are transferred to the components of intrinsic types that ultimately make up these structured objects.

For data transfer, the file must be positioned so that the record read is a formatted record or an end-of-file record.

If the number of I/O list items is less than the number of fields in an input record, the statement ignores the excess fields.

If the number of I/O list items is greater than the number of fields in an input record, the input record is padded with blanks. However, if PAD='NO' was specified for file connection, the input list and file specification must not require more characters from the record than it contains. If more characters are required and nonadvancing input is in effect, an end-of-record condition occurs.

If the file is connected for unformatted I/O, formatted data transfer is prohibited.

Examples

The following example shows formatted, sequential READ statements:

  READ (*, '(B)', ADVANCE='NO') C

  READ (FMT="(E2.4)", UNIT=6, IOSTAT=IO_STATUS) A, B, C

For More Information:

  • See READ.
  • See Forms for Sequential READ Statements.


Rules for List-Directed Sequential READ Statements

List-directed, sequential READ statements translate data from character to binary form by using the data types of the corresponding I/O list item to determine the form of the data. The translated data is then assigned to the entities in the I/O list in the order in which they appear, from left to right.

If a slash ( / ) is encountered during execution, the READ statement is terminated, and any remaining input list items are unchanged.

If the file is connected for unformatted I/O, list-directed data transfer is prohibited.

List-Directed Records

A list-directed external record consists of a sequence of values and value separators. A value can be any of the following:

  • A constant

    Each constant must be a literal constant of type integer, real, complex, logical, or character; or a nondelimited character string. Binary, octal, hexadecimal, Hollerith, and named constants are not permitted.

    In general, the form of the constant must be acceptable for the type of the list item. The data type of the constant determines the data type of the value and the translation from external to internal form. The following rules also apply:

    • A numeric list item can correspond only to a numeric constant, and a character list item can correspond only to a character constant. If the data types of a numeric list element and its corresponding numeric constant do not match, conversion is performed according to the rules for arithmetic assignment (see the table in Numeric Assignment Statements).

    • A complex constant has the form of a pair of real or integer constants separated by a comma and enclosed in parentheses. Blanks can appear between the opening parenthesis and the first constant, before and after the separating comma, and between the second constant and the closing parenthesis.

    • A logical constant represents true values (.TRUE. or any value beginning with T, .T, t, or .t) or false values (.FALSE. or any value beginning with F, .F, f, or .f).

    A character string does not need delimiting apostrophes or quotation marks if the corresponding I/O list item is of type default character, and the following is true:

    • The character string does not contain a blank, comma (,), or slash ( / ).
    • The character string is not continued across a record boundary.
    • The first nonblank character in the string is not an apostrophe or a quotation mark.
    • The leading character is not a string of digits followed by an asterisk.

    A nondelimited character string is terminated by the first blank, comma, slash, or end-of-record encountered. Apostrophes and quotation marks within nondelimited character strings are transferred as is.

  • A null value

    A null value is specified by two consecutive value separators (such as ,,) or a nonblank initial value separator. (A value separator before the end of the record does not signify a null value.)

    A null value indicates that the corresponding list element remains unchanged. A null value can represent an entire complex constant, but cannot be used for either part of a complex constant.

  • A repetition of a null value (r*) or a constant (r*constant), where r is an unsigned, nonzero, integer literal constant with no kind parameter, and no embedded blanks.

A value separator is any number of blanks, or a comma or slash, preceded or followed by any number of blanks. When any of these appear in a character constant, they are considered part of the constant, not value separators.

The end of a record is equivalent to a blank character, except when it occurs in a character constant. In this case, the end of the record is ignored, and the character constant is continued with the next record (the last character in the previous record is immediately followed by the first character of the next record).

Blanks at the beginning of a record are ignored unless they are part of a character constant continued from the previous record. In this case, the blanks at the beginning of the record are considered part of the constant.

Examples

Suppose the following statements are specified:

  CHARACTER*14 C
  DOUBLE PRECISION T
  COMPLEX D,E
  LOGICAL L,M
  READ (1,*) I,R,D,E,L,M,J,K,S,T,C,A,B

Then suppose the following external record is read:

  4 6.3 (3.4,4.2), (3, 2 ) , T,F,,3*14.6 ,'ABC,DEF/GHI''JK'/

The following values are assigned to the I/O list items:

I/O List Item | Value Assigned
I | 4
R | 6.3
D | (3.4,4.2)
E | (3.0,2.0)
L | .TRUE.
M | .FALSE.
J | Unchanged
K | 14
S | 14.6
T | 14.6D0
C | ABC,DEF/GHI' JK
A | Unchanged
B | Unchanged

The following example shows list-directed input and output:

 REAL    a
 INTEGER i
 COMPLEX c
 LOGICAL up, down
 DATA a /2358.2E-8/, i /91585/, c /(705.60,819.60)/
 DATA up /.TRUE./, down /.FALSE./
 OPEN (UNIT = 9, FILE = 'listout', STATUS = 'NEW')
 WRITE  (9, *) a, i
 WRITE  (9, *) c, up, down
 REWIND (9)
 READ   (9, *) a, i
 READ   (9, *) c, up, down
 WRITE  (*, *) a, i
 WRITE  (*, *) c, up, down
 END

The preceding program produces the following output:

   2.3582001E-05     91585
  (705.6000,819.6000) T F

For More Information:

  • See READ.
  • See Forms for Sequential READ Statements.
  • On the literal constant forms of intrinsic data types, see Intrinsic Data Types.
  • On list-directed output, see Rules for List-Directed Sequential WRITE Statements.


Rules for Namelist Sequential READ Statement

Namelist, sequential READ statements translate data from external to internal form by using the data types of the objects in the corresponding NAMELIST statement to determine the form of the data. The translated data is assigned to the specified objects in the namelist group in the order in which they appear, from left to right.

If a slash ( / ) is encountered during execution, the READ statement is terminated, and any remaining input list items are unchanged.

If the file is connected for unformatted I/O, namelist data transfer is prohibited.

Namelist Records

A namelist external record takes the following form:

&group-name object = value [, object = value] .../

group-name
Is the name of the group containing the objects to be given values. The name must have been previously defined in a NAMELIST statement in the scoping unit. The name cannot contain embedded blanks and must be contained within a single record.

object
Is the name (or subobject designator) of an entity defined in the NAMELIST declaration of the group name. The object name must not contain embedded blanks except within the parentheses of a subscript or substring specifier. Each object must be contained in a single record.

value
Is any of the following:

  • A constant

    Each constant must be a literal constant of type integer, real, complex, logical, or character; or a nondelimited character string. Binary, octal, hexadecimal, Hollerith, and named constants are not permitted.

    In general, the form of the constant must be acceptable for the type of the list item. The data type of the constant determines the data type of the value and the translation from external to internal form. The following rules also apply:

    • A numeric list item can correspond only to a numeric constant, and a character list item can correspond only to a character constant. If the data types of a numeric list element and its corresponding numeric constant do not match, conversion is performed according to the rules for arithmetic assignment (see the table in Numeric Assignment Statements).

    • A complex constant has the form of a pair of real or integer constants separated by a comma and enclosed in parentheses. Blanks can appear between the opening parenthesis and the first constant, before and after the separating comma, and between the second constant and the closing parenthesis.

    • A logical constant represents true values (.TRUE. or any value beginning with T, .T, t, or .t) or false values (.FALSE. or any value beginning with F, .F, f, or .f).

    A character string does not need delimiting apostrophes or quotation marks if the corresponding NAMELIST item is of type default character, and the following is true:

    • The character string does not contain a blank, comma (,), slash ( / ), exclamation point(!), ampersand (&), dollar sign ($), left parenthesis, equal sign (=), percent sign (%), or period (.).

    • The character string is not continued across a record boundary.

    • The first nonblank character in the string is not an apostrophe or a quotation mark.

    • The leading character is not a string of digits followed by an asterisk.

    A nondelimited character string is terminated by the first blank, comma, slash, end-of-record, exclamation, ampersand, or dollar sign encountered. Apostrophes and quotation marks within nondelimited character strings are transferred as is.

    If an equal sign, percent sign, or period is encountered while scanning for a nondelimited character string, the string is treated as a variable name (or part of one) and not as a nondelimited character string.

  • A null value

    A null value is specified by two consecutive value separators (such as ,,) or a nonblank initial value separator. (A value separator before the end of the record does not signify a null value.)

    A null value indicates that the corresponding list element remains unchanged. A null value can represent an entire complex constant, but cannot be used for either part of a complex constant.

  • A repetition of a null value (r*) or a constant (r*constant), where r is an unsigned, nonzero, integer literal constant with no kind parameter, and no embedded blanks.

Blanks can precede or follow the beginning ampersand (&), follow the group name, precede or follow the equal sign, or precede the terminating slash.

Comments (beginning with ! only) can appear anywhere in namelist input. The comment extends to the end of the source line.

If an entity appears more than once within the input record for a namelist data transfer, the last value is the one that is used.

If there is more than one object = value pair, they must be separated by value separators.

A value separator is any number of blanks, or a comma or slash, preceded or followed by any number of blanks. When any of these appear in a character constant, they are considered part of the constant, not value separators.

The end of a record is equivalent to a blank character, except when it occurs in a character constant. In this case, the end of the record is ignored, and the character constant is continued with the next record (the last character in the previous record is immediately followed by the first character of the next record).

Blanks at the beginning of a record are ignored unless they are part of a character constant continued from the previous record. In this case, the blanks at the beginning of the record are considered part of the constant.

Prompting for Namelist Group Information

During execution of a program containing a namelist READ statement, you can specify a question mark character (?) or a question mark character preceded by an equal sign (=?) to get information about the namelist group. The ? or =? must follow one or more blanks.

If specified for a unit capable of both input and output, the ? causes display of the group name and the objects in that group. The =? causes display of the group name, objects within that group, and the current values for those objects (in namelist output form). If specified for another type of unit, the symbols are ignored.

For example, consider the following statements:

  NAMELIST /NLIST/ A,B,C
  REAL A /1.5/
  INTEGER B /2/
  CHARACTER*5 C /'ABCDE'/

  READ (5,NML=NLIST)
  WRITE (6,NML=NLIST)
  END

During execution, if a blank followed by ? is entered on a terminal device, the following values are displayed:

 &NLIST
   A
   B
   C
 /

If a blank followed by =? is entered, the following values are displayed:

 &NLIST
   A  =   1.500000    ,
   B  =           2,
   C  = ABCDE
 /

Examples

Suppose the following statements are specified:

  NAMELIST /CONTROL/ TITLE, RESET, START, STOP, INTERVAL
  CHARACTER*10 TITLE
  REAL(KIND=8) START, STOP
  LOGICAL(KIND=4) RESET
  INTEGER(KIND=4) INTERVAL
  READ (UNIT=1, NML=CONTROL)

The NAMELIST statement associates the group name CONTROL with a list of five objects. The corresponding READ statement reads the following input data from unit 1:

&CONTROL
   TITLE='TESTT002AA',
   INTERVAL=1,
   RESET=.TRUE.,
   START=10.2,
   STOP =14.5
/

The following values are assigned to objects in group CONTROL:

Namelist Object | Value Assigned
TITLE | TESTT002AA
RESET | T
START | 10.2
STOP | 14.5
INTERVAL | 1

It is not necessary to assign values to all of the objects declared in the corresponding NAMELIST group. If a namelist object does not appear in the input statement, its value (if any) is unchanged.

Similarly, when character substrings and array elements are specified, only the values of the specified variable substrings and array elements are changed. For example, suppose the following input is read:

&CONTROL TITLE(9:10)='BB' /

The new value for TITLE is TESTT002BB; only the last two characters in the variable change.

The following example shows an array as an object:

  DIMENSION ARRAY_A(20)
  NAMELIST /ELEM/ ARRAY_A
  READ (UNIT=1,NML=ELEM)

Suppose the following input is read:

&ELEM
ARRAY_A=1.1, 1.2, , 1.4
/

The following values are assigned to the ARRAY_A elements:

Array Element | Value Assigned
ARRAY_A(1) | 1.1
ARRAY_A(2) | 1.2
ARRAY_A(3) | Unchanged
ARRAY_A(4) | 1.4
ARRAY_A(5)...ARRAY(20) | Unchanged

When a list of values is assigned to an array element, the assignment begins with the specified array element, rather than with the first element of the array. For example, suppose the following input is read:

&ELEM
ARRAY_A(3)=34.54, 45.34, 87.63, 3*20.00
/

New values are assigned only to array ARRAY_A elements 3 through 8. The other element values are unchanged.

The following shows another example:

       INTEGER a, b
       NAMELIST /mynml/ a, b
 ...
 !  The following are all valid namelist variable assignments:
       &mynml a = 1 /
       $mynml a = 1 $
       $mynml a = 1 $end
       &mynml a = 1 &
       &mynml a = 1 $END
       &mynml
       a = 1
       b = 2
       /
Nondelimited character strings that are written out by using a NAMELIST write may not be read in as expected by a corresponding NAMELIST read. Consider the following:

NAMELIST/TEST/ CHARR
CHARACTER*3 CHARR(4)
DATA CHARR/'AAA', 'BBB', 'CCC', 'DDD'/
OPEN (UNIT=1, FILE='NMLTEST.DAT')
WRITE (1, NML=TEST)
END
The output file NMLTEST.DAT will contain:

&TEST
CHARR   = AAABBBCCCDDD
/
If an attempt is then made to read the data in NMLTEST.DAT with a NAMELIST read using nondelimited character strings, as follows:

NAMELIST/TEST/ CHARR
CHARACTER*3 CHARR(4)
DATA CHARR/4*'   '/
OPEN (UNIT=1, FILE='NMLTEST.DAT')
READ (1, NML=TEST)
PRINT *, 'CHARR read in >', CHARR(1),'<  >',CHARR(2),'<  >',
1       CHARR(3), '<  >', CHARR(4), '<'
END
The result is the following:

CHARR read in >AAA<  >   <  >   <  >   <

For More Information:

  • See the NAMELIST statement.
  • See Rules for Formatted Sequential READ Statements.
  • See an Alternative Form for Namelist External Records.
  • On namelist output, see Rules for Namelist Sequential WRITE Statements.


Rules for Unformatted Sequential READ Statements

Unformatted, sequential READ statements transfer binary data (without translation) between the current record and the entities specified in the I/O list. Only one record is read.

Objects of intrinsic or derived types can be transferred.

For data transfer, the file must be positioned so that the record read is an unformatted record or an end-of-file record.

The unformatted, sequential READ statement reads a single record. Each value in the record must be of the same type as the corresponding entity in the input list, unless the value is real or complex.

If the value is real or complex, one complex value can correspond to two real list entities, or two real values can correspond to one complex list entity. The corresponding values and entities must have the same kind parameter.

If the number of I/O list items is less than the number of fields in an input record, the statement ignores the excess fields. If the number of I/O list items is greater than the number of fields in an input record, an error occurs.

If a statement contains no I/O list, it skips over one full record, positioning the file to read the following record on the next execution of a READ statement.

If the file is connected for formatted, list-directed, or namelist I/O, unformatted data transfer is prohibited.

Examples

The following example shows an unformatted, sequential READ statement:

  READ (UNIT=6, IOSTAT=IO_STATUS) A, B, C

For More Information:

  • See READ.
  • See Forms for Sequential READ Statements.


Forms for Direct-Access READ Statements

Direct-access READ statements transfer input data from external records with direct access. (The attributes of a direct-access file are established by the OPEN statement.)

A direct-access READ statement can be formatted or unformatted, and takes one of the following forms:

Formatted:

READ (eunit, format, rec [, iostat] [, err]) [io-list]

Unformatted:

READ (eunit, rec [, iostat] [, err]) [io-list]

For more information, see READ in the A to Z Reference.

This section discusses the following topics:

  • Rules for Formatted Direct-Access READ Statements
  • Rules for Unformatted Direct-Access READ Statements

For More Information:

  • See I/O control-list specifiers.
  • See I/O lists.
  • On file sharing, see your programmer's guide.


Rules for Formatted Direct-Access READ Statements

Formatted, direct-access READ statements translate data from character to binary form by using format specifications for editing (if any). The translated data is assigned to the entities in the I/O list in the order in which the entities appear, from left to right.

Values can be transferred to objects of intrinsic or derived types. For derived types, values of intrinsic types are transferred to the components of intrinsic types that ultimately make up these structured objects.

For data transfer, the file must be positioned so that the record read is a formatted record or an end-of-file record.

If the number of I/O list items is less than the number of fields in an input record, the statement ignores the excess fields.

If the number of I/O list items is greater than the number of fields in an input record, the input record is padded with blanks. However, if PAD='NO' was specified for file connection, the input list and file specification must not require more characters from the record than it contains. If more characters are required and nonadvancing input is in effect, an end-of-record condition occurs.

If the format specification specifies another record, the record number is increased by one as each subsequent record is read by that input statement.

Examples

The following example shows a formatted, direct-access READ statement:

  READ (2, REC=35, FMT=10) (NUM(K), K=1,10)


Rules for Unformatted Direct-Access READ Statements

Unformatted, direct-access READ statements transfer binary data (without translation) between the current record and the entities specified in the I/O list. Only one record is read.

Objects of intrinsic or derived types can be transferred.

For data transfer, the file must be positioned so that the record read is an unformatted record or an end-of-file record.

The unformatted, direct-access READ statement reads a single record. Each value in the record must be of the same type as the corresponding entity in the input list, unless the value is real or complex.

If the value is real or complex, one complex value can correspond to two real list entities, or two real values can correspond to one complex list entity. The corresponding values and entities must have the same kind parameter.

If the number of I/O list items is less than the number of fields in an input record, the statement ignores the excess fields. If the number of I/O list items is greater than the number of fields in an input record, an error occurs.

If the file is connected for formatted, list-directed, or namelist I/O, unformatted data transfer is prohibited.

Examples

The following example shows unformatted, direct-access READ statements:

  READ (1, REC=10) LIST(1), LIST(8)
  READ (4, REC=58, IOSTAT=K, ERR=500) (RHO(N), N=1,5)


Forms for Indexed READ Statements (VMS only)

Indexed READ statements transfer input data from external records that have keyed access.

In an indexed file, a series of records can be read in key value sequence by using an indexed READ statement and sequential READ statements. The first record in the sequence is read by using the indexed statement, the rest are read by using the sequential READ statements.

An indexed READ statement can be formatted or unformatted, and takes one of the following forms:

Formatted:

READ (eunit, format, key [, keyid] [, iostat] [, err]) [io-list]

Unformatted:

READ (eunit, key [, keyid] [, err]) [io-list]

For more information, see READ in the A to Z Reference.

This section discusses the following topics:

  • Rules for Formatted Indexed READ Statements (VMS only)
  • Rules for Unformatted Indexed READ Statements (VMS only)

For More Information:

  • See I/O control-list specifiers.
  • See I/O lists.


Rules for Formatted Indexed READ Statements (VMS only)

Formatted, indexed READ statements translate data from character to binary form by using format specifications for editing (if any). The translated data is assigned to the entities in the I/O list in the order in which the entities appear, from left to right.

If the I/O list and format specifications indicate that additional records are to be read, the statement reads the additional records sequentially by using the current key-of-reference value.

If KEYID is omitted, the key-of-reference value is the same as the most recent specification. If KEYID is omitted from the first indexed READ statement, the key of reference is the primary key.

If the specified key value is shorter than the key field referenced, the key value is matched against the leftmost characters of the appropriate key field until a match is found. The record supplying the match is then read. If the key value is longer than the key field referenced, an error occurs.

If the file is connected for unformatted I/O, formatted data transfer is prohibited.

Examples

Suppose the following statement is specified:

  READ (3, KAT(25), KEY='ABCD') A,B,C,D

The READ statement retrieves a record with a key value of 'ABCD' in the primary key from the file connected to I/O unit 3. It then uses the format contained in the array item KAT(25) to read the first four fields from the record into variables A,B,C, and D.


Rules for Unformatted Indexed READ Statements (VMS only)

Unformatted, indexed READ statements transfer binary data (without translation) between the current record and the entities specified in the I/O list. Only one record is read.

If the number of I/O list items is less than the number of fields in the record being read, the unused fields in the record are discarded. If the number of I/O list items is greater than the number of fields, an error occurs.

If a specified key value is shorter than the key field referenced, the key value is matched against the leftmost characters of the appropriate key field until a match is found. The record supplying the match is then read. If the specified key value is longer than the key field referenced, an error occurs.

If the file is connected for formatted I/O, unformatted data transfer is prohibited.

Examples

Suppose the following statements are specified:

      OPEN (UNIT=3, STATUS='OLD',
1     ACCESS='KEYED', ORGANIZATION='INDEXED',
2     FORM='UNFORMATTED',
3     KEY=(1:5,30:37,18:23))
      READ (3,KEY='SMITH') ALPHA, BETA

The READ statement reads from the file connected to I/O unit 3 and retrieves the record with the value 'SMITH' in the primary key field (bytes 1 through 5). The first two fields of the record retrieved are placed in variables ALPHA and BETA, respectively.

Suppose the following statement is specified:

  READ (3,KEYGE='XYZDEF',KEYID=2,ERR=99) IKEY

In this case, the READ statement retrieves the first record having a value equal to or greater than 'XYZDEF' in the second alternate key field (bytes 18 through 23). The first field of that record is placed in variable IKEY.


Forms and Rules for Internal READ Statements

Internal READ statements transfer input data from an internal file.

An internal READ statement can only be formatted. It must include format specifiers (which can use list-directed formatting). Namelist formatting is not permitted.

An internal READ statement takes the following form:

READ (iunit, format [, iostat] [, err] [, end]) [io-list]

For more information on syntax, see READ in the A to Z Reference.

Formatted, internal READ statements translate data from character to binary form by using format specifications for editing (if any). The translated data is assigned to the entities in the I/O list in the order in which the entities appear, from left to right.

This form of READ statement behaves as if the format begins with a BN edit descriptor. (You can override this behavior by explicitly specifying the BZ edit descriptor.)

Values can be transferred to objects of intrinsic or derived types. For derived types, values of intrinsic types are transferred to the components of intrinsic types that ultimately make up these structured objects.

Before data transfer occurs, the file is positioned at the beginning of the first record. This record becomes the current record.

If the number of I/O list items is less than the number of fields in an input record, the statement ignores the excess fields.

If the number of I/O list items is greater than the number of fields in an input record, the input record is padded with blanks. However, if PAD='NO' was specified for file connection, the input list and file specification must not require more characters from the record than it contains.

In list-directed formatting, character strings have no delimiters.

Examples

The following program segment reads a record and examines the first character to determine whether the remaining data should be interpreted as decimal, octal, or hexadecimal. It then uses internal READ statements to make appropriate conversions from character string representations to binary.

INTEGER IVAL
CHARACTER TYPE, RECORD*80
CHARACTER*(*) AFMT, IFMT, OFMT, ZFMT
PARAMETER (AFMT='(Q,A)', IFMT= '(I10)', OFMT= '(O11)',        &
           ZFMT= '(Z8)')
ACCEPT AFMT, ILEN, RECORD
TYPE = RECORD(1:1)
IF (TYPE .EQ. 'D') THEN
    READ (RECORD(2:MIN(ILEN, 11)), IFMT) IVAL
ELSE IF (TYPE .EQ. 'O') THEN
    READ (RECORD(2:MIN(ILEN, 12)), OFMT) IVAL
ELSE IF (TYPE .EQ. 'X') THEN
    READ (RECORD(2:MIN(ILEN, 9)),ZFMT) IVAL
ELSE
    PRINT *, 'ERROR'
END IF
END

For More Information:

  • See I/O control-list specifiers.
  • See I/O lists.
  • On list-directed input, see Rules for List-Directed Sequential READ Statements.
  • On using internal files, see your programmer's guide.


ACCEPT Statement

The ACCEPT statement is a data transfer input statement. This statement is the same as a formatted, sequential READ statement, except that an ACCEPT statement must never be connected to user-specified I/O units.

For more information, see ACCEPT in the A to Z Reference.


WRITE Statements

The WRITE statement is a data transfer output statement. Data can be output to external sequential, keyed-access (VMS only) or direct-access records, or to internal records. (For more information, see WRITE in the A to Z Reference.)

This section discusses the following topics:

  • Forms for Sequential WRITE Statements
  • Forms for Direct-Access WRITE Statements
  • Forms and Rules for Internal WRITE Statements


Forms for Sequential WRITE Statements

Sequential WRITE statements transfer output data to external sequential access records. The statements can be formatted by using format specifiers (which can use list-directed formatting) or namelist specifiers (for namelist formatting), or they can be unformatted.

A sequential WRITE statement takes one of the following forms:

Formatted:

WRITE (eunit, format [, advance] [, iostat] [, err]) [io-list]

Formatted - List-Directed:

WRITE (eunit, * [, iostat] [, err]) [io-list]

Formatted - Namelist:

WRITE (eunit, nml-group [, iostat] [, err])

Unformatted:

WRITE (eunit [, iostat] [, err]) [io-list]

For more information, see WRITE in the A to Z Reference.

This section discusses the following topics:

  • Rules for Formatted Sequential WRITE Statements
  • Rules for List-Directed Sequential WRITE Statements
  • Rules for Namelist Sequential WRITE Statements
  • Rules for Unformatted Sequential WRITE Statements

For More Information:

  • See I/O control-list specifiers.
  • See I/O lists.


Rules for Formatted Sequential WRITE Statements

Formatted, sequential WRITE statements translate data from binary to character form by using format specifications for editing (if any). The translated data is written to an external file that is connected for sequential access.

Values can be transferred from objects of intrinsic or derived types. For derived types, values of intrinsic types are transferred from the components of intrinsic types that ultimately make up these structured objects.

The output list and format specification must not specify more characters for a record than the record size. (Record size is specified by RECL in an OPEN statement.)

If the file is connected for unformatted I/O, formatted data transfer is prohibited.

Examples

The following example shows formatted, sequential WRITE statements:

  WRITE (UNIT=8, FMT='(B)', ADVANCE='NO') C

  WRITE (*, "(F6.5)", ERR=25, IOSTAT=IO_STATUS) A, B, C

For More Information:

  • See WRITE.
  • See Forms for Sequential WRITE Statements.


Rules for List-Directed Sequential WRITE Statements

List-directed, sequential WRITE statements transfer data from binary to character form by using the data types of the corresponding I/O list item to determine the form of the data. The translated data is then written to an external file.

In general, values transferred as output have the same forms as values transferred as input.

The following table shows the default output formats for each intrinsic data type:

Default Formats for List-Directed Output
Data Type | Output Format
BYTE | I5
LOGICAL(1) | L2
LOGICAL(2) | L2
LOGICAL(4) | L2
LOGICAL(8) | L2
INTEGER(1) | I5
INTEGER(2) | I7
INTEGER(4) | I12
INTEGER(8) | I22
REAL(4) | 1PG15.7E2
REAL(8) T_floating | 1PG24.15E3
REAL(8) D_floating | 1PG24.16E2
REAL(8) G_floating | 1PG24.15E3
REAL(16) 1 | 1PG43.33E4
COMPLEX(4) | '(',1PG14.7E2,',',1PG14.7E2,')'
COMPLEX(8) T_floating | '(',1PG23.15E3,',',1PG23.15E3,')'
COMPLEX(8) D_floating | '(',1PG23.16E2,',',1PG23.16E2,')'
COMPLEX(8) G_floating | '(',1PG23.15E3,',',1PG23.15E3,')'
COMPLEX(16) 1 | '(',1PG42.33E4,',',1PG42.33E4,')'
CHARACTER | Aw 2
1 VMS, U*X. 2 Where w is the length of the character expression.

By default, character constants are not delimited by apostrophes or quotation marks, and each internal apostrophe or quotation mark is represented externally by one apostrophe or quotation mark.

This behavior can be changed by the DELIM specifier (in an OPEN statement) as follows:

  • If the file is opened with the DELIM='QUOTE' specifier, character constants are delimited by quotation marks and each internal quotation mark is represented externally by two consecutive quotation marks.

  • If the file is opened with the DELIM='APOSTROPHE' specifier, character constants are delimited by apostrophes and each internal apostrophe is represented externally by two consecutive apostrophes.

Each output statement writes one or more complete records.

A literal character constant or complex constant can be longer than an entire record. In the case of complex constants, the end of the record can occur between the comma and the imaginary part, if the imaginary part and closing right parenthesis cannot fit in the current record.

Each output record begins with a blank character for carriage control, except for literal character constants that are continued from the previous record.

Slashes, octal values, null values, and repeated forms of values are not output.

If the file is connected for unformatted I/O, list-directed data transfer is prohibited.

Examples

Suppose the following statements are specified:

  DIMENSION A(4)
  DATA A/4*3.4/
  WRITE (1,*) 'ARRAY VALUES FOLLOW'
  WRITE (1,*) A,4

The following records are then written to external unit 1:

ARRAY VALUES FOLLOW
   3.400000      3.400000      3.400000      3.400000      4

The following shows another example:

  INTEGER       i, j
  REAL          a, b
  LOGICAL       on, off
  CHARACTER(20) c
  DATA i /123456/, j /500/, a /28.22/, b /.0015555/
  DATA on /.TRUE./, off/.FALSE./
  DATA c /'Here''s a string'/
  WRITE (*, *)  i, j
  WRITE (*, *)  a, b, on, off
  WRITE (*, *)  c
  END

The preceding example produces the following output:

     123456         500
  28.22000      1.555500E-03 T F
Here's a string

For More Information:

  • See Rules for Formatted Sequential WRITE Statements.
  • On list-directed input, see Rules for List-Directed Sequential READ Statements.


Rules for Namelist Sequential WRITE Statements

Namelist, sequential WRITE statements translate data from internal to external form by using the data types of the objects in the corresponding NAMELIST statement to determine the form of the data. The translated data is then written to an external file.

In general, values transferred as output have the same forms as values transferred as input.

By default, character constants are not delimited by apostrophes or quotation marks, and each internal apostrophe or quotation mark is represented externally by one apostrophe or quotation mark.

This behavior can be changed by the DELIM specifier (in an OPEN statement) as follows:

  • If the file is opened with the DELIM='QUOTE' specifier, character constants are delimited by quotation marks and each internal quotation mark is represented externally by two consecutive quotation marks.

  • If the file is opened with the DELIM='APOSTROPHE' specifier, character constants are delimited by apostrophes and each internal apostrophe is represented externally by two consecutive apostrophes.

Each output statement writes one or more complete records.

A literal character constant or complex constant can be longer than an entire record. In the case of complex constants, the end of the record can occur between the comma and the imaginary part, if the imaginary part and closing right parenthesis cannot fit in the current record.

Each output record begins with a blank character for carriage control, except for literal character constants that are continued from the previous record.

Slashes, octal values, null values, and repeated forms of values are not output.

If the file is connected for unformatted I/O, namelist data transfer is prohibited.

Examples

Consider the following statements:

CHARACTER*19 NAME(2)/2*' '/
REAL PITCH, ROLL, YAW, POSITION(3)
LOGICAL DIAGNOSTICS
INTEGER ITERATIONS
NAMELIST /PARAM/ NAME, PITCH, ROLL, YAW, POSITION,        &
         DIAGNOSTICS, ITERATIONS
...
READ (UNIT=1,NML=PARAM)
WRITE (UNIT=2,NML=PARAM)

Suppose the following input is read:

&PARAM
    NAME(2)(10:)='HEISENBERG',
    PITCH=5.0, YAW=0.0, ROLL=5.0,
    DIAGNOSTICS=.TRUE.
    ITERATIONS=10
/

The following is then written to the file connected to unit 2:

&PARAM
NAME   = '                         ', '        HEISENBERG',
PITCH  =    5.000000    ,
ROLL   =    5.000000    ,
YAW    =   0.0000000E+00,
POSITION        = 3*0.0000000E+00,
DIAGNOSTICS     = T,
ITERATIONS      =                10
/

Note that character values are not enclosed in apostrophes unless the output file is opened with DELIM='APOSTROPHE'. The value of POSITION is not defined in the namelist input, so the current value of POSITION is written.

The following example declares a number of variables, which are placed in a namelist, initialized, and then written to the screen with namelist I/O:

       INTEGER(1) int1
       INTEGER    int2, int3, array(3)
       LOGICAL(1) log1
       LOGICAL log2, log3
       REAL    real1
       REAL(8) real2
       COMPLEX z1, z2
       CHARACTER(1)  char1
       CHARACTER(10) char2

       NAMELIST /example/ int1, int2, int3, log1, log2, log3,       &
      &          real1, real2, z1, z2, char1, char2, array

       int1     = 11
       int2     = 12
       int3     = 14
       log1     = .TRUE.
       log2     = .TRUE.
       log3     = .TRUE.
       real1    = 24.0
       real2    = 28.0d0
       z1       = (38.0,0.0)
       z2       = (316.0d0,0.0d0)
       char1    = 'A'
       char2    = '0123456789'
       array(1) = 41
       array(2) = 42
       array(3) = 43
       WRITE (*, example)

The preceding example produces the following output:

 &EXAMPLE
 INT1  =   11,
 INT2  =          12,
 INT3  =          14,
 LOG1  = T,
 LOG2  = T,
 LOG3  = T,
 REAL1 =   24.00000    ,
 REAL2 =   28.0000000000000     ,
 Z1    = (38.00000,0.0000000E+00),
 Z2    = (316.0000,0.0000000E+00),
 CHAR1 = A,
 CHAR2 = 0123456789,
 ARRAY =          41,          42,          43
 /

For More Information:

  • See the NAMELIST statement.
  • See Rules for Formatted Sequential WRITE Statements.
  • On namelist input, see Rules for Namelist Sequential READ Statements.


Rules for Unformatted Sequential WRITE Statements

Unformatted, sequential WRITE statements transfer binary data (without translation) between the entities specified in the I/O list and the current record. Only one record is written.

Objects of intrinsic or derived types can be transferred.

This form of WRITE statement writes exactly one record. If there is no I/O item list, the statement writes one null record.

If the file is connected for formatted, list-directed, or namelist I/O, unformatted data transfer is prohibited.

Examples

The following example shows an unformatted, sequential WRITE statement:

  WRITE (UNIT=6, IOSTAT=IO_STATUS) A, B, C


Forms for Direct-Access WRITE Statements

Direct-access WRITE statements transfer output data to external records with direct access. (The attributes of a direct-access file are established by the OPEN statement.)

A direct-access WRITE statement can be formatted or unformatted, and takes one of the following forms:

Formatted:

WRITE (eunit, format, rec [, iostat] [, err]) [io-list]

Unformatted:

WRITE (eunit, rec [, iostat] [, err]) [io-list]

For more information, see WRITE in the A to Z Reference.

This section discusses the following topics:

  • Rules for Formatted Direct-Access WRITE Statements
  • Rules for Unformatted Direct-Access WRITE Statements

For More Information:

  • See I/O control-list specifiers.
  • See I/O lists.


Rules for Formatted Direct-Access WRITE Statements

Formatted, direct-access WRITE statements translate data from binary to character form by using format specifications for editing (if any). The translated data is written to an external file that is connected for direct access.

Values can be transferred from objects of intrinsic or derived types. For derived types, values of intrinsic types are transferred from the components of intrinsic types that ultimately make up these structured objects.

If the values specified by the I/O list do not fill a record, blank characters are added to fill the record. If the I/O list specifies too many characters for the record, an error occurs.

If the format specification specifies another record, the record number is increased by one as each subsequent record is written by that output statement.

Examples

The following example shows a formatted, direct-access WRITE statement:

  WRITE (2, REC=35, FMT=10) (NUM(K), K=1,10)


Rules for Unformatted Direct-Access WRITE Statements

Unformatted, direct-access WRITE statements transfer binary data (without translation) between the entities specified in the I/O list and the current record. Only one record is written.

Objects of intrinsic or derived types can be transferred.

If the values specified by the I/O list do not fill a record, blank characters are added to fill the record. If the I/O list specifies too many characters for the record, an error occurs.

If the file is connected for formatted, list-directed, or namelist I/O, unformatted data transfer is prohibited.

Examples

The following example shows unformatted, direct-access WRITE statements:

  WRITE (1, REC=10) LIST(1), LIST(8)

  WRITE (4, REC=58, IOSTAT=K, ERR=500) (RHO(N), N=1,5)


Forms for Indexed WRITE Statements (VMS only)

Indexed WRITE statements transfer output data to external records that have keyed access. (The OPEN statement establishes the characteristics of an indexed file.)

Indexed WRITE statements always write a new record. You should use the REWRITE statement to update an existing record.

The syntax of an indexed WRITE statement is similar to a sequential WRITE statement, but an indexed WRITE statement refers to an I/O unit connected to an indexed file, whereas the sequential WRITE statement refers to an I/O unit connected to a sequential file.

An indexed WRITE statement can be formatted or unformatted, and takes one of the following forms:

Formatted:

WRITE (eunit, format, [, iostat] [, err]) [io-list]

Unformatted:

WRITE (eunit, [, iostat] [, err]) [io-list]

For more information, see WRITE in the A to Z Reference.

This section discusses the following topics:

  • Rules for Formatted Indexed READ Statements (VMS only)
  • Rules for Unformatted Indexed READ Statements (VMS only)

For More Information:

  • See I/O control-list specifiers.
  • See I/O lists.


Rules for Formatted Indexed WRITE Statements (VMS only)

Formatted, indexed WRITE statements translate data from binary to character form by using format specifications for editing (if any). The translated data is written to an external file that is connected for keyed access.

No key parameters are required in the list of control parameters, because all necessary key information is contained in the output record.

When you use a formatted indexed WRITE statement to write an INTEGER key, the key is translated from internal binary form to external character form. A subsequent attempt to read the record by using an integer key may not match the key field in the record.

If the file is connected for unformatted I/O, formatted data transfer is prohibited.

Examples

Consider the following example (which assumes that the first 10 bytes of a record are a character key):

      WRITE (4,100) KEYVAL, (RDATA(I), I=1, 20)
100   FORMAT (A10, 20F15.7)

The WRITE statement writes the translated values of each of the 20 elements of the array RDATA to a new formatted record in the indexed file connected to I/O unit 4. KEYVAL is the key by which the record is accessed.


Rules for Unformatted Indexed WRITE Statements (VMS only)

Unformatted, indexed WRITE statements transfer binary data (without translation) between the entities specified in the I/O list and the current record.

No key parameters are required in the list of control parameters, because all necessary key information is contained in the output record.

If the values specified by the I/O list do not fill a fixed-length record being written, the unused portion of the record is filled with zeros. If the values specified do not fit in the record, an error occurs.

Since derived data types of sequence type usually have a fixed record format, you can write to indexed files by using a sequence derived-type structure that models the file's record format. This lets you perform the I/O operation with a single derived-type variable instead of a potentially long I/O list. Nonsequence derived types should not be used for this purpose.

If the file is connected for formatted I/O, unformatted data transfer is prohibited.

Examples

The following example shows an unformatted, indexed WRITE statement:

  WRITE (UNIT=8, IOSTAT=IO_STATUS) A, B, C


Forms and Rules for Internal WRITE Statements

Internal WRITE statements transfer output data to an internal file.

An internal WRITE statement can only be formatted. It must include format specifiers (which can use list-directed formatting). Namelist formatting is not permitted.

An internal WRITE statement takes the following form:

WRITE (iunit, format [, iostat] [, err]) [io-list]

For more information on syntax, see WRITE in the A to Z Reference.

Formatted, internal WRITE statements translate data from binary to character form by using format specifications for editing (if any). The translated data is written to an internal file.

Values can be transferred from objects of intrinsic or derived types. For derived types, values of intrinsic types are transferred from the components of intrinsic types that ultimately make up these structured objects.

If the number of characters written in a record is less than the length of the record, the rest of the record is filled with blanks. The number of characters to be written must not exceed the length of the record.

Character constants are not delimited by apostrophes or quotation marks, and each internal apostrophe or quotation mark is represented externally by one apostrophe or quotation mark.

Examples

The following example shows an internal WRITE statement:

  INTEGER J, K, STAT_VALUE
  CHARACTER*50 CHAR_50
  ...
  WRITE (FMT=*, UNIT=CHAR_50, IOSTAT=STAT_VALUE) J, K

For More Information:

  • See I/O control-list specifiers.
  • See I/O lists.
  • On list-directed output, see Rules for List-Directed Sequential WRITE Statements.
  • On using internal files, see your programmer's guide.


PRINT and TYPE Statements

The PRINT statement is a data transfer output statement. TYPE is a synonym for PRINT. All forms and rules for the PRINT statement also apply to the TYPE statement.

The PRINT statement is the same as a formatted, sequential WRITE statement, except that the PRINT statement must never transfer data to user-specified I/O units.

For more information, see PRINT in the A to Z Reference.


REWRITE Statement

The REWRITE statement is a data transfer output statement that rewrites the current record.

A REWRITE statement can be formatted or unformatted. For more information, see REWRITE in the A to Z Reference.


I/O Formatting

A format appearing in an input or output (I/O) statement specifies the form of data being transferred and the data conversion (editing) required to achieve that form. The format specified can be explicit or implicit.

Explicit format is indicated in a format specification that appears in a FORMAT statement or a character expression (the expression must evaluate to a valid format specification).

The format specification contains edit descriptors, which can be data edit descriptors, control edit descriptors, or string edit descriptors.

Implicit format is determined by the processor and is specified using list-directed or namelist formatting.

List-directed formatting is specified with an asterisk (*); namelist formatting is specified with a namelist group name.

List-directed formatting can be specified for advancing sequential files and internal files. Namelist formatting can be specified only for advancing sequential files.

This chapter contains information on the following topics:

  • Format specifications
  • Data edit descriptors
  • Control edit descriptors
  • Character string edit descriptors
  • Nested and group repeat specifications
  • Variable Format Expressions
  • Printing of formatted records
  • Interaction between FORMAT statements and I/O lists

For More Information:

  • On list-directed input, see Rules for List-Directed Sequential READ Statements; outout, see Rules for List-Directed Sequential WRITE Statements.
  • On namelist input, see Rules for Namelist Sequential READ Statements; output, see Rules for Namelist Sequential WRITE Statements.


Format Specifications

A format specification can appear in a FORMAT statement or character expression. In a FORMAT statement, it is preceded by the keyword FORMAT. A format specification takes the following form:

(format-list)

format-list
Is a list of one or more of the following edit descriptors, separated by commas or slashes (/):

Data edit descriptors: I, B, O, Z, F, E, EN, ES, D, G, L, and A
Control edit descriptors: T, TL, TR, X, S, SP, SS, BN, BZ, P, :, /, $, \, and Q
String edit descriptors: H, 'c', and "c", where c is a character constant

A comma can be omitted in the following cases:

  • Between a P edit descriptor and an immediately following F, E, EN, ES, D, or G edit descriptor
  • Before a slash (/) edit descriptor when the optional repeat specification is not present
  • After a slash (/) edit descriptor
  • Before or after a colon (:) edit descriptor

Edit descriptors can be nested and a repeat specification can precede data edit descriptors, the slash edit descriptor, or a parenthesized list of edit descriptors.

Rules and Behavior

A FORMAT statement must be labeled.

Named constants are not permitted in format specifications.

If the associated I/O statement contains an I/O list, the format specification must contain at least one data edit descriptor or the control edit descriptor Q.

Blank characters can precede the initial left parenthesis, and additional blanks can appear anywhere within the format specification. These blanks have no meaning unless they are within a character string edit descriptor.

When a formatted input statement is executed, the setting of the BLANK specifier (for the relevant logical unit) determines the interpretation of blanks within the specification. If the BN or BZ edit descriptors are specified for a formatted input statement, they supersede the default interpretation of blanks. (For more information on BLANK defaults, see BLANK Specifier in OPEN statements.)

For formatted input, use the comma as an external field separator. The comma terminates the input of fields (for noncharacter data types) that are shorter than the number of characters expected. It can also designate null (zero-length) fields.

The first character of a record transmitted to a line printer or terminal is typically used for carriage control; it is not printed. The first character of such a record should be a blank, 0, 1, $, +, or ASCII NUL. Any other character is treated as a blank.

A format specification cannot specify more output characters than the external record can contain. For example, a line printer record cannot contain more than 133 characters, including the carriage control character.

The following table summarizes the edit descriptors that can be used in format specifications.

Summary of Edit Descriptors

Code | Form | Effect
A | A[w] | Transfers character or Hollerith values.
B | Bw[.m] | Transfers binary values.
BN | BN | Ignores embedded and trailing blanks in a numeric input field.
BZ | BZ | Treats embedded and trailing blanks in a numeric input field as zeros.
D | Dw.d | Transfers real values with D exponents.
E | Ew.d[Ee] | Transfers real values with E exponents.
EN | ENw.d[Ee] | Transfers real values with engineering notation.
ES | ESw.d[Ee] | Transfers real values with scientific notation.
F | Fw.d | Transfers real values with no exponent.
G | Gw.d[Ee] | Transfers values of all intrinsic types.
H | nHch[ch...] | Transfers characters following the H edit descriptor to an output record.
I | Iw[.m] | Transfers decimal integer values.
L | Lw | Transfers logical values: on input, transfers characters; on output, transfers T or F.
O | Ow[.m] | Transfers octal values.
P | kP | Interprets certain real numbers with a specified scale factor.
Q | Q | Returns the number of characters remaining in an input record.
S | S | Reinvokes optional plus sign (+) in numeric output fields; counters the action of SP and SS.
SP | SP | Writes optional plus sign (+) into numeric output fields.
SS | SS | Suppresses optional plus sign (+) in numeric output fields.
T | Tn | Tabs to specified position.
TL | TLn | Tabs left the specified number of positions.
TR | TRn | Tabs right the specified number of positions.
X | nX | Skips the specified number of positions.
Z | Zw[.m] | Transfers hexadecimal values.
$ | $ | Suppresses trailing carriage return during interactive I/O.
: | : | Terminates format control if there are no more items in the I/O list.
/ | [r]/ | Terminates the current record and moves to the next record.
\ | \ | Continues the same record; same as $.
'c' 1 | 'c' | Transfers the character literal constant (between the delimiters) to an output record.
1 These delimiters can also be quotation marks (").

Character Format Specifications

In data transfer I/O statements, a format specifier ([FMT=]format) can be a character expression that is a character array, character array element, or character constant. This type of format is also called a run-time format because it can be constructed or altered during program execution.

The expression must evaluate to a character string whose leading part is a valid format specification (including the enclosing parentheses).

If the expression is a character array element, the format specification must be contained entirely within that element.

If the expression is a character array, the format specification can continue past the first element into subsequent consecutive elements.

If the expression is a character constant delimited by apostrophes, use two consecutive apostrophes ('' ) to represent an apostrophe character in the format specification; for example:

  PRINT '("NUM can''t be a real number")'

Similarly, if the expression is a character constant delimited by quotation marks, use two consecutive quotation marks ("") to represent a quotation mark character in the format specification.

To avoid using consecutive apostrophes or quotation marks, you can put the character constant in an I/O list instead of a format specification, as follows:

  PRINT "(A)", "NUM can't be a real number"

The following shows another character format specification:

  WRITE (6, '(I12, I4, I12)') I, J, K

In the following example, the format specification changes with each iteration of the DO loop:

SUBROUTINE PRINT(TABLE)
REAL TABLE(10,5)
CHARACTER*5 FORCHR(0:5), RPAR*1, FBIG, FMED, FSML
DATA FORCHR(0),RPAR /'(',')'/
DATA FBIG,FMED,FSML /'F8.2,','F9.4,','F9.6,'/
DO I=1,10
  DO J=1,5
    IF (TABLE(I,J) .GE. 100.) THEN
      FORCHR(J) = FBIG
    ELSE IF (TABLE(I,J) .GT. 0.1) THEN
      FORCHR(J) = FMED
    ELSE
      FORCHR(J) = FSML
    END IF
  END DO
  FORCHR(5)(5:5) = RPAR
  WRITE (6,FORCHR) (TABLE(I,J), J=1,5)
END DO
END

The DATA statement assigns a left parenthesis to character array element FORCHR(0), and (for later use) a right parenthesis and three F edit descriptors to character variables.

Next, the proper F edit descriptors are selected for inclusion in the format specification. The selection is based on the magnitude of the individual elements of array TABLE.

A right parenthesis is added to the format specification just before the WRITE statement uses it.

Note: Format specifications stored in arrays are recompiled at run time each time they are used. If a Hollerith or character run-time format is used in a READ statement to read data into the format itself, that data is not copied back into the original array, and the array is unavailable for subsequent use as a run-time format specification.

Examples

The following example shows a format specification:

        WRITE (*, 9000) int1, real1(3), char1
 9000   FORMAT (I5, 3F4.5, A16)
 !  I5, 3F5.2, A16 is the format list.

In the following example, the integer-variable name MYFMT refers to the FORMAT statement 9000, as assigned just before the FORMAT statement.

       ASSIGN 9000 TO MYFMT
 9000  FORMAT (I5, 3F4.5, A16)
 !  I5, 3F5.2, A16 is the format list.
       WRITE (*, MYFMT) iolist

The following shows a format example using a character expression:

       WRITE (*, '(I5, 3F5.2, A16)')iolist
 ! I5, 3F4.5, A16 is the format list.

In the following example, the format list is put into an 80-character variable called MYLIST:

 CHARACTER(80) MYLIST
 MYLIST = '(I5, 3F5.2, A16)'
 WRITE (*, MYLIST) iolist

Consider the following two-dimensional array:

    1  2  3
    4  5  6

In this case, the elements are stored in memory in the order: 1, 4, 2, 5, 3, 6 as follows:

 CHARACTER(6) array(3)
 DATA array / '(I5', ',3F5.2', ',A16)' /
 WRITE (*, array) iolist

In the following example, the WRITE statement uses the character array element array(2) as the format specifier for data transfer:

 CHARACTER(80) array(5)
 array(2) = '(I5, 3F5.2, A16)'
 WRITE (*, array(2)) iolist

For More Information:

  • See data edit descriptors.
  • See control edit descriptors.
  • See character string edit descriptors.
  • See nested and group repeats.
  • See printing of formatted records.


Data Edit Descriptors

A data edit descriptor causes the transfer or conversion of data to or from its internal representation.

The part of a record that is input or output and formatted with data edit descriptors (or character string edit descriptors) is called a field.

The following topics are discussed in this section:

  • Forms for Data Edit Descriptors
  • General Rules for Numeric Editing
  • Integer Editing
  • Real and Complex Editing
  • Logical Editing (L)
  • Character Editing (A)
  • Default Widths for Data Edit Descriptors
  • Terminating Short Fields of Input Data


Forms for Data Edit Descriptors

A data edit descriptor takes one of the following forms:

[r]c
[r]cw
[r]cw.m
[r]cw.d
[r]cw.d[Ee]

r
Is a repeat specification. The range of r is 1 through 2147483647 (2**31-1). If r is omitted, it is assumed to be 1.

c
Is one of the following format codes: I, B, O, Z, F, E, EN, ES, D, G, L, or A.

w
Is the total number of digits in the field (the field width). If omitted, the system applies default values (see Default Widths for Data Edit Descriptors). The range of w is 1 through 2147483647 (2**31-1) on Alpha and ia64 processors; 1 through 32767 (2**15-1) on ia32 processors. For I, B, O, Z, and F, the range can start at zero.

m
Is the minimum number of digits that must be in the field (including leading zeros). The range of m is 0 through 32767 (2**15-1) on Alpha and ia64 processors; 0 through 255 (2**8-1) on ia32 processors.

d
Is the number of digits to the right of the decimal point (the significant digits). The range of d is 0 through 32767 (2**15-1) on Alpha and ia64 processors; 0 through 255 (2**8-1) on ia32 processors.

The number of significant digits is affected if a scale factor is specified for the data edit descriptor.

E
Identifies an exponent field.

e
Is the number of digits in the exponent. The range of e is 1 through 32767 (2**15-1) on Alpha and ia64 processors; 1 through 255 (2**8-1) on ia32 processors.

Rules and Behavior

Fortran 95/90 (and the previous standard) allows the field width to be omitted only for the A descriptor. However, Compaq Fortran allows the field width to be omitted for any data edit descriptor.

The r, w, m, d, and e must all be positive, unsigned, integer literal constants; or variable format expressions -- no kind parameter can be specified. They must not be named constants.

Actual useful ranges for r, w, m, d, and e may be constrained by record sizes (RECL) and the file system.

The data edit descriptors have the following specific forms:

Integer: | Iw[.m], Bw[.m], Ow[.m], and Zw[.m]
Real and complex: | Fw.d, Ew.d[Ee], ENw.d[Ee], ESw.d[Ee], Dw.d, and Gw.d[Ee]
Logical: | Lw
Character: | A[w]

The d must be specified with F, E, D, and G field descriptors even if d is zero. The decimal point is also required. You must specify both w and d, or omit them both.

A repeat specification can simplify formatting. For example, the following two statements are equivalent:

20  FORMAT (E12.4,E12.4,E12.4,I5,I5,I5,I5)
20  FORMAT (3E12.4,4I5)

Examples

 !  This WRITE outputs three integers, each in a five-space field
 !  and four reals in pairs of F7.2 and F5.2 values.
       INTEGER(2) int1, int2, int3
       REAL(4) r1, r2, r3, r4
       DATA int1, int2, int3 /143, 62, 999/
       DATA r1, r2, r3, r4 /2458.32, 43.78, 664.55, 73.8/
       WRITE (*,9000) int1, int2, int3, r1, r2, r3, r4
 9000  FORMAT (3I5, 2(1X, F7.2, 1X, F5.2))

The following output is produced:

  143  62  999 2458.32 43.78  664.55 73.80

For More Information:

  • See General rules for numeric editing.
  • See Nested and group repeats.


General Rules for Numeric Editing

The following rules apply to input and output data for numeric editing (data edit descriptors I, B, O, Z, F, E, EN, ES, D, and G).

Rules for Input Processing

Leading blanks in the external field are ignored. If BLANK='NULL' is in effect (or the BN edit descriptor has been specified) embedded and trailing blanks are ignored; otherwise, they are treated as zeros. An all-blank field is treated as a value of zero.

The following table shows how blanks are interpreted by default:

Type of Unit or File | Default
An explicitly OPENed unit | BLANK='NULL'
An internal file | BLANK='NULL'
A preconnected file1 | BLANK='NULL'
1 For interactive input from preconnected files, you should explicitly specify the BN or BZ edit descriptor to ensure desired behavior.

A minus sign must precede a negative value in an external field; a plus sign is optional before a positive value.

In input records, constants can include any valid kind parameter. Named constants are not permitted.

If the data field in a record contains fewer than w characters, an input statement will read characters from the next data field in the record. You can prevent this by padding the short field with blanks or zeros, or by using commas to separate the input data. The comma terminates the data field, and can also be used to designate null (zero-length) fields. For more information, see Terminating Short Fields of Input Data.

Rules for Output Processing

The field width w must be large enough to include any leading plus or minus sign, and any decimal point or exponent. For example, the field width for an E data edit descriptor must be large enough to contain the following:

  • For positive numbers: d+5 or d+e+3 characters
  • For negative numbers: d+6 or d+e+4 characters

A positive or zero value (zero is allowed for I, B, O, Z, and F descriptors) can have a plus sign, depending on which sign edit descriptor is in effect. If a value is negative, the leftmost nonblank character is a minus sign.

If the value is smaller than the field width specified, leading blanks are inserted (the value is right-justified). If the value is too large for the field width specified, the entire output field is filled with asterisks (*).

When the value of the field width is zero, the compiler selects the smallest possible positive actual field width that does not result in the field being filled with asterisks.

For More Information:

  • See Forms for data edit descriptors.
  • On format specifications, in general, see Format Specifications.
  • On compiler options, see your programmer's guide.


Integer Editing

Integer editing is controlled by the I (decimal), B (binary), O (octal), and Z (hexadecimal) data edit descriptors.


I Editing

The I edit descriptor transfers decimal integer values. It takes the following form:

I w[.m]

The value of m (the minimum number of digits in the constant) must not exceed the value of w (the field width). The m has no effect on input, only output.

The specified I/O list item must be of type integer or logical.

The G edit descriptor can be used to edit integer data; it follows the same rules as Iw.

Rules for Input Processing

On input, the I data edit descriptor transfers w characters from an external field and assigns their integer value to the corresponding I/O list item. The external field data must be an integer constant.

If the value exceeds the range of the corresponding input list item, an error occurs.

The following shows input using the I edit descriptor (the symbol ^ represents a nonprinting blank character):

Format    Input         Value
I4        2788          2788
I3        -26            -26
I9        ^^^^^^312      312

Rules for Output Processing

On output, the I data edit descriptor transfers the value of the corresponding I/O list item, right-justified, to an external field that is w characters long.

The field consists of zero or more blanks, followed by a sign (a plus sign is optional for positive values, a minus sign is required for negative values), followed by an unsigned integer constant with no leading zeros.

If m is specified, the unsigned integer constant must have at least m digits. If necessary, it is padded with leading zeros.

If m is zero, and the output list item has the value zero, the external field is filled with blanks.

The following shows output using the I edit descriptor (the symbol ^ represents a nonprinting blank character):

Format     Value         Output
I3          284          284
I4         -284          -284
I4            0          ^^^0
I5          174          ^^174
I2         3244          **
I3         -473          ***
I7           29.812      An error; the decimal point is invalid
I4.0          0          ^^^^
I4.2          1          ^^01
I4.4          1          0001

For More Information:

  • See Forms for data edit descriptors.
  • See General rules for numeric editing.


B Editing

The B data edit descriptor transfers binary (base 2) values. It takes the following form:

Bw[.m]

The value of m (the minimum number of digits in the constant) must not exceed the value of w (the field width). The m has no effect on input, only output.

The specified I/O list item can be of type integer, real, or logical.

Rules for Input Processing

On input, the B data edit descriptor transfers w characters from an external field and assigns their binary value to the corresponding I/O list item. The external field must contain only binary digits (0 or 1) or blanks.

If the value exceeds the range of the corresponding input list item, an error occurs.

The following shows input using the B edit descriptor:

Format    Input         Value
B4        1001          9
B1        1             1
B2        0             0

Rules for Output Processing

On output, the B data edit descriptor transfers the binary value of the corresponding I/O list item, right-justified, to an external field that is w characters long.

The field consists of zero or more blanks, followed by an unsigned integer constant (consisting of binary digits) with no leading zeros. A negative value is transferred in internal form.

If m is specified, the unsigned integer constant must have at least m digits. If necessary, it is padded with leading zeros.

If m is zero, and the output list item has the value zero, the external field is filled with blanks.

The following shows output using the B edit descriptor (the symbol ^ represents a nonprinting blank character):

Format      Value        Output
B4          9            1001
B2          0            ^0

For More Information:

  • See Forms for data edit descriptors.
  • See General rules for numeric editing.


O Editing

The O data edit descriptor transfers octal (base 8) values. It takes the following form:

Ow[.m]

The value of m (the minimum number of digits in the constant) must not exceed the value of w (the field width). The m has no effect on input, only output.

The specified I/O list item can be of type integer, real, or logical.

Rules for Input Processing

On input, the O data edit descriptor transfers w characters from an external field and assigns their octal value to the corresponding I/O list item. The external field must contain only octal digits (0 through 7) or blanks.

If the value exceeds the range of the corresponding input list item, an error occurs.

The following shows input using the O edit descriptor (the symbol ^ represents a nonprinting blank character):

Format    Input         Value
O5        32767               32767
O4        16234                1623
O3        97^           An error; the 9 is invalid in octal notation

Rules for Output Processing

On output, the O data edit descriptor transfers the octal value of the corresponding I/O list item, right-justified, to an external field that is w characters long.

The field consists of zero or more blanks, followed by an unsigned integer constant (consisting of octal digits) with no leading zeros. A negative value is transferred in internal form without a leading minus sign.

If m is specified, the unsigned integer constant must have at least m digits. If necessary, it is padded with leading zeros.

If m is zero, and the output list item has the value zero, the external field is filled with blanks.

The following shows output using the O edit descriptor (the symbol ^ represents a nonprinting blank character):

Format     Value         Output
O6          32767        ^77777
O12        -32767        ^37777700001
O2          14261        **
O4             27        ^^33
O5           10.5        41050
O4.2            7        ^^07
O4.4            7        0007

For More Information:

  • See Forms for data edit descriptors.
  • See General rules for numeric editing.


Z Editing

The Z data edit descriptor transfers hexadecimal (base 16) values. It takes the following form:

Zw[.m]

The value of m (the minimum number of digits in the constant) must not exceed the value of w (the field width). The m has no effect on input, only output.

The specified I/O list item can be of type integer, real, or logical.

Rules for Input Processing

On input, the Z data edit descriptor transfers w characters from an external field and assigns their hexadecimal value to the corresponding I/O list item. The external field must contain only hexadecimal digits (0 though 9 and A (a) through F(f)) or blanks.

If the value exceeds the range of the corresponding input list item, an error occurs.

The following shows input using the Z edit descriptor:

Format    Input         Value
Z3        A94                   A94
Z5        A23DEF              A23DE
Z5        95.AF2        An error; the decimal point is invalid

Rules for Output Processing

On output, the Z data edit descriptor transfers the hexadecimal value of the corresponding I/O list item, right-justified, to an external field that is w characters long.

The field consists of zero or more blanks, followed by an unsigned integer constant (consisting of hexadecimal digits) with no leading zeros. A negative value is transferred in internal form without a leading minus sign.

If m is specified, the unsigned integer constant must have at least m digits. If necessary, it is padded with leading zeros.

If m is zero, and the output list item has the value zero, the external field is filled with blanks.

The following shows output using the Z edit descriptor (the symbol ^ represents a nonprinting blank character):

Format      Value         Output
Z4           32767        7FFF
Z9          -32767        ^FFFF8001
Z2              16        10
Z4           -10.5        ****
Z3.3          2708        A94
Z6.4          2708        ^^0A94

For More Information:

  • See Forms for data edit descriptors.
  • See General rules for numeric editing.


Real and Complex Editing

Real and complex editing is controlled by the F, E, D, EN, ES, and G data edit descriptors.

If no field width (w) is specified for a real data edit descriptor, the system supplies default values.

Real data edit descriptors can be affected by specified scale factors.

Note: Do not use the real data edit descriptors when attempting to parse textual input. These descriptors accept some forms that are purely textual as valid numeric input values. For example, input values T and F are treated as values -1.0 and 0.0, respectively, for .TRUE. and .FALSE..

For More Information:

  • See Forms for data edit descriptors.
  • See General rules for numeric editing.
  • On the scale factor, see Scale Factor Editing (P).
  • On system default values for data edit descriptors , see Default Widths for Data Edit Descriptors.


F Editing

The F data edit descriptor transfers real values. It takes the following form:

Fw.d

The value of d (the number of places after the decimal point) must not exceed the value of w (the field width).

The specified I/O list item must be of type real, or it must be the real or imaginary part of a complex type.

Rules for Input Processing

On input, the F data edit descriptor transfers w characters from an external field and assigns their real value to the corresponding I/O list item. The external field data must be an integer or real constant.

If the input field contains only an exponent letter or decimal point, it is treated as a zero value.

If the input field does not contain a decimal point or an exponent, it is treated as a real number of w digits, with d digits to the right of the decimal point. (Leading zeros are added, if necessary.)

If the input field contains a decimal point, the location of that decimal point overrides the location specified by the F descriptor.

If the field contains an exponent, that exponent is used to establish the magnitude of the value before it is assigned to the list element.

The following shows input using the F edit descriptor:

Format    Input         Value
F8.5      123456789       123.45678
F8.5      -1234.567     -1234.56
F8.5      24.77E+2       2477.0
F5.2      1234567.89      123.45

Rules for Output Processing

On output, the F data edit descriptor transfers the real value of the corresponding I/O list item, right-justified and rounded to d decimal positions, to an external field that is w characters long.

The w must be greater than or equal to d+3 to allow for the following:

  • A sign (optional if the value is positive and descriptor SP is not in effect)
  • At least one digit to the left of the decimal point
  • The decimal point
  • The d digits to the right of the decimal point

The following shows output using the F edit descriptor (the symbol ^ represents a nonprinting blank character):

Format      Value             Output
F8.5           2.3547188      ^2.35472
F9.3        8789.7361         ^8789.736
F2.1          51.44           **
F10.4        -23.24352        ^^-23.2435
F5.2         325.013          ******
F5.2           -.2            -0.20

For More Information:

  • See Forms for data edit descriptors.
  • See General rules for numeric editing.


E and D Editing

The E and D data edit descriptors transfer real values in exponential form. They take the following form:

Ew.d[Ee]
Dw.d

For the E edit descriptor, the value of d (the number of places after the decimal point) plus e (the number of digits in the exponent) must not exceed the value of w (the field width).

For the D edit descriptor, the value of d must not exceed the value of w.

The specified I/O list item must be of type real, or it must be the real or imaginary part of a complex type.

Rules for Input Processing

On input, the E and D data edit descriptors transfer w characters from an external field and assigns their real value to the corresponding I/O list item. The E and D descriptors interpret and assign input data in the same way as the F data edit descriptor.

The following shows input using the E and D edit descriptors (the symbol ^ represents a nonprinting blank character):

Format        Input             Value
E9.3          734.432E3           734432.0
E12.4         ^^1022.43E            1022.43E-6
E15.3         52.3759663^^^^^         52.3759663
E12.5         210.5271D+10¹        210.5271E10
BZ,D10.2      12345^^^^^        12345000.0D0
D10.2         ^^123.45^^             123.45D0
D15.3         367.4981763D+04          3.674981763D+06
1 If the I/O list item is single-precision real, the E edit descriptor treats the D exponent indicator as an E indicator.

Rules for Output Processing

On output, the E and D data edit descriptors transfer the real value of the corresponding I/O list item, right-justified and rounded to d decimal positions, to an external field that is w characters long.

The w should be greater than or equal to d+7 to allow for the following:

  • A sign (optional if the value is positive and descriptor SP is not in effect)
  • An optional zero to the left of the decimal point
  • The decimal point
  • The d digits to the right of the decimal point
  • The exponent

The exponent takes one of the following forms:

Edit Descriptor | Absolute Value of Exponent | Positive Form of Exponent | Negative Form of Exponent
Ew.d | |exp| <= 99 | E+nn | E-nn
 | 99 < |exp| <= 999 | +nnn | -nnn
Ew.dEe | |exp| <= 10e - 1 | E+n1n2...ne | E-n1n2...ne
Dw.d | |exp| <= 99 | D+nn or E+nn | D-nn or E-nn
 | 99 < |exp| <= 999 | +nnn | -nnn

If the exponent value is too large to be converted into one of these forms, an error occurs.

The exponent field width (e) is optional for the E edit descriptor; if omitted, the default value is 2. If e is specified, the w should be greater than or equal to d+e+5.

Note: The w can be as small as d+5 or d+e+3, if the optional fields for the sign and the zero are omitted.

The following shows output using the E and D edit descriptors (the symbol ^ represents a nonprinting blank character):

Format       Value               Output
E11.2        475867.222            ^^^0.48E+06
E11.5        475867.222               0.47587E+06
E12.3             0.00069           ^^^0.690E
E10.3            -0.5555              -0.556E+00
E5.3             56.12               *****
E14.5E4          -1.001              -0.10010E+0001
E13.3E6           0.000123            0.123E-000003
D14.3             0.0363         ^^^^^0.363D-01
D23.12         5413.87625793     ^^^^^0.541387625793D+04
D9.6              1.2            *********

For More Information:

  • See Forms for data edit descriptors.
  • See General rules for numeric editing.
  • On the scale factor, see Scale Factor Editing (P).


EN Editing

The EN data edit descriptor transfers values by using engineering notation. It takes the following form:

ENw.d[Ee]

The value of d (the number of places after the decimal point) plus e (the number of digits in the exponent) must not exceed the value of w (the field width).

The specified I/O list item must be of type real, or it must be the real or imaginary part of a complex type.

Rules for Input Processing

On input, the EN data edit descriptor transfers w characters from an external field and assigns their real value to the corresponding I/O list item. The EN descriptor interprets and assigns input data in the same way as the F data edit descriptor.

The following shows input using the EN edit descriptor (the symbol ^ represents a nonprinting blank character):

Format     Input           Value
EN11.3      ^^5.321E+00       5.32100
EN11.3      -600.00E-03       -.60000
EN12.3     ^^^3.150E-03        .00315
EN12.3     ^^^3.829E+03    3829.0

Rules for Output Processing

On output, the EN data edit descriptor transfers the real value of the corresponding I/O list item, right-justified and rounded to d decimal positions, to an external field that is w characters long. The real value is output in engineering notation, where the decimal exponent is divisible by 3 and the absolute value of the significand is greater than or equal to 1 and less than 1000 (unless the output value is zero).

The w should be greater than or equal to d+9 to allow for the following:

  • A sign (optional if the value is positive and descriptor SP is not in effect)
  • One to three digits to the left of the decimal point
  • The decimal point
  • The d digits to the right of the decimal point
  • The exponent

The exponent takes one of the following forms:

Edit Descriptor | Absolute Value of Exponent | Positive Form of Exponent | Negative Form of Exponent
ENw.d | |exp| <= 99 | E+nn | E-nn
 | 99 < |exp| <= 999 | +nnn | -nnn
ENw.dEe | |exp| <= 10e - 1 | E+n1n2...ne | E-n1n2...ne

If the exponent value is too large to be converted into one of these forms, an error occurs.

The exponent field width (e) is optional; if omitted, the default value is 2. If e is specified, the w should be greater than or equal to d+e+5.

The following shows output using the EN edit descriptor (the symbol ^ represents a nonprinting blank character):

Format     Value         Output
EN11.2     475867.222    ^475.87E+03
EN11.5     475867.222    ***********
EN12.3          0.00069  ^690.000E-06
EN10.3         -0.5555   **********
EN11.2          0.0      ^000.00E-03

For More Information:

  • See Forms for data edit descriptors.
  • See General rules for numeric editing.


ES Editing

The ES data edit descriptor transfers values by using scientific notation. It takes the following form:

ESw.d[Ee]

The value of d (the number of places after the decimal point) plus e (the number of digits in the exponent) must not exceed the value of w (the field width).

The specified I/O list item must be of type real, or it must be the real or imaginary part of a complex type.

Rules for Input Processing

On input, the ES data edit descriptor transfers w characters from an external field and assigns their real value to the corresponding I/O list item. The ES descriptor interprets and assigns input data in the same way as the F data edit descriptor.

The following shows input using the ES edit descriptor (the symbol ^ represents a nonprinting blank character):

Format     Input           Value
ES11.3      ^^5.321E+00       5.32100
ES11.3       -6.000E-03       -.60000
ES12.3     ^^^3.150E-03        .00315
ES12.3     ^^^3.829E+03    3829.0

Rules for Output Processing

On output, the ES data edit descriptor transfers the real value of the corresponding I/O list item, right-justified and rounded to d decimal positions, to an external field that is w characters long. The real value is output in scientific notation, where the absolute value of the significand is greater than or equal to 1 and less than 10 (unless the output value is zero).

The w should be greater than or equal to d+7 to allow for the following:

  • A sign (optional if the value is positive and descriptor SP is not in effect)
  • One digit to the left of the decimal point
  • The decimal point
  • The d digits to the right of the decimal point
  • The exponent

The exponent takes one of the following forms:

Edit Descriptor | Absolute Value of Exponent | Positive Form of Exponent | Negative Form of Exponent
ESw.d | |exp| <= 99 | E+nn | E-nn
 | 99 < |exp| <= 999 | +nnn | -nnn
ESw.dEe | |exp| <= 10e - 1 | E+n1n2...ne | E-n1n2...ne

If the exponent value is too large to be converted into one of these forms, an error occurs.

The exponent field width (e) is optional; if omitted, the default value is 2. If e is specified, the w should be greater than or equal to d+e+5.

The following shows output using the ES edit descriptor (the symbol ^ represents a nonprinting blank character):

Format     Value         Output
ES11.2     473214.356    ^^^4.73E+05
ES11.5     473214.356    4.73214E+05
ES12.3          0.00069  ^^^6.900E-04
ES10.3         -0.5555   -5.555E-01
ES11.2          0.0      ^0.000E+00

For More Information:

  • See Forms for data edit descriptors.
  • See General rules for numeric editing.


G Editing

The G data edit descriptor generally transfers values of real type, but it can be used to transfer values of any intrinsic type. It takes the following form:

Gw.d[Ee]

The value of d (the number of places after the decimal point) plus e (the number of digits in the exponent) must not exceed the value of w (the field width).

The specified I/O list item can be of any intrinsic type.

When used to specify I/O for integer, logical, or character data, the edit descriptor follows the same rules as I w, L w, and A w, respectively, and d and e have no effect.

Rules for Real Input Processing

On input, the G data edit descriptor transfers w characters from an external field and assigns their real value to the corresponding I/O list item. The G descriptor interprets and assigns input data in the same way as the F data edit descriptor.

Rules for Real Output Processing

On output, the G data edit descriptor transfers the real value of the corresponding I/O list item, right-justified and rounded to d decimal positions, to an external field that is w characters long.

The form in which the value is written is a function of the magnitude of the value, as described in the following table:

Table: Effect of Data Magnitude on G Format Conversions
Data Magnitude | Effective Conversion
0 < m < 0.1 - 0.5 x 10-d-1 | Ew.d[Ee]
m = 0 | F(w - n).(d -1), n('b')
0.1 - 0.5 x 10-d-1 <= m < 1 - 0.5 x 10-d | F(w - n).d, n('b')
1 - 0.5 x 10-d <= m < 10 - 0.5 x 10-d+1 | F(w - n).(d -1), n('b')
10 - 0.5 x 10-d+1 <= m < 100 - 0.5 x 10-d+2 | F(w - n).(d -2), n('b')
.
.
.
.
.
.
10d-2 - 0.5 x 10-2 <= m < 10d-1 - 0.5 x 10-1 | F(w - n).1, n('b')
10d-1 - 0.5 x 10-1 <= m < 10d - 0.5 | (w - n).0, n('b')
m >= 10d - 0.5 | Ew.d[Ee]

The 'b' is a blank following the numeric data representation. For Gw.d, n('b') is 4 blanks. For Gw.dEe, n('b' ) is e+2 blanks.

The w should be greater than or equal to d+7 to allow for the following:

  • A sign (optional if the value is positive and descriptor SP is not in effect)
  • One digit to the left of the decimal point
  • The decimal point
  • The d digits to the right of the decimal point
  • The 4-digit or e+2-digit exponent

If e is specified, the w should be greater than or equal to d+e+5.

The following shows output using the G edit descriptor and compares it to output using equivalent F editing (the symbol ^ represents a nonprinting blank character):

  Value               Format    Output with G     Format    Output with F
         0.01234567   G13.6     ^0.123457E-01     F13.6     ^^^^^0.012346
        -0.12345678   G13.6     -0.123457^^^^     F13.6     ^^^^-0.123457
         1.23456789   G13.6     ^^1.23457^^^^     F13.6     ^^^^^1.234568
        12.34567890   G13.6     ^^12.3457^^^^     F13.6     ^^^^12.345679
       123.45678901   G13.6     ^^123.457^^^^     F13.6     ^^^123.456789
     -1234.56789012   G13.6     ^-1234.57^^^^     F13.6     ^-1234.567890
     12345.67890123   G13.6     ^^12345.7^^^^     F13.6     ^12345.678901
    123456.78901234   G13.6     ^^123457.^^^^     F13.6     123456.789012
  -1234567.89012345   G13.6     -0.123457E+07     F13.6     *************

For More Information:

  • See Forms for data edit descriptors.
  • See General rules for numeric editing.
  • See the I data edit descriptor.
  • See the L data edit descriptor.
  • See the A data edit descriptor.
  • On the scale factor, see Scale Factor Editing (P).


Complex Editing

A complex value is an ordered pair of real values. Complex editing is specified by a pair of real edit descriptors, using any combination of the forms: Fw.d, Ew.d[Ee], Dw.d, ENw.d[Ee], ESw.d[Ee], or Gw.d[Ee].

Rules for Input Processing

On input, the two successive fields are read and assigned to the corresponding complex I/O list item as its real and imaginary part, respectively.

The following shows input using complex editing:

Format         Input                Value
F8.5,F8.5      1234567812345.67     123.45678, 12345.67
E9.1,F9.3      734.432E8123456789   734.432E8, 123456.789

Rules for Output Processing

On output, the two parts of the complex value are transferred under the control of repeated or successive real edit descriptors. The two parts are transferred consecutively without punctuation or blanks, unless control or character string edit descriptors are specified between the pair of real edit descriptors.

The following shows output using complex editing (the symbol ^ represents a nonprinting blank character):

Format              Value                   Output
2F8.5               2.3547188, 3.456732     ^2.35472 ^3.45673
E9.2,'^,^',E5.3     47587.222, 56.123       ^0.48E+06^,^*****

For More Information:

  • See Forms for data edit descriptors.
  • See General rules for numeric editing.
  • On complex constants, see General Rules for Complex Constants.


Logical Editing (L)

The L data edit descriptor transfers logical values. It takes the following form:

Lw

The specified I/O list item must be of type logical or integer.

The G edit descriptor can be used to edit logical data; it follows the same rules as L w.

Rules for Input Processing

On input, the L data edit descriptor transfers w characters from an external field and assigns their logical value to the corresponding I/O list item. The value assigned depends on the external field data, as follows:

  • .TRUE. is assigned if the first nonblank character is .T, T, .t, or t. The logical constant .TRUE. is an acceptable input form.

  • .FALSE. is assigned if the first nonblank character is .F, F. .f, or f, or the entire field is filled with blanks. The logical constant .FALSE. is an acceptable input form.

If an other value appears in the external field, an error occurs.

Rules for Output Processing

On output, the L data edit descriptor transfers the following to an external field that is w characters long: w - 1 blanks, followed by a T or F (if the value is .TRUE. or .FALSE., respectively).

The following shows output using the L edit descriptor (the symbol ^ represents a nonprinting blank character):

Format     Value         Output
L5         .TRUE.        ^^^^T
L1         .FALSE.       F

For More Information:

See Forms for data edit descriptors.


Character Editing (A)

The A data edit descriptor transfers character or Hollerith values. It takes the following form:

A[w]

If the corresponding I/O list item is of type character, character data is transferred. If the list item is of any other type, Hollerith data is transferred.

The G edit descriptor can be used to edit character data; it follows the same rules as A w.

Rules for Input Processing

On input, the A data edit descriptor transfers w characters from an external field and assigns them to the corresponding I/O list item.

The maximum number of characters that can be stored depends on the size of the I/O list item, as follows:

  • For character data, the maximum size is the length of the corresponding I/O list item.

  • For noncharacter data, the maximum size depends on the data type, as shown in the following table:

    Size Limits for Noncharacter Data Using A Editing

    I/O List Element | Maximum Number of Characters
    BYTE | 1
    LOGICAL(1) or LOGICAL*1 | 1
    LOGICAL(2) or LOGICAL*2 | 2
    LOGICAL(4) or LOGICAL*4 | 4
    LOGICAL(8) or LOGICAL*8 | 8
    INTEGER(1) or INTEGER*1 | 1
    INTEGER(2) or INTEGER*2 | 2
    INTEGER(4) or INTEGER*4 | 4
    INTEGER(8) or INTEGER*8 | 8
    REAL(4) or REAL*4 | 4
    DOUBLE PRECISION | 8
    REAL(8) or REAL*8 | 8
    REAL(16) or REAL*16 | 161
    COMPLEX(4) or COMPLEX*8 | 82
    DOUBLE COMPLEX | 162
    COMPLEX(8) or COMPLEX*16 | 162
    COMPLEX(16) or COMPLEX*32 | 321,2
    1 VMS, U*X
    2 Complex values are treated as pairs of real numbers, so complex editing requires a pair of real edit descriptors. (See Complex Editing.)

If w is equal to or greater than the length (len) of the input item, the rightmost characters are assigned to that item. The leftmost excess characters are ignored.

If w is less than len, or less than the number of characters that can be stored, w characters are assigned to the list item, left-justified, and followed by trailing blanks.

The following shows input using the A edit descriptor (the symbol ^ represents a nonprinting blank character):

Format     Input      Value        Data Type
A6         PAGE^#     #            CHARACTER(LEN=1)
A6         PAGE^#     E^#          CHARACTER(LEN=3)
A6         PAGE^#     PAGE^#       CHARACTER(LEN=6)
A6         PAGE^#     PAGE^#^^     CHARACTER(LEN=8)
A6         PAGE^#     #            LOGICAL(1)
A6         PAGE^#     ^#           INTEGER(2)
A6         PAGE^#     GE^#         REAL(4)
A6         PAGE^#     PAGE^#^^     REAL(8)

Rules for Output Processing

On output, the A data edit descriptor transfers the contents of the corresponding I/O list item to an external field that is w characters long.

If w is greater than the size of the list item, the data is transferred to the output field, right-justified, with leading blanks. If w is less than or equal to the size of the list item, the leftmost w characters are transferred.

The following shows output using the A edit descriptor (the symbol ^ represents a nonprinting blank character):

Format     Value         Output
A5         OHMS          ^OHMS
A5         VOLTS         VOLTS
A5         AMPERES       AMPER

For More Information:

See Forms for data edit descriptors.


Default Widths for Data Edit Descriptors

If w (the field width) is omitted for the data edit descriptors, the system applies default values. For the real data edit descriptors, the system also applies default values for d (the number of characters to the right of the decimal point), and e (the number of characters in the exponent).

These defaults are based on the data type of the I/O list item, and are listed in the following table:

Default Widths for Data Edit Descriptors

Edit Descriptor | Data Type of I/O List Item | w
I, B, O, Z, G | BYTE | 7
INTEGER(1), LOGICAL(1) | 7
INTEGER(2), LOGICAL(2) | 7
INTEGER(4), LOGICAL(4) | 12
INTEGER(8), LOGICAL(8) | 23
O, Z | REAL(4) | 12
REAL(8) | 23
REAL(16)1 | 44
CHARACTER*len | MAX(7, 3*len)
L, G LOGICAL(1), LOGICAL(2)
LOGICAL(4), LOGICAL(8) 		2
F, E, EN, ES, G, D | REAL(4), COMPLEX(4) | 15 d: 7 e: 2
REAL(8), COMPLEX(8) | 25 d: 16 e: 2
REAL(16)1, COMPLEX(16)1 | 42 d: 33 e: 3
A 2, G | LOGICAL(1) | 1
LOGICAL(2), INTEGER(2) | 2
LOGICAL(4), INTEGER(4) | 4
LOGICAL(8), INTEGER(8) | 8
REAL(4), COMPLEX(4) | 4
REAL(8), COMPLEX(8) | 8
REAL(16)1, COMPLEX(16)1 | 16
CHARACTER*len | len
1 VMS, U*X
2 The default is the actual length of the corresponding I/O list item.


Terminating Short Fields of Input Data

On input, an edit descriptor such as Fw.d specifies that w characters (the field width) are to be read from the external field.

If the field contains fewer than w characters, the input statement will read characters from the next data field in the record. You can prevent this by padding the short field with blanks or zeros, or by using commas to separate the input data.

Padding Short Fields

You can use the OPEN statement specifier PAD='YES' to indicate blank padding for short fields of input data. However, blanks can be interpreted as blanks or zeros, depending on which default behavior is in effect at the time. Consider the following:

  READ (2, '(I5)') J

If 3 is input for J, the value of J will be 30000 or 3 depending on which default behavior is in effect (BLANK='NULL' or BLANK='ZERO'). This can give unexpected results.

To ensure that the desired behavior is in effect, explicitly specify the BN or BZ edit descriptor. For example, the following ensures that blanks are interpreted as blanks (and not as zeros):

  READ (2, '(BN, I5)') J

Using Commas to Separate Input Data

You can use a comma to terminate a short data field. The comma has no effect on the d part (the number of characters to the right of the decimal point) of the specification.

The comma overrides the w specified for the I, B, O, Z, F, E, D, EN, ES, G, and L edit descriptors. For example, suppose the following statements are executed:

       READ (5,100) I,J,A,B
  100  FORMAT (2I6,2F10.2)

Suppose a record containing the following values is read:

1, -2, 1.0, 35

The following assignments occur:

I = 1
J = -2
A = 1.0
B = 0.35

A comma can only terminate fields less than w characters long. If a comma follows a field of w or more characters, the comma is considered part of the next field.

A null (zero-length) field is designated by two successive commas, or by a comma after a field of w characters. Depending on the field descriptor specified, the resulting value assigned is 0, 0.0, 0.0D0, 0.0Q0, or .FALSE..

For More Information:

For details on input processing, see General Rules for Numeric Editing.


Control Edit Descriptors

A control edit descriptor either directly determines how text is displayed or affects the conversions performed by subsequent data edit descriptors.

The following topics are discussed in this section:

  • Forms for Control Edit Descriptors
  • Positional Editing
  • Sign Editing
  • Blank Editing
  • Scale Factor Editing (P)
  • Slash Editing (/)
  • Colon Editing (:)
  • Dollar Sign ($) and Backslash (\) Editing
  • Character Count Editing (Q)


Forms for Control Edit Descriptors

A control edit descriptor takes one of the following forms:

c
cn
nc

c
Is one of the following format codes: T, TL, TR, X, S, SP, SS, BN, BZ, P, :, /, \, $, and Q.

n
Is a number of character positions. It must be a positive integer literal constant; or variable format expression -- no kind parameter can be specified. It cannot be a named constant.

The range of n is 1 through 2147483647 (2**31-1) on Alpha and ia64 processors; 1 through 32767 (2**15-1) on ia32 processors. Actual useful ranges may be constrained by record sizes (RECL) and the file system.

Rules and Behavior

In general, control edit descriptors are nonrepeatable. The only exception is the slash (/) edit descriptor, which can be preceded by a repeat specification.

The control edit descriptors have the following specific forms:

Positional: | Tn, TLn, TRn, and nX
Sign: | S, SP, and SS
Blank interpretation: | BN and BZ
Scale factor: | kP
Miscellaneous: | :, /, \, $, and Q

The P edit descriptor is an exception to the general control edit descriptor syntax. It is preceded by a scale factor, rather than a character position specifier.

Control edit descriptors can be grouped in parentheses and preceded by a group repeat specification.

For More Information:

  • See Group repeat specifications.
  • On format specifications, in general, see Format Specifications.


Positional Editing

The T, TL, TR, and X edit descriptors specify the position where the next character is transferred to or from a record.

On output, these descriptors do not themselves cause characters to be transferred and do not affect the length of the record. If characters are transferred to positions at or after the position specified by one of these descriptors, positions skipped and not previously filled are filled with blanks. The result is as if the entire record was initially filled with blanks.

The TR and X edit descriptors produce the same results.

For More Information:

See Forms for Control Edit Descriptors.


T Editing

The T edit descriptor specifies a character position in an I/O record. It takes the following form:

Tn

The n is a positive integer literal constant (with no kind parameter) indicating the character position of the record, relative to the left tab limit.

On input, the T descriptor positions the external record at the character position specified by n. On output, the T descriptor indicates that data transfer begins at the nth character position of the external record.

Examples

In the following examples, the symbol ^ represents a nonprinting blank character.

Suppose a file has a record containing the value ABC^^^XYZ, and the following statements are executed:

       READ (11,10) VALUE1, VALUE2
  10   FORMAT (T7,A3,T1,A3)

The values read first are XYZ, then ABC.

Suppose the following statements are executed:

     PRINT 25
25   FORMAT (T51,'COLUMN 2',T21,'COLUMN 1')

The following line is printed at the positions indicated:

Position 20                    Position 50
   |                              |
   COLUMN 1                       COLUMN 2

Note that the first character of the record printed was reserved as a control character. (For more information, see Printing of Formatted Records.)


TL Editing

The TL edit descriptor specifies a character position to the left of the current position in an I/O record. It takes the following form:

TLn

The n is a positive integer literal constant (with no kind parameter) indicating the nth character position to the left of the current character.

If n is greater than or equal to the current position, the next character accessed is the first character of the record.


TR Editing

The TR edit descriptor specifies a character position to the right of the current position in an I/O record. It takes the following form:

TRn

The n is a positive integer literal constant (with no kind parameter) indicating the nth character position to the right of the current character.


X Editing

The X edit descriptor specifies a character position to the right of the current position in an I/O record. It takes the following form:

nX

The n is a positive integer literal constant (with no kind parameter) indicating the nth character position to the right of the current character.

On output, the X edit descriptor does not output any characters when it appears at the end of a format specification; for example:

     WRITE (6,99) K
99   FORMAT ('^K=',I6,5X)

Note that the symbol ^ represents a nonprinting blank character. This example writes a record of only 9 characters. To cause n trailing blanks to be output at the end of a record, specify a format of n('^').


Sign Editing

The S, SP, and SS edit descriptors control the output of the optional plus (+) sign within numeric output fields. These descriptors have no effect during execution of input statements.

Within a format specification, a sign editing descriptor affects all subsequent I, F, E, EN, ES, D, and G descriptors until another sign editing descriptor occurs.

Examples

       INTEGER i
       REAL r

 !     The following statements write:
 !     251 +251 251 +251 251
       i = 251
       WRITE (*, 100) i, i, i, i, i
 100   FORMAT (I5, SP, I5, SS, I5, SP, I5, S, I5)

 !     The following statements write:
 !     0.673E+4 +.673E+40.673E+4 +.673E+40.673E+4
       r = 67.3E2
       WRITE (*, 200) r, r, r, r, r
 200   FORMAT (E8.3E1, 1X, SP, E8.3E1, SS, E8.3E1, 1X, SP, &
      &            E8.3E1, S, E8.3E1)

For More Information:

See Forms for Control Edit Descriptors.


SP Editing

The SP edit descriptor causes the processor to produce a plus sign in any subsequent position where it would be otherwise optional. It takes the following form:

SP


SS Editing

The SS edit descriptor causes the processor to suppress a plus sign in any subsequent position where it would be otherwise optional. It takes the following form:

SS


S Editing

The S edit descriptor restores the plus sign as optional for all subsequent positive numeric fields. It takes the following form:

S

The S edit descriptor restores to the processor the discretion of producing plus characters on an optional basis.


Blank Editing

The BN and BZ descriptors control the interpretation of embedded and trailing blanks within numeric input fields. These descriptors have no effect during execution of output statements.

Within a format specification, a blank editing descriptor affects all subsequent I, B, O, Z, F, E, EN, ES, D, and G descriptors until another blank editing descriptor occurs.

The blank editing descriptors override the effect of the BLANK specifier during execution of a particular input data transfer statement. (For more information, see the BLANK specifier in OPEN statements.)

For More Information:

See Forms for Control Edit Descriptors.


BN Editing

The BN edit descriptor causes the processor to ignore all embedded and trailing blanks in numeric input fields. It takes the following form:

BN

The input field is treated as if all blanks have been removed and the remainder of the field is right-justified. An all-blank field is treated as zero.

Examples

If an input field formatted as a six-digit integer (I6) contains '2 3 4', it is interpreted as ' 234'.

Consider the following code:

       READ (*, 100) n
 100   FORMAT (BN, I6)

If you enter any one of the following three records and terminate by pressing Enter, the READ statement interprets that record as the value 123:

    123
 123
 123   456

Because the repeatable edit descriptor associated with the I/O list item n is I6, only the first six characters of each record are read (three blanks followed by 123 for the first record, and 123 followed by three blanks for the last two records). Because blanks are ignored, all three records are interpreted as 123.

The following example shows the effect of BN editing with an input record that has fewer characters than the number of characters specified by the edit descriptors and iolist. Suppose you enter 123 and press Enter in response to the following READ statement:

 READ (*, '(I6)') n

The I/O system is looking for six characters to interpret as an integer number. You have entered only three, so the first thing the I/O system does is to pad the record 123 on the right with three blanks. With BN editing in effect, the nonblank characters (123) are right-aligned, so the record is equal to 123.


BZ Editing

The BZ edit descriptor causes the processor to interpret all embedded and trailing blanks in numeric input fields as zeros. It takes the following form:

BZ

Examples

The input field ' 23 4 ' would be interpreted as ' 23040'. If ' 23 4' were entered, the formatter would add one blank to pad the input to the six-digit integer format (I6), but this extra space would be ignored, and the input would be interpreted as ' 2304 '. The blanks following the E or D in real-number input are ignored, regardless of the form of blank interpretation in effect.

Suppose you enter 123 and press Enter in response to the following READ statement:

 READ (*, '(I6)') n

The I/O system is looking for six characters to interpret as an integer number. You have entered only three, so the first thing the I/O system does is to pad the record 123 on the right with three blanks. If BZ editing is in effect, those three blanks are interpreted as zeros, and the record is equal to 123000.


Scale-Factor Editing (P)

The P edit descriptor specifies a scale factor, which moves the location of the decimal point in real values and the two real parts of complex values. It takes the following form:

kP

The k is a signed (sign is optional if positive), integer literal constant specifying the number of positions, to the left or right, that the decimal point is to move (the scale factor). The range of k is -128 to 127.

At the beginning of a formatted I/O statement, the value of the scale factor is zero. If a scale editing descriptor is specified, the scale factor is set to the new value, which affects all subsequent real edit descriptors until another scale editing descriptor occurs.

To reinstate a scale factor of zero, you must explicitly specify 0P.

Format reversion does not affect the scale factor. (For more information on format reversion, see Interaction Between Format Specifications and I/O Lists.)

Rules for Input Processing

On input, a positive scale factor moves the decimal point to the left, and a negative scale factor moves the decimal point to the right. (On output, the effect is the reverse.)

On input, when an input field using an F, E, D, EN, ES, or G real edit descriptor contains an explicit exponent, the scale factor has no effect. Otherwise, the internal value of the corresponding I/O list item is equal to the external field data multiplied by 10-k. For example, a 2P scale factor multiplies an input value by .01, moving the decimal point two places to the left. A -2P scale factor multiplies an input value by 100, moving the decimal point two places to the right.

The following shows input using the P edit descriptor (the symbol ^ represents a nonprinting blank character):

Format    Input         Value
3PE10.5   ^^^37.614^         .037614
3PE10.5   ^^37.614E2     3761.4
-3PE10.5  ^^^^37.614    37614.0

The scale factor must precede the first real edit descriptor associated with it, but it need not immediately precede the descriptor. For example, the following all have the same effect:

  (3P, I6, F6.3, E8.1)
  (I6, 3P, F6.3, E8.1)
  (I6, 3PF6.3, E8.1)

Note that if the scale factor immediately precedes the associated real edit descriptor, the comma separator is optional.

Rules for Output Processing

On output, a positive scale factor moves the decimal point to the right, and a negative scale factor moves the decimal point to the left. (On input, the effect is the reverse.)

On output, the effect of the scale factor depends on which kind of real editing is associated with it, as follows:

  • For F editing, the external value equals the internal value of the I/O list item multiplied by 10k. This changes the magnitude of the data.

  • For E and D editing, the external decimal field of the I/O list item is multiplied by 10k, and k is subtracted from the exponent. This changes the form of the data.

    A positive scale factor decreases the exponent; a negative scale factor increases the exponent.

    For a positive scale factor, k must be less than d + 2 or an output conversion error occurs.

  • For G editing, the scale factor has no effect if the magnitude of the data to be output is within the effective range of the descriptor (the G descriptor supplies its own scaling).

    If the magnitude of the data field is outside G descriptor range, E editing is used, and the scale factor has the same effect as E output editing.

  • For EN and ES editing, the scale factor has no effect.

The following shows output using the P edit descriptor (the symbol ^ represents a nonprinting blank character):

Format     Value         Output
1PE12.3    -270.139      ^^-2.701E+02
1P,E12.2   -270.139      ^^^-2.70E+02
-1PE12.2   -270.139      ^^^-0.03E+04

Examples

The following shows a FORMAT statement containing a scale factor:

     DIMENSION A(6)
     DO 10 I=1,6
10   A(I) = 25.
     WRITE (6, 100) A
100  FORMAT(' ', F8.2, 2PF8.2, F8.2)

The preceding statements produce the following results:

    25.00  2500.00  2500.00
  2500.00  2500.00  2500.00

The following code uses scale-factor editing when reading:

       READ (*, 100) a, b, c, d
 100   FORMAT (F10.6, 1P, F10.6, F10.6, -2P, F10.6)

       WRITE (*, 200) a, b, c, d
 200   FORMAT (4F11.3)

If the following data is entered:

 12340000  12340000  12340000  12340000
    12.34     12.34     12.34     12.34
  12.34e0   12.34e0   12.34e0   12.34e0
  12.34e3   12.34e3   12.34e3   12.34e3

The program's output is:

    12.340      1.234      1.234   1234.000
    12.340      1.234      1.234   1234.000
    12.340     12.340     12.340     12.340
 12340.000  12340.000  12340.000  12340.000

The next code shows scale-factor editing when writing:

       a = 12.34

       WRITE (*, 100) a, a, a, a, a, a
 100   FORMAT (1X, F9.4, E11.4E2, 1P, F9.4, E11.4E2, &
      &        -2P, F9.4, E11.4E2)

This program's output is:

 12.3400 0.1234E+02 123.4000 1.2340E+01   0.1234 0.0012E+04

For More Information:

See Forms for Control Edit Descriptors.


Slash Editing ( / )

The slash edit descriptor terminates data transfer for the current record and starts data transfer for a new record. It takes the following form:

[r]/

The r is a repeat specification. It must be a positive default integer literal constant; no kind parameter can be specified.

The range of r is 1 through 2147483647 (2**31-1) on Alpha and ia64 processors; 1 through 32767 (2**15-1) on ia32 processors. If r is omitted, it is assumed to be 1.

Multiple slashes cause the system to skip input records or to output blank records, as follows:

  • When n consecutive slashes appear between two edit descriptors, n - 1 records are skipped on input, or n - 1 blank records are output. The first slash terminates the current record. The second slash terminates the first skipped or blank record, and so on.

  • When n consecutive slashes appear at the beginning or end of a format specification, n records are skipped or n blank records are output, because the opening and closing parentheses of the format specification are themselves a record initiator and terminator, respectively. For example, suppose the following statements are specified:
         WRITE (6,99)
99   FORMAT ('1',T51,'HEADING LINE'//T51,'SUBHEADING LINE'//)
    The following lines are written:
                      Column 50, top of page
                  |
                  HEADING LINE
(blank line)
                  SUBHEADING LINE
(blank line)
(blank line)

    Note that the first character of the record printed was reserved as a control character (see Printing of Formatted Records).

Examples

 !     The following statements write spreadsheet column and row labels:
       WRITE (*, 100)
 100   FORMAT ('   A     B     C     D     E'                             &
      &        /,' 1',/,' 2',/,' 3',/,' 4',/,' 5')

This example generates the following output:

   A     B     C     D     E
 1
 2
 3
 4
 5

For More Information:

See Forms for Control Edit Descriptors.


Colon Editing (:)

The colon edit descriptor terminates format control if no more items are in the I/O list.

Examples

Suppose the following statements are specified:

     PRINT 1,3
     PRINT 2,13
1    FORMAT (' I=',I2,' J=',I2)
2    FORMAT (' K=',I2,:,' L=',I2)

The following lines are written (the symbol ^ represents a nonprinting blank character):

I=^3^J=
K=13

 !     The following example writes a= 3.20 b= .99
       REAL a, b, c, d
       DATA a /3.2/, b /.9871515/
       WRITE (*, 100) a, b
 100   FORMAT (' a=', F5.2, :, ' b=', F5.2, :, &
      &        ' c=', F5.2, :, ' d=', F5.2)
       END

For More Information:

See Forms for Control Edit Descriptors.


Dollar-Sign ($) and Backslash ( \ ) Editing

The dollar sign and backslash edit descriptors modify the output of carriage control specified by the first character of the record. They only affect carriage control for formatted files, and have no effect on input.

If the first character of the record is a blank or a plus sign (+), the dollar sign and backslash descriptors suppress carriage return (after printing the record).

For terminal device I/O, when this trailing carriage return is suppressed, a response follows output on the same line. For example, suppose the following statements are specified:

     TYPE 100
100  FORMAT (' ENTER RADIUS VALUE ',$)
     ACCEPT 200, RADIUS
200  FORMAT (F6.2)

The following prompt is displayed:

  ENTER RADIUS VALUE

Any response (for example, "12.") is then displayed on the same line:

  ENTER RADIUS VALUE    12.

If the first character of the record is 0, 1, or ASCII NUL, the dollar sign and backslash descriptors have no effect.

Consider the following:

     CHARACTER(20) MYNAME
     WRITE (*,9000)
9000 FORMAT ('0Please type your name:',\)
     READ  (*,9001) MYNAME
9001 FORMAT (A20)
     WRITE (*,9002) ' ',MYNAME
9002 FORMAT (1X,A20)

This example advances two lines, prompts for input, awaits input on the same line as the prompt, and prints the input.

For More Information:

See Forms for Control Edit Descriptors.


Character Count Editing (Q)

The character count edit descriptor returns the remaining number of characters in the current input record.

The corresponding I/O list item must be of type integer or logical. For example, suppose the following statements are specified:

     READ (4,1000) XRAY, KK, NCHRS, (ICHR(I), I=1,NCHRS)
1000 FORMAT (E15.7,I4,Q,(80A1))

Two fields are read into variables XRAY and KK. The number of characters remaining in the record is stored in NCHRS, and exactly that many characters are read into the array ICHR. (This instruction can fail if the record is longer than 80 characters.)

If you place the character count descriptor first in a format specification, you can determine the length of an input record.

On output, the character count edit descriptor causes the corresponding I/O list item to be skipped.

Examples

Consider the following:

       CHARACTER ICHAR(80)
       READ (4, 1000) XRAY, K, NCHAR, (ICHAR(I), I= 1, NCHAR)
 1000  FORMAT (E15.7, I4, Q, 80A1)

The preceding input statement reads the variables XRAY and K. The number of characters remaining in the record is NCHAR, specified by the Q edit descriptor. The array ICHAR is then filled by reading exactly the number of characters left in the record. (Note that this instruction will fail if NCHAR is greater than 80, the length of the array ICHAR.) By placing Q in the format specification, you can determine the actual length of an input record.

Note that the length returned by Q is the number of characters left in the record, not the number of reals or integers or other data types. The length returned by Q can be used immediately after it is read and can be used later in the same format statement or in a variable format expression. (See Variable Format Expressions.)

Assume the file Q.DAT contains:

1234.567Hello, Q Edit

The following program reads in the number REAL1, determines the characters left in the record, and reads those into STR:

       CHARACTER STR(80)
       INTEGER LENGTH
       REAL REAL1
       OPEN (UNIT = 10, FILE = 'Q.DAT')
       READ (10, 100) REAL1, LENGTH, (STR(I), I=1, LENGTH)
 100   FORMAT (F8.3, Q, 80A1)
       WRITE(*,'(F8.3,2X,I2,2X,<LENGTH>A1)') REAL1, LENGTH, (STR(I), &
      & I= 1, LENGTH)
       END

The output on the screen is:

1234.567  13  Hello, Q Edit

A READ statement that contains only a Q edit descriptor advances the file to the next record. For example, consider that Q.DAT contains the following data:

abcdefg
abcd

Consider it is then READ with the following statements:

       OPEN (10, FILE = "Q.DAT")
       READ(10, 100) LENGTH
 100   FORMAT(Q)
       WRITE(*,'(I2)') LENGTH
       READ(10, 100) LENGTH
       WRITE(*,'(I2)') LENGTH
       END

The output to the screen would be:

7
4

For More Information:

See Forms for Control Edit Descriptors.


Character String Edit Descriptors

Character string edit descriptors control the output of character strings. The character string edit descriptors are the character constant and H edit descriptor.

Although no string edit descriptor can be preceded by a repeat specification, a parenthesized group of string edit descriptors can be preceded by a repeat specification (see Nested and Group Repeat Specifications).


Character Constant Editing

The character constant edit descriptor causes a character string to be output to an external record. It takes one of the following forms:

'string'
"string"

The string is a character literal constant; no kind parameter can be specified. Its length is the number of characters between the delimiters; two consecutive delimiters are counted as one character.

To include an apostrophe in a character constant that is enclosed by apostrophes, place two consecutive apostrophes ('') in the format specification; for example:

50   FORMAT ('TODAY''S^DATE^IS:^',I2,'/',I2,'/',I2)

Note that the symbol ^ represents a nonprinting blank character.

Similarly, to include a quotation mark in a character constant that is enclosed by quotation marks, place two consecutive quotation marks ("") in the format specification.

On input, the character constant edit descriptor transfers length of string characters to the edit descriptor.

Examples

Consider the following '(3I5)' format in the WRITE statement:

 WRITE (10, '(3I5)') I1, I2, I3

This is equivalent to:

       WRITE (10, 100) I1, I2, I3
 100   FORMAT( 3I5)

The following shows another example:

 !     These WRITE statements both output ABC'DEF
 !     (The leading blank is a carriage-control character).
       WRITE (*, 970)
 970   FORMAT (' ABC''DEF')
       WRITE (*, '('' ABC''''DEF'')')
 !     The following WRITE also outputs ABC'DEF. No carriage-
 !     control character is necessary for list-directed I/O.
       WRITE (*,*) 'ABC''DEF'

Alternatively, if the delimiter is quotation marks, the apostrophe in the character constant ABC'DEF requires no special treatment:

 WRITE (*,*) "ABC'DEF"

For More Information:

  • See Character constants.
  • On format specifications, in general, see Format Specifications.


H Editing

The H edit descriptor transfers data between the external record and the H edit descriptor itself. The H edit descriptor is a deleted feature in Fortran 95; it was obsolescent in Fortran 90. Compaq Fortran fully supports features deleted in Fortran 95.

An H edit descriptor has the form of a Hollerith constant, as follows:

n H string

n
Is an unsigned, positive default integer literal constant (with no kind parameter) indicating the number of characters in string (including blanks and tabs).

The range of n is 1 through 2147483647 (2**31-1) on Alpha and ia64 processors; 1 through 32767 (2**15-1) on ia32 processors. Actual useful ranges may be constrained by record sizes (RECL) and the file system.

string
Is a string of printable ASCII characters.

On input, the H edit descriptor transfers n characters from the external field to the edit descriptor. The first character appears immediately after the letter H. Any characters in the edit descriptor before input are replaced by the input characters.

On output, the H edit descriptor causes n characters following the letter H to be output to an external record.

Examples

 !     These WRITE statements both print "Don't misspell 'Hollerith'"
 !     (The leading blanks are carriage-control characters).
 !     Hollerith formatting does not require you to embed additional
 !     single quotation marks as shown in the second example.
 !
       WRITE (*, 960)
 960   FORMAT (27H Don't misspell 'Hollerith')
       WRITE (*, 961)
 961   FORMAT (' Don''t misspell ''Hollerith''')

For More Information:

  • See Obsolescent and Deleted Language Features.
  • On format specifications, in general, see Format Specifications.


Nested and Group Repeat Specifications

Format specifications can include nested format specifications enclosed in parentheses; for example:

15   FORMAT (E7.2,I8,I2,(A5,I6))

35   FORMAT (A6,(L8(3I2)),A)

A group repeat specification can precede a nested group of edit descriptors. For example, the following statements are equivalent, and the second statement shows a group repeat specification:

50   FORMAT (I8,I8,F8.3,E15.7,F8.3,E15.7,F8.3,E15.7,I5,I5)

50   FORMAT (2I8,3(F8.3,E15.7),2I5)

If a nested group does not show a repeat count, a default count of 1 is assumed.

Normally, the string edit descriptors and control edit descriptors cannot be repeated (except for slash), but any of these descriptors can be enclosed in parentheses and preceded by a group repeat specification. For example, the following statements are valid:

76   FORMAT ('MONTHLY',3('TOTAL'))

100  FORMAT (I8,4(T7),A4)

For More Information:

  • On repeat specifications for data edit descriptors, see Forms for Data Edit Descriptors.
  • On group repeat specifications and format reversion, see Interaction Between Format Specifications and I/O Lists.


Variable Format Expressions

A variable format expression is a numeric expression enclosed in angle brackets (< >) that can be used in a FORMAT statement or in character format specifications.

The numeric expression can be any valid Fortran expression, including function calls and references to dummy arguments.

If the expression is not of type integer, it is converted to integer type before being used.

If the value of a variable format expression does not obey the restrictions on magnitude applying to its use in the format, an error occurs.

Variable format expressions cannot be used with the H edit descriptor, and they are not allowed in character format specifications.

Variable format expressions are evaluated each time they are encountered in the scan of the format. If the value of the variable used in the expression changes during the execution of the I/O statement, the new value is used the next time the format item containing the expression is processed.

Examples

Consider the following statement:

  FORMAT (I<J+1>)

When the format is scanned, the preceding statement performs an I (integer) data transfer with a field width of J+1. The expression is reevaluated each time it is encountered in the normal format scan.

Consider the following statements:

     DIMENSION A(5)
     DATA A/1.,2.,3.,4.,5./

     DO 10 I=1,10
     WRITE (6,100) I
100  FORMAT (I<MAX(I,5)>)
10   CONTINUE

     DO 20 I=1,5
     WRITE (6,101) (A(I), J=1,I)
101  FORMAT (<I>F10.<I-1>)
20   CONTINUE
     END

On execution, these statements produce the following output:

   1
   2
   3
   4
   5
    6
     7
      8
       9
       10
       1.
      2.0        2.0
     3.00       3.00     3.00
    4.000      4.000    4.000     4.000
   5.0000    5.0000    5.0000    5.0000    5.0000

The following shows another example:

       WRITE(6,20) INT1
 20    FORMAT(I<MAX(20,5)>)

       WRITE(6,FMT=30) REAL2(10), REAL3
 30    FORMAT(<J+K>X, <2*M>F8.3)

The value of the expression is reevaluated each time an input/output item is processed during the execution of the READ, WRITE, or PRINT statement. For example:

       INTEGER width, value
       width=2
       READ (*,10) width, value
 10    FORMAT(I1, I <width>)
       PRINT *, value
       END

When given input 3123, the program will print 123 and not 12.

For More Information:

For details on the synchronization of I/O lists with formats, see Interaction Between Format Specifications and I/O Lists.


Printing of Formatted Records

On output, if a file was opened with CARRIAGECONTROL='FORTRAN' in effect or the file is being processed by the fortpr format utility, the first character of a record transmitted to a line printer or terminal is typically a character that is not printed, but used to control vertical spacing.

The following table lists the valid control characters for printing:

Control Characters for Printing

Character | Meaning | Effect
+ | Overprinting | Outputs the record (at the current position in the current line) and a carriage return.
- | One line feed | Outputs the record (at the beginning of the following line) and a carriage return.
0 | Two line feeds | Outputs the record (after skipping a line) and a carriage return.
1 | Next page | Outputs the record (at the beginning of a new page) and a carriage return.
$ | Prompting | Outputs the record (at the beginning of the following line), but no carriage return.
ASCII NUL1 | Overprinting with no advance | Outputs the record (at the current position in the current line), but no carriage return.
1 Specify as CHAR( 0 ).

Any other character is interpreted as a blank and is deleted from the print line. If you do not specify a control character for printing, the first character of the record is not printed.


Interaction Between Format Specifications and I/O Lists

Format control begins with the execution of a formatted I/O statement. Each action of format control depends on information provided jointly by the next item in the I/O list (if one exists) and the next edit descriptor in the format specification.

Both the I/O list and the format specification are interpreted from left to right, unless repeat specifications or implied-do lists appear.

If an I/O list specifies at least one list item, at least one data edit descriptor (I, B, O, Z, F, E, EN, ES, D, G, L, or A) or the Q edit descriptor must appear in the format specification; otherwise, an error occurs.

Each data edit descriptor (or Q edit descriptor) corresponds to one item in the I/O list, except that an I/O list item of type complex requires the interpretation of two F, E, EN, ES, D, or G edit descriptors. No I/O list item corresponds to a control edit descriptor (X, P, T, TL, TR, SP, SS, S, BN, BZ, $, or :), or a character string edit descriptor (H and character constants). For character string edit descriptors, data transfer occurs directly between the external record and the format specification.

When format control encounters a data edit descriptor in a format specification, it determines whether there is a corresponding I/O list item specified. If there is such an item, it is transferred under control of the edit descriptor, and then format control proceeds. If there is no corresponding I/O list item, format control terminates.

If there are no other I/O list items to be processed, format control also terminates when the following occurs:

  • A colon edit descriptor is encountered.
  • The end of the format specification is reached.

If additional I/O list items remain, part or all of the format specification is reused in format reversion.

In format reversion, the current record is terminated and a new one is initiated. Format control then reverts to one of the following (in order) and continues from that point:

  1. The group repeat specification whose opening parenthesis matches the next-to-last closing parenthesis of the format specification

  2. The initial opening parenthesis of the format specification

Format reversion has no effect on the scale factor (P), the sign control edit descriptors (S, SP, or SS), or the blank interpretation edit descriptors (BN or BZ).

Examples

The data in file FOR002.DAT is to be processed 2 records at a time. Each record starts with a number to be put into an element of a vector B, followed by 5 numbers to be put in a row in matrix A.

FOR002.DAT contains the following data:

001 0101 0102 0103 0104 0105
002 0201 0202 0203 0204 0205
003 0301 0302 0303 0304 0305
004 0401 0402 0403 0404 0405
005 0501 0502 0503 0504 0505
006 0601 0602 0603 0604 0605
007 0701 0702 0703 0704 0705
008 0801 0802 0803 0804 0805
009 0901 0902 0903 0904 0905
010 1001 1002 1003 1004 1005

The following example shows how several different format specifications interact with I/O lists to process data in file FOR002.DAT:

Interaction Between Format Specifications and I/O Lists

        INTEGER I, J, A(2,5), B(2)

        OPEN (unit=2, access='sequential', file='FOR002.DAT')

        READ (2,100) (B(I), (A(I,J), J=1,5),I=1,2)
  100   FORMAT (2 (I3, X, 5(I4,X), /) )

        WRITE (6,999) B, ((A(I,J),J=1,5),I=1,2)
  999   FORMAT (' B is ', 2(I3, X), ';  A is', /
       1       (' ', 5 (I4, X)) )

        READ (2,200) (B(I), (A(I,J), J=1,5),I=1,2)
  200   FORMAT (2 (I3, X, 5(I4,X), :/) )

        WRITE (6,999) B, ((A(I,J),J=1,5),I=1,2)

        READ (2,300) (B(I), (A(I,J), J=1,5),I=1,2)
  300   FORMAT ( (I3, X, 5(I4,X)) )

        WRITE (6,999) B, ((A(I,J),J=1,5),I=1,2)

        READ (2,400) (B(I), (A(I,J), J=1,5),I=1,2)
  400   FORMAT ( I3, X, 5(I4,X) )

        WRITE (6,999) B, ((A(I,J),J=1,5),I=1,2)

        END

This statement reads B(1); then A(1,1) through A(1,5); then B(2) and A(2,1) through A(2,5).

The first record read (starting with 001) starts the processing of the I/O list.

There are two records, each in the format I3, X, 5(I4, X). The slash (/) forces the reading of the second record after A(1,5) is processed. It also forces the reading of the third record after A(2,5) is processed; no data is taken from that record.

This statement produces the following output:

B is   1   2 ;  A is
 101  102  103  104  105
 201  202  203  204  205

This statement reads the record starting with 004. The slash (/) forces the reading of the next record after A(1,5) is processed. The colon (:) stops the reading after A(2,5) is processed, but before the slash (/) forces another read.

This statement produces the following output:

B is   4   5 ;  A is
 401  402  403  404  405
 501  502  503  504  505

This statement reads the record starting with 006. After A(1,5) is processed, format reversion causes the next record to be read and starts format processing at the left parenthesis before the I3.

This statement produces the following output:

B is   6   7 ;  A is
 601  602  603  604  605
 701  702  703  704  705

This statement reads the record starting with 008. After A(1,5) is processed, format reversion causes the next record to be read and starts format processing at the left parenthesis before the I4.

This statement produces the following output:

B is   8  90 ;  A is
 801  802  803  804  805
 9010 9020 9030 9040 100

The record 009 0901 0902 0903 0904 0905 is processed with I4 as "009 " for B(2), which is 90. X skips the next "0". Then "901 " is processed for A(2,1), which is 9010, "902 " for A(2,2), "903 " for A(2,3), and "904 " for A(2,4). The repeat specification of 5 is now exhausted and the format ends. Format reversion causes another record to be read and starts format processing at the left parenthesis before the I4, so "010 " is read for A(2,5), which is 100.

For More Information:

  • See Data edit descriptors.
  • See Control edit descriptors.
  • See the Q edit descriptor.
  • See Character string edit descriptors.
  • On the scale factor, see Scale Factor Editing (P).


File Operation I/O Statements (WNT, W9*, U*X)

The following are file connection, inquiry, and positioning I/O statements on Windows, Tru64 UNIX, and Linux Systems:

  • BACKSPACE

    Positions a sequential file at the beginning of the preceding record.

  • CLOSE

    Terminates the connection between a logical unit and a file or device.

  • DELETE

    Deletes a record from a relative file.

  • ENDFILE

    For sequential files, writes an end-of-file record to the file and positions the file after this record. For direct access files, truncates the file after the current record.

  • INQUIRE

    Requests information on the status of specified properties of a file or logical unit.

  • OPEN

    Connects a Fortran logical unit to a file or device; declares attributes for read and write operations.

  • REWIND

    Positions a sequential file at the beginning of the file.

  • UNLOCK

    Frees a record in a relative or sequential file that was locked by a previous READ statement.

The following table summarizes I/O statement specifiers:

I/O Specifiers
Specifier | Values | Description | Used with:
ACCESS=access | 'SEQUENTIAL', 'DIRECT', or 'APPEND' | Specifies the method of file access. | INQUIRE, OPEN
ACTION=permission | 'READ', 'WRITE' or 'READWRITE' (default is 'READWRITE') | Specifies file I/O mode. | INQUIRE, OPEN
ADVANCE=c-expr | 'NO' or 'YES' (default is 'YES') | Specifies formatted sequential data input as advancing, or non-advancing. | READ
ASSOCIATEVARIABLE=var | Integer variable | Specifies a variable to be updated to reflect the record number of the next sequential record in the file. | OPEN
BINARY=bin | 'NO' or 'YES' | Returns whether file format is binary. | INQUIRE
BLANK=blank_control | 'NULL' or 'ZERO' (default is 'NULL') | Specifies whether blanks are ignored in numeric fields or interpreted as zeros. | INQUIRE, OPEN
BLOCKSIZE=blocksize | Positive integer variable or expression | Specifies or returns the internal buffer size used in I/O. | INQUIRE, OPEN
BUFFERCOUNT=bc | Numeric expression | Specifies the number of buffers to be associated with the unit for multibuffered I/O. | OPEN
BUFFERED=bf | 'YES' or 'NO' (default is 'NO') | Specifies run-time library behavior following WRITE operations. | INQUIRE, OPEN
CARRIAGECONTROL= control | 'FORTRAN', 'LIST', or 'NONE' | Specifies carriage control processing. | INQUIRE, OPEN
CONVERT=form | 'LITTLE_ENDIAN', 'BIG_ENDIAN', 'CRAY', 'FDX', 'FGX', 'IBM', 'VAXD', 'VAXG', or 'NATIVE' (default is 'NATIVE') | Specifies a numeric format for unformatted data. | INQUIRE, OPEN
DEFAULTFILE=var | Character expression | Specifies a default file pathname string. | INQUIRE, OPEN
DELIM=delimiter | 'APOSTROPHE', 'QUOTE' or 'NONE' (default is 'NONE') | Specifies the delimiting character for list-directed or namelist data. | INQUIRE, OPEN
DIRECT=dir | 'NO' or 'YES' | Returns whether file is connected for direct access. | INQUIRE
DISPOSE=dis (or DISP=dis) | 'KEEP', 'SAVE', 'DELETE', 'PRINT', 'PRINT/DELETE', 'SUBMIT', or 'SUBMIT/DELETE' (default is 'DELETE' for scratch files; 'KEEP' for all other files) | Specifies the status of a file after the unit is closed. | OPEN, CLOSE
formatlist | Character variable or expression | Lists edit descriptors. Used in FORMAT statements and format specifiers (the FMT=formatspec option) to describe the format of data. | FORMAT, PRINT, READ, WRITE
END=endlabel | Integer between 1 and 99999 | When an end of file is encountered, transfers control to the statement whose label is specified. | READ
EOR=eorlabel | Integer between 1 and 99999 | When an end of record is encountered, transfers to the statement whose label is specified. | READ
ERR=errlabel | Integer between 1 and 99999 | Specifies the label of an executable statement where execution is transferred after an I/O error. | All except PRINT
EXIST=ex | .TRUE. or .FALSE. | Returns whether a file exists and can be opened. | INQUIRE
FILE=file (or NAME=name) | Character variable or expression. Length and format of the name are determined by the operating system | Specifies the name of a file | INQUIRE, OPEN
[FMT=]formatspec | Character variable or expression | Specifies an editlist to use to format data. | PRINT, READ, WRITE
FORM=form | 'FORMATTED', 'UNFORMATTED', or 'BINARY' | Specifies a file's format. | INQUIRE, OPEN
FORMATTED=fmt | 'NO' or 'YES' | Returns whether a file is connected for formatted data transfer. | INQUIRE
IOFOCUS=iof | .TRUE. or .FALSE. (default is .TRUE. unless unit '*' is specified) | Specifies whether a unit is the active window in a QuickWin application. | INQUIRE, OPEN
iolist | List of variables of any type, character expression, or NAMELIST | Specifies items to be input or output. | PRINT, READ, WRITE
IOSTAT=iostat | Integer variable | Specifies a variable whose value indicates whether an I/O error has occurred. | All except PRINT
MAXREC=var | Numeric expression | Specifies the maximum number of records that can be transferred to or from a direct access file. | OPEN
MODE=permission | 'READ', 'WRITE' or 'READWRITE' (default is 'READWRITE') | Same as ACTION. | INQUIRE, OPEN
NAMED=var | .TRUE. or .FALSE. | Returns whether a file is named. | INQUIRE
NEXTREC=nr | Integer variable | Returns where the next record can be read or written in a file. | INQUIRE
[NML=]nmlspec | Namelist name | Specifies a namelist group to be input or output. | PRINT, READ, WRITE
NUMBER=num | Integer variable | Returns the number of the unit connected to a file. | INQUIRE
OPENED=od | .TRUE. or .FALSE. | Returns whether a file is connected. | INQUIRE
ORGANIZATION=org | 'SEQUENTIAL' or 'RELATIVE' (default is 'SEQUENTIAL') | Specifies the internal organization of a file. | INQUIRE, OPEN
PAD=pad_switch | 'YES' or 'NO' (default is 'YES') | Specifies whether an input record is padded with blanks when the input list or format requires more data than the record holds, or whether the input record is required to contain the data indicated. | INQUIRE, OPEN
POSITION=file_pos | 'ASIS', 'REWIND' or 'APPEND' (default is 'ASIS') | Specifies position in a file. | INQUIRE, OPEN
READ=rd | 'NO' or 'YES' | Returns whether a file can be read. | INQUIRE
READONLY |  | Specifies that only READ statements can refer to this connection. | OPEN
READWRITE=rdwr | 'NO' or 'YES' | Returns whether a file can be both read and written to. | INQUIRE
REC=rec | Positive integer variable or expression | Specifies the first (or only) record of a file to be read from, or written to. | READ, WRITE
RECL=length (or RECORDSIZE=length) | Positive integer variable or expression | Specifies the record length in direct access files, or the maximum record length in sequential files. | INQUIRE, OPEN
RECORDTYPE=typ | 'FIXED', 'VARIABLE', 'SEGMENTED', 'STREAM', 'STREAM_LF', or 'STREAM_CR' | Specifies the type of records in a file. | INQUIRE, OPEN
SEQUENTIAL=seq | 'NO' or 'YES' | Returns whether file is connected for sequential access. | INQUIRE
SHARE=share | 'COMPAT', 'DENYNONE', 'DENYWR', 'DENYRD', or 'DENYRW' (default is 'DENYNONE') | Controls how other processes can simultaneously access a file on networked systems. | INQUIRE, OPEN
SHARED |  | Specifies that a file is connected for shared access by more than one program executing simultaneously. | OPEN
SIZE=size | Integer variable | Returns the number of characters read in a nonadvancing READ before an end-of-record condition occurred. | READ
STATUS=status | 'OLD', 'NEW', 'UNKNOWN' or 'SCRATCH' (default is 'UNKNOWN') | Specifies the status of a file on opening and/or closing. | CLOSE, OPEN
TITLE=name | Character expression | Specifies the name of a child window in a QuickWin application. | OPEN
UNFORMATTED=unf | 'NO' or 'YES' | Returns whether a file is connected for unformatted data transfer. | INQUIRE
[UNIT=]unitspec | Integer variable or expression | Specifies the unit to which a file is connected. | All except PRINT
USEROPEN=fname | Name of a user-written function | Specifies an external function that controls the opening of a file. | OPEN
WRITE=rd | 'NO' or 'YES' | Returns whether a file can be written to. | INQUIRE

For More Information:

  • See Data transfer I/O statements.
  • On control specifiers, see I/O Control List.
  • On record position, advancement, and transfer, see your programmer's guide.


BACKSPACE Statement

The BACKSPACE statement positions a file at the beginning of the preceding record, making it available for subsequent I/O processing. For more information, see BACKSPACE in the A to Z Reference.


CLOSE Statement

The CLOSE statement disconnects a file from a unit. For more information, see CLOSE in the A to Z Reference.


DELETE Statement

The DELETE statement deletes a record from a relative file. For more information, see DELETE in the A to Z Reference.


ENDFILE Statement

The ENDFILE statement writes an end-of-file record to a sequential file and positions the file after this record (the terminal point), or it causes a direct access file to be truncated after the current record.

For more information, see ENDFILE in the A to Z Reference.


INQUIRE Statement

The INQUIRE statement returns information on the status of specified properties of a file or logical unit. For more information, see INQUIRE in the A to Z Reference.

The following are inquiry specifiers:

  • ACCESS
  • ACTION
  • BINARY
  • BLANK
  • BLOCKSIZE
  • BUFFERED
  • CARRIAGECONTROL
  • CONVERT
  • DELIM
  • DIRECT
  • EXIST
  • FORM
  • FORMATTED
  • IOFOCUS
  • MODE
  • NAME
  • NAMED
  • NEXTREC
  • NUMBER
  • OPENED
  • ORGANIZATION
  • PAD
  • POSITION
  • READ
  • READWRITE
  • RECL
  • RECORDTYPE
  • SEQUENTIAL
  • SHARE
  • UNFORMATTED
  • WRITE

For More Information:

  • See the UNIT control specifier.
  • See the ERR control specifier.
  • See the IOSTAT control specifier.
  • See the RECL specifier in OPEN statements.
  • See the FILE specifier in OPEN statements.
  • See the DEFAULTFILE specifier in OPEN statements.


ACCESS Specifier

The ACCESS specifier asks how a file is connected. It takes the following form:

ACCESS = acc

acc
Is a scalar default character variable that is assigned one of the following values:
'SEQUENTIAL' | If the file is connected for sequential access
'DIRECT' | If the file is connected for direct access
'UNDEFINED' | If the file is not connected


ACTION Specifier

The ACTION specifier asks which I/O operations are allowed for a file. It takes the following form:

ACTION = act

act
Is a scalar default character variable that is assigned one of the following values:
'READ' | If the file is connected for input only
'WRITE' | If the file is connected for output only
'READWRITE' | If the file is connected for both input and output
'UNDEFINED' | If the file is not connected


BINARY Specifier (WNT, W9*)

The BINARY specifier asks whether a file is connected to a binary file. It takes the following form:

BINARY = bin

bin
Is a scalar default character variable that is assigned one of the following values:
'YES' | If the file is connected to a binary file
'NO' | If the file is connected to a nonbinary file
'UNKNOWN' | If the file is not connected


BLANK Specifier

The BLANK specifier asks what type of blank control is in effect for a file. It takes the following form:

BLANK = blnk

blnk
Is a scalar default character variable that is assigned one of the following values:
'NULL' | If null blank control is in effect for the file
'ZERO' | If zero blank control is in effect for the file
'UNDEFINED' | If the file is not connected, or it is not connected for formatted data transfer


BLOCKSIZE Specifier

The BLOCKSIZE specifier asks about the I/O buffer size. It takes the following form:

BLOCKSIZE = bks

bks
Is a scalar integer variable.

The bks is assigned the current size of the I/O buffer. If the unit or file is not connected, the value assigned is zero.


BUFFERED Specifier

The BUFFERED specifier asks whether whether run-time buffering is in effect. It takes the following form:

BUFFERED = bf

bf
Is a scalar default character variable that is assigned one of the following values:
'NO' | If the file or unit is connected and buffering is not in effect.
'YES' | If the file or unit is connected and buffering is in effect.
'UNKNOWN' | If the file or unit is not connected.


CARRIAGECONTROL Specifier

The CARRIAGECONTROL specifier asks what type of carriage control is in effect for a file. It takes the following form:

CARRIAGECONTROL = cc

cc
Is a scalar default character variable that is assigned one of the following values:
'FORTRAN' | If the file is connected with Fortran carriage control in effect
'LIST' | If the file is connected with implied carriage control in effect
'NONE' | If the file is connected with no carriage control in effect
'UNKNOWN' | If the file is not connected


CONVERT Specifier

The CONVERT specifier asks what type of data conversion is in effect for a file. It takes the following form:

CONVERT = fm

fm
Is a scalar default character variable that is assigned one of the following values:
'LITTLE_ENDIAN' | If the file is connected with little endian integer and IEEE® floating-point data conversion in effect
'BIG_ENDIAN' | If the file is connected with big endian integer and IEEE floating-point data conversion in effect
'CRAY' | If the file is connected with big endian integer and CRAY® floating-point data conversion in effect
'FDX' | If the file is connected with little endian integer and Compaq (formerly DIGITAL) VAXTM F_floating, D_floating, and IEEE X_floating data conversion in effect
'FGX' | If the file is connected with little endian integer and Compaq VAX F_floating, G_floating, and IEEE X_floating data conversion in effect
'IBM' | If the file is connected with big endian integer and IBM® System\370 floating-point data conversion in effect
'VAXD' | If the file is connected with little endian integer and Compaq VAX F_floating, D_floating, and H_floating in effect
'VAXG' | If the file is connected with little endian integer and Compaq VAX F_floating, G_floating, and H_floating in effect
'NATIVE' | If the file is connected with no data conversion in effect
'UNKNOWN' | If the file or unit is not connected for unformatted data transfer


DELIM Specifier

The DELIM specifier asks how character constants are delimited in list-directed and namelist output. It takes the following form:

DELIM = del

del
Is a scalar default character variable that is assigned one of the following values:
'APOSTROPHE' | If apostrophes are used to delimit character constants in list-directed and namelist output
'QUOTE' | If quotation marks are used to delimit character constants in list-directed and namelist output
'NONE' | If no delimiters are used
'UNDEFINED' | If the file is not connected, or is not connected for formatted data transfer


DIRECT Specifier

The DIRECT specifier asks whether a file is connected for direct access. It takes the following form:

DIRECT = dir

dir
Is a scalar default character variable that is assigned one of the following values:
'YES' | If the file is connected for direct access
'NO' | If the file is not connected for direct access
'UNKNOWN' | If the file is not connected


EXIST Specifier

The EXIST specifier asks whether a file exists and can be opened. It takes the following form:

EXIST = ex

ex
Is a scalar default logical variable that is assigned one of the following values:
.TRUE. | If the specified file exists and can be opened, or if the specified unit exists
.FALSE. | If the specified file or unit does not exist or if the file exists but cannot be opened

The unit exists if it is a number in the range allowed by the processor.


FORM Specifier

The FORM specifier asks whether a file is connected for binary (WNT, W9*), formatted, or unformatted data transfer. It takes the following form:

FORM = fm

fm
Is a scalar default character variable that is assigned one of the following values:
'FORMATTED' | If the file is connected for formatted data transfer
'UNFORMATTED' | If the file is connected for unformatted data transfer
'BINARY' | If the file is connected for binary data transfer
'UNDEFINED' | If the file is not connected


FORMATTED Specifier

The FORMATTED specifier asks whether a file is connected for formatted data transfer. It takes the following form:

FORMATTED = fmt

fmt
Is a scalar default character variable that is assigned one of the following values:
'YES' | If the file is connected for formatted data transfer
'NO' | If the file is not connected for formatted data transfer
'UNKNOWN' | If the processor cannot determine whether the file is connected for formatted data transfer


IOFOCUS Specifier (WNT, W9*)

The IOFOCUS specifier asks if the indicated unit is the active window in a QuickWin application. It takes the following form:

IOFOCUS = iof

iof
Is a scalar default logical variable that is assigned one of the following values:
.TRUE. | If the specified unit is the active window in a QuickWin application
.FALSE. | If the specified unit is not the active window in a QuickWin application

If you use this specifier with a non-Windows application, an error occurs.


MODE Specifier (WNT, W9*)

MODE is a nonstandard synonym for ACTION.


NAME Specifier

The NAME specifier returns the name of a file. It takes the following form:

NAME = nme

nme
Is a scalar default character variable that is assigned the name of the file to which the unit is connected. If the file does not have a name, nme is undefined.

The value assigned to nme is not necessarily the same as the value given in the FILE specifier. However, the value that is assigned is always valid for use with the FILE specifier in an OPEN statement, unless the value has been truncated in a way that makes it unacceptable. (Values are truncated if the declaration of nme is too small to contain the entire value.)

Note: The FILE and NAME specifiers are synonyms when used with the OPEN statement, but not when used with the INQUIRE statement.

For More Information:

For details on the maximum size of file pathnames, see the appropriate manual in your operating system documentation set.


NAMED Specifier

The NAMED specifier asks whether a file is named. It takes the following form:

NAMED = nmd

nmd
Is a scalar default logical variable that is assigned one of the following values:
.TRUE. | If the file has a name
.FALSE. | If the file does not have a name


NEXTREC Specifier

The NEXTREC specifier asks where the next record can be read or written in a file connected for direct access. It takes the following form:

NEXTREC = nr

nr
Is a scalar integer variable that is assigned a value as follows:

  • If the file is connected for direct access and a record (r) was previously read or written, the value assigned is r + 1.

  • If no record has been read or written, the value assigned is 1.

  • If the file is not connected for direct access, or if the file position cannot be determined because of an error condition, the value assigned is zero.

  • If the file is connected for direct access and a REWIND has been performed on the file, the value assigned is 1.


NUMBER Specifier

The NUMBER specifier asks the number of the unit connected to a file. It takes the following form:

NUMBER = num

num
Is a scalar integer variable.

The num is assigned the number of the unit currently connected to the specified file. If there is no unit connected to the file, the value assigned is -1.


OPENED Specifier

The OPENED specifier asks whether a file is connected. It takes the following form:

OPENED = od

od
Is a scalar default logical variable that is assigned one of the following values:
.TRUE. | If the specified file or unit is connected
.FALSE. | If the specified file or unit is not connected


ORGANIZATION Specifier

The ORGANIZATION specifier asks how the file is organized. It takes the following form:

ORGANIZATION = org

org
Is a scalar default character variable that is assigned one of the following values:
'SEQUENTIAL' | If the file is a sequential file
'RELATIVE' | If the file is a relative file
'UNKNOWN' | If the processor cannot determine the file's organization


PAD Specifier

The PAD specifier asks whether blank padding was specified for the file. It takes the following form:

PAD = pd

pd
Is a scalar default character variable that is assigned one of the following values:
'NO' | If the file or unit was connected with PAD='NO'
'YES' | If the file or unit is not connected, or it was connected with PAD='YES'


POSITION Specifier

The POSITION specifier asks the position of the file. It takes the following form:

POSITION = pos

pos
Is a scalar default character variable that is assigned one of the following values:
'REWIND' | If the file is connected with its position at its initial point
'APPEND' | If the file is connected with its position at its terminal point (or before its end-of-file record, if any)
'ASIS' | If the file is connected without changing its position
'UNDEFINED' | If the file is not connected, or is connected for direct access data transfer and a REWIND statement has not been performed on the unit

For More Information:

For details on record position, advancement, and transfer, see your programmer's guide.


READ Specifier

The READ specifier asks whether a file can be read. It takes the following form:

READ = rd

rd
Is a scalar default character variable that is assigned one of the following values:
'YES' | If the file can be read
'NO' | If the file cannot be read
'UNKNOWN' | If the processor cannot determine whether the file can be read


READWRITE Specifier

The READWRITE specifier asks whether a file can be both read and written to. It takes the following form:

READWRITE = rdwr

rdwr
Is a scalar default character variable that is assigned one of the following values:
'YES' | If the file can be both read and written to
'NO' | If the file cannot be both read and written to
'UNKNOWN' | If the processor cannot determine whether the file can be both read and written to


RECL Specifier

The RECL specifier asks the maximum record length for a file. It takes the following form:

RECL = rcl

rcl
Is a scalar integer variable that is assigned a value as follows:

  • If the file or unit is connected, the value assigned is the maximum record length allowed.

  • If the file does not exist, or is not connected, the value assigned is zero.

The assigned value is expressed in 4-byte units if the file is currently (or was previously) connected for unformatted data transfer; otherwise, the value is expressed in bytes.


RECORDTYPE Specifier

The RECORDTYPE specifier asks which type of records are in a file. It takes the following form:

RECORDTYPE = rtype

rtype
Is a scalar default character variable that is assigned one of the following values:
'FIXED' | If the file is connected for fixed-length records
'VARIABLE' | If the file is connected for variable-length records
'SEGMENTED' | If the file is connected for unformatted sequential data transfer using segmented records
'STREAM' | If the file's records are not terminated
'STREAM_CR' | If the file's records are terminated with a carriage return
'STREAM_LF' | If the file's records are terminated with a line feed
'UNKNOWN' | If the file is not connected


SEQUENTIAL Specifier

The SEQUENTIAL specifier asks whether a file is connected for sequential access. It takes the following form:

SEQUENTIAL = seq

seq
Is a scalar default character variable that is assigned one of the following values:
'YES' | If the file is connected for sequential access
'NO' | If the file is not connected for sequential access
'UNKNOWN' | If the processor cannot determine whether the file is connected for sequential access


SHARE Specifier

SHARE Specifier (WNT, W9*)

The SHARE specifier asks the current share status of a file or unit. It takes the following form:

SHARE = shr

shr
Is a scalar default character variable that is assigned one of the following values:
'DENYRW' | If the file is connected for deny-read/write mode
'DENYWR' | If the file is connected for deny-write mode
'DENYRD' | If the file is connected for deny-read mode
'DENYNONE' | If the file is connected for deny-none mode
'UNKNOWN' | If the file or unit is not connected


UNFORMATTED Specifier

The UNFORMATTED specifier asks whether a file is connected for unformatted data transfer. It takes the following form:

UNFORMATTED = unf

unf
Is a scalar default character variable that is assigned one of the following values:
'YES' | If the file is connected for unformatted data transfer
'NO' | If the file is not connected for unformatted data transfer
'UNKNOWN' | If the processor cannot determine whether the file is connected for unformatted data transfer


WRITE Specifier

The WRITE specifier asks whether a file can be written to. It takes the following form:

WRITE = wr

wr
Is a scalar default character variable that is assigned one of the following values:
'YES' | If the file can be written to
'NO' | If the file cannot be written to
'UNKNOWN' | If the processor cannot determine whether the file can be written to


OPEN Statement

The OPEN statement connects an external file to a unit, creates a new file and connects it to a unit, creates a preconnected file, or changes certain properties of a connection. For more information, see OPEN in the A to Z Reference.

The following table summarizes the OPEN statement specifiers (and contains links to their descriptions):

OPEN Statement Specifiers and Values on Windows, Tru64 UNIX, and Linux Systems

Specifier | Values | Function | Default
ACCESS 'SEQUENTIAL'
'DIRECT'
'APPEND' 		Access mode 'SEQUENTIAL'
ACTION
(or MODE 1) 		'READ'
'WRITE'
'READWRITE' 		File access 'READWRITE'
ASSOCIATEVARIABLE | var | Next direct access record | No default
BLANK 'NULL'
'ZERO' 		Interpretation of blanks 'NULL'
BLOCKSIZE | n_expr | Physical block size | Filesystem default
BUFFERCOUNT | n_expr | Number of I/O buffers | One
BUFFERED 'YES'
'NO' 		Buffering for WRITE operations 'NO'
CARRIAGECONTROL 'FORTRAN'
'LIST'
'NONE' 		Print control Formatted: 'LIST' 2
Unformatted: 'NONE'
CONVERT 'LITTLE_ENDIAN'
'BIG_ENDIAN'
'CRAY'
'FDX'
'FGX'
'IBM'
'VAXD'
'VAXG'
'NATIVE' 		Numeric format specification 'NATIVE'
DEFAULTFILE | c_expr | Default file pathname | Current working directory
DELIM 'APOSTROPHE'
'QUOTE'
'NONE' 		Delimiter for character constants 'NONE'
DISPOSE
(or DISP) 		'KEEP' or 'SAVE'
'DELETE'
'PRINT'
'PRINT/DELETE'
'SUBMIT'
'SUBMIT/DELETE' 		File disposition at close 'KEEP'
ERR | label | Error transfer control | No default
FILE
(or NAME) 		c_expr File pathname (file name) fort.n 3
FORM 'FORMATTED'
'UNFORMATTED'
'BINARY' 1 		Format type Depends on ACCESS setting
IOFOCUS 1 | .TRUE. or .FALSE. | Active window in QuickWin application | .TRUE. 4
IOSTAT | var | I/O status | No default
MAXREC | n_expr | Direct access record limit | No limit
ORGANIZATION 'SEQUENTIAL'
'RELATIVE' 		File organization 'SEQUENTIAL'
PAD 'YES'
'NO' 		Record padding 'YES'
POSITION 'ASIS'
'REWIND'
'APPEND' 		File positioning 'ASIS'
READONLY | No value | Write protection | No default
RECL
(or RECORDSIZE) 		n_expr Record length Depends on RECORDTYPE, ORGANIZATION, and FORM settings 5
RECORDTYPE 'FIXED'
'VARIABLE'
'SEGMENTED'
'STREAM'
'STREAM_CR'
'STREAM_LF' 		Record type Depends on ORGANIZATION, CARRIAGECONTROL, ACCESS, and FORM settings
SHARE 1, 6 'DENYRW'
'DENYWR'
'DENYRD'
'DENYNONE' 		File locking 'DENYWR'
SHARED 6 No value File sharing allowed U*X: SHARED
WNT and W9*: No default
STATUS (or TYPE) 'OLD'
'NEW'
'SCRATCH'
'REPLACE'
'UNKNOWN' 		File status at open 'UNKNOWN' 7
TITLE 1 | c_expr | Title for child window in QuickWin application | No default
UNIT | n_expr | Logical unit number | No default; an io-unit must be specified
USEROPEN | func | User program option | No default
1 WNT, W95
2 If you use the compiler option specifying OpenVMS defaults, and the unit is connected to a terminal, the default is 'FORTRAN'.
3 n is the unit number.
4 If you specify unit '*' the default is .FALSE..
5 On Tru64 UNIX and Linux systems, the default depends only on the FORM setting.
6 For information on file sharing, see your user manual or programmer's guide.
7 The default differs under certain conditions (see STATUS Specifier).
Key to Values
   c_expr: A scalar default character expression
   func:   An external function
   label:  A statement label
   n_expr: A scalar numeric expression
   var:    A scalar integer variable

For More Information:

  • On Fortran I/O status, see IOSTAT values in your programmer's guide.
  • On using the INQUIRE statement to get file attributes of existing files, see INQUIRE Statement.
  • On OPEN statements and file connection, see your programmer's guide.


ACCESS Specifier

The ACCESS specifier indicates the access method for the connection of the file. It takes the following form:

ACCESS = acc

acc
Is a scalar default character expression that evaluates to one of the following values:
'DIRECT' | Indicates direct access.
'SEQUENTIAL' | Indicates sequential access.
'APPEND' | Indicates sequential access, but the file is positioned at the end-of-file record.

The default is 'SEQUENTIAL'.

There are limitations on record access by file organization and record type.

For More Information:

For details on limitations on record access, see your programmer's guide.


ACTION Specifier

The ACTION specifier indicates the allowed I/O operations for the file connection. It takes the following form:

ACTION = act

act
Is a scalar default character expression that evaluates to one of the following values:
'READ' | Indicates that only READ statements can refer to this connection.
'WRITE' | Indicates that only WRITE, DELETE, and ENDFILE statements can refer to this connection.
'READWRITE' | Indicates that READ, WRITE, DELETE, and ENDFILE statements can refer to this connection.

The default is 'READWRITE'.

However, if /fpscomp:general is specified on the command line and action is omitted, the system first attempts to open the file with 'READWRITE'. If this fails, the system tries to open the file again, first using 'READ', then using 'WRITE'.

Note that in this case, omitting action is not the same as specifying ACTION='READWRITE'. If you specify ACTION='READWRITE' and the file cannot be opened for both read and write access, the attempt to open the file fails. You can use the INQUIRE statement to determine the actual access mode selected.


ASSOCIATEVARIABLE Specifier

The ASSOCIATEVARIABLE specifier indicates a variable that is updated after each direct access I/O operation, to reflect the record number of the next sequential record in the file. It takes the following form:

ASSOCIATEVARIABLE = asv

asv
Is a scalar integer variable. It cannot be a dummy argument to the routine in which the OPEN statement appears.

Direct access READs, direct access WRITEs, and the FIND, DELETE, and REWRITE statements can affect the value of asv.

This specifier is valid only for direct access; it is ignored for other access modes.


BLANK Specifier

The BLANK specifier indicates how blanks are interpreted in a file. It takes the following form:

BLANK = blnk

blnk
Is a scalar default character expression that evaluates to one of the following values:
'NULL' | Indicates all blanks are ignored, except for an all-blank field (which has a value of zero).
'ZERO' | Indicates all blanks (other than leading blanks) are treated as zeros.

The default is 'NULL' (for explicitly OPENed files, preconnected files, and internal files). If you specify compiler option /f66 (or OPTIONS/NOF77), the default is 'ZERO'.

If the BN or BZ edit descriptors are specified for a formatted input statement, they supersede the default interpretation of blanks.

For More Information:

For details on the BN and BZ edit descriptors, see Blank Editing.


BLOCKSIZE Specifier

The BLOCKSIZE specifier indicates the physical I/O transfer size for the file. It takes the following form:

BLOCKSIZE = bks

bks
Is a scalar numeric expression. If necessary, the value is converted to integer data type before use.

If you specify a nonzero number for bks, it is rounded up to a multiple of 512 byte blocks.

If you omit BLOCKSIZE or specify zero for bks, the filesystem default is assumed.


BUFFERCOUNT Specifier

The BUFFERCOUNT specifier indicates the number of buffers to be associated with the unit for multibuffered I/O. It takes the following form:

BUFFERCOUNT = bc

bc
Is a scalar numeric expression in the range 1 through 127. If necessary, the value is converted to integer data type before use.

The BLOCKSIZE specifier determines the size of each buffer. For example, if BUFFERCOUNT=3 and BLOCKSIZE=2048, the total number of bytes allocated for buffers is 3*2048, or 6144 bytes.

If you do not specify BUFFERCOUNT or you specify zero for bc, the default is 1.

For More Information:

  • See the BLOCKSIZE specifier.
  • On obtaining optimal run-time performance, see your programmer's guide.


BUFFERED Specifier

The BUFFERED specifier indicates run-time library behavior following WRITE operations. It takes the following form:

BUFFERED = bf

bf
Is a scalar default character expression that evaluates to one of the following values:
'NO' Requests that the run-time library send output data to the file system after each WRITE operation.
'YES' Requests that the run-time library accumulate output data in its internal buffer, possibly across several WRITE operations, before the data is sent to the file system.

Buffering may improve run-time performance for output-intensive applications.

The default is 'NO'.

If BUFFERED='YES' is specified, the request may or may not be honored, depending on the output device and other file or connection characteristics.

If BLOCKSIZE and BUFFERCOUNT have been specified for OPEN, their product determines the size in bytes of the internal buffer. Otherwise, the default size of the internal buffer is 8192 bytes.

Note: The default size of the internal buffer is 1024 bytes if compiler option /fpscomp:general is used.

The internal buffer will grow to hold the largest single record but will never shrink.


CARRIAGECONTROL Specifier

The CARRIAGECONTROL specifier indicates the type of carriage control used when a file is displayed at a terminal. It takes the following form:

CARRIAGECONTROL = cc

cc
Is a scalar default character expression that evaluates to one of the following values:
'FORTRAN' | Indicates normal Fortran interpretation of the first character.
'LIST' | Indicates one line feed between records.
'NONE' | Indicates no carriage control processing.

The default for binary (WNT, W9*) and unformatted files is 'NONE'. The default for formatted files is 'LIST'. However, if you specify /vms or /fpscomp:general, and the unit is connected to a terminal, the default is 'FORTRAN'.

On output, if a file was opened with CARRIAGECONTROL='FORTRAN' in effect or the file was processed by the fortpr format utility, the first character of a record transmitted to a line printer or terminal is typically a character that is not printed, but is used to control vertical spacing.

For More Information:

For details on valid control characters for printing, see Printing of Formatted Records.


CONVERT Specifier

The CONVERT specifier indicates a nonnative numeric format for unformatted data. It takes the following form:

CONVERT = fm

fm
Is a scalar default character expression that evaluates to one of the following values:
'LITTLE_ENDIAN' 1 | Little endian integer data 2 and IEEE® floating-point data. 3
'BIG_ENDIAN' 1 | Big endian integer data 2 and IEEE floating-point data. 3
'CRAY' | Big endian integer data 2 and CRAY® floating-point data of size REAL(8) or COMPLEX(8).
'FDX' | Little endian integer data 2 and Compaq (formerly DIGITAL) VAXTM floating-point data of format F_floating for REAL(4) or COMPLEX(4), D_floating for size REAL(8) or COMPLEX(8), and IEEE X_floating for REAL(16) or COMPLEX(16). 4
'FGX' | Little endian integer data 2 and Compaq VAX floating-point data of format F_floating for REAL(4) or COMPLEX(4), G_floating for size REAL(8) or COMPLEX(8), and IEEE X_floating for REAL(16) or COMPLEX(16). 4
'IBM' | Big endian integer data 2 and IBM® System\370 floating-point data of size REAL(4) or COMPLEX(4) (IBM short 4), and size REAL(8) or COMPLEX(8) (IBM long 8).
'VAXD' | Little endian integer data 2 and Compaq VAX floating-point data of format F_floating for size REAL(4) or COMPLEX(4), D_floating for size REAL(8) or COMPLEX(8), and H_floating for REAL(16) or COMPLEX(16). 4
'VAXG' | Little endian integer data 2 and Compaq VAX floating-point data of format F_floating for size REAL(4) or COMPLEX(4), G_floating for size REAL(8) or COMPLEX(8), and H_floating for REAL(16) or COMPLEX(16). 4
'NATIVE' | No data conversion. This is the default.
1 INTEGER(1) data is the same for little endian and big endian.
2 Of the appropriate size: INTEGER(1), INTEGER(2), INTEGER(4), or INTEGER(8)
3 Of the appropriate size and type: REAL(4), REAL(8), REAL(16), COMPLEX(4), COMPLEX(8), or COMPLEX(16)
4 U*X only

You can use CONVERT to specify multiple formats in a single program, usually one format for each specified unit number.

When reading a nonnative format, the nonnative format on disk is converted to native format in memory. If a converted nonnative value is outside the range of the native data type, a run-time message appears.

There are other ways to specify numeric format for unformatted files: you can specify an environment variable, the compiler option /convert, or OPTIONS/CONVERT. The following shows the order of precedence:

Method Used | Precedence
An environment variable | Highest
OPEN(CONVERT=convert) | .
OPTIONS/CONVERT | .
The /convert:keyword compiler option | Lowest

The /convert compiler option and OPTIONS/CONVERT affect all unit numbers used by the program, while environment variables and OPEN (CONVERT=) affect specific unit numbers.

The following example shows how to code the OPEN statement to read unformatted CRAY® numeric data from unit 15, which might be processed and possibly written in native little endian format to unit 20:

 OPEN (CONVERT='CRAY', FILE='graph3.dat', FORM='UNFORMATTED',
1      UNIT=15)
 ...
 OPEN (FILE='graph3_native.dat', FORM='UNFORMATTED', UNIT=20)

For More Information:

  • See Environment Variables Used with the DF Command
  • See Run-Time Environment Variables
  • On supported ranges for data types, see Data Types, Constants, and Variables and your programmer's guide.
  • On compiler options, in general, see your programmer's guide.


DEFAULTFILE Specifier

The DEFAULTFILE specifier indicates a default file pathname string. It takes the following form:

DEFAULTFILE = def

def
Is a character expression indicating a default file pathname string.

The default file pathname string is used primarily when accepting file pathnames interactively. File pathnames known to a user program normally appear in the FILE specifier.

DEFAULTFILE supplies a value to the Fortran I/O system that is prefixed to the name that appears in FILE.

If def does not end in a slash (/), a slash is added.

If DEFAULTFILE is omitted, the Fortran I/O system uses the current working directory.


DELIM Specifier

The DELIM specifier indicates what characters (if any) are used to delimit character constants in list-directed and namelist output. It takes the following form:

DELIM = del

del
Is a scalar default character expression that evaluates to one of the following values:
'APOSTROPHE' | Indicates apostrophes delimit character constants. All internal apostrophes are doubled.
'QUOTE' | Indicates quotation marks delimit character constants. All internal quotation marks are doubled.
'NONE' | Indicates character constants have no delimiters. No internal apostrophes or quotation marks are doubled.

The default is 'NONE'.

The DELIM specifier is only allowed for files connected for formatted data transfer; it is ignored during input.


DISPOSE Specifier

The DISPOSE (or DISP) specifier indicates the status of the file after the unit is closed. It takes one of the following forms:

DISPOSE = dis
DISP = dis

dis
Is a scalar default character expression that evaluates to one of the following values:
'KEEP' or 'SAVE' | Retains the file after the unit closes.
'DELETE' | Deletes the file after the unit closes.
'PRINT' 1 | Submits the file to the line printer spooler and retains it.
'PRINT/DELETE' 1 | Submits the file to the line printer spooler and then deletes it.
'SUBMIT' | Forks a process to execute the file.
'SUBMIT/DELETE' | Forks a process to execute the file, and then deletes the file after the fork is completed.
1 Use only on sequential files.

The default is 'DELETE' for scratch files. For all other files, the default is 'KEEP'.


FILE Specifier

The FILE specifier indicates the name of the file to be connected to the unit. It takes the following form:

FILE = name

name
Is a character or numeric expression.

The name can be any pathname allowed by the operating system.

Any trailing blanks in the name are ignored.

If FILE is omitted and the unit is not connected to a file, the OPEN statement must specify STATUS='SCRATCH'.

If the file name is stored in a numeric scalar or array, the name must consist of ASCII characters terminated by an ASCII null character (zero byte). However, if it is stored in a character scalar or array, it must not contain a zero byte.

If the filename is 'USER' or 'CON', input and output are directed to the console. For a complete list of device names, see Physical Devices.

In a QuickWin application, you can specify FILE='USER' to open a child window. All subsequent I/O statements directed to that unit appear in the child window.

The name can be blank (FILE=' ') if the compatibility compiler option /fpscomp:filesfromcmd is specified. If the name is blank, the following occurs:

  1. The program reads a filename from the list of arguments (if any) in the command line that started the program. If the argument is a null or blank string (" "), you are prompted for the corresponding filename. Each successive OPEN statement that specifies a blank name reads the next following command-line argument.

  2. If no command-line arguments are specified or there are no more arguments in the list, you are prompted for additional filenames.

    Assume the following command line started the program MYPROG (note that quotation marks (") are used):

    myprog first.fil " " third.txt

    MYPROG contains four OPEN statements with blank filenames, in the following order:

       OPEN (2, FILE = ' ')
   OPEN (4, FILE = ' ')
   OPEN (5, FILE = ' ')
   OPEN (10, FILE = ' ')

    Unit 2 is associated with the file FIRST.FIL. Because a blank argument was specified on the command line for the second filename, the OPEN statement for unit 4 produces the following prompt:

     Filename missing or blank -
 Please enter name UNIT 4?

    Unit 5 is associated with the file THIRD.TXT. Because no fourth file was specified on the command line, the OPEN statement for unit 10 produces the following prompt:

     Filename missing or blank -
 Please enter name UNIT 10?

For More Information:

  • See Physical Devices in Files, Devices, and I/O Hardware in the Programmer's Guide.
  • On default file name conventions, see your programmer's guide.
  • On allowable file pathnames, see the appropriate manual in your system documentation set.


FORM Specifier

The FORM specifier indicates whether the file is being connected for binary (WNT, W9*), formatted, or unformatted data transfer. It takes the following form:

FORM = fm

fm
Is a scalar default character expression that evaluates to one of the following values:
'FORMATTED' | Indicates formatted data transfer
'UNFORMATTED' | Indicates unformatted data transfer
'BINARY' | Indicates binary data transfer

The default is 'FORMATTED' for sequential access files, and 'UNFORMATTED' for direct access files.

The data is stored and retrieved in a file according to the file's access (set by the ACCESS specifier) and the form of the data the file contains.

A formatted file is a sequence of formatted records. Formatted records are a series of ASCII characters terminated by an end-of-record mark (a carriage return and line feed sequence). The records in a formatted direct-access file must all be the same length. The records in a formatted sequential file can have varying lengths. All internal files must be formatted.

An unformatted file is a sequence of unformatted records. An unformatted record is a sequence of values. Unformatted direct files contain only this data, and each record is padded to a fixed length with undefined bytes. Unformatted sequential files contain the data plus information that indicates the boundaries of each record.

Binary sequential files are sequences of bytes with no internal structure. There are no records. The file contains only the information specified as I/O list items in WRITE statements referring to the file.

Binary direct files have very little structure. A record length is assigned by the RECL specifier in an OPEN statement. This establishes record boundaries, which are used only for repositioning and padding before and after read and write operations and during BACKSPACE operations. Record boundaries do not restrict the number of bytes that can be transferred during a read or write operation. If an I/O operation attempts to read or write more values than are contained in a record, the read or write operation is continued on the next record.


IOFOCUS Specifier (WNT, W9*)

The IOFOCUS specifier indicates whether a particular unit is the active window in a QuickWin application. It takes the following form:

IOFOCUS = iof

iof
Is a scalar default logical expression that evaluates to one of the following values:
.TRUE. | Indicates the QuickWin child window is the active window
.FALSE. | Indicates the QuickWin child window is not the active window

If unit '*' is specified, the default is .FALSE.; otherwise, the default is .TRUE..

A value of .TRUE. causes a call to FOCUSQQ immediately before any READ, WRITE, or PRINT statement to that window. OUTTEXT, OUTGTEXT, or any other graphics routine call does not cause the focus to shift.

For More Information:

See Giving a Window Focus and Setting the Active Window in Using QuickWin in the Programmer's Guide.


MAXREC Specifier

The MAXREC specifier indicates the maximum number of records that can be transferred from or to a direct access file while the file is connected. It takes the following form:

MAXREC = mr

mr
Is a scalar numeric expression. If necessary, the value is converted to integer data type before use.

The default is an unlimited number of records.


MODE Specifier

MODE Specifier (WNT, W9*)

MODE is a nonstandard synonym for ACTION.


NAME Specifier

NAME is a nonstandard synonym for FILE.


ORGANIZATION Specifier

The ORGANIZATION specifier indicates the internal organization of the file. It takes the following form:

ORGANIZATION = org

org
Is a scalar default character expression that evaluates to one of the following values:
'SEQUENTIAL' | Indicates a sequential file.
'RELATIVE' | Indicates a relative file.

The default is 'SEQUENTIAL'.


PAD Specifier

The PAD specifier indicates whether a formatted input record is padded with blanks when an input list and format specification requires more data than the record contains.

The PAD specifier takes the following form:

PAD = pd

pd
Is a scalar default character expression that evaluates to one of the following values:
'YES' | Indicates the record will be padded with blanks when necessary.
'NO' | Indicates the record will not be padded with blanks. The input record must contain the data required by the input list and format specification.

The default is 'YES'.

This behavior is different from FORTRAN 77, which never pads short records with blanks. For example, consider the following:

  READ (5,'(I5)') J

If you enter 123 followed by a carriage return, FORTRAN 77 turns the I5 into an I3 and J is assigned 123.

However, Compaq Fortran pads the 123 with 2 blanks unless you explicitly open the unit with PAD='NO'.

You can override blank padding by explicitly specifying the BN edit descriptor.

The PAD specifier is ignored during output.


POSITION Specifier

The POSITION specifier indicates the position of a file connected for sequential access. It takes the following form:

POSITION = pos

pos
Is a scalar default character expression that evaluates to one of the following values:
'ASIS' | Indicates the file position is unchanged if the file exists and is already connected. The position is unspecified if the file exists but is not connected.
'REWIND' | Indicates the file is positioned at its initial point.
'APPEND' | Indicates the file is positioned at its terminal point (or before its end-of-file record, if any).

The default is 'ASIS'. (On Fortran I/O systems, this is the same as 'REWIND'.)

A new file (whether specified as new explicitly or by default) is always positioned at its initial point.

In addition to the POSITION= specifier, you can use position statements. The BACKSPACE statement positions a file back one record. The REWIND statement positions a file at its initial point. The ENDFILE statement writes an end-of-file record at the current position and positions the file after it. Note that ENDFILE does not go the end of an existing file, but creates an end-of-file where it is.

For More Information:

For details on record position, advancement, and transfer, see your programmer's guide.


READONLY Specifier

The READONLY specifier indicates only READ statements can refer to this connection. It takes the following form:

READONLY

READONLY is similar to specifying ACTION='READ', but READONLY prevents deletion of the file if it is closed with STATUS='DELETE' in effect.

The Fortran I/O system's default privileges for file access are READWRITE. If access is denied, the I/O system automatically retries accessing the file for READ access.

However, if you use the /vms compiler option, the I/O system does not retry accessing for READ access. So, run-time I/O errors can occur if the file protection does not permit WRITE access. To prevent such errors, if you wish to read a file for which you do not have write access, specify READONLY.


RECL Specifier

The RECL specifier indicates the length of each record in a file connected for direct access, or the maximum length of a record in a file connected for sequential access.

The RECL specifier takes the following form:

RECL = rl

rl
Is a positive numeric expression indicating the length of records in the file. If necessary, the value is converted to integer data type before use.

If the file is connected for formatted data transfer, the value must be expressed in bytes (characters). Otherwise, the value is expressed in 4-byte units (longwords).

If the file is connected for unformatted data transfer, the value can be expressed in bytes if compiler option /assume:byterecl is specified.

Except for segmented records, the rl is the length for record data only, it does not include space for control information.

The length specified is interpreted depending on the type of records in the connected file, as follows:

  • For segmented records, RECL indicates the maximum length for any segment (including the four bytes of control information).

  • For fixed-length records, RECL indicates the size of each record; it must be specified. If the records are unformatted, the size must be expressed as an even multiple of four.

    You can use the RECL specifier in an INQUIRE statement to get the record length before opening the file.

  • For variable-length records, RECL indicates the maximum length for any record.

If you read a fixed-length file with a record length different from the one used to create the file, indeterminate results can occur.

The maximum length for rl depends on the record type and the setting of the CARRIAGECONTROL specifier, as shown in the following table:

Maximum Record Lengths (RECL) on Windows, Tru64 UNIX, and Linux Systems

Record Type | CARRIAGECONTROL | Formatted (size in bytes)
Fixed-length | 'NONE' | 2147483647 (2**31-1) 1
Variable-length | 'NONE' | 2147483640 (2**31-8)
Segmented | 'NONE' | 32764 (2**15-4)
Stream | 'NONE' | 2147483647 (2**31-1)
Stream_CR | 'LIST' | 2147483647 (2**31-1)
 | 'FORTRAN' | 2147483646 (2**31-2)
Stream_LF | 'LIST' | 2147483647 (2**31-1) 2
 | 'FORTRAN' | 2147483646 (2**31-2)
1 Subtract 1 if the /vms compiler option is used. 2 U*X only

The default value depends on the setting of the RECORDTYPE specifier, as shown in the following table:

Default Record Lengths (RECL) on Windows, Tru64 UNIX, and Linux Systems

RECORDTYPE | RECL value
'FIXED' | None; value must be explicitly specified.
All other settings | 132 bytes for formatted records; 510 longwords for unformatted records.


RECORDSIZE Specifier

RECORDSIZE is a nonstandard synonym for RECL.


RECORDTYPE Specifier

The RECORDTYPE specifier indicates the type of records in a file. It takes the following form:

RECORDTYPE = typ

typ
Is a scalar default character expression that evaluates to one of the following values:
'FIXED' | Indicates fixed-length records.
'VARIABLE' | Indicates variable-length records.
'SEGMENTED' | Indicates segmented records.
'STREAM' | Indicates stream-type variable length records.
'STREAM_LF' | Indicates stream-type variable length records, terminated with a line feed.
'STREAM_CR' | Indicates stream-type variable length records, terminated with a carriage return.

When you open a file, default record types are as follows:

'FIXED' | For relative files
'FIXED' | For direct access sequential files
'STREAM_LF' | For formatted sequential access files
'VARIABLE' | For unformatted sequential access files

A segmented record is a logical record consisting of segments that are physical records. Since the length of a segmented record can be greater than 65,535 bytes, only use segmented records for unformatted sequential access to disk or raw magnetic tape files.

Files containing segmented records can be accessed only by unformatted sequential data transfer statements.

If an output statement does not specify a full record for a file containing fixed-length records, the following occurs:

  • In formatted files, the record is filled with blanks
  • In unformatted files, the record is filled with zeros

For More Information:

For details on record types and file organization, see your programmer's guide.


SHARE Specifier (WNT, W9*)

The SHARE specifier indicates whether file locking is implemented while the unit is open. It takes the following form:

SHARE = shr

shr
Is a scalar default character expression that evaluates to one of the following values:
'DENYRW' | Indicates deny-read/write mode. No other process can open the file.
'DENYWR' | Indicates deny-write mode. No process can open the file with write access.
'DENYRD' | Indicates deny-read mode. No process can open the file with read access.
'DENYNONE' | Indicates deny-none mode. Any process can open the file in any mode.

The default is 'DENYWR'. However, if you specify compiler option /fpscomp:general or the SHARED specifier, the default is 'DENYNONE'.

'COMPAT' is accepted for compatibility with previous versions. It is equivalent to 'DENYNONE'.

Use the ACCESS specifier in an INQUIRE statement to determine the access permission for a file.

Be careful not to permit other users to perform operations that might cause problems. For example, if you open a file intending only to read from it, and want no other user to write to it while you have it open, you could open it with ACTION='READ' and SHARE='DENYRW'. Other users would not be able to open it with ACTION='WRITE' and change the file.

Suppose you want several users to read a file, and you want to make sure no user updates the file while anyone is reading it. First, determine what type of access to the file you want to allow the original user. Because you want the initial user to read the file only, that user should open the file with ACTION='READ'. Next, determine what type of access the initial user should allow other users; in this case, other users should be able only to read the file. The first user should open the file with SHARE='DENYWR'. Other users can also open the same file with ACTION='READ' and SHARE='DENYWR'.

For More Information:

For details on limitations on record access, see your programmer's guide.


SHARED Specifier

The SHARED specifier indicates that the file is connected for shared access by more than one program executing simultaneously. It takes the following form:

SHARED

On Tru64 UNIX and Linux systems, shared access is the default for the Fortran I/O system. On Windows systems, it is the default if SHARED or compiler option /fpscomp:general is specified.

For More Information:

For details on file sharing, see your programmer's guide.


STATUS Specifier

The STATUS specifier indicates the status of a file when it is opened. It takes the following form:

STATUS = sta

sta
Is a scalar default character expression that evaluates to one of the following values:
'OLD' | Indicates an existing file.
'NEW' | Indicates a new file; if the file already exists, an error occurs. Once the file is created, its status changes to 'OLD'.
'SCRATCH' | Indicates a new file that is unnamed (called a scratch file). When the file is closed or the program terminates, the scratch file is deleted.
'REPLACE' | Indicates the file replaces another. If the file to be replaced exists, it is deleted and a new file is created with the same name. If the file to be replaced does not exist, a new file is created and its status changes to 'OLD'.
'UNKNOWN' | Indicates the file may or may not exist. If the file does not exist, a new file is created and its status changes to 'OLD'.

Scratch files go into a temporary directory and are visible while they are open. Scratch files are deleted when the unit is closed or when the program terminates normally, whichever occurs first. You can use the TMP or TEMP environment variable to specify the path for scratch files; if neither environment variable is defined, the default is the current directory.

The default is 'UNKNOWN'. This is also the default if you implicitly open a file by using WRITE. However, if you implicitly open a file using READ, the default is 'OLD'. If you specify compiler option /f66 (or OPTIONS/NOF77), the default is 'NEW'.

Note: The STATUS specifier can also appear in CLOSE statements to indicate the file's status after it is closed. However, in CLOSE statements the STATUS values are the same as those listed for the DISPOSE specifier.


TITLE Specifier

TITLE Specifier (WNT, W95)

The TITLE specifier indicates the name of a child window in a QuickWin application. It takes the following form:

TITLE = name

name
Is a character expression.

If TITLE is specified in a non-Quickwin application, a run-time error occurs.

For More Information:

For details on QuickWin applications, see Using QuickWin in the Programmer's Guide.


TYPE Specifier

TYPE is a nonstandard synonym for STATUS.


USEROPEN Specifier

The USEROPEN specifier lets you pass control to a routine that directly opens a file. The file can use system calls or library routines to establish a special context that changes the effect of subsequent Fortran I/O statements.

The USEROPEN specifier takes the following form:

USEROPEN = function-name

function-name
Is the name of an external function.

The Visual Fortran Run-time Library (RTL) I/O support routines call the function named in USEROPEN in place of the system calls normally used when the file is first opened for I/O. On Win32 platforms, the Fortran RTL would normally call CreateFile( ) to open a file.

The called function must open the file (or pipe, etc.) using CreateFile( ) and return the handle of the file (return value from CreateFile( )) when it returns control to the calling Visual Fortran program. When opening the file, the called function usually specifies options different from those provided by a normal Fortran OPEN statement.

The main purpose of the function named in USEROPEN is to jacket a call to the CreateFile( ) Win32 api. The function can be written in Fortran, C, or other languages. If the function is written in Fortran, do not execute a Fortran OPEN statement to open the file named in USEROPEN.

Examples

In the calling Fortran program, the function named in USEROPEN must first be declared in an EXTERNAL statement. For example, the following Fortran code might be used to call the USEROPEN procedure UOPEN:

  IMPLICIT INTEGER (A-Z)
  EXTERNAL UOPEN
  ...
  OPEN(UNIT=10,FILE='UOPEN.DAT',STATUS='NEW',USEROPEN=UOPEN)

When the OPEN statement is executed, the UOPEN function receives control. The function opens the file by calling CreateFile( ), performs whatever operations were specified, and subsequently returns control (with the handle returned by CreateFile( )) to the calling Fortran program.

Here is what the UOPEN function might look like:

        INTEGER FUNCTION UOPEN( FILENAME,	&
                DESIRED_ACCESS,	&
                SHARE_MODE,	&
                A_NULL,		&
                CREATE_DISP,	&
                FLAGS_ATTR,	&
                B_NULL,		&
                UNIT,		&
                FLEN )
    !DEC$ ATTRIBUTES C, ALIAS:'_UOPEN' :: UOPEN
    !DEC$ ATTRIBUTES REFERENCE :: FILENAME
    !DEC$ ATTRIBUTES REFERENCE :: DESIRED_ACCESS
    !DEC$ ATTRIBUTES REFERENCE :: SHARE_MODE
    !DEC$ ATTRIBUTES REFERENCE :: CREATE_DISP
    !DEC$ ATTRIBUTES REFERENCE :: FLAGS_ATTR
    !DEC$ ATTRIBUTES REFERENCE :: UNIT

    USE DFWIN

    IMPLICIT INTEGER (A-Z)
    CHARACTER*(FLEN) FILENAME
    TYPE(T_SECURITY_ATTRIBUTES), POINTER :: NULL_SEC_ATTR

! Set the FILE_FLAG_WRITE_THROUGH bit in the flag attributes to CreateFile( )
! (for whatever reason)
    FLAGS_ATTR = FLAGS_ATTR + FILE_FLAG_WRITE_THROUGH

! Do the CreateFile( ) call and return the status to the Fortran rtl
    STS = CreateFile( FILENAME,		&
              DESIRED_ACCESS,	&
              SHARE_MODE,		&
              NULL_SEC_ATTR,	&
              CREATE_DISP,		&
              FLAGS_ATTR,		&
              0 )

    UOPEN = STS
    RETURN
    END

The UOPEN function is declared to use the cdecl calling convention, so it matches the Fortran rtl declaration of a useropen routine.

The following function definition and arguments are passed from the Visual Fortran Run-time Library to the function named in USEROPEN:

    INTEGER FUNCTION UOPEN( FILENAME,	&
                DESIRED_ACCESS,	&
                SHARE_MODE,	&
                A_NULL,		&
                CREATE_DISP,	&
                FLAGS_ATTR,	&
                B_NULL,		&
                UNIT,		&
                FLEN )
    !DEC$ ATTRIBUTES C, ALIAS:'_UOPEN' :: UOPEN
    !DEC$ ATTRIBUTES REFERENCE :: DESIRED_ACCESS
    !DEC$ ATTRIBUTES REFERENCE :: SHARE_MODE
    !DEC$ ATTRIBUTES REFERENCE :: CREATE_DISP
    !DEC$ ATTRIBUTES REFERENCE :: FLAGS_ATTR
    !DEC$ ATTRIBUTES REFERENCE :: UNIT

The first 7 arguments correspond to the CreateFile( ) api arguments. The value of these arguments is set according the caller's OPEN( ) arguments:

FILENAME
Is the address of a null terminated character string that is the name of the file.
DESIRED_ACCESS
Is the desired access (read-write) mode passed by reference.
SHARE_MODE
Is the file sharing mode passed by reference.
A_NULL
Is always null. The Fortran runtime library always passes a NULL for the pointer to a SECURITY_ATTRIBUTES structure in its CreateFile( ) call.
CREATE_DISP
Is the creation disposition specifying what action to take on files that exist, and what action to take on files that do not exist. It is passed by reference.
FLAGS_ATTR
Specifies the file attributes and flags for the file. It is passed by reference.
B_NULL
Is always null. The Fortran runtime library always passes a NULL for the handle to a template file in it's CreateFile( ) call.

The last 2 arguments are the Fortran unit number and length of the file name:

UNIT
Is the Fortran unit number on which this OPEN is being done. It is passed by reference.
FLEN
Is the length of the file name, not counting the terminating null, and passed by value.


REWIND Statement

The REWIND statement positions a sequential or direct access file at the beginning of the file (the initial point). For more information, see REWIND in the A to Z Reference.


UNLOCK Statement

The UNLOCK statement frees a record in a relative or sequential file that was locked by a previous READ statement. For more information, see UNLOCK in the A to Z Reference.


Compilation Control Statements

In addition to specifying options on the compiler command line, you can specify the following statements in a program unit to influence compilation:

  • The INCLUDE Statement

    Incorporates external source code into programs.

  • The OPTIONS Statement

    Sets options usually specified in the compiler command line. OPTIONS statement settings override command line options.


Compiler Directives

Compaq Fortran provides the following compiler directives:

  • General directives

    Perform general-purpose tasks during compilation.

  • Parallel directives (TU*X only)

    Specify parallel regions, and characteristics of data and threads for shared access of data in memory.


General Compiler Directives

Compaq Fortran provides several general-purpose compiler directives to perform tasks during compilation. You do not need to specify a compiler option to enable general directives.

The following general compiler directives are available:

  • ALIAS

    Specifies an alternate external name to be used when referring to external subprograms.

  • ATTRIBUTES

    Specifies properties for data objects and procedures.

  • DECLARE and NODECLARE

    Generates or disables warnings for variables that have been used but not declared.

  • DEFINE and UNDEFINE

    Specifies a symbolic variable whose existence (or value) can be tested during conditional compilation.

  • FIXEDFORMLINESIZE

    Sets the line length for fixed-form source code.

  • FREEFORM and NOFREEFORM

    Specifies free-format or fixed-format source code.

  • IDENT

    Specifies an identifier for an object module.

  • IF and IF DEFINED

    Specifies a conditional compilation construct.

  • INTEGER

    Specifies the default integer kind.

  • IVDEP

    Assists the compiler's dependence analysis.

  • MESSAGE

    Specifies a character string to be sent to the standard output device during the first compiler pass.

  • OBJCOMMENT

    Specifies a library search path in an object file.

  • OPTIONS

    Affects data alignment and warnings about data alignment.

  • PACK

    Specifies the memory starting addresses of derived-type items.

  • PSECT

    Modifies certain characteristics of a common block.

  • REAL

    Specifies the default real kind.

  • STRICT and NOSTRICT

    Disables or enables language features not found in the language standard specified on the command line (Fortran 95 or Fortran 90).

  • TITLE and SUBTITLE

    Specifies a title or subtitle for a listing header.

  • UNROLL

    Tells the compiler's optimizer how many times to unroll a DO loop.

The following sections describe:

  • Syntax Rules for General Directives
  • Equivalent Compiler Options


Syntax Rules for General Directives

The following general syntax rules apply to all general compiler directives. You must follow these rules precisely to compile your program properly and obtain meaningful results.

A general directive prefix (tag) takes the following form:

c DEC$

c
Is one of the following: C (or c), !, or *.

The following are source form rules for directive prefixes:

  • Prefixes beginning with C (or c) and * are only allowed in fixed or tab source forms.

    In these source forms, the prefix must appear in columns 1 through 5; column 6 must be a blank or tab. From column 7 on, blanks are insignificant, so the directive can be positioned anywhere on the line after column 6.

  • Prefixes beginning with ! are allowed in all source forms.

    The prefix can appear in any valid column, but it cannot be preceded by any nonblank characters on the same line. It can only be preceded by whitespace.

A general directive ends in column 72 (or column 132, if compiler option /extend_source is specified).

General directives cannot be continued.

A comment can follow a directive on the same line.

Additional Fortran statements (or directives) cannot appear on the same line as the general directive.

General directives cannot appear within a continued Fortran statement.

If a blank common is used in a general compiler directive, it must be specified as two slashes (/ /).

For More Information:

For more details, see General Compiler Directives.


Parallel Directives for Tru64 UNIX Systems

Compaq Fortran provides two sets of directives that support shared memory parallel programming. These directives provide ways to specify the actions taken by the compiler and run-time system when executing a Fortran program in parallel.

This section describes syntax rules and the following sets of directives:

  • OpenMP Fortran compiler directives

    These directives comply with OpenMP Fortran Application Program Interface (API) specification Version 1.0.

  • Compaq Fortran parallel compiler directives

    These directives are provided for compatibility with older programs that were written for parallel execution.

Each set has a specific prefix that identifies the directives in the set. You can only use one set of directives within the same program.

For more information on how to use these directives, see your user manual.


Syntax Rules for Parallel Directives (TU*X only)

The following general syntax rules apply to all parallel compiler directives. You must follow these rules precisely to compile your program properly and obtain meaningful results.

A parallel directive prefix (tag) takes one of the following forms:

c$OMP
c$PAR

c
Is one of the following: C (or c), !, or *.

The following are source form rules for directive prefixes:

  • Prefixes beginning with C (or c) and * are only allowed in fixed and tab source forms.

    In these source forms, the prefix must appear in columns 1 through 5; column 6 must be a blank or tab. From column 7 on, blanks are insignificant, so the directive can be positioned anywhere on the line after column 6. A directive ends in column 72 (or column 132, if a compiler option is specified).

  • Prefixes beginning with ! are allowed in all source forms.

    In fixed and tab source forms, a prefix beginning with ! must follow the same rules for prefixes beginning with C, c, or * (see above).

    In free source form, the prefix need not start in column 1, but it cannot be preceded by any nonblank characters on the same line. It can only be preceded by whitespace.

Parallel directives can be continued and comments can be mixed within a continued parallel directive. The directive prefix must appear on each line of a continued directive.

A comment can follow a directive on the same line.

Additional Fortran statements (or directives) cannot appear on the same line as the parallel directive.

Parallel directives cannot appear within a continued Fortran statement.

Examples

The following examples are equivalent:

  !$OMP PARALLEL DO  &
  !$OMP SHARED(A,B,C)

  !$OMP PARALLEL  &
  !$OMP SHARED(A,B,C)

  !$OMP PARALLEL DO SHARED(A,B,C)


Data Scope Attribute Clauses (TU*X only)

Some of the OpenMP Fortran and Compaq Fortran parallel directives have clauses (or keywords) you can specify to control the scope attributes of variables for the duration of the directive. This section discusses the following clauses:

  • COPYIN
  • DEFAULT
  • FIRSTPRIVATE
  • LASTPRIVATE
  • PRIVATE
  • REDUCTION
  • SHARED

Other clauses (or keywords) are available for some parallel directives. For more information, see each directive description.


OpenMP Fortran API Compiler Directives (TU*X only)

Compaq Fortran supplies parallel directives that comply with OpenMP Fortran Application Program Interface (API) specification Version 1.0.

Use these directives when writing new programs for parallel execution.

This section describes conditional compilation rules, nesting and binding rules, and the following directives:

  • ATOMIC

    Specifies that a specific memory location is to be updated dynamically.

  • BARRIER

    Synchronizes all the threads in a team.

  • CRITICAL

    Restricts access for a block of code to only one thread at a time.

  • DO

    Specifies that the iterations of the immediately following DO loop must be executed in parallel.

  • FLUSH

    Specifies synchronization points where the implementation must have a consistent view of memory.

  • MASTER

    Specifies a block of code to be executed by the master thread of the team.

  • ORDERED

    Specifies a block of code to be executed sequentially.

  • PARALLEL

    Defines a parallel region.

  • PARALLEL DO

    Defines a parallel region that contains a single DO directive.

  • PARALLEL SECTIONS

    Defines a parallel region that contains SECTIONS directives.

  • SECTIONS

    Specifies a block of code to be divided among threads in a team (a worksharing area).

  • SINGLE

    Specifies a block of code to be executed by only one thread in a team.

  • THREADPRIVATE

    Makes named common blocks private to a thread but global within the thread.

The OpenMP parallel directives can be grouped into the categories shown in the following table:

Categories of OpenMP Fortran Parallel Directives (TU*X only)

Category | Description
Parallel region | Defines a parallel region: PARALLEL
Work-sharing | Divide the execution of the enclosed block of code among the members of the team that encounter it: DO and SECTIONS
Combined parallel work-sharing | Shortcut for denoting a parallel region that contains only one work-sharing construct: PARALLEL DO and PARALLEL SECTIONS
Synchronization | Provide various aspects of synchronization; for example, access to a block of code, or execution order of statements within a block of code: ATOMIC, BARRIER, CRITICAL, FLUSH, MASTER, and ORDERED.
Data Environment | Control the data environment during the execution of parallel constructs: THREADPRIVATE

For details on how to use these directives, see your user manual.

See Also: Parallel Directives for Tru64 UNIX Systems, Compaq Fortran Parallel Compiler Directives (TU*X only), the OpenMP web site at http://www.openmp.org/


Conditional Compilation Rules (TU*X)

The OpenMP Fortran API lets you conditionally compile Compaq Fortran statements if you use the appropriate directive prefix.

The prefix depends on which source form you are using, although !$ is valid in all forms.

The prefix must be followed by a valid Compaq Fortran statement on the same line.

Fixed Source Form

For fixed source form programs, the conditional compilation prefix is one of the following: !$ , C$ (or c$), or *$.

The prefix must start in column one and appear as a single string with no intervening white space. Fixed-form source rules apply to the directive line.

Initial lines must have a space or zero in column six, and continuation lines must have a character other than a space or zero in column six. For example, the following forms for specifying conditional compilation are equivalent:

  c23456789
  !$    IAM = OMP_GET_THREAD_NUM( ) +
  !$   *      INDEX

  #IFDEF _OPENMP
        IAM = OMP_GET_THREAD_NUM( ) +
       *      INDEX
  #ENDIF

Free Source Form

The free source form conditional compilation prefix is !$. This prefix can appear in any column as long as it is preceded only by white space. It must appear as a single word with no intervening white space. Free-form source rules apply to the directive line.

Initial lines must have a space after the prefix. Continued lines must have an ampersand as the last nonblank character on the line. Continuation lines can have an ampersand after the prefix with optional white space before and after the ampersand.

For More Information:

  • On how the conditional prefix is interpreted, see your user manual.
  • On a macro that can be used to denote conditional compilation, see your user manual.


Nesting and Binding Rules (TU*X only)

This section describes the dynamic nesting and binding rules for OpenMP Fortran API directives.

Binding Rules

The following rules apply to dynamic binding:

  • The DO, SECTIONS, SINGLE, MASTER, and BARRIER directives bind to the dynamically enclosing PARALLEL directive, if one exists.

  • The ORDERED directive binds to the dynamically enclosing DO directive.

  • The ATOMIC directive enforces exclusive access with respect to ATOMIC directives in all threads, not just the current team.

  • The CRITICAL directive enforces exclusive access with respect to CRITICAL directives in all threads, not just the current team.

  • A directive can never bind to any directive outside the closest enclosing PARALLEL directive.

Nesting Rules

The following rules apply to dynamic nesting:

  • A PARALLEL directive dynamically inside another PARALLEL directive logically establishes a new team, which is composed of only the current thread unless nested parallelism is enabled.

  • DO, SECTIONS, and SINGLE directives that bind to the same PARALLEL directive are not allowed to be nested one inside the other.

  • DO, SECTIONS, and SINGLE directives are not permitted in the dynamic extent of CRITICAL and MASTER directives.

  • BARRIER directives are not permitted in the dynamic extent of DO, SECTIONS, SINGLE, MASTER, and CRITICAL directives.

  • MASTER directives are not permitted in the dynamic extent of DO, SECTIONS, and SINGLE directives.

  • ORDERED sections are not allowed in the dynamic extent of CRITICAL sections.

  • Any directive set that is legal when executed dynamically inside a PARALLEL region is also legal when executed outside a parallel region. When executed dynamically outside a user-specified parallel region, the directive is executed with respect to a team composed of only the master thread.

Examples

The following example shows nested PARALLEL regions:

  c$OMP PARALLEL DEFAULT(SHARED)
  c$OMP DO
        DO I =1, N
  c$OMP PARALLEL SHARED(I,N)
  c$OMP DO
          DO J =1, N
            CALL WORK(I,J)
          END DO
  c$OMP END   PARALLEL
        END DO
  c$OMP END PARALLEL

Note that the inner and outer DO directives bind to different PARALLEL regions.

The following example shows a variation of the preceding example:

  c$OMP PARALLEL DEFAULT(SHARED)
  c$OMP DO
          DO I =1, N
            CALL SOME_WORK(I,N)
          END DO
  c$OMP END PARALLEL
        ...
        SUBROUTINE SOME_WORK(I,N)
  c$OMP PARALLEL DEFAULT(SHARED)
  c$OMP DO
          DO J =1, N
            CALL WORK(I,J)
          END DO
  c$OMP END PARALLEL
        RETURN
        END


Compaq Fortran Parallel Compiler Directives (TU*X only)

Compaq Fortran supplies parallel directives that you can use for compatibility with older programs that were written for parallel execution.

This section describes the following parallel directives:

  • BARRIER

    Synchronizes all the threads in a team. This directive is the same as the OpenMP Fortran API BARRIER directive.

  • CHUNK

    Sets a default chunksize to adjust the number of iterations assigned to a thread.

  • COPYIN

    Copies the values of listed data objects from the master thread to PRIVATE data objects of the same name in slave threads.

  • CRITICAL SECTION

    Restricts access to a block of code to only one thread at a time.

  • INSTANCE

    Specifies the availability of named common blocks.

  • MP_SCHEDTYPE

    Sets a default run-time scheduling type.

  • PARALLEL

    Defines a parallel region. This directive is the same as the OpenMP Fortran API PARALLEL directive with the following exceptions:

    • No REDUCTION clause is permitted.

    • LOCAL is permitted as an alternative spelling for the PRIVATE clause and SHARE is permitted as an alternative spelling for the SHARED clause.

  • PARALLEL DO

    Defines a parallel region that contains a single DO directive. This directive is the same as the OpenMP Fortran API PARALLEL DO directive except that the keyword DOACROSS is permitted as an alternative spelling for PARALLEL DO.

  • PARALLEL SECTIONS

    Defines a parallel region that contains SECTIONS directives. This directive is the same as the OpenMP Fortran API PARALLEL SECTIONS directive.

  • PDO

    Specifies that the iterations of the immediately following DO loop must be executed in parallel.

  • PDONE

    Terminates the current parallel DO loop.

  • PSECTIONS

    Specifies a block of code to be divided among threads in a team (a worksharing area). This directive is the same as the OpenMP Fortran API SECTIONS directive with the following exceptions:

    • No REDUCTION clause or LASTPRIVATE clause is permitted.

    • LOCAL is permitted as an alternative spelling for the PRIVATE clause.

  • SINGLE PROCESS

    Specifies a block of code to be executed by only one thread in a team. This directive is the same as the OpenMP Fortran API SINGLE directive except that LOCAL is permitted as an alternative spelling for the PRIVATE clause.

  • TASKCOMMON

    Makes named common blocks private to a thread but global within the thread. This directive is the same as the OpenMP Fortran API THREADPRIVATE directive except that slashes (/ /) do not have to be used to delimit named common blocks.

The Compaq Fortran parallel directives can be grouped into the categories shown in the following table.

Categories of Compaq Fortran Parallel Directives (TU*X only)

Category | Description
Parallel region | Defines a parallel region: PARALLEL
Work-sharing | Divide the execution of the enclosed block of code among the members of the team that encounter it: PDO, PSECTIONS, and SINGLE PROCESS
Combined parallel work-sharing | Shortcut for denoting a parallel region that contains only one work-sharing construct: PARALLEL DO and PARALLEL SECTIONS
Synchronization | Provide various aspects of synchronization; for example, access to a block of code, or execution order of statements within a block of code: BARRIER and CRITICAL SECTION
Data Environment | Control the data environment during the execution of parallel constructs: COPYIN, INSTANCE, and TASKCOMMON
Execution Defaults | Specify a default chunk or schedule type: CHUNK and MP_SCHEDTYPE

For details on how to use these directives, see your user manual.

See Also: Parallel Directives for Tru64 UNIX Systems, OpenMP Fortran API Compiler Directives (TU*X only)


Equivalent Compiler Options

Some compiler directives and compiler options have the same effect (see the following table). However, compiler directives can be turned on and off throughout a program, while compiler options remain in effect for the whole compilation unless overridden by a compiler directive.

Compiler directive | Equivalent command-line compiler option
DECLARE | /warn:declarations or /4Yd
NODECLARE | /warn:nodeclarations or /4Nd
DEFINE symbol | /define:symbol or /Dsymbol
FIXEDFORMLINESIZE:option | /extend_source[:option] or /4Loption
FREEFORM | /free or /nofixed, or /4Yf
NOFREEFORM | /nofree, /fixed, or /4Nf
INTEGER:option | /integer_size:option or /4Ioption
OBJCOMMENT | /libdir
PACK:option | /alignment[:option] or /Zpoption
REAL:option | /real_size:option or /4Roption
STRICT | /warn:stderrors with /stand:f90 or /4Ys
NOSTRICT | /4Ns

Note that any of the compiler directive names above can be specified using the prefix !MS$; for example, !MS$NOSTRICT is allowed.

For rules on using compiler directives, see Syntax Rules for General Directives.


Scope and Association

Program entities are identified by names, labels, input/output unit numbers, operator symbols, or assignment symbols. For example, a variable, a derived type, or a subroutine is identified by its name.

Scope refers to the area in which a name is recognized. A scoping unit is the program or part of a program in which a name is defined or known. It can be any of the following:

  • An entire executable program
  • A single scoping unit
  • A single statement (or part of a statement)

The region of the program in which a name is known and accessible is referred to as the scope of that name. These different scopes allow the same name to be used for different things in different regions of the program.

Association is the language concept that allows different names to refer to the same entity in a particular region of a program.

This section contains information on the following topics:

  • Scope
  • Unambiguous generic procedure references
  • Resolving procedure references
  • Association


Scope

Program entities have the following kinds of scope (as shown in the table below):

  • Global

    Entities that are accessible throughout an executable program. The name of a global entity must be unique. It cannot be used to identify any other global entity in the same executable program.

  • Scoping unit (Local scope)

    Entities that are declared within a scoping unit. These entities are local to that scoping unit. The names of local entities are divided into classes (see the table below).

    A scoping unit is one of the following:

    • A derived-type definition
    • A procedure interface body (excluding any derived-type definitions and interface bodies contained within it)
    • A program unit or subprogram (excluding any derived-type definitions, interface bodies, and subprograms contained within it)

    A scoping unit that immediately surrounds another scoping unit is called the host scoping unit. Named entities within the host scoping unit are accessible to the nested scoping unit by host association. (For information about host association, see Use and Host Association.)

    Once an entity is declared in a scoping unit, its name can be used throughout that scoping unit. An entity declared in another scoping unit is a different entity even if it has the same name and properties.

    Within a scoping unit, a local entity name that is not generic must be unique within its class. However, the name of a local entity in one class can be used to identify a local entity of another class.

    Within a scoping unit, a generic name can be the same as any one of the procedure names in the interface block.

    A component name has the same scope as the derived type of which it is a component. It can appear only within a component designator of a structure of that type.

    For information on interactions between local and global names, see the table below.

  • Statement

    Entities that are accessible only within a statement or part of a statement; such entities cannot be referenced in subsequent statements.

    The name of a statement entity can also be the name of a global or local entity in the same scoping unit; in this case, the name is interpreted within the statement as that of the statement entity.

Scope of Program Entities

Entity | Scope |
Program units | Global |
Common blocks1 | Global |
External procedures | Global |
Intrinsic procedures | Global2 |
Module procedures | Local | Class I
Internal procedures | Local | Class I
Dummy procedures | Local | Class I
Statement functions | Local | Class I
Derived types | Local | Class I
Components of derived types | Local | Class II
Named constants | Local | Class I
Named constructs | Local | Class I
Namelist group names | Local | Class I
Generic identifiers | Local | Class I
Argument keywords in procedures | Local | Class III
Variables that can be referenced throughout a subprogram | Local | Class I
Variables that are dummy arguments in statement functions | Statement |
DO variables in an implied-do list3 of a DATA or FORALL statement, or an array constructor | Statement |
Intrinsic operators | Global |
Defined operators | Local |
Statement labels | Local |
External I/O unit numbers | Global |
Intrinsic assignment | Global4 |
Defined assignment | Local |
1 Names of common blocks can also be used to identify local entities. 2 If an intrinsic procedure is not used in a scoping unit, its name can be used as a local entity within that scoping unit. For example, if intrinsic function COS is not used in a program unit, COS can be used as a local variable there. 3 The DO variable in an implied-do list of an I/O list has local scope. 4 The scope of the assignment symbol (=) is global, but it can identify additional operations (see Defining Generic Assignment).

Scoping units can contain other scoping units. For example, the following shows six scoping units:

 MODULE MOD_1                    ! Scoping unit 1
    ...                          ! Scoping unit 1
 CONTAINS                        ! Scoping unit 1
   FUNCTION FIRST                ! Scoping unit 2
     TYPE NAME                   ! Scoping unit 3
     ...                         ! Scoping unit 3
     END TYPE NAME               ! Scoping unit 3
     ...                         ! Scoping unit 2
   CONTAINS                      ! Scoping unit 2
     SUBROUTINE SUB_B            ! Scoping unit 4
       TYPE PROCESS              ! Scoping unit 5
       ...                       ! Scoping unit 5
       END TYPE PROCESS          ! Scoping unit 5
       INTERFACE                 ! Scoping unit 5
         SUBROUTINE SUB_A        ! Scoping unit 6
         ...                     ! Scoping unit 6
         END SUBROUTINE SUB_A    ! Scoping unit 6
       END INTERFACE             ! Scoping unit 5
     END SUBROUTINE SUB_B        ! Scoping unit 4
   END FUNCTION   FIRST          ! Scoping unit 2
 END MODULE                      ! Scoping unit 1

For More Information:

  • See Derived data types.
  • On user-defined generic procedures, see Defining Generic Names for Procedures.
  • See Intrinsic procedures.
  • On procedures and subprograms, see Program Units and Procedures.
  • See Use and host association.
  • On defined operations, see Defining Generic Operators.
  • On defined assignment, see Defining Generic Assignment.
  • On how the PRIVATE attribute can affect accessibility of entities, see PRIVATE and PUBLIC Attributes and Statements.


Unambiguous Generic Procedure References

When a generic procedure reference is made, a specific procedure is invoked. If the following rules are used, the generic reference will be unambiguous:

  • Within a scoping unit, two procedures that have the same generic name must both be subroutines (or both be functions). One of the procedures must have a nonoptional dummy argument that is one of the following:

    • Not present by position or argument keyword in the other argument list
    • Is present, but has different type and kind parameters, or rank

  • Within a scoping unit, two procedures that have the same generic operator must both have the same number of arguments or both define assignment. One of the procedures must have a dummy argument that corresponds by position in the argument list to a dummy argument of the other procedure that has a different type and kind parameters, or rank.

When an interface block extends an intrinsic procedure, operator, or assignment, the rules apply as if the intrinsic consists of a collection of specific procedures, one for each allowed set of arguments.

When a generic procedure is accessed from a module, the rules apply to all the specific versions, even if some of them are inaccessible by their specific names.

For More Information:

For details on generic procedure names, see Defining Generic Names for Procedures.


Resolving Procedure References

The procedure name in a procedure reference is either established to be generic or specific, or is not established. The rules for resolving a procedure reference differ depending on whether the procedure is established and how it is established.

This section discusses the following topics:

  • References to Generic Names
  • References to Specific Names
  • References to Nonestablished Names


References to Generic Names

Within a scoping unit, a procedure name is established to be generic if any of the following is true:

  • The scoping unit contains an interface block with that procedure name.

  • The procedure name matches the name of a generic intrinsic procedure, and it is specified with the INTRINSIC attribute in that scoping unit.

  • The procedure name is established to be generic in a module, and the scoping unit contains a USE statement making that procedure name accessible.

  • The scoping unit contains no declarations for that procedure name, but the procedure name is established to be generic in a host scoping unit.

To resolve a reference to a procedure name established to be generic, the following rules are used in the order shown:

  1. If an interface block with that procedure name appears in one of the following, the reference is to the specific procedure providing that interface:

    1. The scoping unit that contains the reference
    2. A module made accessible by a USE statement in the scoping unit

    The reference must be consistent with one of the specific interfaces of the interface block.

  2. If the procedure name is specified with the INTRINSIC attribute in one of the following, the reference is to that intrinsic procedure:

    1. The same scoping unit
    2. A module made accessible by a USE statement in the scoping unit

    The reference must be consistent with the interface of that intrinsic procedure.

  3. If the following is true, the reference is resolved by applying rules 1 and 2 to the host scoping unit:

    1. The procedure name is established to be generic in the host scoping unit
    2. There is agreement between the scoping unit and the host scoping unit as to whether the procedure is a function or subroutine name.

  4. If none of the preceding rules apply, the reference must be to the generic intrinsic procedure with that name. The reference must be consistent with the interface of that intrinsic procedure.

Examples

The following example shows how a module can define three separate procedures, and a main program give them a generic name DUP through an interface block. Although the main program calls all three by the generic name, there is no ambiguity since the arguments are of different data types, and DUP is a function rather than a subroutine. The module UN_MOD must give each procedure a different name.

 MODULE UN_MOD
 !

 CONTAINS
    subroutine dup1(x,y)
    real x,y
    print *, ' Real arguments', x, y
    end subroutine dup1

    subroutine dup2(m,n)
    integer m,n
    print *, ' Integer arguments', m, n
    end subroutine dup2

    character function dup3 (z)
    character(len=2) z
    dup3 = 'String argument '// z
    end function dup3

 END MODULE

 program unclear
 !
 ! demonstrates how to use generic procedure references

 USE UN_MOD
 INTERFACE DUP
    MODULE PROCEDURE dup1, dup2, dup3
 END INTERFACE

 real a,b
 integer c,d
 character (len=2) state

 a = 1.5
 b = 2.32
 c = 5
 d = 47
 state = 'WA'

 call dup(a,b)
 call dup(c,d)
 print *, dup(state)       !actual output is 'S'only
 END

Note that the function DUP3 only prints one character, since module UN_MOD specifies no length parameter for the function result.

If the dummy arguments x and y for DUP were declared as integers instead of reals, then any calls to DUP would be ambiguous. If this is the case, a compile-time error results.

The subroutine definitions, DUP1, DUP2, and DUP3, must have different names. The generic name is specified in the first line of the interface block, and in the example is DUP.


References to Specific Names

In a scoping unit, a procedure name is established to be specific if it is not established to be generic and any of the following is true:

  • The scoping unit contains an interface body with that procedure name.

  • The scoping unit contains an internal procedure, module procedure, or statement function with that procedure name.

  • The procedure name is the same as the name of a generic intrinsic procedure, and it is specified with the INTRINSIC attribute in that scoping unit.

  • The procedure name is specified with the EXTERNAL attribute in that scoping unit.

  • The procedure name is established to be specific in a module, and the scoping unit contains a USE statement making that procedure name accessible.

  • The scoping unit contains no declarations for that procedure name, but the procedure name is established to be specific in a host scoping unit.

To resolve a reference to a procedure name established to be specific, the following rules are used in the order shown:

  1. If either of the following is true, the dummy argument is a dummy procedure and the reference is to that dummy procedure:

    1. The scoping unit is a subprogram, and it contains an interface body with that procedure name.

    2. The procedure name has been declared EXTERNAL, and the procedure name is a dummy argument of that subprogram.

    The procedure invoked by the reference is the one supplied as the corresponding actual argument.

  2. If the scoping unit contains an interface body or the procedure name has been declared EXTERNAL, and Rule 1 does not apply, the reference is to an external procedure with that name.

  3. If the scoping unit contains an internal procedure or statement function with that procedure name, the reference is to that entity.

  4. If the procedure name has been declared INTRINSIC in the scoping unit, the reference is to the intrinsic procedure with that name.

  5. If the scoping unit contains a USE statement that makes the name of a module procedure accessible, the reference is to that procedure. (The USE statement allows renaming, so the name referenced may differ from the name of the module procedure.)

  6. If none of the preceding rules apply, the reference is resolved by applying these rules to the host scoping unit.


References to Nonestablished Names

In a scoping unit, a procedure name is not established if it is not determined to be generic or specific.

To resolve a reference to a procedure name that is not established, the following rules are used in the order shown:

  1. If both of the following are true, the dummy argument is a dummy procedure and the reference is to that dummy procedure:

    1. The scoping unit is a subprogram.
    2. The procedure name is a dummy argument of that subprogram.

    The procedure invoked by the reference is the one supplied as the corresponding actual argument.

  2. If both of the following are true, the procedure is an intrinsic procedure and the reference is to that intrinsic procedure:

    1. The procedure name matches the name of an intrinsic procedure.
    2. There is agreement between the intrinsic procedure definition and the reference of the name as a function or subroutine.

  3. If neither of the preceding rules apply, the reference is to an external procedure with that name.

For More Information:

  • See Function references.
  • See the USE statement.
  • On subroutine references, see the CALL Statement.
  • On generic procedure names, see Defining Generic Names for Procedures.


Association

Association allows different program units to access the same value through different names. Entities are associated when each is associated with the same storage location.

There are three kinds of association:

  • Name association
  • Pointer association
  • Storage association

The following example shows name, pointer, and storage association between an external program unit and an external procedure.

Example of Name, Pointer, and Storage Association

! Scoping Unit 1: An external program unit

REAL A, B(4)
REAL, POINTER :: M(:)
REAL, TARGET :: N(12)
COMMON /COM/...
EQUIVALENCE (A, B(1))         ! Storage association between A and B(1)
M => N                        ! Pointer association
CALL P (actual-arg,...)
...

! Scoping Unit 2: An external procedure
SUBROUTINE P (dummy-arg,...)  ! Name and storage association between
                              !    these arguments and the calling
                              !    routine's arguments in scoping unit 1

  COMMON /COM/...             ! Storage association with common block COM
                              !    in scoping unit 1
  REAL Y
  CALL Q (actual-arg,...)
  CONTAINS
    SUBROUTINE Q (dummy-arg,...) ! Name and storage association between
                                 !   these arguments and the calling
                                 !   routine's arguments in host procedure
                                 !   P (subprogram Q has host association
                                 !   with procedure P)
      Y = 2.0*(Y-1.0)         ! Name association with Y in host procedure P
    ...


Name Association

Name association allows an entity to be accessed from different scoping units by the same name or by different names. There are three types of name association: argument, use, and host.


Argument Association

Arguments are the values passed to and from functions and subroutines through calling program argument lists.

Execution of a procedure reference establishes argument association between an actual argument and its corresponding dummy argument. The name of a dummy argument can be different from the name of its associated actual argument (if any).

When the procedure completes execution, the argument association is terminated.

For More Information:

For more details, see also Argument Association.


Use and Host Association

Use association allows the entities in a module to be accessible to other scoping units. The mechanism for use association is the USE statement. The USE statement provides access to all public entities in the module, unless ONLY is specified. In this case, only the entities named in the ONLY list can be accessed.

Host association allows the entities in a host scoping unit to be accessible to an internal procedure, derived-type definition, or module procedure contained within the host. The accessed entities are known by the same name and have the same attributes as in the host. Entities that are local to a procedure are not accessible to its host.

Use or host association remains in effect throughout the execution of the executable program.

If an entity that is accessed by use association has the same nongeneric name as a host entity, the host entity is inaccessible. A name that appears in the scoping unit as an external name in an EXTERNAL statement is a global name, and any entity of the host that has this as its nongeneric name is inaccessible.

An interface body does not access named entities by host association, but it can access entities by use association.

If a procedure gains access to a pointer by host association, the association of the pointer with a target that is current at the time the procedure is invoked remains current within the procedure. This pointer association can be changed within the procedure. After execution of the procedure, the pointer association remains current, unless the execution caused the target to become undefined. If this occurs, the host associated pointer becomes undefined.

Note: Implicit declarations can cause problems for host association. It is recommended that you use IMPLICIT NONE in both the host and the contained procedure, and that you explicitly declare all entities.

When all entities are explicitly declared, local declarations override host declarations, and host declarations that are not overridden are available in the contained procedure.

Examples

The following example shows host and use association:

 MODULE SHARE_DATA
   REAL Y, Z
 END MODULE

 PROGRAM DEMO
   USE SHARE_DATA         ! All entities in SHARE_DATA are available
   REAL B, Q              !   through use association.
   ...
   CALL CONS (Y)
 CONTAINS
   SUBROUTINE CONS (Y)    ! Y is a local entity (dummy argument).
     REAL C, Y
     ...
     Y = B + C + Q + Z    ! B and Q are available through host association.
     ...                  !   C is a local entity, explicitly declared.  Z
   END SUBROUTINE CONS    !   is available through use association.
 END PROGRAM DEMO

The following example shows how a host and an internal procedure can use host-associated entities:

 program INTERNAL
 ! shows use of internal subroutine and CONTAINS statement
    real a,b,c
    call find
    print *, c
 contains
    subroutine find
      read *, a,b
      c = sqrt(a**2 + b**2)
    end subroutine find
 end

In this example, the variables a, b, and c are available to the internal subroutine find through host association. They do not have to be passed as arguments to the internal procedure. In fact, if they are, they become local variables to the subroutine and hide the variables declared in the host program.

Conversely, the host program knows the value of c, when it returns from the internal subroutine that has defined c.

For More Information:

  • See the USE statement.
  • On entities with local scope, see Scope.


Pointer Association

A pointer can be associated with a target. At different times during the execution of a program, a pointer can be undefined, associated with different targets, or be disassociated. The initial association status of a pointer is undefined. A pointer can become associated by the following:

  • By pointer assignment (pointer => target)

    The target must be associated, or specified with the TARGET attribute. If the target is allocatable, it must be currently allocated.

  • By allocation (successful execution of an ALLOCATE statement)

    The ALLOCATE statement must reference the pointer.

A pointer becomes disassociated if any of the following occur:

  • The pointer is nullified by a NULLIFY statement.
  • The pointer is deallocated by a DEALLOCATE statement.
  • The pointer is assigned a disassociated pointer (or the NULL intrinsic function).

When a pointer is associated with a target, the definition status of the pointer is defined or undefined, depending on the definition status of the target. A target is undefined in the following cases:

  • If it was never allocated
  • If it is not deallocated through the pointer
  • If a RETURN or END statement causes it to become undefined

If a pointer is associated with a definable target, the definition status of the pointer can be defined or undefined, according to the rules for a variable.

If the association status of a pointer is disassociated or undefined, the pointer must not be referenced or deallocated.

Whatever its association status, a pointer can always be nullified, allocated, or associated with a target. When a pointer is nullified, it is disassociated. When a pointer is allocated, it becomes associated, but is undefined. When a pointer is associated with a target, its association and definition status are determined by its target.

For More Information:

  • See Pointer assignments.
  • See the NULL intrinsic function.
  • On the ALLOCATE and DEALLOCATE statements, see Dynamic Allocation.
  • On the NULLIFY statement, see Dynamic Allocation


Storage Association

Storage association is the association of two or more data objects. It occurs when two or more storage sequences share (or are aligned with) one or more storage units. Storage sequences are used to describe relationships among variables, common blocks, and result variables.

This section discusses the following topics:

  • Storage Units and Storage Sequence
  • Array Association


Storage Units and Storage Sequence

A storage unit is a fixed unit of physical memory allocated to certain data. A storage sequence is a sequence of storage units. The size of a storage sequence is the number of storage units in the storage sequence. A storage unit can be numeric, character, or unspecified.

A nonpointer scalar of type default real, integer, or logical occupies one numeric storage unit. A nonpointer scalar of type double precision real or default complex occupies two contiguous numeric storage units. In Compaq Fortran, one numeric storage unit corresponds to 4 bytes of memory.

A nonpointer scalar of type default character with character length 1 occupies one character storage unit. A nonpointer scalar of type default character with character length len occupies len contiguous character storage units. In Compaq Fortran, one character storage unit corresponds to 1 byte of memory.

A nonpointer scalar of nondefault data type occupies a single unspecified storage unit. The number of bytes corresponding to the unspecified storage unit differs depending on the data type.

The following table lists the storage requirements (in bytes) for the intrinsic data types:

Data Type Storage Requirements

Data Type | Storage Requirements (in bytes)
BYTE | 1
LOGICAL | 2, 4, or 8 1
LOGICAL(1) | 1
LOGICAL(2) | 2
LOGICAL(4) | 4
LOGICAL(8) | 8
INTEGER | 2, 4, or 8 1
INTEGER(1) | 1
INTEGER(2) | 2
INTEGER(4) | 4
INTEGER(8) | 8
REAL | 4, 8, or 16 2
REAL(4) | 4
DOUBLE PRECISION | 8
REAL(8) | 8
REAL(16) 3 | 16
COMPLEX | 8, 16, or 32 2
COMPLEX(4) | 8
DOUBLE COMPLEX | 16
COMPLEX(8) | 16
COMPLEX(16) 3 | 32
CHARACTER | 1
CHARACTER*len | len 4
CHARACTER*(*) | assumed-length 5
1 Depending on default integer, LOGICAL and INTEGER can have 2, 4, or 8 bytes. The default allocation is four bytes. 2 Depending on default real, REAL can have 4, 8, or 16 bytes and COMPLEX can have 8, 16, or 32 bytes. The default allocations are four bytes for REAL and eight bytes for COMPLEX. 3 VMS, U*X 4 The value of len is the number of characters specified. The largest valid value is 2147483647 (2**31-1) for Tru64 UNIX, Linux, and Windows systems; 65535 for OpenVMS systems. Negative values are treated as zero. 5 The assumed-length format *(*) applies to dummy arguments, PARAMETER statements, or character functions, and indicates that the length of the actual argument or function is used. (See Assumed-Length Character Arguments and your programmer's guide.)

A nonpointer scalar of sequence derived type occupies a sequence of storage sequences corresponding to the components of the structure, in the order they occur in the derived-type definition. (A sequence derived type has a SEQUENCE statement.)

A pointer occupies a single unspecified storage unit that is different from that of any nonpointer object and is different for each combination of type, type parameters, and rank.

The definition status and value of a data object affects the definition status and value of any storage-associated entity.

When two objects occupy the same storage sequence, they are totally storage-associated. When two objects occupy parts of the same storage sequence, they are partially associated. An EQUIVALENCE statement, a COMMON statement, or an ENTRY statement can cause total or partial storage association of storage sequences.

For More Information:

  • See the COMMON statement.
  • See the ENTRY statement.
  • See the EQUIVALENCE statement.
  • On the hardware representations of data types, see your programmer's guide.


Array Association

A nonpointer array occupies a sequence of contiguous storage sequences, one for each array element, in array element order.

Two or more arrays are associated when each one is associated with the same storage location. They are partially associated when part of the storage associated with one array is the same as part or all of the storage associated with another array.

If arrays with different data types are associated (or partially associated) with the same storage location, and the value of one array is defined (for example, by assignment), the value of the other array becomes undefined. This happens because an element of an array is considered defined only if the storage associated with it contains data of the same type as the array name.

An array element, array section, or whole array is defined by a DATA statement before program execution. (The array properties must be declared in a previous specification statement.) During program execution, array elements and sections are defined by an assignment or input statement, and entire arrays are defined by input statements.

For More Information:

  • See Arrays.
  • See the DATA statement.
  • On array element order, see Array Elements.


Obsolescent and Deleted Language Features

Fortran 90 identified some FORTRAN 77 features to be obsolescent. Fortran 95 deletes some of these features, and identifies a few more language features to be obsolescent. Features considered obsolescent may be removed from future revisions of the Fortran Standard.

You can specify the /stand compiler option to have these features flagged.

Note: Compaq Fortran fully supports features deleted from Fortran 95.

This section discusses the following topics:

  • Deleted Language Features in Fortran 95
  • Obsolescent Language Features in Fortran 95
  • Obsolescent Language Features in Fortran 90


Deleted Language Features in Fortran 95

Some language features, considered redundant in FORTRAN 77, are not included in Fortran 95. However, they are still fully supported by Compaq Fortran:

  • ASSIGN and assigned GO TO statements
  • Assigned FORMAT specifier
  • Branching to an END IF statement from outside its IF block
  • H edit descriptor
  • PAUSE statement
  • Real and double precision DO control variables and DO loop control expressions

Compaq Fortran flags these features if you specify the /stand compiler option.

For suggested methods to achieve the functionality of these features, see Obsolescent Language Features in Fortran 90.


Obsolescent Language Features in Fortran 95

Some language features, considered redundant in Fortran 90 are identified as obsolescent in Fortran 95.

Compaq Fortran flags these features if you specify the /stand compiler option.

Other methods are suggested to achieve the functionality of the following obsolescent features:

  • Alternate returns

    To replace this functionality, it is recommended that you use an integer variable to return a value to the calling program, and let the calling program use a CASE construct to test the value and perform operations.

  • Arithmetic IF

    To replace this functionality, it is recommended that you use an IF statement or construct.

  • Assumed-length character functions

    To replace this functionality, it is recommended that you use one of the following:

    • An automatic character-length function, where the length of the function result is declared in a specification expression
    • A subroutine whose arguments correspond to the function result and the function arguments

    Dummy arguments of a function can still have assumed character length; this feature is not obsolescent.

  • CHARACTER*(*) form of CHARACTER declaration

    To replace this functionality, it is recommended that you use the Fortran 90 forms of specifying a length selector in CHARACTER declarations (see Declaration Statements for Character Types).

  • Computed GO TO statement

    To replace this functionality, it is recommended that you use a CASE construct.

  • DATA statements among executable statements

    This functionality has been included since FORTRAN 66, but is considered to be a potential source of errors.

  • Fixed source form

    Newer methods of entering data have made this source form obsolescent and error-prone.

    The recommended method for coding is to use free source form.

  • Shared DO termination and termination on a statement other than END DO or CONTINUE

    To replace this functionality, it is recommended that you use an END DO statement (see Forms for DO Constructs) or a CONTINUE statement.

  • Statement functions

    To replace this functionality, it is recommended that you use an internal function.


Obsolescent Language Features in Fortran 90

Fortran 90 did not delete any of the features in FORTRAN 77, but some FORTRAN 77 features were identified as obsolescent.

Compaq Fortran flags these features if you specify the /stand compiler option.

Other methods are suggested to achieve the functionality of the following obsolescent features:

  • Alternate return (labels in an argument list)

    To replace this functionality, it is recommended that you use an integer variable to return a value to the calling program, and let the calling program test the value and perform operations, using a computed GO TO statement or CASE construct.

  • Arithmetic IF

    To replace this functionality, it is recommended that you use an IF statement or construct.

  • ASSIGN and assigned GO TO statements

    These statements are usually used to simulate internal procedures, which can now be coded directly.

  • Assigned FORMAT specifier (label of a FORMAT statement assigned to an integer variable)

    To replace this functionality, it is recommended that you use character expressions to define format specifications.

  • Branching to an END IF statement from outside its IF block

    To replace this functionality, it is recommended that you branch to the statement following the END IF statement (see IF Construct).

  • H edit descriptor

    To replace this functionality, it is recommended that you use the character constant edit descriptor (see Character Constant Editing).

  • PAUSE statement

    To replace this functionality, it is recommended that you use a READ statement that awaits input data.

  • Real and double precision DO control variables and DO loop control expressions

    To replace this functionality, it is recommended that you use integer DO variables and expressions (see DO Constructs).

  • Shared DO termination and termination on a statement other than END DO or CONTINUE

    To replace this functionality, it is recommended that you use an END DO statement (see Forms for DO Constructs) or a CONTINUE statement.


Additional Language Features

To facilitate compatibility with older versions of Fortran, Compaq Fortran provides the following additional language features:

  • The DEFINE FILE statement
  • The ENCODE and DECODE statements
  • The FIND statement
  • FORTRAN-66 Interpretation of the EXTERNAL Statement
  • An alternative syntax for the PARAMETER statement
  • The VIRTUAL statement
  • An alternative syntax for octal and hexadecimal constants
  • An alternative syntax for a record specifier
  • An alternate syntax for the DELETE statement
  • An alternative form for namelist external records
  • The Compaq Fortran POINTER statement
  • Record structures

These language features are particularly useful in porting older Fortran programs to Fortran 95/90. However, you should avoid using them in new programs on these systems, and in new programs for which portability to other Fortran 95/90 implementations is important.


FORTRAN-66 Interpretation of the EXTERNAL Statement

If you specify compiler option /f66, the EXTERNAL statement is interpreted in a way that was specified by the FORTRAN IV (FORTRAN-66) standard. This interpretation became incompatible with FORTRAN 77 and later revisions of the Fortran standard.

The FORTRAN-66 interpretation of the EXTERNAL statement combines the functionality of the INTRINSIC statement with that of the EXTERNAL statement.

This lets you use subprograms as arguments to other subprograms. The subprograms to be used as arguments can be either user-supplied functions or Fortran 95/90 library functions.

The FORTRAN-66 EXTERNAL statement takes the following form:

EXTERNAL [*]v [, [*]v] ...

*
Specifies that a user-supplied function is to be used instead of a Fortran 95/90 library function having the same name.

v
Is the name of a subprogram or the name of a dummy argument associated with the name of a subprogram.

Rules and Behavior

The FORTRAN-66 EXTERNAL statement declares that each name in its list is an external function name. Such a name can then be used as an actual argument to a subprogram, which then can use the corresponding dummy argument in a function reference or CALL statement.

However, when used as an argument, a complete function reference represents a value, not a subprogram name; for example, SQRT(B) in CALL SUBR(A, SQRT(B), C). It is not, therefore, defined in an EXTERNAL statement (as would be the incomplete reference SQRT).

Examples

The following example demonstrates the FORTRAN-66 EXTERNAL statement:

Main Program                        Subprograms

EXTERNAL SIN, COS, *TAN, SINDEG     SUBROUTINE TRIG(X,F,Y)
   .                                Y = F(X)
   .                                RETURN
   .                                END
CALL TRIG(ANGLE, SIN, SINE)
   .
   .                                FUNCTION TAN(X)
   .                                TAN = SIN(X)/COS(X)
CALL TRIG(ANGLE, COS, COSINE)       RETURN
   .                                END
   .
   .
CALL TRIG(ANGLE, TAN, TANGNT)       FUNCTION SINDEG(X)
   .                                SINDEG = SIN(X*3.1459/180)
   .                                RETURN
   .                                END
CALL TRIG(ANGLED, SINDEG, SINE)

The CALL statements pass the name of a function to the subroutine TRIG. The function reference F(X) subsequently invokes the function in the second statement of TRIG. Depending on which CALL statement invoked TRIG, the second statement is equivalent to one of the following:

Y = SIN(X)
Y = COS(X)
Y = TAN(X)
Y = SINDEG(X)

The functions SIN and COS are examples of trigonometric functions supplied in the Fortran 95/90 library. The function TAN is also supplied in the library, but the asterisk (*) in the EXTERNAL statement specifies that the user-supplied function be used, instead of the library function. The function SINDEG is also a user-supplied function. Because no library function has the same name, no asterisk is required.


Alternative Syntax for the PARAMETER Statement

The PARAMETER statement discussed here is similar to the one discussed in PARAMETER; they both assign a name to a constant. However, this PARAMETER statement differs from the other one in the following ways:

  • Its list is not bounded with parentheses.

  • The form of the constant, rather than implicit or explicit typing of the name, determines the data type of the variable.

This PARAMETER statement takes the following form:

PARAMETER c = expr [, c = expr] ...

c
Is the name of the constant.

expr
Is an initialization expression. It can be of any data type.

Rules and Behavior

Each name c becomes a constant and is defined as the value of expression expr. Once a name is defined as a constant, it can appear in any position in which a constant is allowed. The effect is the same as if the constant were written there instead of the name.

The name of a constant cannot appear as part of another constant, except as the real or imaginary part of a complex constant. For example:

 PARAMETER I=3
 PARAMETER M=I.25            ! Not allowed
 PARAMETER N=(1.703, I)      ! Allowed

The name used in the PARAMETER statement identifies only the name's corresponding constant in that program unit. Such a name can be defined only once in PARAMETER statements within the same program unit.

The name of a constant assumes the data type of its corresponding constant expression. The data type of a parameter constant cannot be specified in a type declaration statement. Nor does the initial letter of the constant's name implicitly affect its data type.

Examples

The following are valid examples of this form of the PARAMETER statement:

  PARAMETER PI=3.1415927, DPI=3.141592653589793238D0
  PARAMETER PIOV2=PI/2, DPIOV2=DPI/2
  PARAMETER FLAG=.TRUE., LONGNAME='A STRING OF 25 CHARACTERS'

For More Information:

For details on compile-time constant expressions, see PARAMETER.


Alternative Syntax for Octal and Hexadecimal Constants

In Compaq Fortran, you can use an alternative syntax for octal and hexadecimal constants. The following table shows this alternative syntax and equivalents:

Constant | Alternative Syntax | Equivalent
Octal | '0..7'O | O'0..7'
Hexadecimal | '0..F'X | Z'0..F'

You can use a quotation mark (") in place of an apostrophe in all the above syntax forms.

For More Information:

  • See Octal constants.
  • See Hexadecimal constants.


Alternative Syntax for a Record Specifier

In Compaq Fortran, you can specify the following form for a record specifier in an I/O control list:

'r

r
Is a numeric expression with a value that represents the position of the record to be accessed using direct access I/O.

The value must be greater than or equal to 1, and less than or equal to the maximum number of records allowed in the file. If necessary, a record number is converted to integer data type before being used.

If this nonkeyword form is used in an I/O control list, it must immediately follow the nonkeyword form of the io-unit specifier.


Alternative Syntax for the DELETE Statement

In Compaq Fortran, you can specify the following form of the DELETE statement when deleting records from a relative file:

DELETE (io-unit'r [, ERR=label] [, IOSTAT=i-var])

io-unit
Is the number of the logical unit containing the record to be deleted.

r
Is the positional number of the record to be deleted.

label
Is the label of an executable statement that receives control if an error condition occurs.

i-var
Is a scalar integer variable that is defined as a positive integer if an error occurs and zero if no error occurs.

This form deletes the direct access record specified by r.

For More Information:

See also the DELETE statement.


Alternative Form for Namelist External Records

In Compaq Fortran, you can use the following form for an external record:

$group-name object = value [object = value] ...$[END]

group-name
Is the name of the group containing the objects to be given values. The name must have been previously defined in a NAMELIST statement in the scoping unit.

object
Is the name (or subobject designator) of an entity defined in the NAMELIST declaration of the group name. The object name must not contain embedded blanks, but it can be preceded or followed by blanks.

value
Is a null value, a constant (or list of constants), a repetition of constants in the form r*c, or a repetition of null values in the form r*.

If more than one object=value or more than one value is specified, they must be separated by value separators.

A value separator is any number of blanks, or a comma or slash, preceded or followed by any number of blanks.

For More Information:

  • See the NAMELIST statement.
  • On namelist input, see Rules for Namelist Sequential READ Statements.
  • On namelist output, see Rules for Namelist Sequential WRITE Statements.


Record Structures

The record structure was defined in earlier versions of Compaq Fortran as a language extension. It is still supported in Visual Fortran, although its functionality has been replaced by standard Fortran 95/90 derived types. Record structures in existing code can be easily converted to Fortran 95/90 derived type structures for portability, but can also be left in their old form. In most cases, a Compaq Fortran record and a Fortran 95/90 derived type can be used interchangeably.

Compaq Fortran record structures are similar to Fortran 95/90 derived types.

A record structure is an aggregate entity containing one or more elements. (Record elements are also called fields or components.) You can use records when you need to declare and operate on multi-field data structures in your programs.

Creating a record is a two-step process:

  1. You must define the form of the record with a multistatement structure declaration.

  2. You must use a RECORD statement to declare the record as an entity with a name. (More than one RECORD statement can refer to a given structure.)

Examples

Compaq Fortran record structures, using only intrinsic types, easily convert to Fortran 95/90 derived types. The conversion can be as simple as replacing the keyword STRUCTURE with TYPE and removing slash ( / ) marks. The following shows an example conversion:

Record Structure Fortran 95/90 Derived-Type
STRUCTURE /employee_name/
  CHARACTER*25  last_name
  CHARACTER*15  first_name
END STRUCTURE
STRUCTURE /employee_addr/
  CHARACTER*20  street_name
  INTEGER(2)    street_number
  INTEGER(2)    apt_number
  CHARACTER*20  city
  CHARACTER*2   state
  INTEGER(4)    zip
END STRUCTURE

TYPE employee_name
  CHARACTER*25  last_name
  CHARACTER*15  first_name
END TYPE
TYPE employee_addr
  CHARACTER*20  street_name
  INTEGER(2)    street_number
  INTEGER(2)    apt_number
  CHARACTER*20  city
  CHARACTER*2   state
  INTEGER(4)    zip
END TYPE
The record structures can be used as subordinate record variables within another record, such as the employee_data record. The equivalent Fortran 90 derived type would use the derived-type objects as components in a similar manner, as shown below:

Record Structure Fortran 95/90 Derived-Type
STRUCTURE /employee_data/
  RECORD  /employee_name/ name
  RECORD  /employee_addr/ addr
  INTEGER(4) telephone
  INTEGER(2) date_of_birth
  INTEGER(2) date_of_hire
  INTEGER(2) social_security(3)
  LOGICAL(2) married
  INTEGER(2) dependents
END STRUCTURE

TYPE employee_data
  TYPE (employee_name) name
  TYPE (employee_addr) addr
  INTEGER(4) telephone
  INTEGER(2) date_of_birth
  INTEGER(2) date_of_hire
  INTEGER(2) social_security(3)
  LOGICAL(2) married
  INTEGER(2) dependents
END TYPE
The following topics are also related to record structures:

  • Structure Declarations
  • RECORD Statement
  • References to Record Fields
  • Aggregate Assignment


Structure Declarations

A structure declaration defines the field names, types of data within fields, and order and alignment of fields within a record. Fields and structures can be initialized, but records cannot be initialized. For more information, see STRUCTURE in the A to Z Reference.

The following are related topics:

  • Type Declarations
  • Substructure Declarations
  • Union Declarations


Type Declarations

The syntax of a type declaration within a record structure is identical to that of a normal Fortran type statement.

The following rules and behavior apply to type declarations in record structures:

  • %FILL can be specified in place of a field name to leave space in a record for purposes such as alignment. This creates an unnamed field.

    %FILL can have an array specification; for example:

      INTEGER %FILL (2,2)

    Unnamed fields cannot be initialized. For example, the following statement is invalid and generates an error message:

      INTEGER %FILL /1980/
  • Initial values can be supplied in field declaration statements. Unnamed fields cannot be initialized; they are always undefined.

  • Field names must always be given explicit data types. The IMPLICIT statement does not affect field declarations.

  • Any required array dimensions must be specified in the field declaration statements. DIMENSION statements cannot be used to define field names.

  • Adjustable or assumed sized arrays and assumed-length CHARACTER declarations are not allowed in field declarations.


Substructure Declarations

A field within a structure can itself be a structured item composed of other fields, other structures, or both. You can declare a substructure in two ways:

  • By nesting structure declarations within other structure or union declarations (with the limitation that you cannot refer to a structure inside itself at any level of nesting).

    One or more field names must be defined in the STRUCTURE statement for the substructure, because all fields in a structure must be named. In this case, the substructure is being used as a field within a structure or union.

    Field names within the same declaration nesting level must be unique, but an inner structure declaration can include field names used in an outer structure declaration without conflict.

  • By using a RECORD statement that specifies another previously defined record structure, thereby including it in the structure being declared.

See the example in STRUCTURE for a sample structure declaration containing both a nested structure declaration (TIME) and an included structure (DATE).


References to Record Fields

References to record fields must correspond to the kind of field being referenced. Aggregate field references refer to composite structures (and substructures). Scalar field references refer to singular data items, such as variables.

An operation on a record can involve one or more fields.

Record field references take one of the following forms:

Aggregate Field Reference:

record-name [.aggregate-field-name] ...

Scalar Field Reference:

record-name [.aggregate-field-name] ... .scalar-field-name

record-name
Is the name used in a RECORD statement to identify a record.

aggregate-field-name
Is the name of a field that is a substructure (a record or a nested structure declaration) within the record structure identified by the record name.

scalar-field-name
Is the name of a data item (having a data type) defined within a structure declaration.

Rules and Behavior

Records and record fields cannot be used in EQUIVALENCE statements. However, you can make fields of record structures equivalent to themselves by using the UNION and MAP statements in a structure declaration.

Records and record fields cannot be used in DATA statements, but individual fields can be initialized in the STRUCTURE definition.

An automatic array cannot be a record field.

A scalar field reference consists of the name of a record (as specified in a RECORD statement) and zero or more levels of aggregate field names followed by the name of a scalar field. A scalar field reference refers to a single data item (having a data type) and can be treated like a normal reference to a Fortran variable or array element.

You can use scalar field references in statement functions and in executable statements. However, they cannot be used in COMMON, SAVE, NAMELIST, or EQUIVALENCE statements, or as the control variable in an indexed DO-loop.

Type conversion rules for scalar field references are the same as those for variables and array elements.

An aggregate field reference consists of the name of a record (as specified in a RECORD statement) and zero or more levels of aggregate field names.

You can only assign an aggregate field to another aggregate field (record = record) if the records have the same structure. Compaq Fortran supports no other operations (such as arithmetic or comparison) on aggregate fields.

Compaq Fortran requires qualification on all levels. While some languages allow omission of aggregate field names when there is no ambiguity as to which field is intended, Compaq Fortran requires all aggregate field names to be included in references.

You can use aggregate field references in unformatted I/O statements; one I/O record is written no matter how many aggregate and array name references appear in the I/O list. You cannot use aggregate field references in formatted, namelist, and list-directed I/O statements.

You can use aggregate field references as actual arguments and record dummy arguments. The declaration of the dummy record in the subprogram must match the form of the aggregate field reference passed by the calling program unit; each structure must have the same number and types of fields in the same order. The order of map fields within a union declaration is irrelevant.

Records are passed by reference. Aggregate field references are treated like normal variables. You can use adjustable arrays in RECORD statements that are used as dummy arguments.

Note: Because periods are used in record references to separate fields, you should not use relational operators (.EQ., .XOR.), logical constants (.TRUE., .FALSE.), and logical expressions (.AND., .NOT., .OR.) as field names in structure declarations.

Examples

The following examples show record and field references. Consider the following structure declarations:

Structure DATE:

 STRUCTURE /DATE/
   INTEGER*1 DAY, MONTH
   INTEGER*2 YEAR
 STRUCTURE

Structure APPOINTMENT:

 STRUCTURE /APPOINTMENT/
   RECORD /DATE/      APP_DATE
   STRUCTURE /TIME/   APP_TIME(2)
     INTEGER*1        HOUR, MINUTE
   END STRUCTURE
   CHARACTER*20       APP_MEMO(4)
   LOGICAL*1          APP_FLAG
 END STRUCTURE

The following RECORD statement creates a variable named NEXT_APP and a 10-element array named APP_LIST. Both the variable and each element of the array take the form of the structure APPOINTMENT.

 RECORD /APPOINTMENT/    NEXT_APP,APP_LIST(10)

Each of the following examples of record and field references are derived from the previous structure declarations and RECORD statement:

Aggregate Field References

  • The record NEXT_APP:
     NEXT_APP
  • The field APP_DATE, a 4-byte array field in the record array APP_LIST(3):
     APP_LIST(3).APP_DATE

Scalar Field References

  • The field APP_FLAG, a LOGICAL field of the record NEXT_APP:
     NEXT_APP.APP_FLAG
  • The first character of APP_MEMO(1), a CHARACTER*20 field of the record NEXT_APP:
     NEXT_APP.APP_MEMO(1)(1:1)

For More Information:

  • See the RECORD statement.
  • On specification of fields within structure declarations, see the STRUCTURE statement.
  • On structure declarations, see the STRUCTURE statement.
  • On UNION and MAP statements, see the UNION statement.
  • On alignment of data, see your programmer's guide.


Aggregate Assignment

For aggregate assignment statements, the variable and expression must have the same structure as the aggregate they reference.

The aggregate assignment statement assigns the value of each field of the aggregate on the right of an equal sign to the corresponding field of the aggregate on the left. Both aggregates must be declared with the same structure.

Examples

The following example shows valid aggregate assignments:

 STRUCTURE /DATE/
   INTEGER*1 DAY, MONTH
   INTEGER*2 YEAR
 END STRUCTURE

 RECORD /DATE/ TODAY, THIS_WEEK(7)
 STRUCTURE /APPOINTMENT/
   ...
   RECORD /DATE/ APP_DATE
 END STRUCTURE

 RECORD /APPOINTMENT/ MEETING

 DO I =  1,7
   CALL GET_DATE (TODAY)
   THIS_WEEK(I) =     TODAY
   THIS_WEEK(I).DAY = TODAY.DAY + 1
 END DO
 MEETING.APP_DATE =   TODAY


Character and Key Code Charts

This section contains the ASCII and ANSI character code charts, and the Key code charts that are available on Windows systems. Other character sets are available on OpenVMS, Tru64 UNIX, and Linux systems; for details, see the printed Compaq Fortran Language Reference Manual.

For details on the Fortran 95/90 character set, see Character Sets.


ASCII Character Codes

The ASCII character code charts contain the decimal and hexadecimal values of the extended ASCII (American Standards Committee for Information Interchange) character set. The extended character set includes the ASCII character set ( Chart 1 ) and 128 other characters for graphics and line drawing ( Chart 2 ), often called the "IBM® character set".


ASCII Character Codes Chart 1


ASCII Character Codes Chart 2 (IBM character set)


ANSI Character Codes

The ANSI character code chart lists the extended character set of most of the programs used by Windows. The codes of the ANSI (American National Standards Institute) character set from 32 through 126 are displayable characters from the ASCII character set. The ANSI characters displayed as solid blocks are undefined characters and may appear differently on output devices.


ANSI Character Codes Chart


Key Codes

Some keys, such as function keys, cursor keys, and ALT+KEY combinations, have no ASCII code. When a key is pressed, a microprocessor within the keyboard generates an "extended scan code" of two bytes.

The first (low-order) byte contains the ASCII code, if any. The second (high-order) byte has the scan code--a unique code generated by the keyboard when a key is either pressed or released. Because the extended scan code is more extensive than the standard ASCII code, programs can use it to identify keys which do not have an ASCII code.

For more details on key codes, see:

  • Key Codes Chart 1
  • Key Codes Chart 2


Key Codes Chart 1


Key Codes Chart 2


Data Representation Models

Several of the numeric intrinsic functions are defined by a model set for integers (for each intrinsic kind used) and reals (for each real kind used). The bit functions are defined by a model set for bits (binary digits).

For more information on the range of values for each data type (and kind), see your programmer's guide.

This section discusses the following topics:

  • The model for Integer Data
  • The model for Real Data
  • The model for Bit Data


Model for Integer Data

In general, the model set for integers is defined as follows:

The following values apply to this model set:

  • i is the integer value.
  • s is the sign (either +1 or -1).
  • q is the number of digits (a positive integer).
  • r is the radix (an integer greater than 1).
  • wk is a nonnegative number less than r.

The model for INTEGER(4) follows:

The following example shows the general integer model for i = -20 using a base (r) of 2:

i = (-1) x (0 x 20 + 0 x 21 + 1 x 22 + 0 x 23 + 1 x 24)

i = (-1) x (4 + 16)

i = -1 x 20

i = -20


Model for Real Data

The model set for reals, in general, is defined as one of the following:

The following values apply to this model set:

  • x is the real value.
  • s is the sign (either +1 or -1).
  • b is the base (real radix; an integer greater than 1).
  • p is the number of mantissa digits (an integer greater than 1). The number of digits differs depending on the real format, as follows:

    IEEE S_floating | 24
    Compaq (formerly DIGITAL) VAX F_floating 1 | 24
    IEEE T_floating | 53
    Compaq VAX D_floating 1 | 53 2
    Compaq VAX G_floating 1 | 53
    1VMS only
    2The memory format for VAX D_floating format is 56 mantissa digits, but computationally it is 53 digits. It is considered to have 53 digits by Compaq Fortran.

  • e is an integer in the range emin to emax inclusive. This range differs depending on the real format, as follows:

    emin | emax
    IEEE S_floating | -125 | 128
    Compaq VAX F_floating 1 | -127 | 127
    IEEE T_floating | -1021 | 1024
    Compaq VAX D_floating 1 | -127 | 127
    Compaq VAX G_floating 1 | -1023 | 1023
    1VMS only

  • fk is a nonnegative number less than b (f1 is also nonzero).

For x = 0, its exponent e and digits fk are defined to be zero.

The model set for single-precision real (REAL(4)) is defined as one of the following:

The following example shows the general real model for x = 20.0 using a base (b) of 2:

x = 1 x 25 x (1 x 2-1 + 0 x 2-2 + 1 x 2-3)

x = 1 x 32 x (.5 + .125)

x = 32 x (.625)

x = 20.0


Model for Bit Data

The model set for bits (binary digits) interprets a nonnegative scalar data object of type integer as a sequence, as follows:

The following values apply to this model set:

  • j is the integer value.
  • s is the number of bits.
  • wk is a bit value of 0 or 1.

The bits are numbered from right to left beginning with 0.

The following example shows the bit model for j = 1001 (integer 9) using a bit number (s) of 4:

j = (w0 x 20) + (w1 x 21) + (w2 x 22) + (w3 x 23)

j = 1 + 0 + 0 + 8

j = 9


Run-Time Library Routines on Tru64 UNIX and Linux Systems

Compaq Fortran provides the following routines for Tru64 UNIX and Linux systems:

  • General routines

  • Parallel routines

    These routines are only available on Tru64 UNIX systems.


General Library Routines (U*X)

Compaq Fortran provides library routines you can use for general purposes on Tru64 UNIX and Linux systems.

The following table summarizes these routines, which are also listed in reference page intro(3f).

For more information on a specific routine, see the appropriate reference page; for example, for more information on alarm, see alarm(3f). If a routine is described on a differently named reference page, it is specified in the tables.

Summary of General Routines (U*X)

Name | Description
abort | Terminates a program (abnormally).
access | Determines accessibility of a file.
alarm | Executes a subroutine after a specified time.
and | Returns bitwise AND of two operands. See bit(3f).
besj0 | Returns a REAL*4 bessel function (kind:1, order:0). See bessel(3f).
besj1 | Returns a REAL*4 bessel function (kind:1, order:1). See bessel(3f).
besjn | Returns a REAL*4 bessel function (kind:1, order:n). See bessel(3f).
bessel | Returns bessel functions.
besy0 | Returns a REAL*4 bessel function (kind:2, order:0). See bessel(3f).
besy1 | Returns a REAL*4 bessel function (kind:2, order:1). See bessel(3f).
besyn | Returns a REAL*4 bessel function (kind:2, order:n). See bessel(3f).
bit | Returns bitwise functions.
chdir | Changes the default directory.
chmod | Changes the mode of a file.
ctime | Returns the system time. See time(3f).
dbesj0 | Returns a REAL*8 bessel function (kind:1, order:0). See bessel(3f).
dbesj1 | Returns a REAL*8 bessel function (kind:1, order:1). See bessel(3f).
dbesjn | Returns a REAL*8 bessel function (kind:1, order:n). See bessel(3f).
dbesy0 | Returns a REAL*8 bessel function (kind:2, order:0). See bessel(3f).
dbesy1 | Returns a REAL*8 bessel function (kind:2, order:1). See bessel(3f).
dbesyn | Returns a REAL*8 bessel function (kind:2, order:n). See bessel(3f).
derf | Returns a REAL*8 error function. See erf(3f).
derfc | Returns a complimentary REAL*8 error function. See erf(3f).
dffrac | Returns fractional accuracy of a REAL*8 floating-point value. See flmin(3f).
dflmax | Returns the maximum positive REAL*8 floating-point value. See flmin(3f).
dflmin | Returns the minimum positive REAL*8 floating-point value. See flmin(3f).
dlgamma | Returns the REAL*8 log of the gamma function. See lgamma(3f).
drand | Generates a random number (use drandm instead). See rand(3f).
drandm | Generates a REAL*8 random number. See random(3f).
dtime | Returns elapsed delta execution time. See etime(3f).
erf | Returns a REAL*4 error function.
erfc | Returns a complimentary REAL*4 error function. See erf(3f).
etime | Returns elapsed execution time.
falloc | Allocates memory for an array. See malloc(3f).
fdate | Returns date and time in an ASCII string.
ffrac | Returns the fractional accuracy of a REAL*4 floating-point value. See flmin(3f).
fgetc | Returns a character from a logical unit. See getc(3f).
flmax | Returns the maximum positive REAL*4 floating-point value. See flmin(3f).
flmin | Returns the minimum positive REAL*4 floating-point value.
flush | Writes output to a logical unit.
for_get_fpe | Returns floating-point exception flags.
for_rtl_finish_ | Initializes the Fortran run-time environment. See for_rtl_init_(3f).
for_rtl_init_ | Cleans up the Fortran run-time environment.
for_set_fpe | Sets floating-point exception flags. See for_get_fpe(3f).
for_set_reentrancy | Sets reentrancy protection for the Fortran RTL.
fork | Creates a copy of a calling process.
fputc | Writes a character to a logical unit. See putc(3f).
free | Frees memory allocated by malloc or falloc. See malloc(3f).
fseek | Repositions a file on a logical unit.
fstat | Returns file status. See stat(3f).
fsync | Writes logical unit changes to permanent storage.
ftell | Returns the position of a file associated with a logical unit. See fseek(3f).
gerror | Writes system error messages. See perror(3f).
getarg | Returns command line arguments.
getc | Returns a character from a logical unit.
getcwd | Returns the pathname of the current working directory.
getenv | Returns the value of environment variables.
getfd | Returns the file descriptor associated with a Fortran logical unit.
getgid | Returns the group ID of the caller. See getuid(3f).
getlog | Returns the user's login name.
getpid | Returns the process ID. See getuid(3f).
getuid | Returns the user ID of the caller.
gmtime | Returns the GMT system time as month, day, and so forth. See time(3f).
iargc | Returns the index of the last command line argument. See getarg(3f).
idate | Returns the date in numerical form.
ierrno | Returns the system error number for the last error. See perror(3f).
index | Returns the position of a substring within a string.
inmax | Returns the maximum positive integer value. See flmin(3f).
irand | Returns random values (use irandm instead). See rand(3f).
irandm | Generates an integer random number. See random(3f).
isatty | Finds the name of a terminal port. See ttynam(3f).
itime | Returns the time in numerical form. See idate(3f).
kill | Sends a signal to a process.
len | Returns the length of a string. See index(3f).
lgamma | Returns the REAL*4 log of the gamma function.
link | Makes a link to an existing file.
lnblnk | Returns the position of the last non-blank string character. See index(3f).
loc | Returns the address of an object.
long | Converts INTEGER*2 to INTEGER*4.
lshift | Shifts a word left by n bits. See bit(3f).
lstat | Returns information about a file or a link. See stat(3f).
ltime | Returns the local zone system time as month, day, and so forth. See time(3f).
malloc | Returns the address of a block of memory.
not | Returns the bitwise NOT (complement) of an operand. See bit(3f).
or | Returns the bitwise OR of two operands. See bit(3f).
perror | Writes system error messages.
putc | Writes a character to a logical unit.
qsort | Performs a quick sort of array elements.
rand | Generates random numbers (use random instead).
random | Generates random numbers.
rename | Changes the name of a file.
rshift | Shifts a word right by n bits. See bit(3f).
shcom_connect1 | Lets a shared library's data be shared between call_shared processes.
short | Converts INTEGER*4 to INTEGER*2. See long(3f).
signal | Changes the action for a signal.
sleep | Suspends execution for an interval.
srand | Initializes the seed for successive invocations of rand, drand, and irand. See rand(3f).
stat | Returns file status.
symlnk | Creates a symbolic link to an existing file. See link(3f).
system | Calls system(3).
time | Returns the system time.
ttynam | Finds the name of a terminal port.
umask | Sets a file mode creation mask.
unlink | Removes a directory entry.
wait | Waits for a process to terminate.
xor | Returns the bitwise exclusive OR of two operands. See bit(3f).
1 TU*X only


Parallel Library Routines (TU*X)

Compaq Fortran provides library routines you can use for directed parallel decomposition (when specifying the -mp and -omp compiler options) on Tru64 UNIX systems:

  • Routines using the OpenMP Fortran API format

  • Equivalent routines using a format compatible with existing programs

When writing new programs that call the run-time parallel library routines, use the OpenMP Fortran API format.

For a helpful program interface, you should add the following statement to the program unit containing the parallel routines:

  INCLUDE '/usr/include/forompdef.f'

For more information on a specific routine, see the appropriate reference page; for example, for more information on omp_set_lock, see omp_set_lock(3f).

For More Information:

  • On parallel routines, see your user manual.
  • On parallel directives, see Parallel Directives for Tru64 UNIX Systems.


OpenMP Fortran API Run-Time Library Routines (TU*X)

The following table summarizes the the Compaq Fortran OpenMP Fortran API run-time library routines. These routines are all external procedures.

Summary of OpenMP Fortran Parallel Routines (TU*X)

Name | Description
omp_set_num_threads | Sets the number of threads to use for the next parallel region.
omp_get_num_threads | Gets the number of threads currently in the team executing the parallel region from which the routine is called.
omp_get_max_threads | Gets the maximum value that can be returned by calls to the omp_get_num_threads( ) function.
omp_get_thread_num | Gets the thread number, within the team, in the range from zero to omp_get_num_threads( ) minus one.
omp_get_num_procs | Gets the number of processors that are available to the program.
omp_in_parallel | Informs whether or not a region is executing in parallel.
omp_set_dynamic | Enables or disables dynamic adjustment of the number of threads available for execution of parallel regions.
omp_get_dynamic | Informs whether or not dynamic thread adjustment is enabled.
omp_set_nested | Enables or disables nested parallelism.
omp_get_nested | Informs whether or not nested parallelism is enabled.
omp_init_lock | Initializes a lock to be used in subsequent calls.
omp_destroy_lock | Disassociates a lock variable from any locks.
omp_set_lock | Makes the executing thread wait until the specified lock is available.
omp_unset_lock | Releases the executing thread from ownership of a lock.
omp_test_lock | Tries to set the lock associated with a lock variable.


Parallel Threads Routines for Compatibility (TU*X)

The following table summarizes the equivalent parallel thread routines you can use for compatibility with existing programs. For new programs, you should use the OpenMP Fortran API Run-Time Library Routines.

For most of the routines, two spellings are shown: an _Ots xxxx form and an mpc_xxxx form. These routine names are equivalent; for example, calling _OtsGetNumThreads is the same as calling mpc_numthreads.

Summary of Parallel Routines for Compatibility (TU*X)

Name | Description
_OtsInitParallel | Equivalent to the c$OMP PARALLEL directive, which defines the start of a parallel region.
_OtsStopWorkers mpc_destroy | Equivalent to the c$OMP PARALLEL directive, which defines the end of a parallel region.
_OtsGetNumThreads mpc_numthreads | Equivalent to omp_get_num_threads. Gets the number of threads currently in the team executing the parallel region from which the routine is called.
_OtsGetMaxThreads mpc_maxnumthreads | Equivalent to omp_get_max_threads. Gets the maximum value that can be returned by calls to the _OtsGetNumThreads( ) function.
_OtsGetThreadNum mpc_my_threadnum | Equivalent to omp_get_thread_num. Gets the thread number, within the team, in the range from zero to _OtsGetNumThreads( ) minus one.
_OtsInParallel mpc_in_parallel_region | Equivalent to omp_in_parallel. Informs whether or not a region is executing in parallel.


FORTRAN 77 Syntax

This section contains the syntax for the following features of ANSI FORTRAN 77:

  • FORTRAN 77 Data Types
  • FORTRAN 77 Intrinsic Functions
  • FORTRAN 77 Statements

All are recognized by Visual Fortran without the use of special compiler options, except in certain special instances.


FORTRAN 77 Data Types

The data types defined by ANSI FORTRAN 77 are as follows:

  • INTEGER
  • REAL
  • DOUBLE PRECISION
  • COMPLEX
  • LOGICAL
  • CHARACTER [*n], where n is between 1 and 32,767

The data type of a variable, symbolic constant, or function can be declared in a specification statement. If its type is not declared, the compiler determines a data type by the first letter of the variable, constant, or function name. A type statement can also dimension an array variable.

Default requirements for these data types are listed in the following table:

Type | Bytes
INTEGER | 4
REAL | 4
DOUBLE PRECISION | 8
COMPLEX | 8
LOGICAL | 4
CHARACTER | 1
CHARACTER*n | n 1
1 Where the maximum n is 32,767.


FORTRAN 77 Intrinsic Functions

Function syntax | Type of return value
ABS (gen) | Same as argument
ACOS (real) | Same as argument
AIMAG (cmp8) | REAL
AINT (real) | Same as argument
ALOG (real4) | REAL
ALOG10 (real4) | REAL
AMAX0 (intA, intB [, intC ] ...) | REAL
AMAX1 (real4A, real4B, [, real4C ] ...) | REAL
AMIN0 (intA, intB [, intC ] ...) | REAL
AMIN1 (real4A, real4B [, real4C ] ...) | REAL
AMOD (value, mod) | REAL
ANINT (value) | REAL
ASIN (real) | Same as argument
ATAN (real) | Same as argument
ATAN2 (realA, realB) | Same as argument
CABS (cmp) | Same as argument; COMPLEX returns REAL
CCOS (cmp8) | COMPLEX
CHAR (int) | CHARACTER
CLOG (cmp8) | COMPLEX
CMPLX (genA [, genB ]) | COMPLEX
CONJG (cx8value) | COMPLEX
COS (gen) | Same as argument
COSH (real) | Same as argument
CSIN (cmp8) | COMPLEX
CSQRT (cx8value) | COMPLEX
DABS (r8value) | DOUBLE PRECISION
DACOS (dbl) | DOUBLE PRECISION
DASIN (dbl) | DOUBLE PRECISION
DATAN (dbl) | DOUBLE PRECISION
DATAN2 (dblA, dblB) | DOUBLE PRECISION
DBLE (value) | DOUBLE PRECISION
DCOS (dbl) | DOUBLE PRECISION
DCOSH (dbl) | DOUBLE PRECISION
DDIM (dblA, dblB) | DOUBLE PRECISION
DEXP (dbl) | DOUBLE PRECISION
DIM (genA, genB) | Same as arguments
DINT (rvalue) | DOUBLE PRECISION
DLOG (dbl) | DOUBLE PRECISION
DLOG10 (dbl) | DOUBLE PRECISION
DMAX1 (dblA, dblB [, dblC ] ...) | DOUBLE PRECISION
DMIN1 (dblA, dblB [dblC ] ...) | DOUBLE PRECISION
DMOD (value, mod) | DOUBLE PRECISION
DNINT (dbl) | DOUBLE PRECISION
DPROD (real4A, real4B) | DOUBLE PRECISION
DREAL (cxvalue) | DOUBLE PRECISION
DSIGN (dblA, dblB) | DOUBLE PRECISION
DSIN (dbl) | DOUBLE PRECISION
DSINH (dbl) | DOUBLE PRECISION
DSQRT (rvalue) | DOUBLE PRECISION
DTAN (dbl) | DOUBLE PRECISION
DTANH (dbl) | DOUBLE PRECISION
EXP (gen) | Same as argument
FLOAT (ivalue) | REAL
IABS (int) | Same as argument
ICHAR (char) | INTEGER
IDIM (intA, intB) | INTEGER
IDINT (dbl) | INTEGER
IDNINT (dbl) | INTEGER
IFIX (real4) | REAL
INDEX (charA, charB) | INTEGER
INT (gen) | INTEGER
ISIGN (intA, intB) | INTEGER
LEN (char) | INTEGER
LGE (charA, charB) | LOGICAL
LGT (charA, charB) | LOGICAL
LLE (charA, charB) | LOGICAL
LLT (charA, charB) | LOGICAL
LOG (gen) | Same as argument
LOG10 (real) | Same as argument
MAX (genA, genB [, genC ] ...) | INTEGER or REAL
MAX0 (intA, intB [, intC ] ...) | INTEGER
MAX1 (realA, realB [, realC ] ...) | INTEGER
MIN (genA, genB [, genC ] ...) | INTEGER or REAL
MIN0 (intA, intB [, intC ] ...) | INTEGER
MIN1 (realA, real [, real ] ...) | INTEGER
MOD (genA, genB) | REAL
NINT (real) | INTEGER
REAL (gen) | REAL
SIGN (genA, genB) | INTEGER or REAL
SIN (gen) | Same as argument
SINH (real) | Same as argument
SNGL(dbl) | REAL
SQRT (gen) | Same as argument
TAN (real) | Same as argument
TANH (real) | Same as argument


FORTRAN 77 Statements

ASSIGN label TO variable

BACKSPACE {unitspec |
( [UNIT=]unitspec
[, ERR=errlabel]
[, IOSTAT=iocheck] )}

BLOCK DATA [blockdataname]

CALL sub [( [actuals] )]

CHARACTER [*chars] vname [*length] [(dim)] [, vname [*length] [(dim)]

CLOSE ( [UNIT=]unitspec
[, ERR=errlabel]
[, IOSTAT=iocheck]
[, STATUS=status] )

COMMON [/[cname] /] nlist[[,] / [cname] /nlist ] ...

COMPLEX vnam [(dim)] [, vname [(dim)]] ...

CONTINUE

DATA nlist /clist/ [[,] nlist /clist/ ] ...

DIMENSION array ([lower:]upper [, {[lower:]upper ] )

DO [label [,] ] dovar = start, stop [, inc]

DOUBLE PRECISION vname [(dim)] [, vname [(dim)] ] ...

ELSE
statementblock

ELSE IF (expression) THEN
statementblock

END

END IF

ENDFILE {unitspec |
( [UNIT=] unitspec
[, ERR=errlabel]
[, IOSTAT=iocheck] )}

ENTRY ename [ ( [formal [, formal ] ...] )]

EQUIVALENCE (nlist) [, (nlist)] ...

EXTERNAL name [, name ] ...

FORMAT [editlist]

[type] FUNCTION func ([formal ] [, formal ] ...)

GOTO variable [ [,] (labels)]

GOTO (labels) [,] n

GOTO label

IF (expression) label1, label2, label3

IF (expression) statement

IF (expression) THEN
statementblock1
[ELSE IF (expression) THEN
statementblock2] ...
[ELSE
statementblock3]
END IF

IMPLICIT type (letters) [, type (letters)] ...

INQUIRE ( {[UNIT=]unitspec | FILE=file}
[, ACCESS=access]
[, BLANK=blank] [, DIRECT=direct] [, ERR=errlabel] [, EXIST=exist] [, FORM=form]
[, FORMATTED=formatted] [, IOSTAT=iocheck]
[, NAME=name] [, NAMED=named]
[, NEXTREC=nextrec] [, NUMBER=num] [, OPENED=opened]
[, RECL=recl] [, SEQUENTIAL=seq] [, UNFORMATTED=unformatted] )

INTEGER vname [(dim)] [, vname [ (dim)] ] ...

INTRINSIC names

LOGICAL vname [(dim)] [, vname [(dim)] ] ...

OPEN ( [UNIT=]unitspec [, ACCESS=access]
[, BLANK=blanks]
[, ERR=errlabel] [, FILE=file]
[, FORM=form] [, IOSTAT=iocheck]
[, RECL=recl] [, STATUS=status] )

PARAMETER (name=constexpr [, name=constexpr] ...)

PAUSE [prompt]

PRINT { *, | formatspec | } [, iolist]

PROGRAM program-name

READ {formatspec, | ( [UNIT=] unitspec
[, [FMT=]formatspec]
[, END=endlabel ]
[, ERR=errlabel]
[, IOSTAT=iocheck]
[, REC=rec] )}
iolist

REAL vname [(dim)] [, vname [(dim)] ] ...

RETURN [ordinal ]

REWIND {unitspec | ( [UNIT=] unitspec
[, ERR=errlabel]
[, IOSTAT=iocheck] )}

SAVE [names]

STOP [message]

SUBROUTINE subr [([ formal [, formal ] ...] )]

WRITE ( [UNIT=] unitspec
[, [FMT=] formatspec]
[, ERR=errlabel]
[, IOSTAT=iocheck]
[, REC=rec] )
iolist


Summary of Language Extensions

This appendix summarizes the Compaq Fortran language extensions to the ANSI/ISO Fortran 95 Standard.

For more information, see the following sections:

  • Compaq Fortran Language Extensions

  • High Performance Fortran Language Extensions


Compaq Fortran Language Extensions

This section summarizes the Compaq Fortran language extensions. Most extensions are available on all systems, but some extensions are limited to certain platforms. If an extension is limited, it is labeled.

Extensions in the following topics are discussed:

  • Source Forms
  • Names
  • Character Sets
  • Intrinsic Data Types
  • Constants
  • Expressions and Assignment
  • Specification Statements
  • Execution Control
  • Compilation Control Statements
  • Built-In Functions
  • I/O Statements
  • I/O Formatting
  • File Operation Statements
  • Compiler Directives
  • Intrinsic Procedures
  • Additional Language Features

For information on other extensions, see High Performance Fortran Language Extensions.


Source Forms

The following are extensions to the methods and rules for source forms:

  • Tab-formatting as a method to code lines
  • The letter D as a debugging statement indicator in column 1 of fixed or tab source form
  • An optional statement field width of 132 columns for fixed or tab source form
  • An optional sequence number field for fixed source form
  • Up to 511 continuation lines in a source program


Names

The following are extensions to the Fortran 90 rules for names (see names):

  • Names can contain up to 63 characters

  • The dollar sign ($) is a valid character in names, and can be the first character


Character Sets

The following are extensions to the Fortran 90 character set:

  • The Tab (<Tab>) character (see Character Sets)
  • The DEC Multinational extension to the ASCII character set (VMS, U*X) 1
  • ASCII Character Code Chart 2--IBM Character Set (WNT, W9*)
  • ANSI Character Code Chart (WNT, W9*)
  • Key Code Charts (WNT, W9*)

1 See the printed Compaq Fortran Language Reference Manual.


Intrinsic Data Types

The following are data-type extensions:

BYTE | INTEGER*1 | REAL*8 1
LOGICAL*1 | INTEGER*2 | REAL*16 2
LOGICAL*2 | INTEGER*4 | COMPLEX*8
LOGICAL*4 | INTEGER*8 | COMPLEX*16 1
LOGICAL*8 | REAL*4 | COMPLEX*32 2
1 D_floating and G_floating implementations are available on OpenVMS systems only. 2 VMS, U*X

For more information, see Intrinsic Data Types.


Constants

Hollerith constants are allowed as an extension.

C Strings are allowed as extensions in character constants.


Expressions and Assignment

When operands of different intrinsic data types are combined in expressions, conversions are performed as necessary (see Data Type of Numeric Expressions).

Binary, octal, hexadecimal, and Hollerith constants can appear wherever numeric constants are allowed.

The following are extensions allowed in logical expressions:

  • .XOR. as a synonym for .NEQV.
  • Integers as valid logical items


Specification Statements

The following specification attributes and statements are extensions:

  • AUTOMATIC attribute and statement
  • STATIC attribute and statement
  • VOLATILE attribute and statement


Execution Control

The following control statements are extensions to Fortran 95:

  • ASSIGN
  • Assigned GO TO
  • PAUSE

These are older Fortran features that have been deleted in Fortran 95. Compaq Fortran fully supports these features.


Compilation Control Statements

The following statements are extensions that can influence compilation:

  • INCLUDE statement format (VMS only):

    INCLUDE '[text-lib] (module-name) [/[NO]LIST]'

  • OPTIONS statement:
        /ASSUME = [NO]UNDERSCORE   (Alpha only)

             {ALL            }
             {[NO]BOUNDS     }
    /CHECK = {[NO]OVERFLOW   }
             {[NO]UNDERFLOW  }
             {NONE           }

    /NOCHECK

               {BIG_ENDIAN     }
               {CRAY           }
               {FDX            }
               {FGX            }
    /CONVERT = {IBM            }
               {LITTLE_ENDIAN  }
               {NATIVE         }
               {VAXD           }
               {VAXG           }

    /[NO]EXTEND_SOURCE
    /[NO]F77

             {D_FLOAT   (VMS only)  }
    /FLOAT = {G_FLOAT   (VMS only)  }
             {IEEE_FLOAT            }

    /[NO]G_FLOATING   (VMS only)
    /[NO]I4
    /[NO]RECURSIVE


Built-In Functions

The %VAL, %REF, %DESCR, and %LOC built-in functions are extensions.


I/O Statements

The following I/O statements and specifiers are extensions:

  • ACCEPT statement
  • REWRITE statement
  • TYPE statements as synonyms for PRINT statements
  • A key-field-value specifier as a control list parameter (VMS only)
  • A key-of-reference specifier as a control list parameter (VMS only)
  • Indexed READ Statement (VMS only)
  • Indexed WRITE Statement (VMS only)


I/O Formatting

The following are extensions allowed in I/O Formatting:

  • The Q edit descriptor

  • The dollar sign ($) edit descriptor and carriage-control character

  • The backslash (\) edit descriptor

  • The ASCII NUL carriage-control character

  • Variable format expressions

  • The H edit descriptor

    This is an older Fortran feature that has been deleted in Fortran 95. Compaq Fortran fully supports this feature.


File Operation Statements

The following statement specifiers and statements are extensions:

  • CLOSE statement specifiers:

    • STATUS values: 'SAVE' (as a synonym for 'KEEP'), 'PRINT', 'PRINT/DELETE', 'SUBMIT', 'SUBMIT/DELETE'
    • DISPOSE (or DISP)

  • DELETE statement

  • INQUIRE statement specifiers:

    • ACCESS value: 'KEYED' (VMS only)
    • BINARY (WNT, W9*)
    • BUFFERED
    • BLOCKSIZE
    • CARRIAGECONTROL
    • CONVERT
    • DEFAULTFILE
    • FORM values: 'UNKNOWN', 'BINARY' (WNT, W9*)
    • IOFOCUS (WNT, W9*)
    • KEYED (VMS only)
    • MODE as a synonym for ACTION (WNT, W9*)
    • ORGANIZATION
    • RECORDTYPE
    • SHARE (WNT, W9*)

    See also INQUIRE Statement.

  • OPEN statement specifiers:

    • ACCESS values: 'KEYED' (VMS only), 'APPEND'
    • ASSOCIATEVARIABLE
    • BLOCKSIZE
    • BUFFERCOUNT
    • BUFFERED
    • CARRIAGECONTROL
    • CONVERT
    • DEFAULTFILE
    • DISPOSE
    • EXTENDSIZE (VMS only)
    • FORM value: 'BINARY' (WNT, W9*)
    • INITIALSIZE (VMS only)
    • IOFOCUS (WNT, W9*)
    • KEY (VMS only)
    • MAXREC
    • MODE as a synonym for ACTION (WNT, W9*)
    • NAME as a synonym for FILE
    • NOSPANBLOCKS (VMS only)
    • ORGANIZATION
    • READONLY
    • RECORDSIZE as a synonym for RECL
    • RECORDTYPE
    • SHARE (WNT, W9*)
    • SHARED
    • TITLE (WNT, W9*)
    • TYPE as a synonym for STATUS
    • USEROPEN

    See also OPEN Statement.

  • UNLOCK statement


Compiler Directives

The following General Compiler Directives are extensions:

  • ALIAS
  • ATTRIBUTES
  • DECLARE and NODECLARE
  • DEFINE and UNDEFINE
  • FIXEDFORMLINESIZE
  • FREEFORM and NOFREEFORM
  • IDENT
  • IF and IF DEFINED
  • INTEGER
  • IVDEP
  • MESSAGE
  • OBJCOMMENT
  • OPTIONS
  • PACK
  • PSECT
  • REAL
  • STRICT and NOSTRICT
  • SUBTITLE
  • TITLE
  • UNROLL

The following OpenMP Fortran API parallel directives are extensions available on Tru64 UNIX systems:

  • ATOMIC
  • BARRIER
  • CRITICAL
  • DO
  • FLUSH
  • MASTER
  • ORDERED
  • PARALLEL
  • PARALLEL DO
  • PARALLEL SECTIONS
  • SECTIONS
  • SINGLE
  • THREADPRIVATE

The following Compaq Fortran parallel directives are extensions available on Tru64 UNIX systems:

  • BARRIER
  • CHUNK
  • COPYIN
  • CRITICAL SECTION
  • INSTANCE
  • MP_SCHEDTYPE
  • PARALLEL
  • PARALLEL DO
  • PARALLEL SECTIONS
  • PDO
  • PDONE
  • PSECTIONS
  • SINGLE PROCESS
  • TASKCOMMON


Intrinsic Procedures

The following intrinsic procedures are extensions available on all platforms:

ACOSD | DFLOAT | IISIGN | JMIN0
AIMAX0 | DFLOTI | IMAX0 | JMIN1
AIMIN0 | DFLOTJ | IMAX1 | JMOD
AJMAX0 | DIMAG | IMIN0 | JMVBITS
AJMIN0 | DREAL | IMIN1 | JNINT
AND | DSIND | IMOD | JNOT
ASIND | DTAND | IMVBITS | JZEXT
ASM | EOF | ININT | LEADZ
ATAN2D | ERRSNS | INOT | LOC
ATAND | EXIT | INT1 | LSHIFT
BITEST | FASM | INT2 | MALLOC
BJTEST | FLOATI | INT4 | MULT_HIGH
CDABS | FLOATJ | ISHA | NWORKERS
CDCOS | FP_CLASS | ISHC | OR
CDEXP | FREE | ISHL | POPCNT
CDLOG | HFIX | ISNAN | POPPAR
CDSIN | IARGPTR | IZEXT | RAN
CDSQRT | IBCHNG | JFIX | RANDU
COSD | IDATE | JIAND | RSHIFT
COTAN | IIABS | JIBCLR | SECNDS
COTAND | IIAND | JIBITS | SIND
DACOSD | IIBCLR | JIBSET | SIZEOF
DASIND | IIBITS | JIDIM | TAND
DASM | IIBSET | JIDINT | TIME
DATAN2 | IIDIM | JIDNNT | TRAILZ
DATAN2D | IIDINT | JIEOR | XOR
DATAND | IIDNNT | JINT | ZABS
DATE | IIEOR | JIOR | ZCOS
DCMPLX | IIFIX | JISHFT | ZEXP
DCONJG | IINT | JISHFTC | ZEXT
DCOSD | IIOR | JISIGN | ZLOG
DCOTAN | IISHFT | JMAX0 | ZSIN
DCOTAND | IISHFTC | JMAX1 | ZSQRT

The following intrinsic procedures are extensions available on OpenVMS, Tru64 UNIX, and Linux systems:

CQABS | KIQNNT | QCOSH | QMOD
CQCOS | QABS | QCOTAN | QNINT
CQEXP | QACOS | QCOTAND | QREAL
CQLOG | QACOSD | QDIM | QSIGN
CQSIN | QASIN | QEXP | QSIN
CQSQRT | QASIND | QEXT | QSIND
DBLEQ | QATAN | QEXTD | QSINH
IIQINT | QATAN2 | QFLOAT | QSQRT
IIQNNT | QATAN2D | QIMAG | QTAN
IQINT | QATAND | QINT | QTAND
IQNINT | QCMPLX | QLOG | QTANH
JIQINT | QCONJG | QLOG10 | SNGLQ
JIQNNT | QCOS | QMAX1 |
KIQINT | QCOSD | QMIN1 |

The intrinsic procedure IARGCOUNT is an extension available on OpenVMS systems.

The argument KIND is an extension available in the following intrinsic procedures:

COUNT | LEN_TRIM | SHAPE | ZEXT
INDEX | MAXLOC | SIZE |
LBOUND | MINLOC | UBOUND |
LEN | SCAN | VERIFY |


Additional Language Features

The following are language extensions that facilitate compatibility with other versions of Fortran:

  • DEFINE FILE statement
  • ENCODE and DECODE statements
  • FIND statement
  • An alternative syntax for the PARAMETER statement
  • VIRTUAL statement
  • AND, OR, XOR, IMAG, LSHIFT, RSHIFT intrinsics (see the A to Z Reference)
  • FORTRAN-66 Interpretation of the EXTERNAL statement
  • An alternative syntax for octal and hexadecimal constants
  • An alternative syntax for an I/O record specifier
  • An alternate syntax for the DELETE statement
  • An alternative form for namelist external records
  • The Compaq Fortran 77 POINTER statement
  • Record structures


High Performance Fortran Language Extensions

This section summarizes the High Performance Fortran language extensions to the Fortran 95 standard.

The following extensions are discussed:

  • Procedure Prefixes
  • Intrinsic Procedures

For information on other extensions, see Compaq Fortran Language Extensions.


Procedure Prefixes

The following prefixes are allowed in functions and subroutines as extensions:

  • EXTRINSIC (HPF) - functional only on Tru64 UNIX systems
  • EXTRINSIC (HPF_LOCAL) - functional only on Tru64 UNIX systems
  • EXTRINSIC (HPF_SERIAL) - functional only on Tru64 UNIX systems


Intrinsic Procedures

System Inquiry Intrinsic Procedures

The following intrinsic procedures are extensions:

  • NUMBER_OF_PROCESSORS intrinsic function
  • PROCESSORS_SHAPE intrinsic function

Bit Manipulation Functions

The ILEN intrinsic function is an extension.


A to Z Reference

This section contains the following:

  • Language Summary Tables

    This section organizes the functions, subroutines, and statements available in Visual Fortran by the operations they perform. You can use the tables to locate a particular routine for a particular task.

  • The descriptions of all Visual Fortran statements and intrinsics, which are listed in alphabetical order.

    In the description of routines, pointers and handles are INTEGER(4) on ia32 processors and INTEGER(8) on ia64 processors.

Remember that REAL(16) and COMPLEX(16) are only available on OpenVMS, Tru64 UNIX, and Linux systems.

The Fortran compiler understands statements and intrinsic functions in your program without any additional information, such as that provided in modules.

However, modules must be included in the following types of programs:

  • Programs that contain run-time or graphics functions and subroutines must specifically include the Visual Fortran library and graphics modules with the USE DFLIB statement.

  • Programs that contain Portability procedures must access the Portability library with the USE DFPORT statement.

  • Programs that use NLS procedures must access the NLS library with the USE DFNLS statement.

  • Programs that use Dialog procedures must access the Dialog library with the USE DFLOGM statement.

  • Programs that use Component Object Module (COM) and Automation servers must access the appropriate libraries with the USE DFCOM or USE DFAUTO statement, whichever is appropriate.

Whenever required, these USE module statements are prominent in the A to Z Reference.

In addition to the appropriate USE statement, you must specify the types of libraries to be used when linking:

  • When using the visual development environment, the project type selected and the project settings in the Libraries category (see Categories of Compiler Options) determine the libraries linked against. Also see Errors During the Build Process.

  • When using the command line (DF command), see Using the Compiler and Linker from the Command Line and Categories of Compiler Options (especially the options under the Libraries category).


Language Summary Tables

In the following tables, optional arguments for intrinsic procedures are enclosed between brackets: [optional arg]. The argument names given in the tables are the keyword names. Keywords allow you to specify optional arguments without regard to order. For example, when invoking PRODUCT(ARRAY [, DIM][, MASK]), you can skip the argument DIM by using the statement: array3 = PRODUCT(array1, MASK = array2).

The Fortran procedures and statements have been organized into the following tables:

  • Program Unit Calls and Definition
  • Program Control Statements and Procedures
  • Specifying Variables
  • System, Drive, and Directory Procedures
  • File Management
  • Input/Output Procedures
  • Random Number Procedures
  • Date and Time Procedures
  • Keyboard and Speaker Procedures
  • Error Handling
  • Argument Inquiry
  • Memory Allocation and Deallocation Procedures
  • Array Procedures
  • Numeric and Type Conversion Procedures
  • Trigonometric, Exponential, Root, and Logarithmic Procedures
  • Floating-Point Inquiry and Control Procedures
  • Character Procedures
  • Bit Operation and Representation Procedures
  • QuickWin Procedures
  • Graphics Procedures
  • Dialog Procedures
  • General Compiler Directives
  • National Language Standard Procedures
  • Portability Procedures
  • COM and Automation Procedures
  • Serial Port Procedures
  • Miscellaneous Run-Time Procedures (FOR_* routines)
  • Functions Not Allowed as Actual Arguments

For more information on keywords, see Argument Keywords in Intrinsic Procedures. For information on using procedures in general, see Program Units and Procedures.


Program Unit Calls and Definitions: table

All the following are statements:

Name | Description
BLOCK DATA | Identifies a block-data subprogram
CALL | Executes a subroutine
COMMON | Delineates variables shared between program units
CONTAINS | Identifies start of a module within a host module
ENTRY | Specifies a secondary entry point to a subroutine or external function
EXTERNAL | Declares a user-defined subroutine or function to be passable as an argument
FUNCTION | Identifies a program unit as a function
INCLUDE | Inserts the contents of a specified file into the source file
INTERFACE | Specifies an explicit interface for external functions and subroutines
INTRINSIC | Declares a predefined function
MODULE | Identifies a module program unit
PROGRAM | Identifies a program unit as a main program
RETURN | Returns control to the program unit that called a subroutine or function
SUBROUTINE | Identifies a program unit as a subroutine
USE | Gives a program unit access to a module


Program Control Statements and Procedures: table

Name | Description
Statements
CASE | Within a SELECT CASE structure, marks a block of statements that are executed if an associated value matches the SELECT CASE expression
CONTINUE | Often used as the target of GOTO or as the terminal statement in a DO loop; performs no operation
CYCLE | Advances control to the end statement of a DO loop; the intervening loop statements are not executed
DO | Evaluates statements in the DO loop, through and including the ending statement, a specific number of times
DO WHILE | Evaluates statements in the DO WHILE loop, through and including the ending statement, until a logical condition becomes .FALSE.
ELSE | Introduces an ELSE block
ELSE IF | Introduces an ELSE IF block
ELSEWHERE | Introduces an ELSEWHERE block
END | Marks the end of a program unit
END DO | Marks the end of a series of statements following a DO or DO WHILE statement
END FORALL | Marks the end of a series of statements following a block FORALL statement
END IF | Marks the end of a series of statements following a block IF statement
END SELECT | Marks the end of a SELECT CASE statement
END WHERE | Marks the end of a series of statements following a block WHERE statement
EXIT | Leaves a DO loop; execution continues with the first statement following
FORALL | Controls conditional execution of other statements
GOTO | Transfers control to a specified part of the program
IF | Controls conditional execution of other statement(s)
PAUSE | Suspends program execution and, optionally, executes operating-system commands
SELECT CASE | Transfers program control to a block of statements, determined by a controlling argument
STOP | Terminates program execution
WHERE | Controls conditional execution of other statements
Routines
EXIT | CALL EXIT(exitvalue). Run-time Subroutine. Terminates the program, flushes and closes all open files, and returns control to the operating system
RAISEQQ | RAISEQQ(sig). Run-time Function. Sends an interrupt to the executing program, simulating an interrupt from the operating system
SIGNALQQ | SIGNALQQ(sig, func). Run-time Function. Controls signal handling
SLEEPQQ | CALL SLEEPQQ(duration). Run-time Subroutine. Delays execution of the program for the specified time


Specifying Variables: table

The following are all statements:

Name | Description
AUTOMATIC | Declares a variable on the stack, rather than at a static memory location.
BYTE | Specifies variables as the BYTE data type; BYTE is equivalent to INTEGER(1).
CHARACTER | Specifies variables as the CHARACTER data type.
COMPLEX | Specifies variables as the COMPLEX data type.
DATA | Assigns initial values to variables.
DIMENSION | Identifies a variable as an array and specifies the number of elements.
DOUBLE COMPLEX | Specifies variables as the DOUBLE COMPLEX data type, equivalent to COMPLEX(8).
DOUBLE PRECISION | Specifies variables as the DOUBLE-PRECISION real data type, equivalent to REAL(8).
EQUIVALENCE | Specifies that two or more variables or arrays share the same memory location.
IMPLICIT | Specifies the default typing for real and integer variables and functions.
INTEGER | Specifies variables as the INTEGER data type.
LOGICAL | Specifies variables as the LOGICAL data type.
MAP...END MAP | Within a UNION statement, delimits a group of variable type declarations that are to be ordered contiguously within memory.
NAMELIST | Declares a group name for a set of variables to be read or written in a single statement.
PARAMETER | Equates a constant expression with a name.
REAL | Specifies variables as the REAL data type.
RECORD | Declares one or more variables of a user-defined structure type.
SAVE | Causes variables to retain their values between invocations of the procedure in which they are defined.
STATIC | Declares a variable is in a static memory location, rather than on the stack.
STRUCTURE...END STRUCTURE | Defines a new variable type, composed of a collection of other variable types.
TYPE...END TYPE | Defines a new variable type, composed of a collection of other variable types.
UNION...END UNION | Within a structure, causes two or more maps to occupy the same memory locations.
VOLATILE | Specifies that the value of an object is totally unpredictable based on information available to the current program unit.


System, Drive, and Directory Procedures: table

All the following are run-time functions:

Name | Description
CHANGEDIRQQ | CHANGEDIRQQ(dir). Makes the specified directory the current (default) directory.
CHANGEDRIVEQQ | CHANGEDRIVEQQ(drive). Makes the specified drive the current drive.
DELDIRQQ | DELDIRQQ(dir). Deletes a specified directory.
GETDRIVEDIRQQ | GETDRIVEDIRQQ(drivedir). Returns the current drive and directory path.
GETDRIVESIZEQQ | GETDRIVESIZEQQ(drive, total, avail). Gets the size of the specified drive.
GETDRIVESQQ | GETDRIVESQQ( ). Reports the drives available to the system.
GETENVQQ | GETENVQQ(varname, value). Gets a value from the current environment.
MAKEDIRQQ | MAKEDIRQQ(dirname). Makes a directory with the specified directory name.
RUNQQ | RUNQQ(filename, commandline). Calls another program and waits for it to execute
SETENVQQ | SETENVQQ(varvalue). Adds a new environment variable, or sets the value of an existing one.
SYSTEMQQ | SYSTEMQQ(commandline). Executes a command by passing a command string to the operating system's command interpretor.


File Management: table

Name | Procedure Type | Description
DELFILESQQ | Run-time Function | DELFILESQQ(files). Deletes the specified files in a specified directory.
FINDFILEQQ | Run-time Function | FINDFILEQQ(filename, varname, pathbuf). Searches for a file in the directories specified in the PATH environment variable.
FULLPATHQQ | Run-time Function | FULLPATHQQ(name, pathbuf). Returns the full path for a specified file or directory.
GETDRIVEDIRQQ | Run-time Function | GETDRIVEDIRQQ(drivedir). Returns current drive and directory path.
GETFILEINFOQQ | Run-time Function | GETFILEINFOQQ(files, buffer, handle). Returns information about files with names that match a request string.
PACKTIMEQQ | Run-time Subroutine | PACKTIMEQQ(timedate, iyr, imon, iday, ihr, imin, isec). Packs time values for use by SETFILETIMEQQ.
RENAMEFILEQQ | Run-time Function | RENAMEFILEQQ(oldname, newname). Renames a file.
SETFILEACCESSQQ | Run-time Function | SETFILEACCESSQQ(filename, access). Sets file-access mode for the specified file.
SETFILETIMEQQ | Run-time Function | SETFILETIMEQQ(filename, timedate). Sets modification time for a given file.
SPLITPATHQQ | Run-time Function | SPLITPATHQQ(path, drive, dir, name, ext). Breaks a full path into four components.
TRACEBACKQQ | Run-time Subroutine | TRACEBACKQQ(string, user_exit_code, status, expr). Generates a stack trace.
UNPACKTIMEQQ | Run-time Subroutine | UNPACKTIMEQQ(timedate, iyr, imon, iday, ihr, imin, isec). Unpacks a file's packed time and date value into its component parts.


Input/Output Procedures: table

Name | Procedure Type | Description
ACCEPT | Statement | Similar to a formatted, sequential READ statement.
BACKSPACE | Statement | Positions a file to the beginning of the previous record.
CLOSE | Statement | Disconnects the specified unit.
DELETE | Statement | Deletes a record from a relative file.
ENDFILE | Statement | Writes an end-of-file record or truncates a file.
EOF | Intrinsic Function | EOF(unit). Checks for end-of-file record. .TRUE. if at or past end-of-file.
INQUIRE | Statement | Returns the properties of a file or unit.
OPEN | Statement | Associates a unit number with an external device or file.
PRINT (or TYPE) | Statement | Displays data on the screen.
READ | Statement | Transfers data from a file to the items in an I/O list.
REWIND | Statement | Repositions a file to its first record.
REWRITE | Statement | Rewrites the current record.
UNLOCK | Statement | Frees a record in a relative or sequential file that was locked by a previous READ statement.
WRITE | Statement | Transfers data from the items in an I/O list to a file


Random Number Procedures: table

Note: Square brackets [...] denote optional arguments.

Name | Procedure Type | Description
RAN | Intrinsic function | result = RAN(i). Returns the next number from a sequence of pseudorandom numbers of uniform distribution over the range 0 to 1.
RANDOM | Run-time Subroutine | CALL RANDOM(ranval). Returns a pseudorandom real value greater than or equal to zero and less than one.
RANDOM_NUMBER | Intrinsic Subroutine | CALL RANDOM_NUMBER(harvest). Returns a pseudorandom real value greater than or equal to zero and less than one.
RANDOM_SEED | Intrinsic Subroutine | CALL RANDOM_SEED([size] [, put] [, get]). Changes the starting point of RANDOM_NUMBER; takes one or no arguments.
RANDU | Intrinsic Subroutine | CALL RANDU(i1, i2, x). Computes a pseudorandom number as a single-precision value.
SEED | Run-time Subroutine | CALL SEED(seedval). Changes the starting point of RANDOM.


Date and Time Procedures: table

Note: Square brackets [...] denote optional arguments.

Name | Procedure Type | Description
CPU_TIME | Intrinsic Subroutine | CALL CPU_TIME (time). Returns the processor time in seconds.
DATE | Intrinsic Subroutine | CALL DATE (buf). Returns the ASCII representation of the current date (in dd-mmm-yy form).
DATE_AND_TIME | Intrinsic Subroutine | CALL DATE_AND_TIME([date] [, time] [, zone] [, values]). Returns the date and time.
GETDAT | Run-time Subroutine | CALL GETDAT (iyr, imon, iday). Returns the date.
GETTIM | Run-time Subroutine | CALL GETTIM (ihr, imin, isec, i100th). Returns the time.
IDATE | Intrinsic Subroutine | CALL IDATE (i, j, k). Returns three integer values representing the current month, day, and year.
SETDAT | Run-time Function | SETDAT (iyr, imon, iday). Sets the date.
SETTIM | Run-time Function | SETTIM (ihr, imin, isec, i100th). Sets the time.
SYSTEM_CLOCK | Intrinsic Subroutine | CALL SYSTEM_CLOCK (count, count_rate, count_max). Returns data from the system clock.
TIME | Intrinsic Subroutine | CALL TIME (buf). Returns the ASCII representation of the current time (in hh:mm:ss form).


Keyboard and Speaker Procedures: table

Name | Procedure Type | Description
BEEPQQ | Run-time Subroutine | CALL BEEPQQ(freq, duration). Sounds the speaker for a specified duration in milliseconds at a specified frequency in Hertz.
GETCHARQQ | Run-time Function | GETCHARQQ( ). Returns the next keyboard keystroke.
GETSTRQQ | Run-time Function | GETSTRQQ(buffer). Reads a character string from the keyboard using buffered input.
PEEKCHARQQ | Run-time Function | PEEKCHARQQ( ). Checks the buffer to see if a keystroke is waiting.


Error Handling: table

Name | Procedure Type | Description
GETLASTERRORQQ | Run-time Function | GETLASTERRORQQ( ). Returns the last error set by a run-time function or subroutine.
MATHERRQQ 1 | Run-time Subroutine | CALL MATHERRQQ(name, len, info, retcode). Replaces default error handling for errors from intrinsic math functions.
SETERRORMODEQQ | Run-time Subroutine | CALL SETERRORMODEQQ(prompt). Sets the mode for handling critical errors.
1 ia32 only


Argument Inquiry: table

Note: Square brackets [...] denote optional arguments.

Name | Procedure Type | Description | Argument/Function Type
ALLOCATED | Intrinsic Function | ALLOCATED(array). Determines whether an allocatable array is allocated. | array: allocatable array result: Logical scalar
ASSOCIATED | Intrinsic Function | ASSOCIATED(pointer[, target]). Determines whether a pointer and (optional) target are associated. | pointer: any type target: any type result: Logical
DIGITS | Intrinsic Function | DIGITS(x). Returns number of significant digits for data of the same type as x. | x: Integer or Real result: Integer
EPSILON | Intrinsic Function | EPSILON(x). Returns the smallest positive number that when added to one produces a number greater than one for data of the same type as x. | x: Real result: same type as x
GETARG | Run-time Subroutine | CALL GETARG(n, buffer[, status]). Returns the specified command line argument (where the command itself is argument number zero). | n: INTEGER(2) or INTEGER(4) buffer: Character*(*) status: INTEGER(2)
HUGE | Intrinsic Function | HUGE(x). Returns the largest number that can be represented by numbers of type x. | x: Integer or Real result: same type as x
ILEN | Intrinsic Function | ILEN(i). Returns the length (in bits) of the two's complement representation of an integer. | i: Integer. result: same type as i
KIND | Intrinsic Function | KIND(x). Returns the value of the kind parameter of x. | x: any intrinsic type result: Integer
LOC | Intrinsic Function | LOC(a). Returns the address of a. a can be a variable, function call, expression, or constant. | a: any type result: INTEGER(4)
%LOC | Intrinsic Function | Same as LOC. |
MAXEXPONENT | Intrinsic Function | MAXEXPONENT(x). Returns the largest positive decimal exponent for data of the same type as x. | x: Real result: INTEGER(4)
MINEXPONENT | Intrinsic Function | MINEXPONENT(x). Returns the largest negative decimal exponent for data of the same type as x. | x: Real result: INTEGER(4)
NARGS | Run-time Function | NARGS( ). Returns the total number of command-line arguments, including the command. | result: INTEGER(4)
PRECISION | Intrinsic Function | PRECISION(x). Returns the number of significant digits for data of the same type as x. | x: Real or Complex result: INTEGER(4)
PRESENT | Intrinsic Function | PRESENT(a). Determines whether an optional argument is present. | a: any type result: Logical
RADIX | Intrinsic Function | RADIX(x). Returns the base for data of the same type as x. | x: Integer or Real result: INTEGER(4)
RANGE | Intrinsic Function | RANGE(x). Returns the decimal exponent range for data of the same type as x. | x: Integer, Real or Complex result: INTEGER(4)
SELECTED_INT_KIND | Intrinsic Function | SELECTED_INT_KIND(r). Returns the value of the kind parameter of integers in range r. | r: Integer result: Integer
SELECTED_REAL_KIND | Intrinsic Function | SELECTED_REAL_KIND([p], [r]). Returns the value of the kind parameter of reals with (optional) p digits and (optional) r exponent range. At least one optional argument is required. | p: Integer r: Integer result: Integer
SIZEOF | Intrinsic Function | SIZEOF(x). Returns the number of bytes of storage used by the argument. | x: any type result: INTEGER(4)
TINY | Intrinsic Function | TINY(x). Returns the smallest positive number that can be represented by numbers of type x. | x: Real result: same type as x


Memory Allocation and Deallocation Procedures: table

Name | Procedure Type | Description | Argument/Function Type
ALLOCATE | Statement | Dynamically establishes allocatable array dimensions. |
ALLOCATED | Intrinsic Function | ALLOCATED(array). Determines whether an allocatable array is allocated. | array: allocatable array result: Logical scalar
DEALLOCATE | Statement | Frees the storage space previously reserved in an ALLOCATE statement. |
FREE | Intrinsic Subroutine | FREE(addr). Frees the memory block specified by the integer pointer addr. | addr: INTEGER(4)
MALLOC | Intrinsic Function | MALLOC(size). Allocates a memory block of size size bytes and returns an integer pointer to the block. | size: INTEGER(4) result: INTEGER(4)


Array Procedures: table

Note: Square brackets [...] denote optional arguments.

Name | Procedure Type | Description | Argument/Function Type
ALL | Intrinsic Function | ALL(mask[, dim]). Determines whether all array values meet the conditions in mask along (optional) dimension dim. | mask: Logical dim: Integer result: Logical and a scalar if dim is absent or mask is one-dimensional; otherwise, one dimension smaller than mask
ANY | Intrinsic Function | ANY(mask[, dim]). Determines whether any array values meet the conditions in mask along (optional) dimension dim. | mask: Logical dim: Integer result: Logical and a scalar if dim is absent or mask is one-dimensional; otherwise, one dimension smaller than mask
BSEARCHQQ | Run-time Function | BSEARCHQQ(adr1, adr2, length, size). Performs a binary search for a specified element on a sorted one-dimensional array of non-structure data types (derived types are not allowed). | adr1: INTEGER(4) adr2: INTEGER(4) length: INTEGER(4) size: INTEGER(4) result: INTEGER(4)
COUNT | Intrinsic Function | COUNT(mask[, dim]). Counts the number of array elements that meet the conditions in mask along (optional) dimension dim. | mask: Logical dim: Integer result: Integer and a scalar if dim is absent or array is one-dimensional; otherwise, one-dimension smaller than mask
CSHIFT | Intrinsic Function | CSHIFT(array, shift [, dim]). Performs a circular shift along (optional) dimension dim. | array: any type shift: Integer dim: Integer result: same type and shape as array
DIMENSION | Statement | Identifies a variable as an array and specifies the number of elements. |
DOT_PRODUCT | Intrinsic Function | DOT_PRODUCT(vector_a, vector_b). Performs dot-product multiplication on vectors (one-dimensional arrays). | vector_a: any except Character vector_b: same type and size as vector_a result: a scalar of the same type as vector_a
EOSHIFT | Intinsic Function | EOSHIFT(array, shift [, boundary] [, dim]). Shifts elements off one end of array along (optional) dimension dim and copies (optional) boundary values in other end. | array: any type shift: Integer boundary: same as array dim: Integer result: same type and shape as array
LBOUND | Intrinsic Function | LBOUND(array [, dim] [, kind]). Returns lower dimensional bound(s) of an array along dimension dim (optional). | array: any type dim: Integer kind: Integer result: Integer and a scalar if dim is absent or array is one-dimensional; otherwise, a vector
MATMUL | Intrinsic Function | MATMUL(matrix_a, matrix_b). Performs matrix multiplication on matrices (two-dimensional arrays). | matrix_a: any except Character matrix_b: same as matrix_a result: same type as matrix_a
MAXLOC | Intrinsic Function | MAXLOC(array[, dim] [, mask]). Returns the location of the maximum value in an array meeting conditions in (optional) mask along optional dimension dim. | array: Integer or Real dim: Integer mask: Logical result: Integer vector whose size is equal to the number of dimensions in array
MAXVAL | Intrinsic Function | MAXVAL(array [, dim] [, mask]). Returns the maximum value in an array along (optional) dimension dim that meets conditions in (optional) mask. | array: Integer or Real dim: Integer mask: Logical result: same type as array and a scalar if dim is absent or array is one-dimensional; otherwise, one dimension smaller than array
MERGE | Intrinsic Function | MERGE(tsource, fsource, mask). Merges two arrays according to conditions in mask. | tsource: any type fsource: same type and shape as tsource mask: Logical result: same type and shape as tsource
MINLOC | Intrinsic Function | MINLOC(array [, dim] [, mask]). Returns the location of the minimum value in an array meeting conditions in (optional) mask along optional dimension dim. | array: Integer or Real dim: Integer mask: Logical result: Integer vector whose size is equal to the number of dimensions in array
MINVAL | Intrinsic Function | MINVAL(array [, dim] [, mask]). Returns the minimum value in an array along (optional) dimension dim that meets conditions in (optional) mask. | array: Integer or Real dim: Integer mask: Logical result: same type as array and a scalar if dim is absent or array is one-dimensional; otherwise, one dimension smaller than array
PACK | Intrinsic Function | PACK(array, mask [,vector]). Packs an array into a vector (one-dimensional array) of (optional) size vector using mask. | array: any type mask: Logical vector: same as array result: a vector (one-dimensional array) of the same type as array
PRODUCT | Intrinsic Function | PRODUCT(array [, dim] [, mask]). Returns product of elements of an array along (optional) dimension dim that meet conditions in (optional) mask. | array: Integer, Real or Complex dim: Integer mask: Logical result: same type as array and a scalar if dim is absent or array is one-dimensional; otherwise, one dimension smaller than array
RESHAPE | Intrinsic Function | RESHAPE(source, shape [, pad] [, order]). Reshapes an array with subscript order (optional), padded with array elements pad (optional). | source: any type shape: Integer pad: same as source order: Integer result: same type as source and same shape as shape
SHAPE | Intrinsic Function | SHAPE(source [, kind]). Returns the shape of an array. | source: any type kind: Integer result: a vector (one-dimensional array) of the same type as source
SIZE | Intrinsic Function | SIZE(array [, dim] [, kind]). Returns the extent of array along dimension dim (optional). | array: any type dim: Integer kind: Integer result: Integer scalar
SORTQQ | Run-time Subroutine | CALL SORTQQ(addr, count, size). Sorts a one-dimensional array of non-structure data types (derived types are not allowed). | addr: INTEGER(4) count: INTEGER(4) size: INTEGER(4)
SPREAD | Intrinsic Function | SPREAD(source, dim, ncopies). Replicates an array by adding a dimension. | source: any type dim: Integer ncopies: Integer result: same type as source and one dimension larger
SUM | Intrinsic Function | SUM(array [, dim] [, mask]). Sums array elements along dimension dim (optional) that meet conditions of mask (optional). | array: Integer, Real or Complex dim: Integer mask: Logical result: same type as array and a scalar if dim is absent or array is one-dimensional; otherwise, one dimension smaller than array
TRANSPOSE | Intrinsic Function | TRANSPOSE(matrix). Transposes a two-dimensional array. | matrix: any type result: a two-dimensional array the same type as matrix
UBOUND | Intrinsic Function | UBOUND(array [, dim] [, kind]). Returns upper dimensional bound(s) of an array along dimension dim (optional). | array: any type dim: Integer kind: Integer result: same type as array and a scalar if dim is absent or array is one-dimensional; otherwise, a vector.
UNPACK | Intrinsic Function | UNPACK(vector, mask, field). Unpacks a vector (one-dimensional array) into an array under mask padding with values from field. | vector: any type mask: Logical field: same as vector result: same type as vector and same shape as mask


Numeric and Type Conversion Procedures: table

Note: Square brackets [...] denote optional arguments.

Name | Procedure Type | Description | Argument/Function Type
ABS | Intrinsic Function | ABS(a). Returns absolute value of a. When ABS is passed as an argument, a must be REAL(4). | a: Integer, Real or Complex result: same type as a, except Real for Complex
AIMAG | Intrinsic Function | AIMAG (z). Returns imaginary part of complex number z. | z: COMPLEX(4) result: REAL(4)
AINT | Intrinsic Function | AINT (a[, kind]). Truncates a to whole number of specified kind (optional). When AINT is passed as an argument, a must be REAL(4). | a: Real kind: Integer result: Real of type kind if present; else same as a
AMAX0 | Intrinsic Function | AMAX0(a1, a2 [, a3...]). Returns largest value among integer arguments as real. | All a: INTEGER(4) result: REAL(4)
AMIN0 | Intrinsic Function | AMIN0(a1, a2 [, a3...]). Returns smallest value among integer arguments as real. | All a: INTEGER(4) result: REAL(4)
ANINT | Intrinsic Function | ANINT(a [, kind]). Rounds to nearest whole number of specified kind (optional). When ANINT is passed as an argument, a must be REAL(4). | a: Real kind: Integer result: Real of type kind if present; else same as a
CEILING | Intrinsic Function | CEILING(a [, kind]). Returns smallest integer greater than a. | a: Real kind: Integer result: INTEGER(4)
CMPLX | Intrinsic Function | CMPLX(x [,y] [,kind]). Converts x and (optional) y to complex of (optional) kind. | x: Integer, Real, or Complex. y: Integer or Real; cannot appear if x is complex type kind: Integer result: Complex of type kind if present; otherwise, single-precision complex
CONJG | Intrinsic Function | CONJG(z). Returns the conjugate of a complex number. | z: COMPLEX(4) result: COMPLEX(4)
DBLE | Intrinsic Function | DBLE(a). Converts a to double precision type. | a: Integer, Real, or Complex. result: REAL(8)
DCMPLX | Intrinsic Function | DCMPLX(x [, y]). Converts the argument to double complex type. | x: Integer, Real, or Complex. y: Integer or Real; cannot appear if x is complex type result: Double complex
DFLOAT | Intrinsic Function | DFLOAT(a). Converts an integer to double precision type. | a: Integer result: REAL(8)
DIM | Intrinsic Function | DIM(x, y). Returns x-y if positive; else 0. When DIM is passed as an argument, a must be REAL(4). | x: Integer or Real y: same as x result: same type as x
DPROD | Intrinsic Function | DPROD(x, y). Returns double-precision product of single precision x and y. | x: REAL(4) y: REAL (4) result: REAL(8)
FLOAT | Intrinsic Function | FLOAT(i). Converts i to REAL(4). | i: Integer result: REAL(4)
FLOOR | Intrinsic Function | FLOOR(a [, kind]). Returns the greatest integer less than or equal to a. | a: Real kind: Integer result: Integer
IFIX | Intrinsic Function | IFIX(a). Converts a single-precision real argument to an integer argument by truncating. | x: REAL(4) result: Default integer (usually INTEGER(4))
IMAG | Intrinsic Function | Same as AIMAG. |
INT | Intrinsic Function | INT(a [, kind]). Converts a value to integer type. | a: Integer, Real, or Complex kind: Integer result: Integer of type kind if present; else same as a
LOGICAL | Intrinsic Function | LOGICAL(l [, kind]). Converts between logical arguments of (optional) kind. | l: Logical kind: Integer
MAX | Intrinsic Function | MAX(a1, a2 [, a3...]). Returns largest value among arguments. | All a: any type result: same type as a
MAX1 | Intrinsic Function | MAX1(a1, a2 [, a3...]). Returns largest value among real arguments as integer. | All a: Real(4) result: Integer
MIN | Intrinsic Function | MIN(a1, a2 [, a3...]). Returns largest value among arguments. | All a: any type result: same type as a
MIN1 | Intrinsic Function | MIN1(a1, a2 [, a3...]). Returns smallest value among real arguments as integer | All a: REAL(4) result: Integer
MOD | Intrinsic Function | MOD(a, p). Returns remainder of a/p. When MOD is passed as an argument, a must be integer. | a: Integer or Real p: same as a result: same type as a
MODULO | Intrinsic Function | MODULO(a, p). Returns a modulo p. | a: Integer or Real p: same as a result: same type as a
NINT | Intrinsic Function | NINT(a [, kind]). Returns the nearest integer to a. | a: Real kind: Integer result: Integer of type kind if present; else see Reference entry
REAL | Intrinsic Function | REAL(a [, kind]). Converts a value to real type. | a: Integer, Real, or Complex result: REAL(4)
SIGN | Intrinsic Function | SIGN(a, b). Returns absolute value of a times the sign of b. When SIGN is passed as an argument, a must be REAL(4). | a: Integer or Real b: same as a result: same type as a
SNGL | Intrinsic Function | SNGL(a). Converts a double-precision argument to single-precision real type. | a: REAL(8) result: REAL(4)
TRANSFER | Intrinsic Function | TRANSFER(source, mold[, size]). Transforms first argument into type of second argument with (optional) size if array. | source: any type mold: any type size: Integer result: same type as mold
ZEXT | Intrinsic Function | ZEXT(x). Extends x with zeros. | a: Logical or Integer result: Default integer (usually INTEGER(4))


Trigonometric, Exponential, Root, and Logarithmic Procedures: table

Name | Description | Argument/Function Type
ACOS | ACOS(x). Returns the arc cosine of x, expressed in radians between 0 and pi. When ACOS is passed as an argument, x must be REAL(4). | x: Real result: same type as x
ACOSD | ACOSD(x). Returns the arc cosine of x, expressed in degrees between 0 and 180. When ACOSD is passed as an argument, x must be REAL(4). | x: Real result: same type as x
ALOG | ALOG(x). Returns natural log of x. | x: REAL(4) result: REAL(4)
ALOG10 | ALOG10(x). Returns common log (base 10) of x. | x: REAL(4) result: REAL(4)
ASIN | ASIN(x). Returns the arc sine of x, expressed in radians between ±pi/2. When ASIN is passed as an argument, x must be REAL(4). | x: Real result: same type as x
ASIND | ASIND(x). Returns the arc sine of x, expressed in degrees between ±90°. When ASIND is passed as an argument, x must be REAL(4). | x: Real result: same type as x
ATAN | ATAN(x). Returns the arc tangent of x, expressed in radians between ±pi/2. When ATAN is passed as an argument, x must be REAL(4). | x: Real result: same type as x
ATAND | ATAND(x). Returns the arc tangent of x, expressed in degrees between ±90°. When ATAND is passed as an argument, x must be REAL(4). | x: Real result: same type as x
ATAN2 | ATAN2(y, x). Returns the arc tangent of y/x, expressed in radians between ±pi. When ATAN2 is passed as an argument, y and x must be REAL(4). | y: Real x: same as y result: same type as y
ATAN2D | ATAN2D(y, x). Returns the arc tangent of y/x, expressed in degrees between ±180°. When ATAN2D is passed as an argument, y and x must be REAL(4). | y: Real x: same as y result: same type as y
CCOS | CCOS(x). Returns complex cosine of x. | x: COMPLEX(4) result: COMPLEX(4)
CDCOS | CDCOS(x). Returns double-precision complex cosine of x. | x: COMPLEX(8) result: COMPLEX(8)
CDEXP | CDEXP(x). Returns double-precision complex value of e**x. | x: COMPLEX(8) result: COMPLEX(8)
CDLOG | CDLOG(x). Returns double-precision complex natural log of x. | x: COMPLEX(8) result: COMPLEX(8)
CDSIN | CDSIN(x). Returns double-precision complex sine of x. | x: COMPLEX(8) result: COMPLEX(8)
CDSQRT | CDSQRT(x). Returns double-precision complex square root of x. | x COMPLEX(8) result: COMPLEX(8)
CEXP | CEXP(x). Returns complex value of e**x. | x: COMPLEX(4) result: COMPLEX(4)
CLOG | CLOG(x). Returns complex natural log of x. | x: COMPLEX(4) result: COMPLEX(4)
COS | COS(x). Returns the cosine of x, which is in radians. When COS is passed as an argument, x must be REAL(4). | x: Real or Complex result: same type as x
COSD | COSD(x). Returns the cosine of x, which is in degrees. When COSD is passed as an argument, x must be REAL(4). | x: Real result: same type as x
COSH | COSH(x). Returns the hyperbolic cosine of x. When COSH is passed as an argument, x must be REAL(4). | x: Real result: same type as x
COTAN | COTAN (x). Returns the cotangent of x, which is in radians. | x: Real result: same type as x
COTAND | COTAND (x). Returns the cotangent of x, which is in degrees. | x: Real result: same type as x
CSIN | CSIN(x). Returns complex sine of x. | x: COMPLEX(4) result: COMPLEX(4)
CSQRT | CSQRT(x). Returns complex square root of x. | x: COMPLEX(4) result: COMPLEX(4)
DACOS | DACOS(x). Returns double-precision arc cosine of x radians between 0 and pi. | x: REAL(8) result: REAL(8)
DACOSD | DACOSD(x). Returns the arc cosine of x in degrees between 0 and 180. When DACOSD is passed as an argument, x must be REAL(4). | x: REAL(8) result: REAL(8)
DASIN | DASIN(x). Returns double-precision arc sine of x in radians between ±pi/2. | x: REAL(8) result: REAL(8)
DASIND | DASIND(x). Returns double-precision arc sine of x degrees between ±90°. | x: REAL(8) result: REAL(8)
DATAN | DATAN(x). Returns double-precision arc tangent of x radians between ±pi/2. | x: REAL(8) result: REAL(8)
DATAND | DATAND(x). Returns double-precision arc tangent of x degrees between ±90°. | x: REAL(8) result: REAL(8)
DATAN2 | DATAN2(y, x). Returns double-precision arc tangent of y/x radians between ±pi. | y: REAL(8) x: REAL(8) result: REAL(8)
DATAN2D | DATAN2D(y, x). Returns double-precision arc tangent of y/x degrees between ±180°. | y: REAL(8) x: REAL(8) result: REAL(8)
DCOS | DCOS(x). Returns double-precision cosine of x radians. | x: REAL(8) result: REAL(8)
DCOSD | DCOSD(x). Returns double-precision cosine of x degrees. | x: REAL(8) result: REAL(8)
DCOSH | DCOSH(x). Returns double-precision hyperbolic cosine of x. | x: REAL(8) result: REAL(8)
DCOTAN | DCOTAN(x). Returns double-precision cotangent of x. | x: REAL(8) result: REAL(8)
DEXP | DEXP(x). Returns double-precision value of e**x | x: REAL(8) result: REAL(8)
DLOG | DLOG(x). Returns double-precision natural log of x. | x: REAL(8) result: REAL(8)
DLOG10 | DLOG10(x). Returns double-precision common log (base 10) of x. | x: REAL(8) result: REAL(8)
DSIN | DSIN(x). Returns double-precision sin of x radians. | x: REAL(8) result: REAL(8)
DSIND | DSIND(x). Returns double-precision sin of x degrees. | x: REAL(8) result: REAL(8)
DSINH | DSINH(x). Returns double-precision hyperbolic sine of x. | x: REAL(8) result: REAL(8)
DSQRT | DSQRT(x). Returns double-precision square root of x. | x: REAL(8) result: REAL(8)
DTAN | DTAN(x). Returns double-precision tangent of x radians. | x: REAL(8) result: REAL(8)
DTAND | DTAND(x). Returns double-precision tangent of x degrees. | x: REAL(8) result: REAL(8)
DTANH | DTANH(x). Returns double-precision hyperbolic tangent of x. | x: REAL(8) result: REAL(8)
EXP | EXP(x). Returns value of e**x. When EXP is passed as an argument, x must be REAL(4). | x: Real or Complex result: same type as x
LOG | LOG(x) Returns the natural log of x. | x: Real or Complex result: same type as x
LOG10 | LOG10(x). Returns the common log (base 10) of x. | x: Real result: same type as x
SIN | SIN(x). Returns the sine of x, which is in radians. When SIN is passed as an argument, x must be REAL(4). | x: Real or Complex result: same type as x
SIND | SIND(x). Returns the sine of x, which is in degrees. When SIND is passed as an argument, x must be REAL(4). | x: Real result: same type as x
SINH | SINH(x). Returns the hyperbolic sine of x. When SINH is passed as an argument, x must be REAL(4). | x: Real result: same type as x
SQRT | SQRT(x). Returns the square root of x. When SQRT is passed as an argument, x must be REAL(4). | x: Real or Complex result: same type as x
TAN | TAN(x). Returns the tangent of x, which is in radians. When TAN is passed as an argument, x must be REAL(4). | x: Real result: same type as x
TAND | TAND(x). Returns the tangent of x, which is in degrees. When TAND is passed as an argument, x must be REAL(4). | x: Real result: same type as x
TANH | TANH(x). Returns the hyperbolic tangent of x. When TANH is passed as an argument, x must be REAL(4). | x: Real result: same type as x


Floating-Point Inquiry and Control Procedures: table

Note: Certain functions (EXPONENT, FRACTION, NEAREST, RRSPACING, SCALE, SET_EXPONENT and SPACING) return values related to components of the model set of real numbers. For a description of this model, see the Model for Real Data.

Name | Procedure Type | Description | Argument/Function Type
DIGITS | Intrinsic Function | DIGITS(x). Returns number of significant digits for data of the same type as x. | x: Integer or Real result: Integer
EPSILON | Intrinsic Function | EPSILON(x). Returns the smallest positive number that when added to one produces a number greater than one for data of the same type as x. | x: Real result: same type as x
EXPONENT | Intrinsic Function | EXPONENT(x). Returns the exponent part of the representation of x. | x: Real result: Integer
FRACTION | Intrinsic Function | FRACTION(x). Returns the fractional part of the representation of x. | x: Real result: same type as x
GETCONTROLFPQQ 1 | Run-time Subroutine | GETCONTROLFPQQ(control). Returns the value of the floating-point processor control word. | control: INTEGER(2)
GETSTATUSFPQQ 1 | Run-time Subroutine | GETSTATUSFPQQ(status). Returns the value of the floating-point processor status word. | status: INTEGER(2)
HUGE | Intrinsic Function | HUGE(x). Returns largest number that can be represented by data of type x. | x: Integer or Real result: same type as x
LCWRQQ 1 | Run-time Subroutine | Same as SETCONTROLFPQQ. |
MAXEXPONENT | Intrinsic Function | MAXEXPONENT(x). Returns the largest positive decimal exponent for data of the same type as x. | x: Real result: INTEGER(4)
MINEXPONENT | Intrinsic Function | MINEXPONENT(x). Returns the largest negative decimal exponent for data of the same type as x. | x: Real result: INTEGER(4)
NEAREST | Intrinsic Function | NEAREST(x, s). Returns the nearest different machine representable number to x in the direction of the sign of s. | x: Real s: Real and not zero result: same type as x
PRECISION | Intrinsic Function | PRECISION(x). Returns the number of significant digits for data of the same type as x. | x: Real or Complex result: INTEGER(4)
RADIX | Intrinsic Function | RADIX(x). Returns the base for data of the same type as x. | x: Integer or Real result: INTEGER(4)
RANGE | Intrinsic Function | RANGE(x). Returns the decimal exponent range for data of the same type as x. | x: Integer, Real or Complex result: INTEGER(4)
RRSPACING | Intrinsic Function | RRSPACING(x). Returns the reciprocal of the relative spacing of numbers near x. | x: Real result: same type as x
SCALE | Intrinsic Function | SCALE(x, i). Multiplies x by 2 raised to the power of i. | x: Real i: Integer result: same type as x
SCWRQQ 1 | Run-time Subroutine | Same as GETCONTROLFPQQ. |
SETCONTROLFPQQ 1 | Run-time Subroutine | SETCONTROLFPQQ (controlword). Sets the value of the floating-point processor control word. | controlword: INTEGER(2)
SET_EXPONENT | Intrinsic Function | SET_EXPONENT(x, i). Returns a number whose fractional part is x and whose exponential part is i. | x: Real i: Integer result: same type as x
SPACING | Intrinsic Function | SPACING(x). Returns the absolute spacing of numbers near x. | x: Real result: same type as x
SSWRQQ 1 | Run-time Subroutine | Same as GETSTATUSFPQQ. |
TINY | Intrinsic Function | TINY(x). Returns smallest positive number that can be represented by data of type x. | x: Real result: same type as x
1 ia32 only

See also Miscellaneous Run-Time Procedures: table.


Character Procedures: table

Note: Square brackets [...] denote optional arguments.

Name | Procedure Type | Description | Argument/Function Type
ACHAR | Intrinsic Function | ACHAR(i). Returns character in position i in the ASCII character set. | i: Integer from 0 to 255 result: CHARACTER(1)
ADJUSTL | Intrinsic Function | ADJUSTL(string). Adjusts left, removing leading blanks and inserting trailing blanks. | string: Character*(*) result: same type as string
ADJUSTR | Intrinsic Function | ADJUSTR(string). Adjusts right, removing trailing blanks and inserting leading blanks. | string: Character*(*) result: same type as string
CHAR | Intrinsic Function | CHAR(i [, kind]). Returns character in position i in the processor's character set of (optional) kind. | i: Integer kind: Integer result: CHARACTER(1) of type kind if present; otherwise, default kind.
IACHAR | Intrinsic Function | IACHAR(c). Returns the position of c in the ASCII character set. | c: CHARACTER(1) result: Integer
ICHAR | Intrinsic Function | ICHAR(c). Returns the position of c in the processor's character set. | c: CHARACTER(1) result: Integer
INDEX | Intrinsic Function | INDEX(string, substring, back ]). Returns the starting position of a substring in a string, leftmost or (optional) rightmost occurance. | string: Character*(*) substring: Character*(*) back: Logical result: Integer
LEN | Intrinsic Function | LEN(string [, kind]). Returns the size of the variable string. | string: Character*(*) kind: Integer result: Integer of type kind if present; otherwise, default kind.
LEN_TRIM | Intrinsic Function | LEN_TRIM(string). Returns the number of characters in string, not counting trailing blanks. | string: Character*(*) result: Integer
LGE | Intrinsic Function | LGE(string_a, string_b). Tests whether string_a is greater than or equal to string_b, based on the ASCII collating sequence; TRUE if equal or string_a is last. | string_a: Character*(*) string_b: Character*(*) result: Logical
LGT | Intrinsic Function | LGT(string_a, string_b). Tests whether string_a is greater than string_b, based on the ASCII collating sequence; TRUE if string_a is last. | string_a: Character*(*) string_b: Character*(*) result: Logical
LLE | Intrinsic Function | LLE(string_a, string_b). Tests whether string_a is less than or equal to string_b, based on the ASCII collating sequence; TRUE if equal or string_a is first. | string_a: Character*(*) string_b: Character*(*) result: Logical
LLT | Intrinsic Function | LLT(string_a, string_b). Tests whether string_a is less than string_b, based on the ASCII collating sequence; TRUE if string_a is first. | string_a: Character*(*) string_b: Character*(*) result: Logical
REPEAT | Intrinsic Function | REPEAT(string, ncopies). Concatenates multiple copies of a string. | string: Character*(*) ncopies: Integer result: Character*(*)
SCAN | Intrinsic Function | SCAN(string, set [, back]). Scans a string for any characters in a set and returns leftmost or (optional) rightmost position where a match is found. | string: Character*(*) set: Character*(*) back: Logical result: Integer
TRIM | Intrinsic Function | TRIM(string). Removes trailing blanks from a string. | string: Character*(*) result: Character*(*)
VERIFY | Intrinsic Function | VERIFY(string, set [, back]). Returns the position of the leftmost or (optional) rightmost character in string not in set, or zero if all characters inset are present. | string: Character*(*) set: Character*(*) back: Logical result: Integer


Bit Operation and Representation Procedures: table

Note: Square brackets [...] denote optional arguments.

Name | Procedure Type | Description | Argument/Function Type
Bit Operation
BIT_SIZE | Intrinsic Function | BIT_SIZE(i). Returns the number of bits in integers of type i. | i: Integer result: same type as i
BTEST | Intrinsic Function | BTEST(i, pos). Tests a bit in position pos of i; true if bit is 1. | i: Integer pos: positive Integer result: Logical
IAND | Intrinsic Function | IAND(i, j). Performs a logical AND. | i: Integer j: Integer result: same type as i
IBCHNG | Intrinsic Function | IBCHNG(i, pos). Reverses value of bit in position pos of i. | i: Integer pos: positive Integer result: same type as i
IBCLR | Intrinsic Function | IBCLR(i, pos). Clears the bit in position pos of i to zero. | i: Integer pos: positive Integer result: same type as i
IBITS | Intrinsic Function | IBITS(i, pos, len). Extracts a sequence of bits of length len from i starting in position pos. | i: Integer pos: positive Integer len: positive Integer result: same type as i
IBSET | Intrinsic Function | IBSET(i, pos). Sets the bit in position pos of i to one. | i: Integer pos: positive Integer result: same type as i
IEOR | Intrinsic Function | IEOR(i, j). Performs an exclusive OR. | i: Integer j: Integer result: same type as i
IOR | Intrinsic Function | IOR(i, j). Performs an inclusive OR. | i: Integer j: Integer result: same type as i
ISHA | Intrinsic Function | ISHA(i, shift). Shifts i arithmetically left or right by shift bits; left if shift positive, right if shift negative. Zeros shifted in from the right, ones shifted in from the left. | i: Integer shift: Integer result: same type as i
ISHC | Intrinsic Function | ISHC(i, shift). Performs a circular shift of i left or right by shift bits; left if shift positive, right if shift negative. No bits lost. | i: Integer shift: Integer result: same type as i
ISHFT | Intrinsic Function | ISHFT(i, shift). Shifts i logically left or right by shift bits; left if shift positive, right if shift negative. Zeros shifted in from opposite end. | i: Integer shift: Integer result: same type as i
ISHFTC | Intrinsic Function | ISHFTC(i, shift[, size]). Performs a circular shift of the rightmost bits of (optional) size by shift bits. No bits lost. | i: Integer shift: Integer size: positive Integer result: same type as i
ISHL | Intrinsic Function | ISHL(i, shift). Shifts i logically left or right by shift bits. Zeros shifted in from opposite end. | i: Integer shift: Integer result: same type as i
MVBITS | Intrinsic Subroutine | MVBITS(from, frompos, len, to, topos). Copies a sequence of bits from one integer to another. | from: Integer frompos: positive Integer to: Integer topos: positive Integer
NOT | Intrinsic Function | NOT(i). Performs a logical complement. | i: Integer result: same type as i
Bit Representation
LEADZ | Intrinsic Function | LEADZ(i). Returns leading zero bits in an integer. | i: Integer result: same type as i
POPCNT | Intrinsic Function | POPCNT(i). Returns number of 1 bits in an integer. | i: Integer result: same type as i
POPPAR | Intrinsic Function | POPPAR(i). Returns the parity of an integer. | i: Integer result: same type as i
TRAILZ | Intrinsic Function | TRAILZ(i). Returns trailing zero bits in an integer. | i: Integer result: same type as i


QuickWin Procedures: table

Note: Programs that use these procedures must access the appropriate library with USE DFLIB.

Name | Procedure Type | Description
ABOUTBOXQQ | Function | Adds an About Box with customized text.
APPENDMENUQQ | Function | Appends a menu item.
CLICKMENUQQ | Function | Sends menu click messages to the application window.
DELETEMENUQQ | Function | Deletes a menu item.
FOCUSQQ | Function | Makes a child window active, and gives focus to the child window.
GETACTIVEQQ | Function | Gets the unit number of the active child window.
GETHWNDQQ | Function | Gets the true windows handle from window with the specified unit number.
GETWINDOWCONFIG | Function | Returns the current window's properties.
GETWSIZEQQ | Function | Gets the size of the child or frame window.
GETUNITQQ | Function | Gets the unit number corresponding to the specified windows handle. Inverse of GETHWNDQQ.
INCHARQQ | Function | Reads a keyboard input and return its ASCII value.
INITIALSETTINGS | Function | Controls initial menu settings and initial frame window settings.
INQFOCUSQQ | Function | Determines which window is active and has the focus.
INSERTMENUQQ | Function | Inserts a menu item.
INTEGERTORGB | Subroutine | Converts a true color value into its red, green and blue components.
MESSAGEBOXQQ | Function | Displays a message box.
MODIFYMENUFLAGSQQ | Function | Modifies a menu item state.
MODIFYMENUROUTINEQQ | Function | Modifies a menu item's callback routine.
MODIFYMENUSTRINGQQ | Function | Changes a menu item's text string.
PASSDIRKEYSQQ | Function | Determines the behavior of direction and page keys.
REGISTERMOUSEEVENT | Function | Registers the application-defined routines to be called on mouse events.
RGBTOINTEGER | Function | Converts a trio of red, green and blue values to a true color value for use with RGB functions and subroutines.
SETACTIVEQQ | Function | Makes the specified window the current active window without giving it the focus.
SETMESSAGEQQ | Subroutine | Changes any QuickWin message, including status bar messages, state messages and dialog box messages.
SETWINDOWCONFIG | Function | Configures the current window's properties.
SETWINDOWMENUQQ | Function | Sets the Window menu to which current child window names will be appended.
SETWSIZEQQ | Function | Sets the size of the child or frame window.
UNREGISTERMOUSEEVENT | Function | Removes the callback routine registered by REGISTERMOUSEEVENT.
WAITONMOUSEEVENT | Function | Blocks return until a mouse event occurs.

For more information on using these procedures, see Using QuickWin.


Graphics Procedures: table

Note: Programs that use these procedures must access the appropriate library with USE DFLIB.

Name | Procedure Type | Description
ARC, ARC_W | Functions | Draws an arc.
CLEARSCREEN | Subroutine | Clears the screen, viewport, or text window.
DISPLAYCURSOR | Function | Turns the cursor off and on.
ELLIPSE, ELLIPSE_W | Functions | Draws an ellipse or circle.
FLOODFILL, FLOODFILL_W | Functions | Fills an enclosed area of the screen with the current color index, using the current fill mask.
FLOODFILLRGB, FLOODFILLRGB_W | Functions | Fills an enclosed area of the screen with the current RGB color, using the current fill mask.
GETARCINFO | Function | Determines the end points of the most recently drawn arc or pie.
GETBKCOLOR | Function | Returns the current background color index.
GETBKCOLORRGB | Function | Returns the current background RGB color.
GETCOLOR | Function | Returns the current color index.
GETCOLORRGB | Function | Returns the current RGB color.
GETCURRENTPOSITION, GETCURRENTPOSITION_W | Subroutines | Returns the coordinates of the current graphics-output position.
GETFILLMASK | Subroutine | Returns the current fill mask.
GETFONTINFO | Function | Returns the current font characteristics.
GETGTEXTEXTENT | Function | Determines the width of the specified text in the current font.
GETGTEXTROTATION | Function | Get the current text rotation angle.
GETIMAGE, GETIMAGE_W | Subroutines | Stores a screen image in memory.
GETLINESTYLE | Function | Returns the current line style.
GETPHYSCOORD | Subroutine | Converts viewport coordinates to physical coordinates.
GETPIXEL, GETPIXEL_W | Functions | Returns a pixel's color index.
GETPIXELRGB, GETPIXELRGB_W | Functions | Returns a pixel's RGB color.
GETPIXELS | Function | Returns the color indices of multiple pixels.
GETPIXELSRGB | Function | Returns the RGB colors of multiple pixels.
GETTEXTCOLOR | Function | Returns the current text color index.
GETTEXTCOLORRGB | Function | Returns the current text RGB color.
GETTEXTPOSITION | Subroutine | Returns the current text-output position.
GETTEXTWINDOW | Subroutine | Returns the boundaries of the current text window.
GETVIEWCOORD, GETVIEWCOORD_W | Subroutines | Converts physical or window coordinates to viewport coordinates.
GETWINDOWCOORD | Subroutine | Converts viewport coordinates to window coordinates.
GETWRITEMODE | Function | Returns the logical write mode for lines.
GRSTATUS | Function | Returns the status (success or failure) of the most recently called graphics routine.
IMAGESIZE, IMAGESIZE_W | Functions | Returns image size in bytes.
INITIALIZEFONTS | Function | Initializes the font library.
LINETO, LINETO_W | Functions | Draws a line from the current position to a specified point.
LINETOAR | Function | Draws a line between points in one array and corresponding points in another array.
LINETOAREX | Function | Similar to LINETOAR, but also lets you specify color and line style.
LOADIMAGE, LOADIMAGE_W | Functions | Reads a Windows bitmap file (.BMP) and displays it at the specified location.
MOVETO, MOVETO_W | Subroutines | Moves the current position to the specified point.
OUTGTEXT | Subroutine | Sends text in the current font to the screen at the current position.
OUTTEXT | Subroutine | Sends text to the screen at the current position.
PIE, PIE_W | Functions | Draws a pie slice.
POLYBEZIER, POLYBEZIER_W | Functions | Draws one or more Bezier curves.
POLYBEZIERTO, POLYBEZIERTO_W | Functions | Draws one or more Bezier curves.
POLYGON, POLYGON_W | Functions | Draws a polygon.
POLYLINEQQ | Function | Draws a line between successive points in an array.
PUTIMAGE, PUTIMAGE_W | Subroutines | Retrieves an image from memory and displays it.
RECTANGLE, RECTANGLE_W | Functions | Draws a rectangle.
REMAPALLPALETTERGB | Function | Remaps a set of RGB color values to indices recognized by the current video configuration.
REMAPPALETTERGB | Function | Remaps a single RGB color value to a color index.
SAVEIMAGE, SAVEIMAGE_W | Functions | Captures a screen image and saves it as a Windows bitmap file.
SCROLLTEXTWINDOW | Subroutine | Scrolls the contents of a text window.
SETBKCOLOR | Function | Sets the current background color.
SETBKCOLORRGB | Function | Sets the current background color to a direct color value rather than an index to a defined palette.
SETCLIPRGN | Subroutine | Limits graphics output to a part of the screen.
SETCOLOR | Function | Sets the current color to a new color index.
SETCOLORRGB | Function | Sets the current color to a direct color value rather than an index to a defined palette.
SETFILLMASK | Subroutine | Changes the current fill mask to a new pattern.
SETFONT | Function | Finds a single font matching the specified characteristics and assigns it to OUTGTEXT.
SETGTEXTROTATION | Subroutine | Sets the direction in which text is written to the specified angle.
SETLINESTYLE | Subroutine | Changes the current line style.
SETMOUSECURSOR | Function | Sets the mouse cursor for the window in focus.
SETPIXEL, SETPIXEL_W | Functions | Sets color of a pixel at a specified location.
SETPIXELRGB, SETPIXELRGB_W | Functions | Sets RGB color of a pixel at a specified location.
SETPIXELS | Subroutine | Sets the color indices of multiple pixels.
SETPIXELSRGB | Subroutine | Sets the RGB color of multiple pixels.
SETTEXTCOLOR | Function | Sets the current text color to a new color index.
SETTEXTCOLORRGB | Function | Sets the current text color to a direct color value rather than an index to a defined palette.
SETTEXTCURSOR | Function | Sets the height and width of the text cursor for the window in focus.
SETTEXTPOSITION | Subroutine | Changes the current text position.
SETTEXTWINDOW | Subroutine | Sets the current text display window.
SETVIEWORG | Subroutine | Positions the viewport coordinate origin.
SETVIEWPORT | Subroutine | Defines the size and screen position of the viewport.
SETWINDOW | Function | Defines the window coordinate system.
SETWRITEMODE | Function | Changes the current logical write mode for lines.
WRAPON | Function | Turns line wrapping on or off.

For more information on using these procedures, see Using QuickWin.


Dialog Procedures: table

Note: Programs that use these procedures must access the Dialog library with USE DFLOGM. Square brackets [...] denote optional arguments.

Name | Procedure Type | Description | Argument/Function Type
DLGEXIT | Subroutine | CALL DLGEXIT(dlg). Closes an open dialog. | dlg: DIALOG derived type
DLGFLUSH | Subroutine | CALL DLGFLUSH(dlg [, flushall]). Updates the display of a dialog box. | dlg: DIALOG derived type flushall: Logical
DLGGET | Function | DLGGET(dlg, controlid, value [, index]). Retrieves values of dialog control variables. | dlg: DIALOG derived type controlid: Integer value: Integer, Logical or Character index: Integer result: Logical
DLGGETCHAR | Function | DLGGETCHAR(dlg, controlid, value [, index]). Retrieves values of dialog control variables of type Character. | dlg: DIALOG derived type controlid: Integer value: Character index: Integer result: Logical
DLGGETINT | Function | DLGGETINT(dlg, controlid, value [, index]). Retrieves values of dialog control variables of type Integer. | dlg: DIALOG derived type controlid: Integer value: Integer index: Integer result: Logical
DLGGETLOG | Function | DLGGETLOG(dlg, controlid, value [, index]). Retrieves values of dialog control variables of type Logical. | dlg: DIALOG derived type controlid: Integer value: Logical index: Integer result: Logical
DLGINIT | Function | DLGINIT(dlgid, dlg). Initializes a dialog. | dlgid: Integer dlg: DIALOG derived type result: Logical
DLGINITWITHRESOURCEHANDLE | Function | DLGINITWITHRESOURCEHANDLE(dlgid, hinst, dlg). Initializes a dialog. | dlgid: Integer hinst: Integer dlg: DIALOG derived type result: Logical
DLGISDLGMESSAGE | Function | DLGISDLGMESSAGE(mesg). Determines whether a message is intended for a modeless dialog box and, if it is, processes it. | mesg: T_MSG derived type result: Logical
DLGISDLGMESSAGEWITHDLG | Function | DLGISDLGMESSAGEWITHDLG(mesg, dlg). Determines whether a message is intended for a specific modeless dialog box and, if it is, processes it. | mesg: T_MSG derived type dlg: DIALOG derived type result: Logical
DLGMODAL | Function | DLGMODAL(dlg). Displays a dialog and processes dialog selections from user. | dlg: DIALOG derived type result: Integer
DLGMODALWITHPARENT | Function | DLGMODALWITHPARENT(dlg, hwndParent). Displays a dialog in a specific parent window and processes dialog selections from user. | dlg: DIALOG derived type hwndParent: Integer result: Integer
DLGMODELESS | Function | DLGMODELESS(dlg [, nCmdShow, hwndParent]). Displays a modeless dialog box. | dlg: DIALOG derived type nCmdShow: Integer hwndParent: Integer result: Logical
DLGSENDCTRLMESSAGE | Function | DLGSENDCTRLMESSAGE(dlg, controlid, msg, wparam, lparam). Sends a message to a dialog box control. | dlg: DIALOG derived type controlid: Integer msg: Integer wparam: Integer lparam: Integer result: Integer
DLGSET | Function | DLGSET(dlg, controlid, value [, index]). Assigns values to dialog control variables. | dlg: DIALOG derived type controlid: Integer value: Integer, Logical or Character index: Integer result: Logical
DLGSETCHAR | Function | DLGSETCHAR(dlg, controlid, value [, index]). Assigns values to dialog control variables of type Character. | dlg: DIALOG derived type controlid: Integer value: Character index: Integer result: Logical
DLGSETCTRLEVENTHANDLER | Function | DLGSETCTRLEVENTHANDLER(dlg, controlid, handler, dispid [, iid]). Assigns your own event handlers to ActiveX controls in a dialog box. | dlg: DIALOG derived type controlid: Integer handler: external procedure name dispid: Integer iid: GUID derived type result: INTEGER(4)
DLGSETINT | Function | DLGSETINT(dlg, controlid, value [, index]). Assigns values to dialog control variables of type Integer. | dlg: DIALOG derived type controlid: Integer value: Integer index: Integer result: Logical
DLGSETLOG | Function | DLGSETLOG(dlg, controlid, value [, index]). Assigns values to dialog control variables of type Logical. | dlg: DIALOG derived type controlid: Integer value: Logical index: Integer result: Logical
DLGSETRETURN | Subroutine | CALL DLGSETRETURN(dlg, retval). Sets the return value for DLGMODAL. | dlg: DIALOG derived type retval: Integer
DLGSETSUB | Function | DLGSETSUB(dlg, controlid, value [, index]). Assigns procedures (callback routines) to dialog controls. | dlg: DIALOG derived type controlid: Integer value: external procedure name index: Integer result: Logical
DLGSETTITLE | Subroutine | CALL DLGSETTITLE(dlg, title). Sets the title of a dialog box. | dlg: DIALOG derived type title: Character*(*)
DLGUNINIT | Subroutine | CALL DLGUNINIT(dlg). Deallocates memory occupied by an initialized dialog. | dlg: DIALOG derived type

For more information on using these procedures, see Using Dialogs.


General Compiler Directives: table

Note: Each directive name is preceded by the prefix c DEC$; for example, c DEC$ ALIAS. The c can be a c, C, !, or *.

Name | Description
ALIAS | Specifies an alternate external name to be used when referring to external subprograms.
ATTRIBUTES | Applies attributes to variables and procedures.
DECLARE | Generates warning messages for undeclared variables.
DEFINE | Creates a variable whose existence can be tested during conditional compilation.
ELSE | Marks the beginning of an alternative conditional-compilation block to an IF directive construct.
ELSEIF | Marks the beginning of an alternative conditional-compilation block to an IF directive construct.
ENDIF | Marks the end of a conditional-compilation block.
FIXEDFORMLINESIZE | Sets fixed-form line length. This directive has no effect on freeform code.
FREEFORM | Uses freeform format for source code.
IDENT | Specifies an identifier for an object module.
IF | Marks the beginning of a conditional-compilation block.
IF DEFINED | Marks the beginning of a conditional-compilation block.
INTEGER | Selects default integer size.
IVDEP | Assists the compiler's dependence analysis.
MESSAGE | Sends a character string to the standard output device.
NODECLARE | (Default) Turns off warning messages for undeclared variables.
NOFREEFORM | (Default) Uses standard FORTRAN 77 code formatting column rules.
NOSTRICT | (Default) Disables a previous STRICT directive.
OBJCOMMENT | Specifies a library search path in an object file.
OPTIONS | Controls whether fields in records and data items in common blocks are naturally aligned or packed on arbitrary byte boundaries.
PACK | Specifies the memory starting addresses of derived-type items.
PSECT | Modifies certain characteristics of a common block.
REAL | Selects default real size.
STRICT | Disables Visual Fortran features not in the Fortran 90 Standard.
SUBTITLE | Prints the specified subtitle on subsequent pages of the source listing.
TITLE | Prints the specified title on subsequent pages of the source listing.
UNDEFINE | Removes a symbolic variable name created with the DEFINE directive.
UNROLL | Tells the compiler's optimizer how many times to unroll a DO loop.

For more information on using these directives, see General Compiler Directives.


National Language Standard Procedures: table

Note: Programs that use these procedures must access the NLS library with USE DFNLS.

Name | Procedure Type | Description
MBCharLen | Function | Returns the length of the first multibyte character in a string.
MBConvertMBToUnicode | Function | Converts a character string from a multibyte codepage to a Unicode string.
MBConvertUnicodeToMB | Function | Converts a Unicode string to a multibyte character string of the current codepage.
MBCurMax | Function | Returns the longest possible mutlibyte character for the current codepage.
MBINCHARQQ | Function | Same as INCHARQQ, but can read a single multibyte character at once.
MBINDEX | Function | Same as INDEX, except that multibyte characters can be included in its arguments.
MBJISToJMS | Function | Converts a Japan Industry Standard (JIS) character to a Kanji (Shift JIS or JMS) character.
MBJMSToJIS | Function | Converts a Kanji (Shift JIS or JMS) character to a Japan Industry Standard (JIS) character.
MBLead | Function | Determines whether a given character is the first byte of a multibyte character.
MBLen | Function | Returns the number of multibyte characters in a string, including trailing spaces.
MBLen_Trim | Function | Returns the number of multibyte characters in a string, not including trailing spaces.
MBLGE, MBLGT, MBLLE, MBLLT,MBLEQ, MBLNE | Function | Same as LGE, LGT, LLE, and LLT, and the logical operators .EQ. and .NE., except that multibyte characters can be included in their arguments.
MBNext | Function | Returns the string position of the first byte of the multibyte character immediately after the given string position.
MBPrev | Function | Returns the string position of the first byte of the multibyte character immediately before the given string position.
MBSCAN | Function | Same as SCAN, except that multibyte characters can be included. in its arguments
MBStrLead | Function | Performs a context sensitive test to determine whether a given byte in a character string is a lead byte.
MBVERIFY | Function | Same as VERIFY, except that multibyte characters can be included in its arguments.
NLSEnumCodepages | Function | Returns an array of valid codepages for the current console.
NLSEnumLocales | Function | Returns an array of locales (langauge/country combinations) installed on the system.
NLSFormatCurrency | Function | Formats a currency number according to conventions of the current locale (language/country).
NLSFormatDate | Function | Formats a date according to conventions of the current locale (language/country).
NLSFormatNumber | Function | Formats a number according to conventions of the current locale (language/country).
NLSFormatTime | Function | Formats a time according to conventions of the current locale (language/country).
NLSGetEnvironmentCodepage | Function | Returns the current codepage for the system Window or console.
NLSGetLocale | Subroutine | Returns the current language, country, and/or codepage.
NLSGetLocaleInfo | Function | Returns information about the current locale.
NLSSetEnvironmentCodepage | Function | Sets the codepage for the console.
NLSSetLocale | Function | Sets the current language, country, and codepage.

For more information on using these procedures, see Using National Language Support Routines.

See also NLS Date and Time Format.


Portability Procedures: table

Note: Programs that use these procedures must access the portability library with USE DFPORT. Square brackets [...] denote optional arguments.

Name | Procedure Type | Description | Argument/Function Type
ABORT | Subroutine | CALL ABORT([str]). Flushes and closes all I/O buffers and terminates execution with the optional abort message in string. | str: CHARACTER*(*)
ACCESS Function ACCESS(nm, md). Checks the file name specified by nm for accessibility to the caller in md mode. nm: CHARACTER*(*)

md: CHARACTER*(*)

result: INTEGER(4)

ALARM Function ALARM(time, proc). Executes the subroutine proc after time seconds elapse. time: INTEGER(4)

proc: External procedure

result: INTEGER(4)

BESJ0, BESJ1,
BESJN, BESY0,
BESY1, BESYN 		Functions Bessel functions of the first and second kinds and integer orders. BESJ0(x), BESJ1(x), BESY0(x), BESY1(x) take argument x. BESJN(n, x) and BESYN(n, x) take arguments integer order n and value x. n: INTEGER(4)

x: REAL(4)

result: REAL(4)

BIC, BIS, BIT Subroutines
and
Function 		Bit clear and set subroutines, and bit test function.

CALL BIC(bitnum, target) clears a bit.

CALL BIS(bitnum, target) sets a bit.

BIT(bitnum, source) tests a bit.

bitnum: INTEGER(4)

target: INTEGER(4)

source: INTEGER(4)

return from BIT: Logical

CHDIR Function CHDIR(dir_name). Changes the default directory to dir_name. dir_name: CHARACTER*(*)

result: INTEGER(4)

CHMOD Function CHMOD(nm, md). Changes the md attributes of a file name specified by nm. nm: CHARACTER*(*)

md: CHARACTER*(*)

result: INTEGER(4)

CLOCK Function CLOCK( ). Returns the time in HH:MM:SS format. result:
CHARACTER(len=8)
CTIME Function CTIME(stime). Converts system time to a 24-character ASCII string. stime: INTEGER(4)

result:
CHARACTER(len=24)

DATE Subroutine
or Function 		CALL DATE(str) or
DATE( ). Returns the date as an ASCII string. 		str: CHARACTER*(*)

return from DATE:
CHARACTER(len=8)
DBESJ0, DBESJ1,
DBESJN, DBESY0,
DBESY1, DBESYN 		Functions REAL(8) Bessel functions of the first and second kinds and integer orders. DBESJ0(x), DBESJ1(x), DBESY0(x), DBESY1(x) take argument x. DBESJN(n, x) and DBESYN(n, x) take arguments integer order n and value x. n: INTEGER(4)

x: REAL(8)

result: REAL(8)

DRAND,
DRANDM 		Functions DRAND(iflag) and DRANDM(iflag). Return random numbers between 0.0 and 1.0, chosen according to the value of iflag. iflag: INTEGER(4)

result: REAL(8)

DTIME 1 Function DTIME(tarray). Returns the elapsed time since the last call to DTIME or the program start. tarray(2): REAL(4)

result: REAL(4)

ETIME 1 Function ETIME(tarray). Returns the elapsed CPU time since the last call to ETIME or the program start. tarray(2): REAL(4)

result: REAL(4)

FDATE Subroutine
or Function 		CALL FDATE(str) or
FDATE( ). Returns the date and time as an ASCII string. 		str: CHARACTER*(*)

return from FDATE:
CHARACTER(len=24)
FGETC Function FGETC(lunit, char). Reads the next available character from lunit and places it in char. lunit: INTEGER(4)

char:CHARACTER(len=1)

result: INTEGER(4)

FLUSH | Subroutine | CALL FLUSH(lunit). Causes the contents of the lunit buffer to be flushed to the associated file. | lunit: INTEGER(4)
FPUTC Function FPUTC(lunit, char). Writes a character char to the file associated with lunit, bypassing normal Fortran I/O. lunit: INTEGER(4)

char:CHARACTER(len=1)

result: INTEGER(4)

FSEEK Subroutine FSEEK(lunit, offset, from). Repositions a file on a logical unit to offset bytes relative to position from. lunit: INTEGER(4)

offset: INTEGER(4)

from: INTEGER(4)

result: INTEGER(4)

FSTAT Function FSTAT(lunit, statb). Returns information about lunit in the array statb. lunit: INTEGER(4)

statb(12): INTEGER(4)

result: INTEGER(4)

FTELL Function FTELL(lunit). Returns the current position of the file associated with lunit as an offset in bytes from the beginning of the file. lunit: INTEGER(4)

result: INTEGER(4)

GERROR | Subroutine | CALL GERROR(str). Fills string with a message for the last detected IERRNO error. | str: CHARACTER*(*)
GETC Function GETC(char). Gets the next available character from logical unit 5, usually connected to the console, and places it in char, bypassing normal Fortran I/O. char:CHARACTER(len=1)

result: INTEGER(4)

GETCWD Function GETCWD(dirname). Places the current working directory path in dirname. dirname: CHARACTER*(*)

result: INTEGER(4)

GETENV Function CALL GETENV(ename, eval). Searches the environment list for a string of the form ename=eval and returns the value found in eval or blanks. ename:
CHARACTER*(*)

eval:
CHARACTER*(*)

GETGID | Function | GETGID( ). Included for portability. Always returns 1. | result: INTEGER(4) equal to 1
GETLOG | Subroutine | CALL GETLOG(nm). Returns the user's login name or blanks. | nm: CHARACTER*(*)
GETPID | Function | GETPID( ). Returns the process ID number of the current process. | result: INTEGER(4)
GETUID | Function | GETUID( ). Included for portability. Always returns 1. | result: INTEGER(4) equal to 1
GMTIME Subroutine CALL GMTIME(stime, tarray). Separates the time returned by TIME( ) in stime into GMT date and time and stores in tarray. stime: INTEGER(4)

tarray(9): INTEGER(4)
HOSTNAM Function HOSTNAM(nm). Puts the name of the current host into nm. nm: CHARACTER*(*)

result: INTEGER(4)

IARGC | Function | IARGC( ). Returns the index of the last command-line argument. | result: INTEGER(4)
IDATE Subroutine CALL IDATE(iarray) or
CALL IDATE(month, day, year). Returns the day, month and year in iarray or the parameters month, day, and year. 		iarray(3): INTEGER(4)

month: INTEGER(4)

day: INTEGER(4)

year: INTEGER(4)
IERRNO | Function | IERRNO( ). Returns the last IERRNO error code. | result: INTEGER(4)
IRAND,
IRANDM 		Functions IRAND(iflag) and IRANDM(iflag). Return integer random numbers between 0 and (2**31) -1, chosen according to the value of iflag. iflag: INTEGER(4)

result: INTEGER(4)

ITIME | Subroutine | CALL ITIME(iarray). Returns the current time in iarray. | iarray(3): INTEGER(4)
JDATE Function JDATE( ). Return the Julian date in the form YYDDD. result:
CHARACTER(len=8)
KILL Function KILL(pid, signum). Sends a signal designated by signum (defined in SIGNAL) to the calling process designated by pid (returned by GETPID). pid: INTEGER(4)

signum: INTEGER(4)

result: INTEGER(4)

LNBLNK Function LNBLNK(str). Returns the index of the last nonblank character in str. str: CHARACTER*(*)

result: INTEGER(4)

LONG Function LONG(int2). Returns an INTEGER(2) argument as an INTEGER(4). int2: INTEGER(2)

result: INTEGER(4)

LSTAT Function LSTAT(nm, statb). Returns information about the file named nm in the array statb. nm: CHARACTER*(*)

statb(12): INTEGER(4)

result: INTEGER(4)

LTIME Subroutine CALL LTIME(stime, tarray). Separates the time returned by TIME( ) in stime into the date and time for the local time zone and stores in tarray. stime: INTEGER(4)

tarray(9): INTEGER(4)

PERROR | Subroutine | CALL PERROR(str). Sends an error message to the standard error stream, preceded by str with a message for the last detected IERRNO error. | str: CHARACTER*(*)
PUTC Function PUTC(char).Writes a character char to logical unit 6. char:CHARACTER(len=1)

result: INTEGER(4)

QSORT Subroutine CALL QSORT(array, len, isize, compar). Sorts len elements of array each of length size according to the sorting order in a user-supplied function compar. array: any type

len: INTEGER(4)

isize: INTEGER(4)

compar: External INTEGER(2) function

RAN Function RAN(iseed). Returns a uniformly distributed random number between 0.0 and 1.0. seed: INTEGER(4)

result: REAL(4)

RAND,
RANDOM 		Functions RAND(iflag) and RANDOM(iflag). Return random numbers between 0.0 and 1.0, chosen according to the value of iflag. iflag: INTEGER(4)

result: REAL(4)

RENAME Function RENAME(from, to). Renames a file from from to to. If to exists it is removed first. from:
CHARACTER*(*)

to: CHARACTER*(*)

result: INTEGER(4)

RINDEX Function RINDEX(str, substr). Returns the index of the last occurrence of substr in str, or 0. str: CHARACTER*(*)

substr:
CHARACTER*(*)

result: INTEGER(4)

RTC | Function | RTC( ). Returns the number of seconds since 00:00:00 Greenwich mean time, January 1, 1970. | result: REAL(8)
SECNDS Function SECNDS(offset). Returns the number of seconds that have elapsed since midnight, minus offset. offset: REAL(4)

result: REAL(4)

SHORT Function SHORT(int4). Returns an INTEGER(4) argument as an INTEGER(2). int4: INTEGER(4)

result: INTEGER(2)

SIGNAL Function SIGNAL(signum, proc, flag). Changes the action taken for the signal designated by signum to the external signal processing procedure proc. Implementation of proc is controlled by flag. signum: INTEGER(4)

proc: External function

flag: INTEGER(4)

result: INTEGER(4)

SLEEP | Subroutine | CALL SLEEP(itime). Suspends the calling process for itime seconds. | itime: INTEGER(4)
STAT Function STAT(nm, statb). Returns information about the file named nm in the array statb. nm: CHARACTER*(*)

statb(12): INTEGER(4)

result: INTEGER(4)

SYSTEM Function SYSTEM(str). Causes str to be given to your shell as input as if str had been typed as a command. str: CHARACTER*(*)

result: INTEGER(4)

TIME Subroutine
or Function 		CALL TIME(str) or
TIME( ). As a subroutine, fills str with the current time formatted as HH:MM:SS. As a function, returns elapsed seconds since 00:00:00 Greenwich mean time, January 1, 1970. 		str:CHARACTER(len=8)

result: INTEGER(4)

TIMEF | Function | TIMEF( ). Returns the number of seconds since the first time it was called. The first time called, TIMEF returns 0.0D0. | result: REAL(8)
UNLINK Function UNLINK(nm). Removes the file specified by path nm. nm: CHARACTER*(*)

result: INTEGER(4)

1 WNT only

Warning: The two-digit year return value of DATE, IDATE, and JDATE may cause problems with the year 2000. Use DATE_AND_TIME instead.

For more information on using these procedures, see Portability Library in the Programmer's Guide.


COM and Automation Procedures: table

Note: Programs that use COM procedures must access the appropriate libraries with USE DFCOM. Programs that use Automation procedures must access the appropriate libraries with USE DFAUTO. Some procedures also require the USE DFWINTY module.

Component Object Model (COM) Procedures (DFCOM)
Name | Procedure Type | Description
COMAddObjectReference | Function | Adds a reference to an object's interface.
COMCLSIDFromProgID | Subroutine | Passes a programmatic identifier and returns the corresponding class identifier.
COMCLSIDFromString | Subroutine | Passes a class identifier string and returns the corresponding class identifier.
COMCreateObjectByGUID | Subroutine | Passes a class identifier, creates an instance of an object, and returns a pointer to the object's interface.
COMCreateObjectByProgID | Subroutine | Passes a programmatic identifier, creates an instance of an object, and returns a pointer to the object's IDispatch interface.
COMGetActiveObjectByGUID | Subroutine | Passes a class identifier and returns a pointer to the interface of a currently active object.
COMGetActiveObjectByProgID | Subroutine | Passes a programmatic identifier and returns a pointer to the IDispatch interface of a currently active object.
COMGetFileObject | Subroutine | Passes a file name and returns a pointer to the IDispatch interface of an Automation object that can manipulate the file.
COMInitialize | Subroutine | Initializes the COM library.
COMIsEqualGUID | Function | Determines whether two GUIDs are the same.
COMQueryInterface | Subroutine | Passes an interface identifier and returns a pointer to an object's interface.
COMReleaseObject | Function | Indicates that the program is done with a reference to an object's interface.
COMStringFromGUID | Subroutine | Passes a GUID and returns a string of printable characters.
COMUninitialize | Subroutine | Uninitializes the COM library.
Automation Server Procedures (DFAUTO)
Name | Procedure Type | Description
AUTOAddArg | Subroutine | Passes an argument name and value and adds the argument to the argument list data structure.
AUTOAllocateInvokeArgs | Function | Allocates an argument list data structure that holds the arguments to be passed to AUTOInvoke.
AUTODeallocateInvokeArgs | Subroutine | Deallocates an argument list data structure.
AUTOGetExceptInfo | Subroutine | Retrieves the exception information when a method has returned an exception status.
AUTOGetProperty | Function | Passes the name or identifier of the property and gets the value of the Automation object's property.
AUTOGetPropertyByID | Function | Passes the member ID of the property and gets the value of the Automation object's property into the argument list's first argument.
AUTOGetPropertyInvokeArgs | Function | Passes an argument list data structure and gets the value of the Automation object's property specified in the argument list's first argument.
AUTOInvoke | Function | Passes the name or identifier of an object's method and an argument list data structure and invokes the method with the passed arguments.
AUTOSetProperty | Function | Passes the name or identifier of the property and a value, and sets the value of the Automation object's property.
AUTOSetPropertyByID | Function | Passes the member ID of the property and sets the value of the Automation object's property, using the argument list's first argument.
AUTOSetPropertyInvokeArgs | Function | Passes an argument list data structure and sets the value of the Automation object's property specified in the argument list's first argument.

For more information on using these procedures, see Using COM and Automation Objects.


Serial Port Procedures: table

Note: Programs that use SPORT_nnnn procedures must access the appropriate libraries with USE DFLIB. The following are all functions.

Name | Description
SPORT_CONNECT | Establishes the connection to a serial port.
SPORT_RELEASE | Releases a serial port that has previously been connected.
SPORT_GET_HANDLE | Returns the Win32 handle associated with the communications port.
SPORT_GET_STATE | Returns the baud rate, parity, data bits and stop bit settings of the communications port.
SPORT_SET_STATE | Sets the baud rate, parity, data bits and stop bit settings of the communications port.
SPORT_SHOW_STAT | Displays the state of a port.
SPORT_GET_TIMEOUTS | Returns the user selectable timeouts for the serial port.
SPORT_SET_TIMEOUTS | Sets the user selectable timeouts for the serial port.
SPORT_SPECIAL_FUNC | Executes a communications function on a specified port.
SPORT_WRITE_DATA | Outputs data to a specified port.
SPORT_WRITE_LINE | Outputs data to a specified port and follows it with a record terminator.
SPORT_READ_DATA | Reads available data from the port specified.
SPORT_READ_LINE | Reads a record from the port specified.
SPORT_PEEK_DATA | Returns information about the availability of input data.
SPORT_PEEK_LINE | Returns information about the availability of input records.
SPORT_PURGE | Executes a purge function on the specified port.
SPORT_CANCEL_IO | Cancels any I/O in progress to the specified port.

For more information on using these procedures, see Using the Serial I/O Port Routines, and Communications and Communications Functions in the "Platform SDK".


Miscellaneous Run-Time Procedures: table

Name | Procedure Type | Description
FOR_CHECK_FLAWED_PENTIUM | Function | FOR_CHECK_FLAWED_PENTIUM( ). Checks the processor to determine if it shows characteristics of the Pentium® floating-point divide flaw.
FOR_GET_FPE | Function | FOR_GET_FPE( ). Returns the current settings of floating-point exception flags.
FOR_RTL_FINISH_ | Function | FOR_RTL_FINISH_ ( ). Cleans up the Fortran run-time environment; for example, flushing buffers and closing files. It also issues messages about floating-point exceptions, if any occur.
FOR_RTL_INIT_ | Subroutine | FOR_RTL_INIT_(argcount, actarg). Initializes the Fortran run-time environment. It establishes handlers and floating-point exception handling, so Fortran subroutines behave the same as when called from a Fortran main program.
FOR_SET_FPE | Function | FOR_SET_FPE(a). Sets the floating-point exception flags.
FOR_SET_REENTRANCY | Function | FOR_SET_REENTRANCY(mode). Controls the type of reentrancy protection that the Fortran Run-Time Library (RTL) exhibits.


Functions Not Allowed as Actual Arguments: table

The following specific functions cannot be passed as actual arguments:

AIMAX0 | EOF | JIDINT | MAX0
AIMIN0 | FLOAT | JIFIX | MAX1
AJMAX0 | FLOATI | JINT | MIN0
AJMIN0 | FLOATJ | JMAX0 | MIN1
AKMAX0 | FLOATK | JMAX1 | MULT_HIGH
AKMIN0 | ICHAR | JMIN0 | NUMBER_OF_PROCESSORS
AMAX0 | IDINT | JMIN1 | NWORKERS
AMAX1 | IFIX | KIDINT | PROCESSORS_SHAPE
AMIN0 | IIDINT | KIFIX | QCMPLX
AMIN1 | IIFIX | KINT | QEXT
CHAR | IINT | KIQINT | QEXTD
CMPLX | IMAX0 | KIQNNT | QMAX1
DBLE | IMAX1 | KMAX0 | QMIN1
DBLEQ | IMIN0 | KMAX1 | QREAL
DCMPLX | IMIN1 | KMIN0 | RAN
DFLOTI | INT | KMIN1 | REAL
DFLOTJ | INT_PTR_KIND | LGE | SECNDS
DFLOTK | INT1 | LGT | SIZEOF
DMAX1 | INT2 | LLE | SNGL
DMIN1 | INT4 | LLT | SNGLQ
DPROD | INT8 | LOC | ZEXT
DREAL | JFIX | MALLOC |


ABORT

Portability Subroutine: Flushes and closes I/O buffers, and terminates program execution.

Module: USE DFPORT

Syntax

CALL ABORT [string]

string
(Input; optional) Character*(*). Allows you to specify an abort message at program termination. When ABORT is called, "abort:" is written to external unit 0, followed by string. If omitted, the default message written to external unit 0 is "abort: Fortran Abort Called."

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: EXIT, STOP

Example

!The following prints "abort: Fortran Abort Called"
CALL ABORT

!The following prints "abort: Out of here!"
Call ABORT ("Out of here!")


ABOUTBOXQQ

QuickWin Function: Specifies the information displayed in the message box that appears when the user selects the About command from a QuickWin application's Help menu.

Module: USE DFLIB

Syntax

result = ABOUTBOXQQ (cstring)

cstring
(Input; output) Character*(*). Null-terminated C string.

Results:

The value of the result is INTEGER(4). It is zero if successful; otherwise, nonzero.

If your program does not call ABOUTBOXQQ, the QuickWin run-time library supplies a default string. For further discussion, see Using QuickWin in the Programmer's Guide.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: Using QuickWin

Example

        USE DFLIB
        INTEGER(4) dummy
! Set the About box message
        dummy = ABOUTBOXQQ ('Matrix Multiplier\r      Version 1.0'C)


ABS

Elemental Intrinsic Function (Generic): Computes an absolute value.

Syntax

result = ABS (a)

a
(Input) Must be of type integer, real, or complex.

Results:

If a is an integer or real value, the value of the result is | a |; if a is a complex value (X, Y), the result is the real value SQRT (X**2 + Y**2).

Specific Name | Argument Type | Result Type
 | INTEGER(1) | INTEGER(1)
IIABS | INTEGER(2) | INTEGER(2)
IABS 1 | INTEGER(4) | INTEGER(4)
KIABS | INTEGER(8) | INTEGER(8)
ABS | REAL(4) | REAL(4)
DABS | REAL(8) | REAL(8)
QABS 2 | REAL(16) | REAL(16)
CABS 3 | COMPLEX(4) | REAL(4)
CDABS 4 | COMPLEX(8) | REAL(8)
CQABS 2 | COMPLEX(16) | REAL(16)
1 Or JIABS. For compatibility with older versions of Fortran, IABS can also be specified as a generic function. 2 VMS and U*X 3 The setting of compiler option /real_size can affect CABS. 4 This function can also be specified as ZABS.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Examples

ABS (-7.4) has the value 7.4.

ABS ((6.0, 8.0)) has the value 10.0.

The following ABS.F90 program calculates two square roots, retaining the sign:

        REAL mag(2), sgn(2), result(2)
        WRITE (*, '(A)') ' Enter two signed magnitudes: '
        READ (*, *) mag
        sgn = SIGN((/1.0, 1.0/), mag) ! transfer the signs to 1.0s
        result = SQRT (ABS (mag))
! Restore the sign by multiplying by -1 or +1:
        result = result * sgn
        WRITE (*, *) result
        END


ACCEPT

Statement: A data transfer input statement. It is the same as a formatted, sequential READ statement, except that an ACCEPT statement must never be commented to user-specified I/O units.

Syntax

Formatted:

ACCEPT form [, io-list]

Formatted - List-Directed:

ACCEPT * [, io-list]

Formatted - Namelist:

ACCEPT nml

form
Is the nonkeyword form of a format specifier (no FMT=).

io-list
Is an I/O list.

*
Is the format specifier indicating list-directed formatting. (It can also be specified as FMT=*.)

nml
Is the nonkeyword form of a namelist specifier (no NML=) indicating namelist formatting.

Example

In the following example, character data is read from the implicit unit and binary values are assigned to each of the five elements of array CHARAR:

     CHARACTER*10 CHARAR(5)
     ACCEPT 200, CHARAR
200  FORMAT (5A10)


ACCESS

Portability Function: Determines if a file exists and how it can be accessed.

Module: USE DFPORT

Syntax

result = ACCESS (name, mode)

name
(Input) Character*(*). Name of the file whose accessibility is to be determined.

mode
(Input) Character*(*). Modes of accessibility to check for. Must be a character string of length one or greater containing only the characters "r", "w", "x", or "" (a blank). These characters are interpreted as follows.

Character | Meaning
r | Tests for read permission
w | Tests for write permission
x | Tests for execute permission (name must be .COM, .EXE, .BAT, or .CMD)
(blank) | Tests for existence

The characters within mode can appear in any order or combination. For example, wrx and r are legal forms of mode and represent the same set of inquiries.

Results:

The value of the result is INTEGER(4). It is zero if all inquiries specified by mode are affirmative. If either argument is illegal, or if the file cannot be accessed in all of the modes specified, one of the following error codes is returned:

  • EACCES: Access denied; the file's permission setting does not allow the specified access
  • EINVAL: The mode argument is invalid
  • ENOENT: File or path not found

For a list of error codes, see IERRNO.

The name argument can contain either forward or backward slashes for path separators.

Note that all files are readable. A test for read permission always returns 0.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: INQUIRE, GETFILEINFOQQ

Example

! checks for read and write permission on the file "DATAFILE.TXT"

J = ACCESS ("DATAFILE.TXT", "rw")
! checks whether "DATAFILE.TXT" is executable. It is not, since
! it does not end in .COM, .EXE, .BAT, or .CMD
J = ACCESS ("DATAFILE.TXT","x")


ACHAR

Elemental Intrinsic Function (Generic): Returns the character in a specified position of the ASCII character set, even if the processor's default character set is different. It is the inverse of the IACHAR function. In Compaq Fortran, ACHAR is equivalent to the CHAR function.

Syntax

result = ACHAR (i)

i
(Input) Is of type integer.

Results:

The result is of type character with length 1; it has the kind parameter value of KIND ('A').

If I has a value within the range 0 to 127, the result is the character in position I of the ASCII character set. ACHAR (IACHAR(C)) has the value C for any character C capable of representation in the processor. For a complete list of ASCII character codes, see Character and Key Code Charts.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: CHAR, IACHAR, ICHAR

Examples

ACHAR (71) has the value 'G'.

ACHAR (63) has the value '?'.


ACOS

Elemental Intrinsic Function (Generic): Produces the arccosine of x.

Syntax

result = ACOS (x)

x
(Input) Must be of type real. The | x | must be less than or equal to 1.

Results:

The result type is the same as x and is expressed in radians. The value lies in the range 0 to pi.

Specific Name | Argument Type | Result Type
ACOS | REAL(4) | REAL(4)
DACOS | REAL(8) | REAL(8)
QACOS 1 | REAL(16) | REAL(16)
1 VMS and U*X

Example

ACOS (0.68032123) has the value .8225955.


ACOSD

Elemental Intrinsic Function (Generic): Produces the arccosine of x.

Syntax

result = ACOSD (x)

x
(Input) Must be of type real and must be greater than or equal to zero. The |x| must be less than or equal to 1.

Results:

The result type is the same as x and is expressed in degrees.

Specific Name | Argument Type | Result Type
ACOSD | REAL(4) | REAL(4)
DACOSD | REAL(8) | REAL(8)
QACOSD 1 | REAL(16) | REAL(16)
1 VMS and U*X

Example

ACOSD (0.886579) has the value 27.55354.


ADJUSTL

Elemental Intrinsic Function (Generic): Adjusts a character string to the left, removing leading blanks and inserting trailing blanks.

Syntax

result = ADJUSTL (string)

string
(Input) Must be of type character.

Results:

The result is of type character with the same length and kind parameter as string. The value of the result is the same as string, except that any leading blanks have been removed and inserted as trailing blanks.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ADJUSTR

Examples

  CHARACTER(16) STRING
  STRING= ADJUSTL('   Fortran 90   ') ! returns 'Fortran 90   '

  ADJUSTL ('    SUMMERTIME')     ! has the value 'SUMMERTIME    '


ADJUSTR

Elemental Intrinsic Function (Generic): Adjusts a character string to the right, removing trailing blanks and inserting leading blanks.

Syntax

result = ADJUSTR (string)

string
(Input) Must be of type character.

Results:

The result is of type character with the same length and kind parameter as string.

The value of the result is the same as string, except that any trailing blanks have been removed and inserted as leading blanks.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ADJUSTL

Example

  CHARACTER(16) STRING
  STRING= ADJUSTR('   Fortran 90   ') ! returns '     Fortran 90'

  ADJUSTR ('SUMMERTIME----')     ! has the value '----SUMMERTIME'


AIMAG

Elemental Intrinsic Function (Generic): Returns the imaginary part of a complex number. This function can also be specified as IMAG.

Syntax

result = AIMAG (z)

z
(Input) Must be of type complex.

Results:

The result is of type real with the same kind parameter as z. If z has the value (x, y), the result has the value y.

The setting of compiler option /real_size can affect AIMAG.

Specific Name | Argument Type | Result Type
AIMAG | COMPLEX(4) | REAL(4)
DIMAG | COMPLEX(8) | REAL(8)
QIMAG | COMPLEX(16) | REAL(16)

To return the real part of complex numbers, use REAL.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: CONJG, DBLE

Examples

AIMAG ((4.0, 5.0)) has the value 5.0.

The program AIMAG.F90 applies the quadratic formula to a polynomial and allows for complex results:

REAL a, b, c
COMPLEX ans1, ans2, d
WRITE ( *, 100)
100 FORMAT ('  Enter A, b, and c of the  ',   &
                           'polynomial ax**2 + bx + c:  '\)
READ (*, *) a, b, c
d = CSQRT (CMPLX (b**2 - 4.0*a*c))  ! d is either:
                                    !  0.0 + i root, or
                                    !  root + i 0.0
ans1 = (-b + d) / (2.0 * a)
ans2 = (-b + d) / (2.0 * a)
WRITE (*, 200)
200 FORMAT (/ '  The roots are:'  /)
WRITE (*, 300) REAL(ans1), AIMAG(ans1), &
                   REAL(ans2), AIMAG(ans2)
300 FORMAT (' X = ', F10.5, ' + i', F10.5)
END


AINT

Elemental Intrinsic Function (Generic): Truncates a value to a whole number.

Syntax

result = AINT (a [, kind] )

a
(Input) Must be of type real.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is of type real. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter is that of a.

The result is defined as the largest integer whose magnitude does not exceed the magnitude of a and whose sign is the same as that of a. If | a | is less than 1, AINT (a) has the value zero.

Specific Name | Argument Type | Result Type
AINT | REAL(4) | REAL(4)
DINT | REAL(8) | REAL(8)
QINT 1 | REAL(16) | REAL(16)
1 VMS and U*X

To round rather than truncate, use ANINT.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Examples

AINT (3.678) has the value 3.0.

AINT (-1.375) has the value -1.0.

REAL r1, r2
REAL(8) r3(2)
r1 = AINT(2.6)   ! returns the value 2.0
r2 = AINT(-2.6)  ! returns the value -2.0
r3 = AINT((/1.3, 1.9/), KIND = 8)       ! returns the values
                                        ! (1.0D0, 1.0D0)


ALARM

Portability Function: Causes a subroutine to begin execution after a specified amount of time has elapsed.

Module: USE DFPORT

Syntax

result = ALARM (time, proc)

time
(Input) Integer. Specifies the time delay, in seconds, between the call to ALARM and the time when proc is to begin execution. If time is 0, the alarm is turned off and no routine is called.

proc
(Input) Name of the procedure to call. The procedure takes no arguments and must be declared EXTERNAL.

Results:

The return value is INTEGER(4). It is zero if no alarm is pending. If an alarm is pending (has already been set by a previous call to ALARM), it returns the number of seconds remaining until the previously set alarm is to go off, rounded up to the nearest second.

After ALARM is called and the timer starts, the calling program continues for time seconds. The calling program then suspends and calls proc, which runs in another thread. When proc finishes, the alarm thread terminates, the original thread resumes, and the calling program resets the alarm. Once the alarm goes off, it is disabled until set again.

If proc performs I/O or otherwise uses the Fortran library, you need to compile it with one of the multithread libraries. For more information on multithreading, see Creating Multithread Applications in the Programmer's Guide.

The thread that proc runs in has a higher priority than any other thread in the process. All other threads are essentially suspended until proc terminates, or is blocked on some other event, such as I/O.

No alarms can occur after the main process ends. If the main program finishes or any thread executes an EXIT call, than any pending alarm is deactivated before it has a chance to run.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RUNQQ

Example

USE DFPORT
INTEGER(4) numsec, istat
EXTERNAL subprog
numsec = 4
write *, "subprog will begin in ", numsec, " seconds"
ISTAT = ALARM (numsec, subprog)


ALIAS

General Compiler Directive: Declares alternate external names for external subprograms.

Syntax

c DEC$ ALIAS internal-name, external-name

c
Is a c, C, !, or *. (See Syntax Rules for General Directives.)

internal-name
The name of the subprogram as used in the current program unit.

external-name
A name or a character constant, delimited by apostrophes or quotation marks.

Rules and Behavior

If a name is specified, the name (in uppercase) is used as the external name for the specified internal-name. If a character constant is specified, it is used as is; the string is not changed to uppercase, nor are blanks removed.

The ALIAS directive affects only the external name used for references to the specified internal-name.

Names that are not acceptable to the linker will cause link-time errors.

You can use the prefix !MS$ in place of cDEC$.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ATTRIBUTES - ALIAS option, General Compiler Directives


ALL

Transformational Intrinsic Function (Generic): Determines if all values are true in an entire array or in a specified dimension of an array.

Syntax

result = ALL (mask [, dim] )

mask
(Input) Must be a logical array.

dim
(Optional; input) Must be a scalar integer with a value in the range 1 to n, where n is the rank of mask.

Results:

The result is an array or a scalar of type logical.

The result is a scalar if dim is omitted or mask has rank one. A scalar result is true only if all elements of mask are true, or mask has size zero. The result has the value false if any element of mask is false.

An array result has the same type and kind parameters as mask, and a rank that is one less than mask. Its shape is (d1, d2, ..., ddim-1, ddim+1, ..., dn), where (d1, d2,..., dn) is the shape of mask.

Each element in an array result is true only if all elements in the one dimensional array defined by mask (s1, s2, ..., sdim-1, :, sdim+1, ..., sn) are true.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ANY, COUNT

Examples

        LOGICAL mask( 2, 3), AR1(3), AR2(2)
        mask = RESHAPE((/.TRUE., .TRUE., .FALSE., .TRUE., .FALSE., &
                        .FALSE./),(/2,3/))
! mask is true false false
! true true false
        AR1 = ALL(mask,DIM = 1) ! evaluates the elements column by
                ! column yielding [true false false]
        AR2 = ALL(mask,DIM = 2) ! evaluates the elements row by row
                ! yielding [false false].

ALL ((/.TRUE., .FALSE., .TRUE./)) has the value false because some elements of MASK are not true.

ALL ((/.TRUE., .TRUE., .TRUE./)) has the value true because all elements of MASK are true.

A is the array

    [ 1  5  7 ]
    [ 3  6  8 ]
and B is the array

    [ 0  5  7 ]
    [ 2  6  9 ].

ALL (A .EQ. B, DIM=1) tests to see if all elements in each column of A are equal to the elements in the corresponding column of B. The result has the value (false, true, false) because only the second column has elements that are all equal.

ALL (A .EQ. B, DIM=2) tests to see if all elements in each row of A are equal to the elements in the corresponding row of B. The result has the value (false, false) because each row has some elements that are not equal.


ALLOCATABLE

Statement and Attribute: Specifies that an array is an allocatable array with a deferred shape. The shape of an allocatable array is determined when an ALLOCATE statement is executed, dynamically allocating space for the array.

The ALLOCATABLE attribute can be specified in a type declaration statement or an ALLOCATABLE statement, and takes one of the following forms:

Type Declaration Statement:

type, [att-ls,] ALLOCATABLE [att-ls,] :: a[(d-spec)] [, a[(d-spec)]] ...

Statement:

ALLOCATABLE [::] a[(d-spec)] [, a[(d-spec)]] ...

type
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

a
Is the name of the allocatable array; it must not be a dummy argument or function result.

d-spec
Is a deferred-shape specification (: [, :] ...). Each colon represents a dimension of the array.

Rules and Behavior

If the array is given the DIMENSION attribute elsewhere in the program, it must be declared as a deferred-shape array.

When the allocatable array is no longer needed, it can be deallocated by execution of a DEALLOCATE statement.

An allocatable array cannot be specified in a COMMON, EQUIVALENCE, DATA, or NAMELIST statement.

Allocatable arrays are not saved by default. If you want to retain the values of an allocatable array across procedure calls, you must specify the SAVE attribute for the array.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Type declaration statements, Compatible attributes, DEALLOCATE, Arrays, Allocation of Allocatable Arrays, SAVE

Examples

  !Method for creating and allocating deferred-shape arrays.
  INTEGER, ALLOCATABLE :: matrix(:,:)
  REAL, ALLOCATABLE    :: vector(:)
  ...
  ALLOCATE(matrix(3,5),vector(-2:N+2))
  ...

The following example shows a type declaration statement specifying the ALLOCATABLE attribute:

  REAL, ALLOCATABLE :: Z(:, :, :)

The following is an example of the ALLOCATABLE statement:

  REAL A, B(:)
  ALLOCATABLE :: A(:,:), B


ALLOCATE

Statement: Dynamically creates storage for allocatable arrays and pointer targets. The storage space allocated is uninitialized.

Syntax

ALLOCATE (object [(s-spec)] [, object [(s-spec [, s-spec...])] ] ...[, STAT=sv])

object
Is the object to be allocated. It is a variable name or structure component, and must be a pointer or allocatable array. The object can be of type character with zero length.

s-spec
Is a shape specification in the form [lower-bound:]upper-bound. Each bound must be a scalar integer expression. The number of shape specifications must be the same as the rank of the object.

sv
(Output) Is a scalar integer variable in which the status of the allocation is stored.

Rules and Behavior

A bound in s-spec must not be an expression containing an array inquiry function whose argument is any allocatable object in the same ALLOCATE statement; for example, the following is not permitted:

  INTEGER ERR
  INTEGER, ALLOCATABLE :: A(:), B(:)
  ...
  ALLOCATE(A(10:25), B(SIZE(A)), STAT=ERR)  ! A is invalid as an argument
                                            !   to function SIZE

If a STAT variable is specified, it must not be allocated in the ALLOCATE statement in which it appears. If the allocation is successful, the variable is set to zero. If the allocation is not successful, an error condition occurs, and the variable is set to a positive integer value (representing the run-time error). If no STAT variable is specified and an error condition occurs, program execution terminates.

To release the storage for an allocated array, use DEALLOCATE.

To determine whether an allocatable array is currently allocated, use the ALLOCATED intrinsic function.

To determine whether a pointer is currently associated with a target, use the ASSOCIATED intrinsic function.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ALLOCATABLE, ALLOCATED, DEALLOCATE, ASSOCIATED, POINTER, Dynamic Allocation

Examples

  !Method for creating and allocating deferred shape arrays.
  INTEGER,ALLOCATABLE::matrix(:,:)
  REAL, ALLOCATABLE:: vector(:)
  . . .
  ALLOCATE (matrix(3,5),vector(-2:N+2))
  . . .

The following is another example of the ALLOCATE statement:

  INTEGER J, N, ALLOC_ERR
  REAL, ALLOCATABLE :: A(:), B(:,:)
  ...
  ALLOCATE(A(0:80), B(-3:J+1, N), STAT = ALLOC_ERR)


ALLOCATED

Inquiry Intrinsic Function (Generic): Indicates whether an allocatable array is currently allocated.

Syntax

ALLOCATED (array)

array
(Input) Must be an allocatable array.

Results:

The result is a scalar of type default logical.

The result has the value true if array is currently allocated, false if array is not currently allocated, or undefined if its allocation status is undefined.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ALLOCATABLE, ALLOCATE, DEALLOCATE, Arrays, Dynamic Allocation

Examples

  REAL, ALLOCATABLE :: A(:)
  ...
  IF (.NOT. ALLOCATED(A)) ALLOCATE (A (5))

Consider the following:

  REAL, ALLOCATABLE, DIMENSION (:,:,:) :: E
  PRINT *, ALLOCATED (E)       ! Returns the value false
  ALLOCATE (E (12, 15, 20))
  PRINT *, ALLOCATED (E)       ! Returns the value true


AND

Elemental Intrinsic Function (Generic): See IAND.

Example

  INTEGER(1) i, m
  INTEGER result
  INTEGER(2) result2
  i = 1
  m = 3
  result = AND(i,m) ! returns an integer of default type
          ! (INTEGER(4) unless reset by user) whose
          ! value = 1
  result2 = AND(i,m) ! returns an INTEGER(2) with value = 1


ANINT

Elemental Intrinsic Function (Generic): Calculates the nearest whole number.

Syntax

result = ANINT (a [, kind] )

a
(Input) Must be of type real.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is of type real. If kind is present, the kind parameter is that specified by kind; otherwise, the kind parameter is that of a. If a is greater than zero, ANINT (a) has the value AINT (a + 0.5); if a is less than or equal to zero, ANINT (a) has the value AINT (a - 0.5).

Specific Name | Argument Type | Result Type
ANINT | REAL(4) | REAL(4)
DNINT | REAL(8) | REAL(8)
QNINT 1 | REAL(16) | REAL(16)
1 VMS and U*X

To truncate rather than round, use AINT.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NINT

Examples

       REAL r1, r2
       r1 = ANINT(2.6)     ! returns the value 3.0
       r2 = ANINT(-2.6)    ! returns the value -3.0

! ANINT.F90 Calculates and adds tax to a purchase amount.
       REAL amount, taxrate, tax, total
       taxrate = 0.081
       amount = 12.99
       tax = ANINT (amount * taxrate * 100.0) / 100.0
       total = amount + tax
       WRITE (*, 100) amount, tax, total
  100  FORMAT ( 1X, 'AMOUNT', F7.2 /
      + 1X, 'TAX ', F7.2 /
      + 1X, 'TOTAL ', F7.2)
       END

ANINT (3.456) has the value 3.0.

ANINT (-2.798) has the value -3.0.


ANY

Transformational Intrinsic Function (Generic): Determines if any value is true in an entire array or in a specified dimension of an array.

Syntax

result = ANY (mask [, dim] )

mask
(Input) Must be a logical array.

dim
(Optional; input) Must be a scalar integer expression with a value in the range 1 to n, where n is the rank of mask.

Results:

The result is an array or a scalar of type logical.

The result is a scalar if dim is omitted or mask has rank one. A scalar result is true if any elements of mask are true. The result has the value false if no element of mask is true, or mask has size zero.

An array result has the same type and kind parameters as mask, and a rank that is one less than mask. Its shape is (d1, d2, ..., ddim-1, ddim+1, ..., dn), where (d1, d2, ..., dn) is the shape of mask.

Each element in an array result is true if any elements in the one dimensional array defined by mask (s1, s2, ..., sdim-1, :, sdim+1, ..., sn) are true.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ALL, COUNT

Example

    LOGICAL mask( 2, 3), AR1(3), AR2(2)
    DATA mask /T, T, F, T, F, F/
! mask is     true false false
!             true true false
    AR1 = ANY(mask,DIM = 1)  ! evaluates the elements column by
                             !   column yielding [true true false]
    AR2 = ANY(mask,DIM = 2)  ! evaluates the elements row by row
                             !   yielding [true true]

ANY ((/.FALSE., .FALSE., .TRUE./)) has the value true because one element is true.

A is the array

  [ 1  5  7 ]
  [ 3  6  8 ]
and B is the array
  [ 0  5  7 ]
  [ 2  6  9 ].

ANY (A .EQ. B, DIM=1) tests to see if any elements in each column of A are equal to the elements in the corresponding column of B. The result has the value (false, true, true) because the second and third columns have at least one element that is equal.

ANY (A .EQ. B, DIM=2) tests to see if any elements in each row of A are equal to the elements in the corresponding row of B. The result has the value (true, true) because each row has at least one element that is equal.


APPENDMENUQQ

QuickWin Function: Appends a menu item to the end of a menu and registers its callback subroutine.

Module: USE DFLIB

Syntax

result = APPENDMENUQQ (menuID, flags, text, routine)

menuID
(Input) INTEGER(4). Identifies the menu to which the item is appended, starting with 1 as the leftmost menu.

flags
(Input) INTEGER(4). Constant indicating the menu state. Flags can be combined with an inclusive OR (see Results). The following constants are available:

  • $MENUGRAYED - Disables and grays out the menu item.
  • $MENUDISABLED - Disables but does not gray out the menu item.
  • $MENUENABLED - Enables the menu item.
  • $MENUSEPARATOR - Draws a separator bar.
  • $MENUCHECKED - Puts a check by the menu item.
  • $MENUUNCHECKED - Removes the check by the menu item.

text
(Input) Character*(*). Menu item name. Must be a null-terminated C string, for example, 'WORDS OF TEXT'C.

routine
(Input) EXTERNAL. Callback subroutine that is called if the menu item is selected. All routines take a single LOGICAL parameter which indicates whether the menu item is checked or not. You can assign the following predefined routines to menus:

  • WINPRINT - Prints the program.
  • WINSAVE - Saves the program.
  • WINEXIT - Terminates the program.
  • WINSELECTTEXT - Selects text from the current window.
  • WINSELECTGRAPHICS - Selects graphics from the current window.
  • WINSELECTALL - Selects the entire contents of the current window.
  • WINCOPY - Copies the selected text and/or graphics from the current window to the Clipboard.
  • WINPASTE - Allows the user to paste Clipboard contents (text only) to the current text window of the active window during a READ.
  • WINCLEARPASTE - Clears the paste buffer.
  • WINSIZETOFIT - Sizes output to fit window.
  • WINFULLSCREEN - Displays output in full screen.
  • WINSTATE - Toggles between pause and resume states of text output.
  • WINCASCADE - Cascades active windows.
  • WINTILE - Tiles active windows.
  • WINARRANGE - Arranges icons.
  • WINSTATUS - Enables a status bar.
  • WININDEX - Displays the index for QuickWin help.
  • WINUSING - Displays information on how to use Help.
  • WINABOUT - Displays information about the current QuickWin application.
  • NUL - No callback routine.

Results:

The result is of type logical. It is .TRUE. if successful; otherwise, .FALSE..

You do not need to specify a menu item number, because APPENDMENUQQ always adds the new item to the bottom of the menu list. If there is no item yet for a menu, your appended item is treated as the top-level menu item (shown on the menu bar), and text becomes the menu title. APPENDMENUQQ ignores the callback routine for a top-level menu item if there are any other menu items in the menu. In this case, you can set routine to NUL.

If you want to insert a menu item into a menu rather than append to the bottom of the menu list, use INSERTMENUQQ.

The constants available for flags can be combined with an inclusive OR where reasonable, for example $MENUCHECKED .OR. $MENUENABLED. Some combinations do not make sense, such as $MENUENABLED and $MENUDISABLED, and lead to undefined behavior.

You can create quick-access keys in the text strings you pass to APPENDMENUQQ as text by placing an ampersand (&) before the letter you want underlined. For example, to add a Print menu item with the r underlined, text should be "P&rint". Quick-access keys allow users of your program to activate that menu item with the key combination ALT+QUICK-ACCESS-KEY (ALT+R in the example) as an alternative to selecting the item with the mouse.

For more information about customizing QuickWin menus, see Using QuickWin in the Programmer's Guide.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: INSERTMENUQQ, DELETEMENUQQ, MODIFYMENUFLAGSQQ, MODIFYMENUROUTINEQQ, MODIFYMENUSTRINGQQ

Example

      USE DFLIB
      LOGICAL(4) result
      CHARACTER(25) str
      ...
! Append two items to the bottom of the first (FILE) menu
      str    = '&Add to File Menu'C ! 'A' is a quick-access key
      result = APPENDMENUQQ(1, $MENUENABLED, str, WINSTATUS)
      str    = 'Menu Item &2b'C ! '2' is a quick-access key
      result = APPENDMENUQQ(1, $MENUENABLED, str, WINCASCADE)
! Append an item to the bottom of the second (EDIT) menu
      str    = 'Add to Second &Menu'C ! 'M' is a quick-access key
      result = APPENDMENUQQ(2, $MENUENABLED, str, WINTILE)


ARC, ARC_W

Graphics Function: Draws elliptical arcs using the current graphics color.

Module: USE DFLIB

Syntax

result = ARC (x1, y1, x2, y2, x3, y3, x4, y4)
result = ARC_W (wx1, wy1, wx2, wy2, wx3, wy3, wx4, wy4)

x1, y1
(Input) INTEGER(2). Viewport coordinates for upper-left corner of bounding rectangle.

x2, y2
(Input) INTEGER(2). Viewport coordinates for lower-right corner of bounding rectangle.

x3, y3
(Input) INTEGER(2). Viewport coordinates of start vector.

x4, y4
(Input) INTEGER(2). Viewport coordinates of end vector.

wx1,wy1
(Input) REAL(8). Window coordinates for upper-left corner of bounding rectangle.

wx2, wy2
(Input) REAL(8). Window coordinates for lower-right corner of bounding rectangle.

wx3, wy3
(Input) REAL(8). Window coordinates of start vector.

wx4, wy4
(Input) REAL(8). Window coordinates of end vector.

Results:

The result is of type INTEGER(2). It is nonzero if successful; otherwise, 0. If the arc is clipped or partially out of bounds, the arc is considered successfully drawn and the return is 1. If the arc is drawn completely out of bounds, the return is 0.

The center of the arc is the center of the bounding rectangle defined by the points (x1, y1) and (x2, y2) for ARC and (wx1, wy1) and (wx2, wy2) for ARC_W.

The arc starts where it intersects an imaginary line extending from the center of the arc through (x3, y3) for ARC and (wx3, wy3) for ARC_W. It is drawn counterclockwise about the center of the arc, ending where it intersects an imaginary line extending from the center of the arc through (x4, y4) for ARC and (wx4, wy4) for ARC_W.

ARC uses the view-coordinate system. ARC_W uses the window-coordinate system. In each case, the arc is drawn using the current color.

Note: The ARC routine described here is a QuickWin routine. If you are trying to use the Win32 SDK version of the Arc routine by including the DFWIN module, you need to specify the routine name as MSFWIN$Arc. For more information, see Special Naming Convention for Certain QuickWin and Win32 Graphics Routines in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

Example

This program draws the arc below.

  USE DFLIB
  INTEGER(2) status, x1, y1, x2, y2, x3, y3, x4, y4

  x1 = 80; y1 = 50
  x2 = 240; y2 = 150
  x3 = 120; y3 = 75
  x4 = 90; y4 = 180
  status = ARC( x1, y1, x2, y2, x3, y3, x4, y4 )
  END

Figure: Output of Program ARC.FOR


ASIN

Elemental Intrinsic Function (Generic): Produces the arcsine of x.

Syntax

result = ASIN (x)

x
(Input) Must be of type real. The | x | must be less than or equal to 1.

Results:

The result type is the same as x and is expressed in radians. The value lies in the range -pi/2 to pi/2.

Specific Name | Argument Type | Result Type
ASIN | REAL(4) | REAL(4)
DASIN | REAL(8) | REAL(8)
QASIN 1 | REAL(16) | REAL(16)
1 VMS and U*X

Example

ASIN (0.79345021) has the value 0.9164571.


ASIND

Elemental Intrinsic Function (Generic): Produces the arcsine of x.

Syntax

result = ASIND (x)

x
(Input) Must be of type real and must be greater than or equal to zero. The |x| must be less than or equal to 1.

Results:

The result type is the same as x and is expressed in degrees.

Specific Name | Argument Type | Result Type
ASIND | REAL(4) | REAL(4)
DASIND | REAL(8) | REAL(8)
QASIND 1 | REAL(16) | REAL(16)
1 VMS and U*X

Example

ASIND (0.2467590) has the value 14.28581.


ASM (Alpha only)

NonElemental Intrinsic Function (Generic): Lets you use assembler instructions in an executable program.

Syntax

result = ASM (string [, a,...]})

string
Character. It is a character constant or a concatenation of character constants containing the assembler instructions.

a
(Optional) Any type. This can be a source or destination argument for the instruction, for example.

Results:

The result is a scalar of type INTEGER(8), REAL(4), or REAL(8).

Arguments are passed by value. If you want to pass an argument by reference (for example, a whole array, a character string, or a record structure), you can use the %REF built-in function.

Labels are allowed, but all references must be from within the same ASM function. This lets you set up looping constructs, for example. Cross-jumping between ASM functions is not permitted.

In general, an ASM function can appear anywhere that an intrinsic function can be used. Since the supplied assembly code, assembly directives, or assembly data is integrated into the code stream, the compiler may choose to use different registers, better code sequences, and so on, just as if the code were written in Fortran.

You do not have absolute control over instruction sequences and registers, and the compiler may intersperse other code together with the ASM code for better performance. Better code sequences may be substituted by the optimizer if it chooses to do so.

Only register names beginning with a dollar sign ($) or percent sign (%) are permitted. For more information on register name conventions, see your operating system documentation set.

Specific Name | Argument Type 1 | Result Type
ASM 2 | CHARACTER | INTEGER(8)
FASM 3 | CHARACTER | REAL(4)
DASM 3 | CHARACTER | REAL(8)
1 For the first argument. 2 The value must be stored in register $0 by the user code. 3 The value must be stored in register $F0 by the user code.

Examples

Consider the following:

 ! Concatenation is recommended for clarity.
 ! Notice that ";" separates instructions.
 !
 nine=9

 type *, asm('addq %0, $17, $0;'//     ! Adds the first two arguments
     1    'ldq $22, %6;'//             !   and puts the answer in
     1    'ldq $23, %7;'//             !   register $0
     1    'ldq $24, %8;'//             !
     1    'mov $0, %fp;'//             ! Comments are not allowed in the
     1    'addq $18, %fp, $0;'//       !   constant, but are allowed here
     1    'addq $19, $0, $0;'//
     1    'addq $20, $0, $0;'//
     1    'addq $21, $0, $0;'//
     1    'addq $22, $0, $0;'//
     1    'addq $23, $0, $0;'//
     1    'addq $24, $0, $0;',
     1 1,2,3,4,5,6,7,8,nine)           ! The actual arguments to the
                                       !   ASM (usually by value)
 end

This example shows an integer ASM function that adds up 9 values and returns the sum as its result. Note that the user stores the function result in register $0.

All arguments are passed by value. The arguments not passed in registers can be named %6, %7, and %8, which correspond to the actual arguments 7, 8, and 9 (since %0 is the first argument). Notice that you can reference reserved registers like %fp.

The compiler creates the appropriate argument list. So, in this example, the first argument value (1) will be available in register $16, and the eighth argument value (8) will be available in %7, which is actually 8($30).


ASSIGN - Label Assignment

Statement: Assigns a statement label value to an integer variable. This feature has been deleted in Fortran 95; it was obsolescent in Fortran 90. Compaq Fortran fully supports features deleted in Fortran 95.

Syntax

ASSIGN label TO var

label
Is the label of a branch target or FORMAT statement in the same scoping unit as the ASSIGN statement.

var
Is a scalar integer variable.

Rules and Behavior

When an ASSIGN statement is executed, the statement label is assigned to the integer variable. The variable is then undefined as an integer variable and can only be used as a label (unless it is later redefined with an integer value).

The ASSIGN statement must be executed before the statements in which the assigned variable is used.

Indirect branching through integer variables makes program flow difficult to read, especially if the integer variable is also used in arithmetic operations. Using these statements permits inconsistent usage of the integer variable, and can be an obscure source of error. The ASSIGN statement was used to simulate internal procedures, which now can be coded directly.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Assignment: intrinsic, Obsolescent Features in Fortran 90

Examples

The value of a label is not the same as its number; instead, the label is identified by a number assigned by the compiler. In the following example, 400 is the label number (not the value) of IVBL:

  ASSIGN 400 TO IVBL

Variables used in ASSIGN statements are not defined as integers. If you want to use a variable defined by an ASSIGN statement in an arithmetic expression, you must first define the variable by a computational assignment statement or by a READ statement, as in the following example:

  IVBL = 400

The following example shows ASSIGN statements:

  INTEGER ERROR
  ...
  ASSIGN 10 TO NSTART
  ASSIGN 99999 TO KSTOP
  ASSIGN 250 TO ERROR

Note that NSTART and KSTOP are integer variables implicitly, but ERROR must be previously declared as an integer variable.

The following statement associates the variable NUMBER with the statement label 100:

  ASSIGN 100 TO NUMBER

If an arithmetic operation is subsequently performed on variable NUMBER (such as follows), the run-time behavior is unpredictable:

  NUMBER = NUMBER + 1

To return NUMBER to the status of an integer variable, you can use the following statement:

  NUMBER = 10

This statement dissociates NUMBER from statement 100 and assigns it an integer value of 10. Once NUMBER is returned to its integer variable status, it can no longer be used in an assigned GO TO statement.


Assignment(=) - Defined Assignment

Statement: An interface block that defines generic assignment. The only procedures allowed in the interface block are subroutines that can be referenced as defined assignments.

The initial line for such an interface block takes the following form:

Syntax

INTERFACE ASSIGNMENT(=)

The subroutines within the interface block must have two nonoptional arguments, the first with intent OUT or INOUT, and the second with intent IN.

A defined assignment is treated as a reference to a subroutine. The left side of the assignment corresponds to the first dummy argument of the subroutine; the right side of the assignment corresponds to the second argument.

The ASSIGNMENT keyword extends or redefines an assignment operation if both sides of the equal sign are of the same derived type.

Defined elemental assignment is indicated by specifying ELEMENTAL in the SUBROUTINE statement.

Any procedure reference involving generic assignment must be resolvable to one specific procedure; it must be unambiguous. For more information, see Unambiguous Generic Procedure References.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: INTERFACE, Assignment Statements

Examples

The following is an example of a procedure interface block defining assignment:

INTERFACE ASSIGNMENT (=)
  SUBROUTINE BIT_TO_NUMERIC (NUM, BIT)
    INTEGER, INTENT(OUT) :: NUM
    LOGICAL, INTENT(IN)  :: BIT(:)
  END SUBROUTINE BIT_TO_NUMERIC

  SUBROUTINE CHAR_TO_STRING (STR, CHAR)
    USE STRING_MODULE                    ! Contains definition of type STRING
    TYPE(STRING), INTENT(OUT) :: STR     ! A variable-length string
    CHARACTER(*), INTENT(IN)  :: CHAR
  END SUBROUTINE  CHAR_TO_STRING
END  INTERFACE

The following example shows two equivalent ways to reference subroutine BIT_TO_NUMERIC:

  CALL BIT_TO_NUMERIC(X, (NUM(I:J)))
  X = NUM(I:J)

The following example shows two equivalent ways to reference subroutine CHAR_TO_STRING:

  CALL CHAR_TO_STRING(CH, '432C')
  CH = '432C'

!Converting circle data to interval data.
module mod1
TYPE CIRCLE
        REAL radius, center_point(2)
END TYPE CIRCLE
TYPE INTERVAL
        REAL lower_bound, upper_bound
END TYPE INTERVAL
CONTAINS
        SUBROUTINE circle_to_interval(I,C)
          type (interval),INTENT(OUT)::I
          type (circle),INTENT(IN)::C
!Project circle center onto the x=-axis
!Note: the length of the interval is the diameter of the circle
                I%lower_bound = C%center_point(1) - C%radius
                I%upper_bound = C%center_point(1) + C%radius
        END SUBROUTINE circle_to_interval
end module mod1

PROGRAM assign
use mod1
TYPE(CIRCLE) circle1
TYPE(INTERVAL) interval1
INTERFACE ASSIGNMENT(=)
        module procedure circle_to_interval
END INTERFACE
!Begin executable part of program
  circle1%radius = 2.5
  circle1%center_point = (/3.0,5.0/)
  interval1 = circle1
. . .
END PROGRAM


Assignment - Intrinsic Computational

Assignment - Intrinsic

Statement: Assigns a value to a nonpointer variable. In the case of pointers, intrinsic assignment is used to assign a value to the target associated with the pointer variable. The value assigned to the variable (or target) is determined by evaluation of the expression to the right of the equal sign.

Syntax

variable = expression

variable
Is the name of a scalar or array of intrinsic or derived type (with no defined assignment). The array cannot be an assumed-size array, and neither the scalar nor the array can be declared with the PARAMETER or INTENT(IN) attribute.

expression
Is of intrinsic type or the same derived type as variable. Its shape must conform with variable. If necessary, it is converted to the same type and kind as variable.

Rules and Behavior

Before a value is assigned to the variable, the expression part of the assignment statement and any expressions within the variable are evaluated. No definition of expressions in the variable can affect or be affected by the evaluation of the expression part of the assignment statement.

Note: When the run-time system assigns a value to a scalar integer or character variable and the variable is shorter than the value being assigned, the assigned value may be truncated and significant bits (or characters) lost. This truncation can occur without warning, and can cause the run- time system to pass incorrect information back to the program.

If the variable is a pointer, it must be associated with a definable target. The shape of the target and expression must conform and their type and kind parameters must match.

If the c DEC$ NOSTRICT compiler directive (the default) is in effect, then you can assign a character expression to a noncharacter variable, and a noncharacter variable or array element (but not an expression) to a character variable.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Assignment: defined, NOSTRICT directive

Example

    REAL a, b, c
    LOGICAL abigger
    CHARACTER(16) assertion
    c = .01
    a = SQRT (c)
    b = c**2

    assertion = 'a > b'
    abigger = (a .GT. b)

    WRITE (*, 100) a, b
100 FORMAT (' a =', F7.4, ' b =', F7.4)

    IF (abigger) THEN
            WRITE (*, *) assertion, ' is true.'
    ELSE
            WRITE (*, *) assertion, ' is false.'
    END IF
    END

! The program above has the following output:
!     a =    .1000     b =   .0001         a > b is true.

! The following code demonstrates legal and illegal
! assignment statements:
!
    INTEGER i, j
    REAL rone(4), rtwo(4), x, y
    COMPLEX z
    CHARACTER name6(6), name8(8)
    i         = 4
    x         = 2.0
    z         = (3.0, 4.0)
    rone(1) = 4.0
    rone(2) = 3.0
    rone(3) = 2.0
    rone(4) = 1.0
    name8   = 'Hello,'
! The following assignment statements are legal:
    i     = rone(2); j = rone(i); j = x
    y     = x; y = z; y = rone(3); rtwo = rone; rtwo = 4.7
    name6 = name8
! The following assignment statements are illegal:
    name6 = x + 1.0; int = name8//'test'; y = rone
    END


ASSOCIATED

Inquiry Intrinsic Function (Generic): Returns the association status of its pointer argument or indicates whether the pointer is associated with the target.

Syntax

result = ASSOCIATED (pointer [, target])

pointer
(Input) Must be a pointer (of any data type).

target
(Optional; input) Must be a pointer or target. The pointer (in pointer or target) must not have an association status that is undefined.

Results:

The result is a scalar of type default logical.

If only pointer appears, the result is true if it is currently associated with a target; otherwise, the result is false.

If target also appears and is a target, the result is true if pointer is currently associated with target; otherwise, the result is false.

If target is a pointer, the result is true if both pointer and target are currently associated with the same target; otherwise, the result is false. (If either pointer or target is disassociated, the result is false.)

The setting of compiler option /integer_size can affect this function.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ALLOCATED, POINTER, TARGET

Example

REAL C (:), D(:), E(5)
POINTER C, D
ARGET E
LOGICAL STATUS
C => E                       ! pointer assignment
D => E                       ! pointer assignment
STATUS = ASSOCIATED(C)       ! returns TRUE; C is associated
STATUS = ASSOCIATED(C, E)    ! returns TRUE; C is associated with E
STATUS = ASSOCIATED (C, D)   ! returns TRUE; C and D are associated
                             ! with the same target

Consider the following:

   REAL, TARGET, DIMENSION (0:50) :: TAR
   REAL, POINTER, DIMENSION (:) :: PTR
   PTR => TAR
   PRINT *, ASSOCIATED (PTR, TAR)          ! Returns the value true

The subscript range for PTR is 0:50. Consider the following pointer assignment statements:

   (1) PTR => TAR (:)
   (2) PTR => TAR (0:50)
   (3) PTR => TAR (0:49)

For statements 1 and 2, ASSOCIATED (PTR, TAR) is true because TAR has not changed (the subscript range for PTR in both cases is 1:51, following the rules for deferred-shape arrays). For statement 3, ASSOCIATED (PTR, TAR) is false because the upper bound of TAR has changed.

Consider the following:

   REAL, POINTER, DIMENSION (:) :: PTR2, PTR3
   ALLOCATE (PTR2 (0:15))
   PTR3 => PTR2
   PRINT *, ASSOCIATED (PTR2, PTR3)          ! Returns the value true
   ...
   NULLIFY (PTR2)
   NULLIFY (PTR3)
   PRINT *, ASSOCIATED (PTR2, PTR3)          ! Returns the value false


ATAN

Elemental Intrinsic Function (Generic): Produces the arctangent of x.

Syntax

result = ATAN (x)

x
(Input) Must be of type real.

Results:

The result type is the same as x and is expressed in radians. The value lies in the range -pi/2 to pi/2.

Specific Name | Argument Type | Result Type
ATAN | REAL(4) | REAL(4)
DATAN | REAL(8) | REAL(8)
QATAN 1 | REAL(16) | REAL(16)
1 VMS and U*X

Example

ATAN (1.5874993) has the value 1.008666.


ATAND

Elemental Intrinsic Function (Generic): Produces the arctangent of x.

Syntax

result = ATAND (x)

x
(Input) Must be of type real and must be greater than or equal to zero.

Results:

The result type is the same as x and is expressed in degrees.

Specific Name | Argument Type | Result Type
ATAND | REAL(4) | REAL(4)
DATAND | REAL(8) | REAL(8)
QATAND 1 | REAL(16) | REAL(16)
1 VMS and U*X

Example

ATAND (0.0874679) has the value 4.998819.


ATAN2

Elemental Intrinsic Function (Generic): Produces an arctangent. The result is the principal value of the argument of the nonzero complex number (x, y).

Syntax

result = ATAN2 (y, x)

y
(Input) Must be of type real.

x
(Input) Must have the same type and kind parameters as y. If y has the value zero, x cannot have the value zero.

Results:

The result type is the same as x and is expressed in radians. The value lies in the range -pi < ATAN2 (y, x) <= pi. If x /= zero, the result is approximately equal to the value of arctan (y/x).

If y > zero, the result is positive.

If y < zero, the result is negative.

If y = zero, the result is zero (if x > zero) or pi (if x < zero).

If x = zero, the absolute value of the result is pi/2.

Specific Name | Argument Type | Result Type
ATAN2 | REAL(4) | REAL(4)
DATAN2 | REAL(8) | REAL(8)
QATAN2 1 | REAL(16) | REAL(16)
1 VMS and U*X

Examples

ATAN2 (2.679676, 1.0) has the value 1.213623.

If Y has the value

  [  1   1 ]
  [ -1  -1 ]
and X has the value
  [ -1  1 ]
  [ -1  1 ],
then ATAN2 (Y, X) is


ATAN2D

Elemental Intrinsic Function (Generic): Produces an arctangent. The result is the principal value of the argument of the nonzero complex number (x, y).

Syntax

result = ATAN2D (x, y)

x
(Input) Must be of type real. It cannot have the value zero.

y
(Input) Must have the same type and kind parameters as y. It cannot have the value zero.

Results:

The result type is the same as x and is expressed in degrees. The value lies in the range -180 degrees to 180 degrees. If x /= zero, the result is approximately equal to the value of arctan (y/x).

If y > zero, the result is positive.

If y < zero, the result is negative.

If y = zero, the result is zero (if x > zero) or 180 degrees (if x < zero).

If x = zero, the absolute value of the result is 90 degrees.

Specific Name | Argument Type | Result Type
ATAN2D | REAL(4) | REAL(4)
DATAN2D | REAL(8) | REAL(8)
QATAN2D 1 | REAL(16) | REAL(16)
1 VMS and U*X

Examples

ATAN2D (2.679676, 1.0) has the value 69.53546.


ATOMIC (TU*X only)

OpenMP Parallel Compiler Directive: Ensures that a specific memory location is updated dynamically; this prevents the possibility of multiple, simultaneous writing threads.

Syntax

c$OMP ATOMIC

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

Rules and Behavior

The ATOMIC directive permits optimization beyond that of the critical section around the assignment. An implementation can replace ATOMIC directives by enclosing each statement in a critical section. The critical section (or sections) must use the same unique name.

The ATOMIC directive applies only to the immediately following statement, which must have one of the following forms:

  x = x operator expr

  x = expr operator x

  x = intrinsic (x, expr)

  x = intrinsic (expr, x)

In the preceding statements:

  • x is a scalar variable of intrinsic type
  • expr is a scalar expression that does not reference x
  • intrinsic is MAX, MIN, IAND, IOR, or IEOR
  • operator is +, *, -, /, .AND., .OR., .EQV., or .NEQV.

All references to storage location x must have the same type and type parameters.

Only the loading and storing of x are dynamic; the evaluation of expr is not dynamic. To avoid race conditions (or concurrency races), all updates of the location in parallel must be protected using the ATOMIC directive, except those that are known to be free of race conditions. The function intrinsic, the operator operator, and the assignment must be the intrinsic function, operator, and assignment.

See Also: Parallel Directives for Tru64 UNIX Systems, OpenMP Fortran API Compiler Directives (TU*X only)

Examples

The following example shows a way to avoid race conditions by using ATOMIC to protect all simultaneous updates of the location by multiple threads:

  c$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(X,Y,INDEX,N)
        DO I=1,N
          CALL WORK(XLOCAL, YLOCAL)
  c$OMP ATOMIC
          X(INDEX(I)) = X(INDEX(I)) + XLOCAL
          Y(I) = Y(I) + YLOCAL
        END DO

Since the ATOMIC directive applies only to the statement immediately following it, note that Y is not updated atomically.


ATTRIBUTES

General Compiler Directive: Declares properties for specified variables.

Syntax

c DEC$ ATTRIBUTES att [, att] ... :: object [, object] ...

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

att
Is one of the following:

ADDRESS641 | DESCRIPTOR322 | REFERENCE
ALIAS | DESCRIPTOR642 | REFERENCE322
ALLOW_NULL | DLLEXPORT | REFERENCE642
ARRAY_VISUALIZER DLLIMPORT STDCALL
C EXTERN VALUE
DECORATE IGNORE_LOC VARYING
DEFAULT NO_ARG_CHECK
DESCRIPTOR2 | NOMIXED_STR_LEN_ARG
1 VMS, WNT
2 VMS only

object
Is the name of a data object or procedure.

The following table shows which properties can be used with various objects:

Property Variable
and Array Declarations 		Common Block Names 1 Subprogram Specification and
EXTERNAL Statements
ADDRESS64 | Yes | Yes | No
ALIAS | No | Yes | Yes
ALLOW_NULL | Yes | No | No
ARRAY_VISUALIZER2 | Yes | No | No
C | No | Yes | Yes
DECORATE | No | No | Yes
DEFAULT | No | Yes | Yes
DESCRIPTOR | Yes3 | No | No
DESCRIPTOR32 | Yes3 | No | No
DESCRIPTOR64 | Yes3 | No | No
DLLEXPORT | Yes4 | Yes | Yes
DLLIMPORT | Yes | Yes | Yes
EXTERN | Yes | No | No
IGNORE_LOC | Yes3 | No | No
NO_ARG_CHECK | Yes | No | Yes5
NOMIXED_STR_LEN_ARG | No | No | Yes
REFERENCE | Yes | No | Yes
REFERENCE32 | Yes | No | No
REFERENCE64 | Yes | No | No
STDCALL | No | Yes | Yes
VALUE | Yes | No | No
VARYING | No | No | Yes
1 A common block name is specified as [/]common-block-name[/]
2 This property can only be applied to arrays.
3 This property can only be applied to INTERFACE blocks.
4 Module-level variables and arrays only.
5 This property cannot be applied to EXTERNAL statements.

These properties can be used in function and subroutine definitions, in type declarations, and with the INTERFACE and ENTRY statements.

Properties applied to entities available through use or host association are in effect during the association. For example, consider the following:

MODULE MOD1
  INTERFACE
    SUBROUTINE SUB1
    !DEC$ ATTRIBUTES C, ALIAS:'othername' :: NEW_SUB
    END SUBROUTINE
  END INTERFACE
  CONTAINS
    SUBROUTINE SUB2
    CALL NEW_SUB
    END SUBROUTINE
END MODULE

In this case, the call to NEW_SUB within SUB2 uses the C and ALIAS properties specified in the interface block.

The properties are described as follows:

  • ADDRESS64 (VMS, WNT)

    Specifies that the object has a 64-bit address. This property can be specified for any variable or dummy argument, including ALLOCATABLE and deferred-shape arrays. However, variables with this property cannot be data-initialized.

    It can also be specified for COMMON blocks or for variables in a COMMON block. If specified for a COMMON block variable, the COMMON block implicitly has the ADDRESS64 property.

    ADDRESS64 is not compatible with the AUTOMATIC attribute.

  • ALIAS

    Specifies an alternate external name to be used when referring to external subprograms. Its form is:

    ALIAS:external-name

    external-name
    Is a character constant delimited by apostrophes or quotation marks. The character constant is used as is; the string is not changed to uppercase, nor are blanks removed.

    The ALIAS property overrides the C (and STDCALL) property. If both C and ALIAS are specified for a subprogram, the subprogram is given the C calling convention, but not the C naming convention. It instead receives the name given for ALIAS, with no modifications.

    ALIAS cannot be used with internal procedures, and it cannot be applied to dummy arguments.

    The following example gives the subroutine happy the name "_OtherName@4" outside this scoping unit:

    INTERFACE
     SUBROUTINE happy(i)
!DEC$ ATTRIBUTES STDCALL, DECORATE, ALIAS:'OtherName' :: happy
     INTEGER i
     END SUBROUTINE
END INTERFACE

    c DEC$ ATTRIBUTES ALIAS has the same effect as the cDEC$ ALIAS directive.

  • ALLOW_NULL

    Enables a corresponding dummy argument to pass a NULL pointer (defined by a zero or the NULL intrinsic) by value for the argument.

    ALLOW_NULL is only valid if the REFERENCE property is also specified; otherwise, it has no effect.

  • ARRAY_VISUALIZER

    Enhances the performance of the Array Visualizer.

    When declaring allocatable arrays to be viewed using the Array Viewer, this option can improve the performance of the Array Viewer. For example:

      real(4), allocatable :: MyArray(:, :)
  !DEC$ ATTRIBUTES array_visualizer :: MyArray

    When this option is used, array memory is shared between the Array Viewer and your application. Otherwise, the array data is copied during each faglUpdate call.

    This option is not useful unless the array is viewed in the Array Visualizer by using fagl* calls.

    For more information on fagl* routines, see your online documentation for Array Visualizer.

  • C and STDCALL

    Specify how data is to be passed when you use routines written in C or assembler with FORTRAN or Fortran 95/90 routines.

    On ia32 processors, C and STDCALL have slightly different meanings; on all other platforms, they are interpreted as synonyms.

    When applied to a subprogram, these properties define the subprogram as having a specific set of calling conventions.

    The following table summarizes the differences between the calling conventions:

    Convention | C 1 | STDCALL 1 | Default 2
    Arguments passed by value | Yes | Yes | No
    Case of external subprogram names VMS: Uppercase
    U*X: Lowercase
    WNT: Lowercase
    W95: Lowercase         		VMS: Uppercase
    U*X: Lowercase
    WNT: Lowercase
    W95: Lowercase         		VMS: Uppercase
    U*X: Lowercase
    WNT: Uppercase
    W95: Uppercase
    U*X only:
    Trailing underscore added | No | No | Yes 3
    WNT, W9*:
    Leading underscore added | Yes | Yes | Yes
    Number of arguments added | No | Yes | Yes
    Caller stack cleanup | Yes | No | No
    Variable number of arguments | Yes | No | No
    1 C and STDCALL are synonyms on OpenVMS, Tru64 UNIX, and Linux systems.
    2 The Fortran 95/90 calling convention
    3 On Linux systems, if there are one or more underscores in the external name, two trailing underscores are added; if there are no underscores, one is added.

    If C or STDCALL is specified for a subprogram, arguments (except for arrays and characters) are passed by value. Subprograms using standard Fortran 95/90 conventions pass arguments by reference.

    On ia32 processors, an underscore ( _ ) is placed at the beginning of the external name of a subprogram. If STDCALL is specified, an at sign (@) followed by the number of argument bytes being passed is placed at the end of the name. For example, a subprogram named SUB1 that has three INTEGER(4) arguments and is defined with STDCALL is assigned the external name _sub1@12.

    Character arguments are passed as follows:

    • By default:

      • On OpenVMS, Tru64 UNIX, and Linux systems, hidden lengths are put at the end of the argument list.

      • On Windows systems, hidden lengths immediately follow the variable. To get the OpenVMS, Tru64 UNIX, and Linux behavior, use the /iface:nomixed_str_len_arg compiler option.

    • If C or STDCALL (only) is specified:

      On all systems, the first character of the string is passed (and padded with zeros out to INTEGER(4) length).

    • If C or STDCALL is specified, and REFERENCE is specified for the argument:

      On all systems, the string is passed with no length.

    • If C or STDCALL is specified, and REFERENCE is specified for the routine (but REFERENCE is not specified for the argument, if any):

      On all systems, the string is passed with the length.

    See also REFERENCE and Adjusting Calling Conventions in Mixed-Language Programming.

  • DECORATE

    Specifies that the external name used in c DEC$ ALIAS or c DEC$ ATTRIBUTES ALIAS should have the prefix and postfix decorations performed on it that are associated with the calling mechanism that is in effect. These are the same decorations performed on the procedure name when ALIAS is not specified.

    The case of the ALIAS external name is not modified.

    If ALIAS is not specified, this option has no effect.

    See also the example in the above description of the ATTRIBUTES option ALIAS, and the summary of prefix and postfix decorations in the above description of the ATTRIBUTES options C and STDCALL.

  • DEFAULT

    Overrides certain compiler options that can affect external routine and COMMON block declarations.

    It specifies that the compiler should ignore compiler options that change the default conventions for external symbol naming and argument passing for routines and COMMON blocks (/iface, /names, and /assume:underscore).

    This option can be combined with other c DEC$ ATTRIBUTES options, such as STDCALL, C, REFERENCE, ALIAS, etc. to specify attributes different from the compiler defaults.

    This option is useful when declaring INTERFACE blocks for external routines, since it prevents compiler options from changing calling or naming conventions.

  • DESCRIPTOR (VMS only)

    Specifies that the argument is passed by VMS descriptor. This property can be specified only for dummy arguments in an INTERFACE block (not for a routine name).

  • DESCRIPTOR32 (VMS only)

    Specifies that the argument is passed as a 32-bit descriptor.

  • DESCRIPTOR64 (VMS only)

    Specifies that the argument is passed as a 64-bit descriptor.

  • DLLEXPORT and DLLIMPORT (WNT, W9*)

    Define a dynamic-link library's (DLL) interface for processes that use them. The properties can be assigned to data objects or procedures.

    DLLEXPORT specifies that procedures or data are being exported to other applications or DLLs. This causes the compiler to produce efficient code, eliminating the need for a module definition (.def) file to export symbols.

    The DLLEXPORT property should be specified in the routine to which it applies.

    Symbols defined in a DLL are imported by programs that use them. The program must link with the import DLL and use the DLLIMPORT property inside the program unit that imports the symbol. DLLIMPORT is specified in a declaration, not a definition, since you cannot define a symbol you are importing.

    For details on working with DLL applications, see Creating Fortran DLLs in the Programmer's Guide.

  • EXTERN

    Specifies that a variable is allocated in another source file. EXTERN can be used in global variable declarations, but it must not be applied to dummy arguments.

    EXTERN must be used when accessing variables declared in other languages.

  • IGNORE_LOC

    Enables %LOC to be stripped from an argument.

    IGNORE_LOC is only valid if the REFERENCE property is also specified; otherwise, it has no effect.

  • NO_ARG_CHECK

    Specifies that type and shape matching rules related to explicit interfaces are to be ignored. This permits the construction of an INTERFACE block for an external procedure or a module procedure that accepts an argument of any type or shape; for example, a memory copying routine.

    NO_ARG_CHECK can appear only in an INTERFACE block for a non-generic procedure or in a module procedure. It can be applied to an individual dummy argument name or to the routine name, in which case the property is applied to all dummy arguments in that interface.

    NO_ARG_CHECK can not be used for procedures with the PURE or ELEMENTAL prefix. If an argument has an INTENT or OPTIONAL attribute, any NO_ARG_CHECK specification is ignored.

  • NOMIXED_STR_LEN_ARG

    Specifies that hidden lengths be placed in sequential order at the end of the argument list. This is the method used on Tru64 UNIX systems by default.

  • REFERENCE and VALUE

    Specify how a dummy argument is to be passed.

    REFERENCE specifies a dummy argument's memory location is to be passed instead of the argument's value.

    VALUE specifies a dummy argument's value is to be passed instead of the argument's memory location.

    When a dummy argument has the VALUE property, the actual argument passed to it can be of a different type. If necessary, type conversion is performed before the subprogram is called.

    When a complex (KIND=4 or KIND=8) argument is passed by value, two floating-point arguments (one containing the real part, the other containing the imaginary part) are passed by immediate value.

    Character values, substrings, assumed-size arrays, and adjustable arrays cannot be passed by value.

    If REFERENCE (only) is specified for a character argument, the following occurs:

    • On OpenVMS, Tru64 UNIX, and Linux systems, the string is passed with no length.

    • On Windows systems, hidden lengths immediately follow the variable. To get the OpenVMS, Tru64 UNIX, and Linux behavior, use the /iface:nomixed_str_len_arg compiler option.

    If REFERENCE is specified for a character argument, and C (or STDCALL) has been specified for the routine, the string is passed with no length. This is true even if REFERENCE is also specified for the routine.

    If REFERENCE and C (or STDCALL) are specified for a routine, but REFERENCE has not been specified for the argument, the string is passed with the length.

    VALUE is the default if the C or STDCALL property is specified in the subprogram definition.

    In the following example integer x is passed by value:

          SUBROUTINE Subr (x)
      INTEGER x
!DEC$ ATTRIBUTES VALUE :: x

    See also C and STDCALL and Adjusting Calling Conventions in Mixed-Language Programming.

  • REFERENCE32 (VMS only)

    Specifies that the argument is accepted only by 32-bit address.

  • REFERENCE64 (VMS only)

    Specifies that the argument is accepted only by 64-bit address.

  • VARYING

    Allows a variable number of calling arguments. If VARYING is specified, the C property must also be specified.

    Either the first argument must be a number indicating how many arguments to process, or the last argument must be a special marker (such as -1) indicating it is the final argument. The sequence of the arguments, and types and kinds must be compatible with the called procedure.

Options C, STDCALL, REFERENCE, VALUE, and VARYING affect the calling conventions of routines:

  • You can specify C, STDCALL, REFERENCE, and VARYING for an entire routine.
  • You can specify VALUE and REFERENCE for individual arguments.

The following form is also allowed for this attribute: !MS$ATTRIBUTES att [,att] ... :: object [,object] ...

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Programming with Mixed Languages, Creating Fortran DLLs, General Compiler Directives

Examples

INTERFACE
   SUBROUTINE For_Sub (I)
     !DEC$ ATTRIBUTES C, ALIAS:'_For_Sub' :: For_Sub
     INTEGER I
   END SUBROUTINE For_Sub
END INTERFACE

You can assign more than one property to multiple variables with the same compiler directive. All properties apply to all the specified variables. For example:

 !DEC$ ATTRIBUTES REFERENCE, VARYING, C :: A, B, C

In this case, the variables A, B, and C are assigned the REFERENCE, VARYING, and C properties. The only restriction on the number of properties and variables is that the entire compiler directive must fit on one line.

The identifier of the variable or procedure assigned properties must be a simple name. It cannot include initialization or array dimensions. For example, the following is not allowed:

 !DEC$ ATTRIBUTES C :: A(10)  ! This is illegal.

The following shows another example:

SUBROUTINE ARRAYTEST(arr)
!DEC$ ATTRIBUTES DLLEXPORT :: ARRAYTEST
   REAL(4) arr(3, 7)
   INTEGER i, j
   DO i = 1, 3
     DO j = 1, 7
       arr (i, j) = 11.0 * i + j
     END DO
   END DO
END SUBROUTINE


AUTOAddArg

DFAUTO Subroutine: Passes an argument name and value and adds the argument to the argument list data structure.

Modules: USE DFAUTO, USE DFWINTY

Syntax

CALL AUTOAddArg (invoke_args, name, value [, intent_arg] [, type])

invoke_args
The argument list data structure. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

name
The argument's name of type CHARACTER*(*).

value
The argument's value. Must be of type INTEGER(2), INTEGER(4), REAL(4), REAL(8), LOGICAL(2), LOGICAL(4), CHARACTER*(*), or a single dimension array of one of these types. Can also be of type VARIANT, which is defined in the DFWINTY module.

intent_arg
Indicates the intended use of the argument by the called method. Must be one of the following constants defined in the DFAUTO module:

  • AUTO_ARG_IN: The argument's value is read by the called method, but not written. This is the default value if intent_arg is not specified.
  • AUTO_ARG_OUT: The argument's value is written by the called method, but not read.
  • AUTO_ARG_INOUT: The argument's value is read and written by the called method.

When the value of intent_arg is AUTO_ARG_OUT or AUTO_ARG_INOUT, the variable used in the value parameter should be declared using the VOLATILE attribute. This is because the value of the variable will be changed by the subsequent call to AUTOInvoke. The compiler's global optimizations need to know that the value can change unexpectedly.

type
The variant type of the argument. Must be one of the following constants defined in the DFWINTY module:

VARIANT Type | Value Type
VT_I2 | INTEGER(2)
VT_I4 | INTEGER(4)
VT_R4 | REAL(4)
VT_R8 | REAL(8)
VT_CY | REAL(8)
VT_DATE | REAL(8)
VT_BSTR | CHARACTER*(*)
VT_DISPATCH | INTEGER(4)
VT_ERROR | INTEGER(4)
VT_BOOL | LOGICAL(2)
VT_VARIANT | TYPE(VARIANT)
VT_UNKNOWN | INTEGER(4)


AUTOAllocateInvokeArgs

DFAUTO Function: Allocates an argument list data structure that holds the arguments to be passed to AUTOInvoke.

Modules: USE DFAUTO

Syntax

result = AUTOAllocateInvokeArgs( )

Results:

The value returned is an argument list data structure of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.


AUTODeallocateInvokeArgs

DFAUTO Subroutine: Deallocates an argument list data structure.

Modules: USE DFAUTO

Syntax

CALL AUTODeallocateInvokeArgs (invoke_args)

invoke_args
The argument list data structure. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.


AUTOGetExceptInfo

DFAUTO Subroutine: Retrieves the exception information when a method has returned an exception status.

Modules: USE DFAUTO

Syntax

CALL AUTOGetExceptInfo (invoke_args, code, source, description, help_file, help_context, scode)

invoke_args
The argument list data structure. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

code
An output argument that returns the error code. Must be of type INTEGER(2).

source
An output argument that returns a human-readable name of the source of the exception. Must be of type CHARACTER*(*).

description
An output argument that returns a human-readable description of the error. Must be of type CHARACTER*(*).

help_file
An output argument that returns the fully qualified path of a Help file with more information about the error. Must be of type CHARACTER*(*).

help_context
An output argument that returns the Help context of the topic within the Help file. Must be of type INTEGER(4).

scode
An output argument that returns an SCODE describing the error. Must be of type INTEGER(4).


AUTOGetProperty

DFAUTO Function: Passes the name or identifier of the property and gets the value of the Automation object's property.

Modules: USE DFAUTO, USE DFWINTY

Syntax

result = AUTOGetProperty (idispatch, id, value [, type])

idispatch
The object's IDispatch interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

id
The argument's name of type CHARACTER*(*), or its member ID of type INTEGER(4).

value
An output argument that returns the argument's value. Must be of type INTEGER(2), INTEGER(4), REAL(4), REAL(8), LOGICAL(2), LOGICAL(4), CHARACTER*(*), or a single dimension array of one of these types.

type
The variant type of the requested argument. Must be one of the following constants defined in the DFWINTY module:

VARIANT Type | Value Type
VT_I2 | INTEGER(2)
VT_I4 | INTEGER(4)
VT_R4 | REAL(4)
VT_R8 | REAL(8)
VT_CY | REAL(8)
VT_DATE | REAL(8)
VT_BSTR | CHARACTER*(*)
VT_DISPATCH | INTEGER(4)
VT_ERROR | INTEGER(4)
VT_BOOL | LOGICAL(2)
VT_UNKNOWN | INTEGER(4)

Results:

Returns an HRESULT describing the status of the operation. Must be of type INTEGER(4).


AUTOGetPropertyByID

DFAUTO Function: Passes the member ID of the property and gets the value of the Automation object's property into the argument list's first argument.

Modules: USE DFAUTO

Syntax

result = AUTOGetPropertyByID (idispatch, memid, invoke_args)

idispatch
The object's IDispatch interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

memid
Member ID of the property. Must be of type INTEGER(4).

invoke_args
The argument list data structure. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

Results:

Returns an HRESULT describing the status of the operation. Must be of type INTEGER(4).


AUTOGetPropertyInvokeArgs

DFAUTO Function: Passes an argument list data structure and gets the value of the Automation object's property specified in the argument list's first argument.

Modules: USE DFAUTO

Syntax

result = AUTOGetPropertyInvokeArgs (idispatch, invoke_args)

idispatch
The object's IDispatch interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

invoke_args
The argument list data structure. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

Results:

Returns an HRESULT describing the status of the operation. Must be of type INTEGER(4).


AUTOInvoke

DFAUTO Function: Passes the name or identifier of an object's method and an argument list data structure and invokes the method with the passed arguments.

Modules: USE DFAUTO

Syntax

result = AUTOInvoke (idispatch, id, invoke_args)

idispatch
The object's IDispatch interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

id
The argument's name of type CHARACTER*(*), or its member ID of type INTEGER(4).

invoke_args
The argument list data structure. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

Results:

Returns an HRESULT describing the status of the operation. Must be of type INTEGER(4).


AUTOMATIC

Statement and Attribute: Controls the storage allocation of variables in subprograms (as does STATIC). Variables declared as AUTOMATIC and allocated in memory reside in the stack storage area, rather than at a static memory location.

The AUTOMATIC attribute can be specified in a type declaration statement or an AUTOMATIC statement, and takes one of the following forms:

Syntax

Type Declaration Statement:

type, [att-ls,] AUTOMATIC [att-ls,] :: v [, v] ...

Statement:

AUTOMATIC [::] v [, v] ...

type
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

v
Is the name of a variable or an array specification. It can be of any type.

Rules and Behavior

AUTOMATIC declarations only affect how data is allocated in storage.

If you want to retain definitions of variables upon reentry to subprograms, you must use the SAVE attribute.

Automatic variables can reduce memory use because only the variables currently being used are allocated to memory.

Automatic variables allow possible recursion. With recursion, a subprogram can call itself (directly or indirectly), and resulting values are available upon a subsequent call or return to the subprogram. For recursion to occur, RECURSIVE must be specified in one of the following ways:

  • As a keyword in a FUNCTION or SUBROUTINE statement
  • As a compiler option
  • As an option in an OPTIONS statement

By default, the compiler allocates local variables of non-recursive subprograms, except for allocatable arrays, in the static storage area. The compiler may choose to allocate a variable in temporary (stack or register) storage if it notices that the variable is always defined before use. Appropriate use of the SAVE attribute can prevent compiler warnings if a variable is used before it is defined.

To change the default for variables, specify them as AUTOMATIC or specify RECURSIVE (in one of the ways mentioned above).

To override any compiler option that may affect variables, explicitly specify the variables as AUTOMATIC.

Note: Variables that are data-initialized, and variables in COMMON and SAVE statements are always static. This is regardless of whether a compiler option specifies recursion.

A variable cannot be specified as AUTOMATIC more than once in the same scoping unit.

If the variable is a pointer, AUTOMATIC applies only to the pointer itself, not to any associated target.

Some variables cannot be specified as AUTOMATIC. The following table shows these restrictions:

Variable | AUTOMATIC
Dummy argument | No
Automatic object | No
Common block item | No
Use-associated item | No
Function result | No
Component of a derived type | No

If a variable is in a module's outer scope, it cannot be specified as AUTOMATIC.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: STATIC, SAVE, Type declaration statements, Compatible attributes, RECURSIVE, /recursive, OPTIONS, POINTER, Modules and Module Procedures

Examples

The following example shows a type declaration statement specifying the AUTOMATIC attribute:

REAL, AUTOMATIC :: A, B, C

The following example uses an AUTOMATIC statement:

...
CONTAINS
 INTEGER FUNCTION REDO_FUNC
   INTEGER I, J(10), K
   REAL C, D, E(30)
   AUTOMATIC I, J, K(20)
   STATIC C, D, E
   ...
 END FUNCTION
...

C       In this example, all variables within the program unit
C       are automatic, except for "var1" and "var2"; these are
C       explicitly declared in a SAVE statement, and thus have
C       static memory locations:
        SUBROUTINE DoIt (arg1, arg2)

        INTEGER(4) arg1, arg2
        INTEGER(4) var1, var2, var3, var4

        AUTOMATIC
        SAVE var1, var3
C       var2 and var4 are automatic


AUTOSetProperty

DFAUTO Function: Passes the name or identifier of the property and a value, and sets the value of the Automation object's property.

Modules: USE DFAUTO, USE DFWINTY

Syntax

result = AUTOSetProperty (idispatch, id, value [, type])

idispatch
The object's IDispatch interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

id
The argument's name of type CHARACTER*(*), or its member ID of type INTEGER(4).

value
The argument's value. Must be of type INTEGER(2), INTEGER(4), REAL(4), REAL(8), LOGICAL(2), LOGICAL(4), CHARACTER*(*), or a single dimension array of one of these types.

type
The variant type of the argument. Must be one of the following constants defined in the DFWINTY module:

VARIANT Type | Value Type
VT_I2 | INTEGER(2)
VT_I4 | INTEGER(4)
VT_R4 | REAL(4)
VT_R8 | REAL(8)
VT_CY | REAL(8)
VT_DATE | REAL(8)
VT_BSTR | CHARACTER*(*)
VT_DISPATCH | INTEGER(4)
VT_ERROR | INTEGER(4)
VT_BOOL | LOGICAL(2)
VT_UNKNOWN | INTEGER(4)

Results:

Returns an HRESULT describing the status of the operation. Must be of type INTEGER(4).


AUTOSetPropertyByID

DFAUTO Function: Passes the member ID of the property and sets the value of the Automation object's property into the argument list's first argument.

Modules: USE DFAUTO

Syntax

result = AUTOSetPropertyByID (idispatch, memid, invoke_args)

idispatch
The object's IDispatch interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

memid
Member ID of the property. Must be of type INTEGER(4).

invoke_args
The argument list data structure. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

Results:

Returns an HRESULT describing the status of the operation. Must be of type INTEGER(4).


AUTOSetPropertyInvokeArgs

DFAUTO Function: Passes an argument list data structure and sets the value of the Automation object's property specified in the argument list's first argument.

Modules: USE DFAUTO

Syntax

result = AUTOSetPropertyInvokeArgs (idispatch, invoke_args)

idispatch
The object's IDispatch interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

invoke_args
The argument list data structure. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

Results:

Returns an HRESULT describing the status of the operation. Must be of type INTEGER(4).


BACKSPACE

Statement: Positions a file at the beginning of the preceding record, making it available for subsequent I/O processing. It takes one of the following forms:

Syntax

BACKSPACE ([UNIT=]io-unit [, ERR=label] [, IOSTAT=i-var])
BACKSPACE io-unit

io-unit
(Input) Is an external unit specifier.

label
Is the label of the branch target statement that receives control if an error occurs.

i-var
(Output) Is a scalar integer variable that is defined as a positive integer if an error occurs and zero if no error occurs.

Rules and Behavior

Use the BACKSPACE statement with files connected for sequential access. BACKSPACE cannot be used to skip over records that have been written using list-directed or namelist formatting.

The I/O unit number must specify an open file on disk or magnetic tape.

Backspacing from the current record n is performed by rewinding to the start of the file and then performing n-1 successive READs to reach the previous record.

A BACKSPACE statement must not be specified for a file that is open for direct or append access, because n is not available to the Fortran I/O system.

If a file is already positioned at the beginning of a file, a BACKSPACE statement has no effect.

If the file is positioned between the last record and the end-of-file record, BACKSPACE positions the file at the start of the last record.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: REWIND, ENDFILE, Data Transfer I/O Statements, Branch Specifiers

Examples

  BACKSPACE 5
  BACKSPACE (5)
  BACKSPACE lunit
  BACKSPACE (UNIT = lunit, ERR = 30, IOSTAT = ios)

The following statement repositions the file connected to I/O unit 4 back to the preceding record:

  BACKSPACE 4

Consider the following statement:

  BACKSPACE (UNIT=9, IOSTAT=IOS, ERR=10)

This statement positions the file connected to unit 9 back to the preceding record. If an error occurs, control is transferred to the statement labeled 10, and a positive integer is stored in variable IOS.


BARRIER (TU*X only)

OpenMP Parallel Compiler Directive: Synchronizes all the threads in a team. It causes each thread to wait until all of the other threads in the team have reached the barrier.

Syntax

c$OMP BARRIER

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

The BARRIER directive must be encountered by all threads in a team or by none at all. It must also be encountered in the same order by all threads in a team.

See Also: Parallel Directives for Tru64 UNIX Systems, OpenMP Fortran API Compiler Directives (TU*X only), Compaq Fortran Parallel Compiler Directives (TU*X only), Nesting and Binding Rules

Examples

The directive binding rules call for a BARRIER directive to bind to the closest enclosing PARALLEL directive. In the following example, the BARRIER directive ensures that all threads have executed the first loop and that it is safe to execute the second loop:

  c$OMP PARALLEL
  c$OMP DO PRIVATE(i)
        DO i = 1, 100
          b(i) = i
        END DO
  c$OMP BARRIER
  c$OMP DO PRIVATE(i)
        DO i = 1, 100
          a(i) = b(101-i)
        END DO
  c$OMP END PARALLEL


BEEPQQ

Run-Time Subroutine: Sounds the speaker at the specified frequency for the specified duration in milliseconds.

Module: USE DFLIB

Syntax

CALL BEEPQQ (frequency, duration)

frequency
(Input) INTEGER(4). Frequency of the tone in Hz.

duration
(Input) INTEGER(4). Length of the beep in milliseconds.

BEEPQQ does not return until the sound terminates.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SLEEPQQ

Example

  USE DFLIB
  INTEGER(4) frequency, duration
  frequency = 4000
  duration  = 1000
  CALL BEEPQQ(frequency, duration)


BESJ0, BESJ1, BESJN, BESY0, BESY1, BESYN

Portability Functions: Compute the single-precision values of Bessel functions of the first and second kinds.

Module: USE DFPORT

Syntax

result = BESJ0 (posvalu)
result = BESJ1 (posvalu)
result = BESJN (n, posvalu)
result = BESY0 (posvalu)
result = BESY1 (posvalu)
result = BESYN (n, posvalu)

posvalue
(Input) REAL(4). Independent variable for a Bessel function. Must be greater than or equal to zero.

n
(Input) Default integer (INTEGER(4) unless changed by the user). Specifies the order of the selected Bessel function computation.

Results:

BESJ0, BESJ1, and BESJN return Bessel functions of the first kind, orders 0, 1, and n, respectively, with the independent variable posvalue.

BESY0, BESY1, and BESYN return Bessel functions of the second kind, orders 0, 1, and n, respectively, with the independent variable posvalue.

Negative arguments cause BESY0, BESY1, and BESYN to return QNAN.

Bessel functions are explained more fully in most mathematics reference books, such as the Handbook of Mathematical Functions (Abramowitz and Stegun. Washington: U.S. Government Printing Office, 1964). These functions are commonly used in the mathematics of electromagnetic wave theory.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DBESJ0, DBESJ1, DBESJN


BIC, BIS

Portability Subroutines: Perform a bit-level set and clear for integers.

Module: USE DFPORT

Syntax

CALL BIC (bitnum, target)
CALL BIS (bitnum, target)

bitnum
(Input) INTEGER(4). Bit number to set. Must be in the range 0 (least significant bit) to 31 (most significant bit).

target
(Input) INTEGER(4). Variable whose bit is to be set.

BIC sets bit bitnum of target to 0; BIS sets bit bitnum to 1.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BIT


BIT

Portability Function: Performs a bit-level test for integers.

Module: USE DFPORT

Syntax

result = BIT (bitnum, source)

bitnum
(Input) INTEGER(4). Bit number to test. Must be in the range 0 (least significant bit) to 31 (most significant bit).

source
(Input) INTEGER(4). Variable being tested.

Results:

The result is of type logical. It is .TRUE. if bit bitnum of source is 1; otherwise, .FALSE..

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BIC, BIS


BIT_SIZE

Inquiry Intrinsic Function (Generic): Returns the number of bits in an integer type.

Syntax

result = BIT_SIZE (i)

i
(Input) Must be of type integer.

Results:

The result is a scalar integer with the same kind parameter as i. The result value is the number of bits (s) defined by the bit model for integers with the kind parameter of the argument. For information on the bit model, see Model for Bit Data.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BTEST, IBCLR, IBITS, IBSET

Examples

BIT_SIZE (1_2) has the value 16 because the KIND=2 integer type contains 16 bits.


BLOCK DATA

Statement: Identifies a block-data program unit, which provides initial values for nonpointer variables in named common blocks.

Syntax

BLOCK DATA [name]
[specification-part]
END [BLOCK DATA [name]]

name
Is the name of the block data program unit.

specification-part
Is one or more of the following statements:

COMMON | INTRINSIC | STATIC
DATA | PARAMETER | TARGET
Derived-type definition | POINTER | Type declaration 2
DIMENSION | RECORD 1 | USE 3
EQUIVALENCE | Record structure declaration 1
IMPLICIT | SAVE
1 For more information, see RECORD statement and record structure declarations.
2 Can only contain attributes: DIMENSION, INTRINSIC, PARAMETER, POINTER, SAVE, STATIC, or TARGET.
3 Allows access to only named constants.

Rules and Behavior

A block data program unit need not be named, but there can only be one unnamed block data program unit in an executable program.

If a name follows the END statement, it must be the same as the name specified in the BLOCK DATA statement.

An interface block must not appear in a block data program unit and a block data program unit must not contain any executable statements.

If a DATA statement initializes any variable in a named common block, the block data program unit must have a complete set of specification statements establishing the common block. However, all of the variables in the block do not have to be initialized.

A block data program unit can establish and define initial values for more than one common block, but a given common block can appear in only one block data program unit in an executable program.

The name of a block data program unit can appear in the EXTERNAL statement of a different program unit to force a search of object libraries for the block data program unit at link time.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: COMMON, DATA, EXTERNAL, Program Units and Procedures

Examples

The following shows a block data program unit:

BLOCK DATA BLKDAT
  INTEGER S,X
  LOGICAL T,W
  DOUBLE PRECISION U
  DIMENSION R(3)
  COMMON /AREA1/R,S,U,T /AREA2/W,X,Y
  DATA R/1.0,2*2.0/, T/.FALSE./, U/0.214537D-7/, W/.TRUE./, Y/3.5/
END

The following shows another example:

C      Main Program
       CHARACTER(LEN=10) LakeType
       REAL X(10), Y(4)
       COMMON/Lakes/a,b,c,d,e,family/Blk2/x,y
       ...
C      The following block-data subprogram initializes
C      the named common block /Lakes/:
C
       BLOCK DATA InitLakes
       COMMON /Lakes/ erie, huron, michigan, ontario,
      +        superior, fname
       DATA erie, huron, michigan, ontario, superior /1, 2, 3, 4, 5/
       CHARACTER(LEN=10) fname/'GreatLakes'/
       END


BSEARCHQQ

Run-Time Function: Performs a binary search of a sorted one-dimensional array for a specified element. The array elements cannot be derived types or structures.

Module: USE DFLIB

Syntax

result = BSEARCHQQ (adrkey, adrarray, length, size)

adrkey
(Input) Address of the variable containing the element to be found (returned by LOC). INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

adrarray
(Input) Address of the array (returned by LOC). INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

length
(Input) INTEGER(4). Number of elements in the array.

size
(Input) INTEGER(4). Positive constant less than 32,767 that specifies the kind of array to be sorted. The following constants, defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory, specify type and kind for numeric arrays:

Constant | Type of array
SRT$INTEGER1 | INTEGER(1)
SRT$INTEGER2 | INTEGER(2) or equivalent
SRT$INTEGER4 | INTEGER(4) or equivalent
SRT$REAL4 | REAL(4) or equivalent
SRT$REAL8 | REAL(8) or equivalent

If the value provided in size is not a symbolic constant and is less than 32,767, the array is assumed to be a character array with size characters per element.

Results:

INTEGER(4). Array index of the matched entry, or 0 if the entry is not found.

The array must be sorted in ascending order before being searched.

Caution: The location of the array and the element to be found must both be passed by address using the LOC function. This defeats Fortran type checking, so you must make certain that the length and size arguments are correct, and that size is the same for the element to be found and the array searched.

If you pass invalid arguments, BSEARCHQQ attempts to search random parts of memory. If the memory it attempts to search is allocated to the current process, that memory is searched. If the memory it attempts to search is not allocated to the current process, the operating system intervenes, the program is halted, and you receive a General Protection Violation message.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SORTQQ, LOC

Example

USE DFLIB
INTEGER(4) array(10), length
INTEGER(4) result, target
length = SIZE(array)
...
result = BSEARCHQQ(LOC(target),LOC(array),length,SRT$INTEGER4)


BTEST

Elemental Intrinsic Function (Generic): Tests a bit of an integer argument.

Syntax

result = BTEST (i, pos)

i
(Input) Must be of type integer.

pos
(Input) Must be of type integer. It must not be negative and it must be less than BIT_SIZE(i).
The rightmost (least significant) bit of i is in position 0.

Results:

The result is of type default logical.

The result is true if bit pos of i has the value 1. The result is false if pos has the value zero. For more information, see Bit Functions.

For information on the model for the interpretation of an integer value as a sequence of bits, see Model for Bit Data.

The setting of compiler option /integer_size can affect this function.

Specific Name | Argument Type | Result Type
 | INTEGER(1) | LOGICAL(1)
BITEST | INTEGER(2) | LOGICAL(2)
BTEST 1 | INTEGER(4) | LOGICAL(4)
BKTEST | INTEGER(8) | LOGICAL(8)
1 Or BJTEST

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: IBCLR, IBSET, IBCHNG, IOR, IEOR, IAND

Examples

BTEST (9, 3) has the value true.

If A has the value

  [ 1  2 ]
  [ 3  4 ],
the value of BTEST (A, 2) is
  [ false  false ]
  [ false   true ]
and the value of BTEST (2, A) is
  [ true   false ]
  [ false  false ].

The following shows more examples:

Function reference | i | Result
BTEST (i,2) | 00011100 01111000 | .FALSE.
BTEST (i,3) | 00011100 01111000 | .TRUE.

The following shows another example:

INTEGER(1) i(2)
LOGICAL result(2)
i(1) = 2#10101010
i(2) = 2#01010101
result = BTEST(i, (/3,2/))   ! returns (.TRUE.,.TRUE.)
write(*,*) result


BYTE

Statement: Specifies the BYTE data type, which is equivalent to INTEGER(1).

See Also: INTEGER, Integer Data Types

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

BYTE count, matrix(4, 4) / 4*1, 4*2, 4(4), 4*8 /
BYTE num  / 10 /


CALL

Statement: Transfers control to a subroutine subprogram.

Syntax

CALL sub [( [a-arg [, a-arg] ...] )]

sub
Is the name of the subroutine subprogram or other external procedure, or a dummy argument associated with a subroutine subprogram or other external procedure.

a-arg
Is an actual argument optionally preceded by [keyword=], where keyword is the name of a dummy argument in the explicit interface for the subroutine. The keyword is assigned a value when the procedure is invoked.

Each actual argument must be a variable, an expression, the name of a procedure, or an alternate return specifier. (It must not be the name of an internal procedure, statement function, or the generic name of a procedure.)

An alternate return specifier is an asterisk (*), or ampersand (&) followed by the label of an executable branch target statement in the same scoping unit as the CALL statement. (An alternate return is an obsolescent feature in Fortran 95 and Fortran 90.)

Rules and Behavior

When the CALL statement is executed, any expressions in the actual argument list are evaluated, then control is passed to the first executable statement or construct in the subroutine. When the subroutine finishes executing, control returns to the next executable statement following the CALL statement, or to a statement identified by an alternate return label (if any).

If an argument list appears, each actual argument is associated with the corresponding dummy argument by its position in the argument list or by the name of its keyword. The arguments must agree in type and kind parameters.

If positional arguments and argument keywords are specified, the argument keywords must appear last in the actual argument list.

If a dummy argument is optional, the actual argument can be omitted.

An actual argument associated with a dummy procedure must be the specific name of a procedure, or be another dummy procedure. Certain specific intrinsic function names must not be used as actual arguments (see Functions Not Allowed as Actual Arguments).

You can use a CALL statement to invoke a function as long as the function is not one of the following types:

  • REAL(8)
  • REAL(16) (VMS, U*X)
  • COMPLEX(8)
  • COMPLEX(16) (VMS, U*X)
  • CHARACTER

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SUBROUTINE, CONTAINS, RECURSIVE, USE, Program Units and Procedures

Examples

The following example shows valid CALL statements:

CALL CURVE(BASE,3.14159+X,Y,LIMIT,R(LT+2))

CALL PNTOUT(A,N,'ABCD')

CALL EXIT

CALL MULT(A,B,*10,*20,C)       ! The asterisks and ampersands denote
CALL SUBA(X,&30,&50,Y)         !     alternate returns

The following example shows a subroutine with argument keywords:

PROGRAM KEYWORD_EXAMPLE
  INTERFACE
    SUBROUTINE TEST_C(I, L, J, KYWD2, D, F, KYWD1)
    INTEGER I, L(20), J, KYWD1
    REAL, OPTIONAL :: D, F
    COMPLEX KYWD2
    ...
    END SUBROUTINE TEST_C
  END INTERFACE
  INTEGER I, J, K
  INTEGER L(20)
  COMPLEX Z1
  CALL TEST_C(I, L, J, KYWD1 = K, KYWD2 = Z1)
  ...

The first three actual arguments are associated with their corresponding dummy arguments by position. The argument keywords are associated by keyword name, so they can appear in any order.

Note that the interface to subroutine TEST has two optional arguments that have been omitted in the CALL statement.

The following is another example of a subroutine call with argument keywords:

CALL TEST(X, Y, N, EQUALITIES = Q, XSTART = X0)

The first three arguments are associated by position.

The following shows another example:

!Variations on a subroutine call
      REAL S,T,X
      INTRINSIC NINT
      S=1.5
      T=2.5
      X=14.7
      !This calls SUB1 using keywords. NINT is an intrinsic function.
      CALL SUB1(B=X,C=S*T,FUNC=NINT,A=4.0)
!Here is the same call using an implicit reference
      CALL SUB1(4.0,X,S*T,NINT)
      CONTAINS
        SUBROUTINE sub1(a,b,c,func)
        INTEGER func
        REAL a,b,c
        PRINT *, a,b,c, func(b)
        END SUBROUTINE
      END


CASE

Statement: Marks the beginning of a CASE construct. A CASE construct conditionally executes one block of constructs or statements depending on the value of a scalar expression in a SELECT CASE statement.

Syntax

[name:] SELECT CASE (expr)
[CASE (case-value [, case-value] ...) [name]
block] ...
[CASE DEFAULT [name]
block]
END SELECT [name]

name
Is the name of the CASE construct.

expr
Is a scalar expression of type integer, logical, or character (enclosed in parentheses). Evaluation of this expression results in a value called the case index.

case-value
Is one or more scalar integer, logical, or character initialization expressions enclosed in parentheses. Each case-value must be of the same type and kind parameter as expr. If the type is character, case-value and expr can be of different lengths, but their kind parameter must be the same.

Integer and character expressions can be expressed as a range of case values, taking one of the following forms:

  low:high
  low:
  :high

Case values must not overlap.

block
Is a sequence of zero or more statements or constructs.

Rules and Behavior

If a construct name is specified in a SELECT CASE statement, the same name must appear in the corresponding END SELECT statement. The same construct name can optionally appear in any CASE statement in the construct. The same construct name must not be used for different named constructs in the same scoping unit.

The case expression (expr) is evaluated first. The resulting case index is compared to the case values to find a matching value (there can only be one). When a match occurs, the block following the matching case value is executed and the construct terminates.

The following rules determine whether a match occurs:

  • When the case value is a single value (no colon appears), a match occurs as follows:

    Data Type | A Match Occurs If:
    Logical | case-index .EQV. case-value
    Integer or Character | case-index = = case-value

  • When the case value is a range of values (a colon appears), a match depends on the range specified, as follows:

    Range | A Match Occurs If:
    low: case-index >= low
    :high | case-index <= high
    low:high | low <= case-index <= high

The following are all valid case values:

CASE (1, 4, 7, 11:14, 22)      ! Individual values as specified:
                               !     1, 4, 7, 11, 12, 13, 14, 22
CASE (:-1)                     ! All values less than zero
CASE (0)                       ! Only zero
CASE (1:)                      ! All values above zero

If no match occurs but a CASE DEFAULT statement is present, the block following that statement is executed and the construct terminates.

If no match occurs and no CASE DEFAULT statement is present, no block is executed, the construct terminates, and control passes to the next executable statement or construct following the END SELECT statement.

The following figure shows the flow of control in a CASE construct:

Flow of Control in CASE Constructs

You cannot use branching statements to transfer control to a CASE statement. However, branching to a SELECT CASE statement is allowed. Branching to the END SELECT statement is allowed only from within the CASE construct.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Execution Control

Examples

The following are examples of CASE constructs:

INTEGER FUNCTION STATUS_CODE (I)
  INTEGER I
  CHECK_STATUS: SELECT CASE (I)
  CASE (:-1)
    STATUS_CODE = -1
  CASE (0)
    STATUS_CODE = 0
  CASE (1:)
    STATUS_CODE = 1
  END SELECT CHECK_STATUS
END FUNCTION STATUS_CODE

SELECT CASE (J)
CASE (1, 3:7, 9)    ! Values: 1, 3, 4, 5, 6, 7, 9
  CALL SUB_A
CASE DEFAULT
  CALL SUB_B
END SELECT

The following three examples are equivalent:

1. SELECT CASE (ITEST .EQ. 1)
   CASE (.TRUE.)
     CALL SUB1 ()
   CASE (.FALSE.)
     CALL SUB2 ()
   END SELECT

2. SELECT CASE (ITEST)
   CASE DEFAULT
     CALL SUB2 ()
   CASE (1)
     CALL SUB1 ()
   END SELECT

3. IF (ITEST .EQ. 1) THEN
     CALL SUB1 ()
   ELSE
     CALL SUB2 ()
   END IF

The following shows another example:

CHARACTER*1 cmdchar
GET_ANSWER: SELECT CASE (cmdchar)
CASE ('0')
   WRITE (*, *) "Must retrieve one to nine files"
CASE ('1':'9')
   CALL RetrieveNumFiles (cmdchar)
CASE ('A', 'a')
   CALL AddEntry
CASE ('D', 'd')
   CALL DeleteEntry
CASE ('H', 'h')
   CALL Help
CASE DEFAULT
   WRITE (*, *) "Command not recognized; please use H for help"
END SELECT GET_ANSWER


CEILING

Elemental Intrinsic Function (Generic): Returns the smallest integer greater than or equal to its argument.

Syntax

result = CEILING (a [, kind])

a
(Input) Must be of type real.

kind
(Optional; input) Must be a scalar integer initialization expression. This argument is a Fortran 95 feature.

Results:

The result is of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

The value of the result is equal to the smallest integer greater than or equal to a.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: FLOOR

Examples

CEILING (4.8) has the value 5.

CEILING (-2.55) has the value -2.0.

The following shows another example:

INTEGER I, IARRAY(2)
I = CEILING(8.01) ! returns 9
I = CEILING(-8.01) ! returns -8
IARRAY = CEILING((/8.01,-5.6/)) ! returns (9, -5)


CHANGEDIRQQ

Run-Time Function: Makes the specified directory the current, default directory.

Module: USE DFLIB

Syntax

result = CHANGEDIRQQ (dir)

dir
(Input) Character*(*). Directory to be made the current directory.

Results

LOGICAL(4). .TRUE. if successful; otherwise, .FALSE..

If you do not specify a drive in the dir string, the named directory on the current drive becomes the current directory. If you specify a drive in dir, the named directory on the specified drive becomes the current directory.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETDRIVEDIRQQ, MAKEDIRQQ, DELDIRQQ, CHANGEDRIVEQQ

Example

  USE DFLIB
  LOGICAL(4) status
  status = CHANGEDIRQQ('d:\fps90\bin\bessel')


CHANGEDRIVEQQ

Run-Time Function: Makes the specified drive the current, default drive.

Module: USE DFLIB

Syntax

result = CHANGEDRIVEQQ (drive)

drive
(Input) Character*(*). String beginning with the drive letter.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE.

Because drives are identified by a single alphabetic character, CHANGEDRIVEQQ examines only the first character of drive. The drive letter can be uppercase or lowercase.

CHANGEDRIVEQQ changes only the current drive. The current directory on the specified drive becomes the new current directory. If no current directory has been established on that drive, the root directory of the specified drive becomes the new current directory.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETDRIVESQQ, GETDRIVESIZEQQ, GETDRIVEDIRQQ, CHANGEDIRQQ

Example

  USE DFLIB
  LOGICAL(4) status
  status = CHANGEDRIVEQQ('d')


CHAR

Elemental Intrinsic Function (Generic): Returns the character in the specified position of the processor's character set. It is the inverse of the function ICHAR.

Syntax

result = CHAR (i [, kind])

i
(Input) Must be of type integer with a value in the range 0 to n - 1, where n is the number of characters in the processor's character set.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is of type character with length 1. The kind parameter is that of default character type.

The result is the character in position i of the processor's character set. ICHAR(CHAR (i, kind(c))) has the value I for 0 to n - 1 and CHAR(ICHAR(c), kind(c)) has the value c for any character c capable of representation in the processor.

Specific Name | Argument Type | Result Type
 | INTEGER(1) | CHARACTER
 | INTEGER(2) | CHARACTER
CHAR 1 | INTEGER(4) | CHARACTER
 | INTEGER(8) | CHARACTER
1 This specific function cannot be passed as an actual argument.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ACHAR, IACHAR, ICHAR, Character and Key Code Charts

Examples

CHAR (76) has the value 'L'.

CHAR (94) has the value '^'.


CHARACTER

Statement: Specifies the CHARACTER data type.

Syntax

CHARACTER
CHARACTER([KIND=]n)
CHARACTER*len

n
Is kind 1.

len
Is a string length (not a kind). For more information, see Declaration Statements for Character Types.

If no kind type parameter is specified, the kind of the constant is default character.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Character Data Type, Character Constants, Character Substrings, C Strings, Declaration Statements for Character Types

Example

C
C   Length of wt and vs is 10, city is 80, and ch is 1
C
    CHARACTER wt*10, city*80, ch
    CHARACTER (LEN = 10), PRIVATE :: vs
    CHARACTER*(*) arg !declares a dummy argument
C   name and plume are ten-element character arrays
C   of length 20

    CHARACTER name(10)*20
    CHARACTER(len=20), dimension(10):: plume
C
C   Length of susan, patty, and dotty are 2, alice is 12,
C   jane is a 79-member array of length 2
C
    CHARACTER(2) susan, patty, alice*12, dotty, jane(79)


CHDIR

Portability Function: Changes the default directory.

Module: USE DFPORT

Syntax

result = CHDIR(dir_name)

dir_name
(Input) Character*(*). Name of a directory to become the default directory.

Results:

The result is of type INTEGER(4). It returns zero if the directory was changed successfully; otherwise, an error code. Possible error codes are:

  • ENOENT: The named directory does not exist.
  • ENOTDIR: The dir_name parameter is not a directory.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: CHANGEDIRQQ

Example

     integer(4) istatus, enoent, enotdir
     character*(*) newdir, prompt, errmsg
     prompt = 'Please enter directory name: '
10     write *, prompt
     read *, newdir
     ISTATUS = CHDIR(newdir)
     select case (istatus)
       case (enoent)
         errmsg = 'The directory'//newdir//' does not exist'
       case (enotdir)
         errmsg = newdir//' is not a directory'
       case else
         goto 40
     end select
     write *, errmsg
     goto 10
40     write *, 'Default directory successfully changed.'
     end


CHMOD

Portability Function: Changes the access mode of a file.

Module: USE DFPORT

Syntax

result = CHMOD (name, mode)

name
(Input) Character*(*). Name of the file whose access mode is to be changed. Must have a single path.

mode
(Input) Character*(*). File permission: either Read, Write, or Execute. The mode parameter can be either symbolic or absolute. An absolute mode is specified with an octal number, consisting of any combination of the following permission bits ORed together:

Permission bit | Description | Action
4000 | Set user ID on execution | Ignored; never true
2000 | Set group ID on execution | Ignored; never true
1000 | Sticky bit | Ignored; never true
0400 | Read by owner | Ignored; always true
0200 | Write by owner | Settable
0100 | Execute by owner | Ignored; based on filename extension
0040, 0020, 0010 | Read, Write, Execute by group | Ignored; assumes owner permissions
0004, 0002, 0001 | Read, Write, Execute by others | Ignored; assumes owner permissions

The following regular expression represents a symbolic mode:

[ugoa]*[+-=] [rwxXst]*

"[ugoa]*" is ignored. "[+ - =]" indicates the operation to carry out:

+ Add the permission
- Remove the permission
= Absolutely set the permission

"[rwxXst]*" indicates the permission to add, subtract, or set. Only "w" is significant and affects write permission. All other letters are ignored.

Results:

INTEGER(4). Zero if the mode was changed successfully; otherwise, an error code. Possible error codes are:

  • ENOENT: The specified file was not found.
  • EINVAL: The mode argument is invalid.
  • EPERM: Permission denied; the file's mode cannot be changed.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SETFILEACCESSQQ

Example

USE DFPORT
integer(4) I,Istatus
I = ACCESS ("DATAFILE.TXT", "w")
if (i) then
   ISTATUS = CHMOD ("datafile.txt", "[+w]")
end if
I = ACCESS ("DATAFILE.TXT","w")
print *, i


CHUNK (TU*X only)

Compaq Fortran Parallel Compiler Directive: Sets a default chunksize to adjust the number of iterations assigned to a thread. The effect of CHUNK varies, depending on the scheduling type.

Syntax

c$PAR CHUNK = chunksize

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

chunksize
Is a scalar integer expression.

Rules and Behavior

The effect of chunksize varies by scheduling type, as follows:

  • For DYNAMIC and INTERLEAVED scheduling, iterations are always assigned to threads in chunksized groups. If the total number of iterations is not divisible by chunksize, the last group has fewer than chunksize iterations.

  • For GUIDED scheduling, chunksize is the minimum number of iterations that can be assigned to a thread. If less than chunksize iterations remain, the next available thread is assigned all of the remaining iterations.

  • For STATIC scheduling, chunksize is ignored and has no effect.

The chunksize used for any parallel DO loop is determined by the following (in the order shown):

  1. A chunksize specified in the PDO directive for the current DO loop

  2. A user-specified default specified in the most recent CHUNK directive

  3. If the scheduling for the current DO loop is INTERLEAVED, DYNAMIC, GUIDED, or RUNTIME, a user-specified default specified in the environment variable MP_CHUNK

  4. The compiler default of one

The following form is also allowed: c$CHUNK = chunksize

See Also: MP_SCHEDTYPE, Parallel Directives for Tru64 UNIX Systems, Compaq Fortran Parallel Compiler Directives (TU*X only), OpenMP Fortran API Compiler Directives (TU*X only)


CLEARSCREEN

Graphics Subroutine: Erases the target area and fills it with the current background color.

Module: USE DFLIB

Syntax

CALL CLEARSCREEN (area)

area
(Input) INTEGER(4). Identifies the target area. Must be one of the following symbolic constants (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory):

  • $GCLEARSCREEN - Clears the entire screen.
  • $GVIEWPORT - Clears only the current viewport.
  • $GWINDOW - Clears only the current text window (set with SETTEXTWINDOW).

All pixels in the target area are set to the color specified with SETBKCOLORRGB. The default color is black.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETBKCOLORRGB, SETBKCOLORRGB, SETTEXTWINDOW, SETVIEWPORT

Example

USE DFLIB
CALL CLEARSCREEN($GCLEARSCREEN)


CLEARSTATUSFPQQ (ia32 only)

Run-Time Subroutine: Clears the exception flags in the floating-point processor status word. This routine is only available on ia32 processors.

Module: USE DFLIB

Syntax

CALL CLEARSTATUSFPQQ( )

The floating-point status word indicates which floating-point exception conditions have occurred. Visual Fortran initially clears (sets to 0) all floating-point status flags, but as exceptions occur, the status flags accumulate until the program clears the flags again. CLEARSTATUSFPQQ will clear the flags.

CLEARSTATUSFPQQ is appropriate for use in applications that poll the floating-point status register as the method for detecting a floating-point exception has occurred.

For a full description of the floating-point status word, exceptions, and error handling, see The Floating Point Environment in the Programmer's Guide.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB

See Also: GETSTATUSFPQQ, SETCONTROLFPQQ, GETCONTROLFPQQ, SIGNALQQ, MATHERRQQ

Example

! Program to demonstrate CLEARSTATUSFPQQ.
! This program uses polling to detect that a
! floating-point exception has occurred.
! So, build this console application with the default
! floating-point exception behavior, fpe3.
  PROGRAM CLEARFP

  USE DFLIB

  REAL*4 A,B,C
  INTEGER*2 STS

  A = 2.0E0
  B = 0.0E0

! Poll and display initial floating point status
  CALL GETSTATUSFPQQ(STS)
  WRITE(*,'(1X,A,Z4.4)') 'Initial fp status = ',STS

! Cause a divide-by-zero exception
! Poll and display the new floating point status
  C = A/B
  CALL GETSTATUSFPQQ(STS)
  WRITE(*,'(1X,A,Z4.4)') 'After div-by-zero fp status = ',STS

! If a divide by zero error occurred, clear the floating point
! status register so future exceptions can be detected.
  IF ((STS .AND. FPSW$ZERODIVIDE) > 0) THEN
    CALL CLEARSTATUSFPQQ()
    CALL GETSTATUSFPQQ(STS)
    WRITE(*,'(1X,A,Z4.4)') 'After CLEARSTATUSFPQQ fp status = ',STS
  ENDIF

  END

This program is available in the online samples.


CLICKMENUQQ

QuickWin Function: Simulates the effect of clicking or selecting a menu command. The QuickWin application responds as though the user had clicked or selected the command.

Modules: USE DFLIB

Syntax

result = CLICKMENUQQ (item)

item
(Input) INTEGER(4). Constant that represents the command selected from the Window menu. Must be one of the following symbolic constants (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory):

  • QWIN$STATUS - Status command
  • QWIN$TILE - Tile command
  • QWIN$CASCADE - Cascade command
  • QWIN$ARRANGE - Arrange Icons command

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, nonzero.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: Using QuickWin, REGISTERMOUSEEVENT, UNREGISTERMOUSEEVENT, WAITONMOUSEEVENT


CLOCK

Portability Function: Converts a system time into an 8-character ASCII string.

Module: USE DFPORT

Syntax

result = CLOCK( )

Results:

The result is of type character with a length of 8. The result is the current time in the form hh:mm:ss, using a 24-hour clock.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE_AND_TIME

Example

USE DFPORT
character(8) whatimeisit
whatimeisit = CLOCK ()
write *, 'The current time is ',whatimeisit


CLOSE

Statement: Disconnects a file from a unit.

Syntax

CLOSE ( [UNIT=]io-unit [, STATUS | DISPOSE | DISP = p] [, ERR=label] [, IOSTAT=i-var] )

io-unit
(Input) an external unit specifier.

p
(Input) a scalar default character expression indicating the status of the file after it is closed. It has one of the following values:

  • 'KEEP' or 'SAVE' - Retains the file after the unit closes.
  • 'DELETE' - Deletes the file after the unit closes (unless OPEN(READONLY) is in effect).
  • 'PRINT' - Submits the file to the line print spooler, then retains it (sequential files only).
  • 'PRINT/DELETE' - Submits the file to the line print spooler, then deletes it (sequential files only).
  • 'SUBMIT' - Forks a process to execute the file.
  • 'SUBMIT/DELETE' - Forks a process to execute the file, then deletes the file after the fork is completed.

The default is 'DELETE' for scratch files and QuickWin applications. For all other files, the default is 'KEEP'.

Files opened without a filename are called "scratch" files. Scratch files are temporary and are always deleted upon normal program termination; specifying STATUS='KEEP' for scratch files causes a run-time error.

For QuickWin applications, STATUS='KEEP' causes the child window to remain on the screen even after the unit closes. The default status is 'DELETE', which removes the child window from the screen.

label
Is the label of the branch target statement that receives control if an error occurs.

i-var
(Output) Is a scalar integer variable that is defined as a positive integer if an error occurs and zero if no error occurs.

Rules and Behavior

The CLOSE statement specifiers can appear in any order. An I/O unit must be specified, but the UNIT= keyword is optional if the unit specifier is the first item in the I/O control list.

The status specified in the CLOSE statement supersedes the status specified in the OPEN statement, except that a file opened as a scratch file cannot be saved, printed, or submitted, and a file opened for read-only access cannot be deleted.

If a CLOSE statement is specified for a unit that is not open, it has no effect.

You do not need to explicitly close open files. Normal program termination closes each file according to its default status. The CLOSE statement does not have to appear in the same program unit that opened the file.

Closing unit 0 automatically reconnects unit 0 to the keyboard and screen. Closing units 5 and 6 automatically reconnects those units to the keyboard or screen, respectively. Closing the asterisk (*) unit causes a compile-time error. In QuickWin, use CLOSE with unit 0, 5, or 6 to close the default window. If all of these units have been detached from the console (through an explicit OPEN), you must close one of these units beforehand to reestablish its connection with the console. You can then close the reconnect unit to close the default window.

If a parameter of the CLOSE statement is an expression that calls a function, that function must not cause an I/O operation or the EOF intrinsic function to be executed, because the results are unpredictable.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Data Transfer I/O Statements, Branch Specifiers

Example

C    Close and discard file:
     CLOSE (7, STATUS = 'DELETE')

Consider the following statement:

  CLOSE (UNIT=J, STATUS='DELETE', ERR=99)

This statement closes the file connected to unit J and deletes it. If an error occurs, control is transferred to the statement labeled 99.


CMPLX

Elemental Intrinsic Function (Generic): Converts the argument to complex type. This function must not be passed as an actual argument.

Syntax

result = CMPLX (x [, y] [, kind])

x
(Input) Must be of type integer, real, or complex.

y
(Optional; input) Must be of type integer or real. It must not be present if x is of type complex.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is of type complex (COMPLEX(4) or COMPLEX*8). If kind is present, the kind parameter is that specified by kind; otherwise, the kind parameter is that of default real type.

If only one noncomplex argument appears, it is converted into the real part of the result value and zero is assigned to the imaginary part. If y is not specified and x is complex, the result value is CMPLX(REAL(x), AIMAG(x)).

If two noncomplex arguments appear, the complex value is produced by converting the first argument into the real part of the value, and converting the second argument into the imaginary part.

CMPLX(x, y, kind) has the complex value whose real part is REAL(x, kind) and whose imaginary part is REAL(y, kind).

The setting of compiler option /real_size can affect this function.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DCMPLX, FLOAT, INT, IFIX, REAL, SNGL

Examples

CMPLX (-3) has the value (-3.0, 0.0).

CMPLX (4.1, 2.3) has the value (4.1, 2.3).

The following shows another example:

COMPLEX z1, z2
COMPLEX(8) z3
z1 = CMPLX(3)     ! returns the value 3.0 + i 0.0
z2 = CMPLX(3,4)   ! returns the value 3.0 + i 4.0
z3 = CMPLX(3,4,8) ! returns a COMPLEX(8) value 3.0D0 + i 4.0D0


COMAddObjectReference

DFCOM Function: Adds a reference to an object's interface.

Modules: USE DFCOM

Syntax

result = COMAddObjectReference (iunknown)

iunknown
An IUnKnown interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

Results:

The result is of type INTEGER(4). It is the object's current reference count.

See Also:

IUnknown::AddRef in the Win32 SDK


COMCLSIDFromProgID

DFCOM Subroutine: Passes a programmatic identifier and returns the corresponding class identifier.

Modules: USE DFCOM, USE DFWINTY

Syntax

CALL COMCLSIDFromProgID (prog_id, clsid, status)

prog_id
The programmatic identifier of type CHARACTER*(*).

clsid
The class identifier corresponding to the programmatic identifier. Must be of type GUID, which is defined in the DFWINTY module.

status
The status of the operation. It can be any status returned by CLSIDFromProgID. Must be of type INTEGER(4).

See Also:

CLSIDFromProgID in the Win32 SDK


COMCLSIDFromString

DFCOM Subroutine: Passes a class identifier string and returns the corresponding class identifier.

Modules: USE DFCOM, USE DFWINTY

Syntax

CALL COMCLSIDFromString (string, clsid, status)

string
The class identifier string of type CHARACTER*(*).

clsid
The class identifier corresponding to the identifier string. Must be of type GUID, which is defined in the DFWINTY module.

status
The status of the operation. It can be any status returned by CLSIDFromString. Must be of type INTEGER(4).

See Also:

CLSIDFromString in the Win32 SDK


COMCreateObjectByGUID

DFCOM Subroutine: Passes a class identifier, creates an instance of an object, and returns a pointer to the object's interface.

Modules: USE DFCOM, USE DFWINTY

Syntax

CALL COMCreateObjectByGUID (clsid, clsctx, iid, interface, status)

clsid
The class identifier of the class of object to be created. Must be of type GUID, which is defined in the DFWINTY module.

clsctx
Lets you restrict the types of servers used for the object. Must be of type INTEGER(4). Must be one of the CLSCTX_* constants defined in the DFWINTY module.

iid
The interface identifier of the interface being requested. Must be of type GUID, which is defined in the DFWINTY module.

interface
An output argument that returns the object's interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

status
The status of the operation. It can be any status returned by CoCreateInstance. Must be of type INTEGER(4).

See Also:

CoCreateInstance in the Win32 SDK


COMCreateObjectByProgID

DFCOM Subroutine: Passes a programmatic identifier, creates an instance of an object, and returns a pointer to the object's IDispatch interface.

Modules: USE DFCOM

Syntax

CALL COMCreateObjectByProgID (prog_id, idispatch, status)

prog_id
The programmatic identifier of type CHARACTER*(*).

idispatch
An output argument that returns the object's IDispatch interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

status
The status of the operation. It can be any status returned by CLSIDFromProgID or CoCreateInstance. Must be of type INTEGER(4).

See Also:

CLSIDFromProgID and CoCreateInstance in the Win32 SDK

For more information on CLSIDFromProgID and CoCreateInstance, see the OLE section of the Win32 SDK.


COMGetActiveObjectByGUID

DFCOM Subroutine: Passes a class identifier and returns a pointer to the interface of a currently active object.

Modules: USE DFCOM, USE DFWINTY

Syntax

CALL COMGetActiveObjectByGUID (clsid, iid, interface, status)

clsid
The class identifier of the class of object to be found. Must be of type GUID, which is defined in the DFWINTY module.

iid
The interface identifier of the interface being requested. Must be of type GUID, which is defined in the DFWINTY module.

interface
An output argument that returns the object's interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

status
The status of the operation. It can be any status returned by GetActiveObject. Must be of type INTEGER(4).

See Also:

GetActiveObject in the Win32 SDK


COMGetActiveObjectByProgID

DFCOM Subroutine: Passes a programmatic identifier and returns a pointer to the IDispatch interface of a currently active object.

Modules: USE DFCOM

Syntax

CALL COMGetActiveObjectByProgID (prog_id, idispatch, status)

prog_id
The programmatic identifier of type CHARACTER*(*).

idispatch
An output argument that returns the object's IDispatch interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

status
The status of the operation. It can be any status returned by CLSIDFromProgID or GetActiveObject. Must be of type INTEGER(4).

See Also:

CLSIDFromProgID and GetActiveObject in the Win32 SDK


COMGetFileObject

DFCOM Subroutine: Passes a file name and returns a pointer to the IDispatch interface of an Automation object that can manipulate the file.

Modules: USE DFCOM

Syntax

CALL COMGetFileObject (filename, idispatch, status)

filename
The path of the file of type CHARACTER*(*).

idispatch
An output argument that returns the object's IDispatch interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

status
The status of the operation. It can be any status returned by the CreateBindCtx or MkParseDisplayName routines, or the IMoniker::BindToObject method. Must be of type INTEGER(4).

See Also:

CreateBindCtx, MkParseDisplayName, and IMonker::BindToObject in the Win32 SDK


COMInitialize

DFCOM Subroutine: Initializes the COM library.

Modules: USE DFCOM

Syntax

CALL COMInitialize (status)

status
The status of the operation. It can be any status returned by OleInitialize. Must be of type INTEGER(4).

You must use this routine to initialize the COM library before calling any other COM or AUTO routine.

See Also:

OleInitialize in the Win32 SDK


COMIsEqualGUID

DFCOM Function: Determines whether two globally unique identifiers (GUIDs) are the same.

Modules: USE DFCOM, USE DFWINTY

Syntax

CALL COMIsEqualGUID (guid1, guid2)

guid1
The first GUID. Must be of type GUID, which is defined in the DFWINTY module. It can be any type of GUID, including a class identifier (CLSID), or an interface identifier (IID).

guid2
The second GUID, which will be compared to guid1. It must be the same type of GUID as guid1. For example, if guid1 is a CLSID, guid2 must also be a CLSID.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if the two GUIDs are the same; otherwise, .FALSE.

See Also:

IsEqualGUID in the Win32 SDK


COMMITQQ

Run-Time Function: Forces the operating system to execute any pending write operations for the file associated with a specified unit to the file's physical device.

Module: USE DFLIB

Syntax

result = COMMITQQ (unit)

unit
(Input) INTEGER(4). Fortran logical unit attached to a file to be flushed from cache memory to a physical device.

Results:

The result is of type LOGICAL(4). If an open unit number is supplied, .TRUE. is returned and uncommitted records (if any) are written. If an unopened unit number is supplied, .FALSE. is returned.

Data written to files on physical devices is often initally written into operating-system buffers and then written to the device when the operating system is ready. Data in the buffer is automatically flushed to disk when the file is closed. However, if the program or the computer crashes before the data is transferred from buffers, the data can be lost. COMMITQQ tells the operating system to write any cached data intended for a file on a physical device to that device immediately. This is called flushing the file.

COMMITQQ is most useful when you want to be certain that no loss of data occurs at a critical point in your program; for example, after a long calculation has concluded and you have written the results to a file, or after the user has entered a group of data items, or if you are on a network with more than one program sharing the same file. Flushing a file to disk provides the benefits of closing and reopening the file without the delay.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: PRINT, WRITE

Example

USE DFLIB
INTEGER unit / 10 /
INTEGER len
CHARACTER(80) stuff
OPEN(unit, FILE='COMMITQQ.TST', ACCESS='Sequential')
DO WHILE (.TRUE.)
  WRITE (*, '(A, \)') 'Enter some data (Hit RETURN to &
                        exit): '
  len = GETSTRQQ (stuff)
  IF (len .EQ. 0) EXIT
  WRITE (unit, *) stuff
  IF (.NOT. COMMITQQ(unit)) WRITE (*,*) 'Failed'
END DO
CLOSE (unit)
END


COMMON

Statement: Defines one or more contiguous areas, or blocks, of physical storage (called common blocks) that can be accessed by any of the scoping units in an executable program. COMMON statements also define the order in which variables and arrays are stored in each common block, which can prevent misaligned data items.

Common blocks can be named or unnamed (a blank common).

Syntax

COMMON [ /[cname]/] var-list [[,] /[cname]/ var-list ] ...

cname
(Optional) Is the name of the common block. The name can be omitted for blank common (//).

var-list
Is a list of variable names, separated by commas.

The variable must not be a dummy argument, allocatable array, automatic object, function, function result, or entry to a procedure. It must not have the PARAMETER attribute. If an object of derived type is specified, it must be a sequence type.

Rules and Behavior

A common block is a global entity, and must not have the same name as any other global entity in the program, such as a subroutine or function.

Any common block name (or blank common) can appear more than once in one or more COMMON statements in a program unit. The list following each successive appearance of the same common block name is treated as a continuation of the list for the block associated with that name. Consider the following COMMON statements:

  COMMON /ralph/ ed, norton, trixie
  COMMON /     / fred, ethel, lucy
  COMMON /ralph/ audrey, meadows
  COMMON /jerry/ mortimer, tom, mickey
  COMMON melvin, purvis

They are equivalent to these COMMON statements:

  COMMON /ralph/ ed, norton, trixie, audrey, meadows
  COMMON         fred, ethel, lucy, melvin, purvis
  COMMON /jerry/ mortimer, tom, mickey

A variable can appear in only one common block within a scoping unit.

If an array is specified, it can be followed by an explicit-shape array specification. The array must not have the POINTER attribute and each bound in the specification must be a constant specification expression.

A pointer can only be associated with pointers of the same type and kind parameters, and rank.

An object with the TARGET attribute can only be associated with another object with the TARGET attribute and the same type and kind parameters.

A nonpointer can only be associated with another nonpointer, but association depends on their types, as follows:

Type of Variable | Type of Associated Variable
Intrinsic numeric 1 or numeric sequence 2 | Can be of any of these types
Default character or character sequence 2 | Can be of either of these types
Any other intrinsic type | Must have the same type and kind parameters
Any other sequence type | Must have the same type
1 Default integer, default real, double precision real, default complex, double complex, or default logical. 2 If an object of numeric sequence or character sequence type appears in a common block, it is as if the individual components were enumerated directly in the common list.

So, variables can be associated if they are of different numeric type. For example, the following is valid:

  INTEGER A(20)
  REAL Y(20)
  COMMON /QUANTA/ A, Y

When common blocks from different program units have the same name, they share the same storage area when the units are combined into an executable program.

Entities are assigned storage in common blocks on a one-for-one basis. So, the data type of entities assigned by a COMMON statement in one program unit should agree with the data type of entities placed in a common block by another program unit. For example:

Program Unit A | Program Unit B
COMMON CENTS | INTEGER(2) MONEY
. . . | COMMON MONEY
 | . . .

When these program units are combined into an executable program, incorrect results can occur if the 2-byte integer variable MONEY is made to correspond to the lower-addressed two bytes of the real variable CENTS.

Named common blocks must be declared to have the same size in each program unit. Blank common can have different lengths in different program units.

Note: On Tru64 UNIX, Linux, and Windows systems, if a common block is initialized by a DATA statement, the module containing the initialization must declare the common block to be its maximum defined length.

This limitation does not apply if you compile all source modules together.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BLOCK DATA, DATA, MODULE, EQUIVALENCE, Specification expressions, Storage association, Interaction between COMMON and EQUIVALENCE Statements

Examples

PROGRAM MyProg
COMMON i, j, x, k(10)
COMMON /mycom/ a(3)
...
END
SUBROUTINE MySub
COMMON pe, mn, z, idum(10)
COMMON /mycom/ a(3)
...
END

In the following example, the COMMON statement in the main program puts HEAT and X in blank common, and KILO and Q in a named common block, BLK1:

Main Program | Subprogram
COMMON HEAT,X /BLK1/KILO,Q | SUBROUTINE FIGURE
. . . | COMMON /BLK1/LIMA,R / /ALFA,BET
 | . . .
CALL FIGURE |
. . . | RETURN
 | END

The COMMON statement in the subroutine makes ALFA and BET share the same storage location as HEAT and X in blank common. It makes LIMA and R share the same storage location as KILO and Q in BLK1.

The following example shows how a COMMON statement can be used to declare arrays:

  COMMON / MIXED / SPOTTED(100), STRIPED(50,50)

The following example shows a valid association between subroutines in different program units. The object lists agree in number, type, and kind of data objects:

  SUBROUTINE unit1
  REAL(8)      x(5)
  INTEGER      J
  CHARACTER    str*12
  TYPE(member) club(50)
  COMMON / blocka / x, j, str, club
  ...

  SUBROUTINE unit2
  REAL(8)      z(5)
  INTEGER      m
  CHARACTER    chr*12
  TYPE(member) myclub(50)
  COMMON / blocka / z, m, chr, myclub
  ...

See also the program example for BLOCK DATA.


COMPLEX

Statement: Specifies the COMPLEX data type.

Syntax

COMPLEX
COMPLEX([KIND=]n)
COMPLEX*s
DOUBLE COMPLEX

n
Is kind 4 or 8.

s
Is 8 or 16.COMPLEX(4) is specified as COMPLEX*8. COMPLEX(8) is specified as COMPLEX*16.

If a kind parameter is specified, the complex constant has the kind specified. If no kind parameter is specified, the kind of both parts is default real, and the constant is of type default complex.

DOUBLE COMPLEX is COMPLEX(8). No kind parameter is permitted for data declared with type DOUBLE COMPLEX.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DOUBLE COMPLEX, Complex Data Type, COMPLEX(4) Constants, COMPLEX(8) or DOUBLE COMPLEX Constants, Data Types, Constants, and Variables

Examples

COMPLEX ch
COMPLEX (KIND=4),PRIVATE :: zz, yy   !equivalent to COMPLEX*8 zz, yy
COMPLEX(8) ax, by        !equivalent to COMPLEX*16 ax, by
COMPLEX (kind(4)) y(10)
complex (kind=8)  x, z(10)


COMQueryInterface

DFCOM Subroutine: Passes an interface identifier and returns a pointer to an object's interface.

Modules: USE DFCOM, USE DFWINTY

Syntax

CALL COMQueryInterface (iunknown, iid, interface, status)

iunknown
An IUnknown interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

iid
The interface identifier of the interface being requested. Must be of type GUID, which is defined in the DFWINTY module.

interface
An output argument that returns the object's interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

status
The status of the operation. It can be any status returned by the IUnknown method QueryInterface. Must be of type INTEGER(4).

See Also:

IUnknown::QueryInterface in the Win32 SDK


COMReleaseObject

DFCOM Function: Indicates that the program is done with a reference to an object's interface.

Modules: USE DFCOM

Syntax

result = COMReleaseObject (iunknown)

iunknown
An IUnknown interface pointer. Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

The result is of type INTEGER(4). It is the object's current reference count.


COMStringFromGUID

DFCOM Subroutine: Passes a globally unique identifier (GUID) and returns a string of printable characters.

Modules: USE DFCOM, USE DFWINTY

Syntax

CALL COMStringFromGUID (guid, string, status)

guid
The GUID to be converted. Must be of type GUID, which is defined in the DFWINTY module. It can be any type of GUID, including a class identifier (CLSID), or an interface identifier (IID).

string
A character variable of type CHARACTER*(*) that receives the string representation of the GUID. The length of the character variable should be at least 38.

status
The status of the operation. If the string is too small to contain the string representation of the GUID, the value is zero. Otherwise, the value is the number of characters in the string representation of the GUID. Must be of type INTEGER(4).

The string representation of a GUID has a format like that of the following:

[c200e360-38c5-11ce-ae62-08002b2b79ef]

where the successive fields break the GUID into the form DWORD-WORD-WORD-WORD-WORD.DWORD covering the 128-bit GUID. The string includes enclosing braces, which are an OLE convention.

See Also:

StringFromGUID2 in the Win32 SDK


COMUninitialize

DFCOM Subroutine: Uninitializes the COM library.

Modules: USE DFCOM

Syntax

CALL COMUninitialize( )

When using COM routines, this must be the last routine called.


CONJG

Elemental Intrinsic Function (Generic): Calculates the conjugate of a complex number.

Syntax

result = CONJG (z)

z
(Input) Must be of type complex.

Results:

The result type is the same as z. If z has the value (x, y), the result has the value (x, -y).

Specific Name | Argument Type | Result Type
CONJG | COMPLEX(4) | COMPLEX(4)
DCONJG | COMPLEX(8) | COMPLEX(8)
QCONJG | COMPLEX(16) | COMPLEX(16)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: AIMAG

Examples

CONJG ((2.0, 3.0)) has the value (2.0, -3.0).

CONJG ((1.0, -4.2)) has the value (1.0, 4.2).

The following shows another example:

COMPLEX z1
COMPLEX(8) z2
z1 = CONJG((3.0, 5.6))       ! returns (3.0, -5.6)
z2 = DCONJG((3.0D0, 5.6D0))  ! returns (3.0D0, -5.6D0)


CONTAINS

Statement: Separates the body of a main program, module, or external subprogram from any internal or module procedures it may contain. It is not executable.

Syntax

CONTAINS

Any number of internal procedures can follow a CONTAINS statement, but a CONTAINS statement cannot appear in the internal procedures themselves.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Internal Procedures, Modules and Module Procedures, Main Program

Example

PROGRAM OUTER
   REAL, DIMENSION(10) :: A
   . . .
   CALL INNER (A)
CONTAINS
   SUBROUTINE INNER (B)
   REAL, DIMENSION(10) :: B
   . . .
   END SUBROUTINE INNER
END PROGRAM OUTER


CONTINUE

Statement: Primarily used to terminate a labeled DO construct when the construct would otherwise end improperly with either a GO TO, arithmetic IF, or other prohibited control statement.

Syntax

CONTINUE

The statement by itself does nothing and has no effect on program results or execution sequence.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: END DO, DO, Execution Control

Examples

The following example shows a CONTINUE statement:

    DO 150 I = 1,40
40  Y = Y + 1
    Z = COS(Y)
    PRINT *, Z
    IF (Y .LT. 30) GO TO 150
    GO TO 40
150 CONTINUE

The following shows another example:

     DIMENSION narray(10)
     DO 100 n = 1, 10
     narray(n) = 120
100  CONTINUE


COPYIN (TU*X only)

Compaq Fortran Parallel Compiler Directive: Copies the values of listed data objects from the master thread to PRIVATE data objects of the same name in slave threads.

Syntax

c$PAR COPYIN object[, object] ...

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

object
Is the name of a variable, a single array element, or a named common block. A named common block must appear between slashes (/ /).

Rules and Behavior

Single array elements can be copied, but array sections cannot be copied.

SHARED variables cannot be copied.

When an ALLOCATABLE array is to be copied, it must be allocated when the COPYIN directive is encountered.

COPYIN directives are permitted only within PARALLEL or PARALLEL DO constructs.

The following form is also allowed: c$COPYIN object[, object] ...

See Also: Parallel Directives for Tru64 UNIX Systems, Compaq Fortran Parallel Compiler Directives (TU*X only), OpenMP Fortran API Compiler Directives (TU*X only)

Examples

Consider the following:

  CPAR$ COPYIN A, B, /X/, C(I)

This statement specifies that the following be copied from the master thread to the PRIVATE data objects of the same name: A and B, the entire contents of common block X, and the Ith element of C.


COPYIN Clause (TU*X only)

Parallel Directive Clause: Specifies that the data in the master thread of the team is to be copied to the thread private copies of the common block at the beginning of the parallel region.

Syntax

COPYIN (list)

list
Is the name of one or more variables or common blocks that are accessible to the scoping unit. Subobjects cannot be specified. Each name must be separated by a comma, and a named common block must appear between slashes (/ /).

The COPYIN clause applies only to common blocks declared as THREADPRIVATE (or TASKCOMMON).

You do not need to specify the whole THREADPRIVATE (or TASKCOMMON) common block, you can specify named variables within the common block.


COS

Elemental Intrinsic Function (Generic): Produces the cosine of x.

Syntax

result = COS (x)

x
(Input) Must be of type real or complex. It must be in radians and is treated as modulo 2*pi. (If x is of type complex, its real part is regarded as a value in radians.)

Results:

The result type is the same as x.

Specific Name | Argument Type | Result Type
COS | REAL(4) | REAL(4)
DCOS | REAL(8) | REAL(8)
QCOS 1 | REAL(16) | REAL(16)
CCOS 2 | COMPLEX(4) | COMPLEX(4)
CDCOS 3 | COMPLEX(8) | COMPLEX(8)
CQCOS 1 | COMPLEX(16) | COMPLEX(16)
1 VMS and U*X 2 The setting of compiler option /real_size can affect CCOS. 3 This function can also be specified as ZCOS.

Examples

COS (2.0) has the value -0.4161468.

COS (0.567745) has the value 0.8431157.


COSD

Elemental Intrinsic Function (Generic): Produces the cosine of x.

Syntax

result = COSD (x)

x
(Input) Must be of type real. It must be in degrees and is treated as modulo 360.

Results:

The result type is the same as x.

Specific Name | Argument Type | Result Type
COSD | REAL(4) | REAL(4)
DCOSD | REAL(8) | REAL(8)
QCOSD 1 | REAL(16) | REAL(16)
1 VMS and U*X

Examples

COSD (2.0) has the value 0.9993908.

COSD (30.4) has the value 0.8625137.


COSH

Elemental Intrinsic Function (Generic): Produces a hyperbolic cosine.

Syntax

result = COSH (x)

x
(Input) Must be of type real.

Results:

The result type is the same as x.

Specific Name | Argument Type | Result Type
COSH | REAL(4) | REAL(4)
DCOSH | REAL(8) | REAL(8)
QCOSH 1 | REAL(16) | REAL(16)
1 VMS and U*X

Examples

COSH (2.0) has the value 3.762196.

COSH (0.65893) has the value 1.225064.


COTAN

Elemental Intrinsic Function (Generic): Produces the cotangent of x.

Syntax

result = COTAN (x)

x
(Input) Must be of type real; it cannot be zero. It must be in radians and is treated as modulo 2*pi.

Results:

The result type is the same as x.

Specific Name | Argument Type | Result Type
COTAN | REAL(4) | REAL(4)
DCOTAN | REAL(8) | REAL(8)
QCOTAN 1 | REAL(16) | REAL(16)
1 VMS and U*X

Examples

COTAN (2.0) has the value -4.576575E-01.

COTAN (0.6) has the value 1.461696.


COTAND

Elemental Intrinsic Function (Generic): Produces the cotangent of x.

Syntax

result = COTAND (x)

x
(Input) Must be of type real. It must be in degrees and is treated as modulo 360.

Results:

The result type is the same as x.

Specific Name | Argument Type | Result Type
COTAND | REAL(4) | REAL(4)
DCOTAND | REAL(8) | REAL(8)
QCOTAND 1 | REAL(16) | REAL(16)
1 VMS, U*X

Examples

COTAND (2.0) has the value 0.2863625E+02.

COTAND (0.6) has the value 0.9548947E+02.


COUNT

Transformational Intrinsic Function (Generic): Counts the number of true elements in an entire array or in a specified dimension of an array.

Syntax

result = COUNT (mask [, dim] [, kind])

mask
(Input) Must be a logical array.

dim
(Optional; input) Must be a scalar integer expression with a value in the range 1 to n, where n is the rank of mask.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is an array or a scalar of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

The result is a scalar if dim is omitted or mask has rank one. A scalar result has a value equal to the number of true elements of mask. If mask has size zero, the result is zero.

An array result has a rank that is one less than mask, and shape (d1, d2, ..., ddim-1, ddim+1, ..., dn), where (d1, d2,..., dn) is the shape of mask.

Each element in an array result equals the number of elements that are true in the one dimensional array defined by mask (s1, s2, ..., sdim-1, :, sdim+1, ..., sn).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ALL, ANY

Example

COUNT ((/.TRUE., .FALSE., .TRUE./)) has the value 2 because two elements are true.

COUNT ((/.TRUE., .TRUE., .TRUE./)) has the value 3 because three elements are true.

A is the array

  [ 1  5  7 ]
  [ 3  6  8 ]
and B is the array
  [ 0  5  7 ]
  [ 2  6  9 ].

COUNT (A .NE. B, DIM=1) tests to see how many elements in each column of A are not equal to the elements in the corresponding column of B. The result has the value (2, 0, 1) because:

  • The first column of A and B have 2 elements that are not equal.
  • The second column of A and B have 0 elements that are not equal.
  • The third column of A and B have 1 element that is not equal.

COUNT (A .NE. B, DIM=2) tests to see how many elements in each row of A are not equal to the elements in the corresponding row of B. The result has the value (1, 2) because:

  • The first row of A and B have 1 element that is not equal.
  • The second row of A and B have 2 elements that are not equal.

The following is another example:

LOGICAL mask (2, 3)
INTEGER AR1(3), AR2(2), I
mask = RESHAPE((/.TRUE., .TRUE., .FALSE., .TRUE., &
                 .FALSE., .FALSE./),(/2,3/))
!
! mask is the array   true false false
!                     true true false
!
AR1 = COUNT(mask,DIM=1) ! counts true elements by
                        ! column yielding [2 1 0]
AR2 = COUNT(mask,DIM=2) ! counts true elements by row
                        ! yielding [1 2]
I = COUNT( mask)        ! returns 3


CPU_TIME

Intrinsic Subroutine: Returns a processor-dependent approximation of the processor time in seconds. This is a new intrinsic subroutine in Fortran 95.

Syntax

CALL CPU_TIME (time)

time
Must be scalar and of type real. It is an INTENT(OUT) argument.

If a meaningful time cannot be returned, a processor-dependent negative value is returned.

Examples

Consider the following:

  REAL time_begin, time_end
  ...
  CALL CPU_TIME ( time_begin )
  !
  !task to be timed
  !
  CALL CPU_TIME ( time_end )
  PRINT *, 'Time of operation was ', time_end - time_begin, ' seconds'


CRITICAL (TU*X only)

OpenMP Parallel Compiler Directive: Restricts access to a block of code to only one thread at a time.

Syntax

c$OMP CRITICAL [(name)]
block
c$OMP END CRITICAL [(name)]

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

name
Is the name of the critical section.

block
Is a structured block (section) of statements or constructs. You cannot branch into or out of the block.

Rules and Behavior

A thread waits at the beginning of a critical section until no other thread in the team is executing a critical section having the same name. All unnamed CRITICAL directives map to the same name.

If a name is specified in the CRITICAL directive, the same name must appear in the corresponding END CRITICAL directive. If no name appears in the CRITICAL directive, no name can appear in the corresponding END CRITICAL directive.

Critical section names are global entities of the program. If the name specified conflicts with any other entity, the behavior of the program is undefined.

See Also: Parallel Directives for Tru64 UNIX Systems, OpenMP Fortran API Compiler Directives (TU*X only)

Examples

The following example shows a queuing model in which a task is dequeued and worked on. To guard against multiple threads dequeuing the same task, the dequeuing operation is placed in a critical section.

Because there are two independent queues in this example, each queue is protected by CRITICAL directives having different names, XAXIS and YAXIS, respectively:

  c$OMP PARALLEL DEFAULT(PRIVATE) SHARED(X,Y)
  c$OMP CRITICAL(XAXIS)
        CALL DEQUEUE(IX_NEXT, X)
  c$OMP END   CRITICAL(XAXIS)
        CALL WORK(IX_NEXT, X)
  c$OMP CRITICAL(YAXIS)
        CALL DEQUEUE(IY_NEXT,Y)
  c$OMP END   CRITICAL(YAXIS)
        CALL WORK(IY_NEXT, Y)
  c$OMP END PARALLEL


CRITICAL SECTION (TU*X only)

Compaq Fortran Parallel Compiler Directive: Restricts access to a block of code to only one thread at a time.

Syntax

c$PAR CRITICAL SECTION [(latch-var)]
block
c$PAR END CRITICAL SECTION

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

latch-var
Is a naturally aligned INTEGER(4) or INTEGER(8) SHARED variable.

block
Is one or more statements or constructs. You cannot branch into or out of the block.

Rules and Behavior

Critical sections can appear anywhere an executable Compaq Fortran statement can appear.

You can use a latch variable to control whether multiple critical sections have unique latches or use the same latch. If a latch variable name is used, the program must explicitly initialize the latch variable to zero before any CRITICAL SECTION using that latch variable is executed.

If you do not specify a latch variable, the compiler supplies a unique latch for each critical section.

A thread waits at the beginning of a critical section until no other thread in the team is executing a critical section having the same latch variable name. When the thread that is executing the critical section reaches the END CRITICAL SECTION directive, the latch variable is set to 1, allowing another thread to enter the critical section.

The program must not reuse that latch variable in anything other than a CRITICAL SECTION until all uses as a latch variable are complete.

All unnamed critical sections map to the same latch variable name supplied by the compiler. Critical section latch variable names are global to the program.

See Also: Parallel Directives for Tru64 UNIX Systems, Compaq Fortran Parallel Compiler Directives (TU*X only), OpenMP Fortran API Compiler Directives (TU*X only)


CSHIFT

Transformational Intrinsic Function (Generic): Performs a circular shift on a rank-one array, or performs circular shifts on all the complete rank-one sections (vectors) along a given dimension of an array of rank two or greater.

Elements shifted off one end are inserted at the other end. Different sections can be shifted by different amounts and in different directions.

Syntax

result = CSHIFT (array, shift [, dim])

array
(Input) Array whose elements are to be shifted. It can be of any data type.

shift
(Input) The number of positions shifted. Must be a scalar integer or an array with a rank that is one less than array, and shape (d1, d2, ..., ddim-1, ddim+1, ..., dn), where (d1, d2, ..., dn) is the shape of array.

dim
(Optional; input) Optional dimension along which to perform the shift. Must be a scalar integer with a value in the range 1 to n, where n is the rank of array. If dim is omitted, it is assumed to be 1.

Results:

The result is an array with the same type and kind parameters, and shape as array.

If array has rank one, element i of the result is array (1 + MODULO (i + shift - 1, SIZE (array))). (The same shift is applied to each element.)

If array has rank greater than one, each section (s1,s2, ..., sdim-1, :, sdim+1, ..., sn) of the result is shifted as follows:

  • By the value of shift, if shift is scalar

  • According to the corresponding value in shift(s1, s2,..., sdim-1, sdim+1,..., sn), if shift is an array

The value of shift determines the amount and direction of the circular shift. A positive shift value causes a shift to the left (in rows) or up (in columns). A negative shift value causes a shift to the right (in rows) or down (in columns). A zero shift value causes no shift.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: EOSHIFT, ISHFT, ISHFTC

Examples

V is the array (1, 2, 3, 4, 5, 6).

CSHIFT (V, SHIFT=2) shifts the elements in V circularly to the left by 2 positions, producing the value (3, 4, 5, 6, 1, 2). 1 and 2 are shifted off the beginning and inserted at the end.

CSHIFT (V, SHIFT= -2) shifts the elements in V circularly to the right by 2 positions, producing the value (5, 6, 1, 2, 3, 4). 5 and 6 are shifted off the end and inserted at the beginning.

M is the array

  [ 1  2  3 ]
  [ 4  5  6 ]
  [ 7  8  9 ].
CSHIFT (M, SHIFT = 1, DIM = 2) produces the result
  [ 2  3  1 ]
  [ 5  6  4 ]
  [ 8  9  7 ].

Each element in rows 1, 2, and 3 is shifted to the left by 2 positions. The elements shifted off the beginning are inserted at the end.

CSHIFT (M, SHIFT = -1, DIM = 1) produces the result

  [ 7  8  9 ]
  [ 1  2  3 ]
  [ 4  5  6 ].

Each element in columns 1, 2, and 3 is shifted down by 1 position. The elements shifted off the end are inserted at the beginning.

CSHIFT (M, SHIFT = (/1, -1, 0/), DIM = 2) produces the result

  [ 2  3  1 ]
  [ 6  4  5 ]
  [ 7  8  9 ].

Each element in row 1 is shifted to the left by 1 position; each element in row 2 is shifted to the right by 1 position; no element in row 3 is shifted at all.

The following is another example:

INTEGER array (3, 3), AR1(3, 3), AR2 (3, 3)
DATA array /1, 4, 7, 2, 5, 8, 3, 6, 9/
!
! array is   1 2 3
!            4 5 6
!            7 8 9
!
AR1 = CSHIFT(array, 1, DIM = 1)  ! shifts all columns
                                 ! by 1 yielding
                                 !         4 5 6
                                 !         7 8 9
                                 !         1 2 3
                 !
AR2=CSHIFT(array,shift=(/-1, 1, 0/),DIM=2) ! shifts
                                 ! each row separately
                                 ! by the amount in
                                 ! shift yielding
                                 !         3 1 2
                                 !         5 6 4
                                 !         7 8 9


CTIME

Portability Function: Converts a system time into a 24-character ASCII string.

Module: USE DFPORT

Syntax

result = CTIME (stime)

stime
(Input) INTEGER(4). An elapsed time in seconds since 00:00:00 Greenwich mean time, January 1, 1970.

Results:

The result is a value in the form Mon Jan 31 04:37:23 1994. Hours are expressed using a 24-hour clock.

The value of stime can be determined by calling the TIME function. CTIME(TIME( )) returns the current time and date.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE_AND_TIME

Example

character (24) systime
systime = CTIME (TIME( ))
print *, 'Current date and time is ',systime


CYCLE

Statement: Interrupts the current execution cycle of the innermost (or named) DO construct.

Syntax

CYCLE [name]

name
(Optional) Is the name of the DO construct.

Rules and Behavior

When a CYCLE statement is executed, the following occurs:

  1. The current execution cycle of the named (or innermost) DO construct is terminated.

    If a DO construct name is specified, the CYCLE statement must be within the range of that construct.

  2. The iteration count (if any) is decremented by 1.

  3. The DO variable (if any) is incremented by the value of the increment parameter (if any).

  4. A new iteration cycle of the DO construct begins.

Any executable statements following the CYCLE statement (including a labeled terminal statement) are not executed.

A CYCLE statement can be labeled, but it cannot be used to terminate a DO construct.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DO, DO WHILE, DO Constructs

Examples

The following example shows a CYCLE statement:

DO I =1, 10
  A(I) = C + D(I)
  IF (D(I) < 0) CYCLE    ! If true, the next statement is omitted
  A(I) = 0               ! from the loop and the loop is tested again.
END DO

The following is from CYCLE.F90 in the /DF98/SAMPLES/TUTORIAL subdirectory:

      sample_loop: do i = 1, 5
           print *,i
             if( i .gt. 3 ) cycle sample_loop
           print *,i
           end do sample_loop
           print *,'done!'
!output:
!     1
!     1
!     2
!     2
!     3
!     3
!     4
!     5
!     done!


DATA

Statement: Assigns initial values to variables before program execution.

Syntax

DATA var-list /clist/ [[,] var-list /clist/] ...

var-list
Is a list of variables or implied-do lists, separated by commas.

Subscript expressions and expressions in substring references must be initialization expressions.

An implied-do list in a DATA statement takes the following form:

(do-list, var = expr1, expr2 [, expr3])

do-list
Is a list of one or more array elements, substrings, scalar structure components, or implied-do lists, separated by commas. Any array elements or scalar structure components must not have a constant parent.

var
Is the name of a scalar integer variable (the implied-do variable).

expr
Are scalar integer expressions. The expressions can contain variables of other implied-do lists that have this implied-do list within their ranges.

clist
Is a list of constants (or names of constants), or for pointer objects, NULL( ); constants must be separated by commas. If the constant is a structure constructor, each component must be an initialization expression. If the constant is in binary, octal, or hexadecimal form, the corresponding object must be of type integer.

A constant can be specified in the form r*constant, where r is a repeat specification. It is a nonnegative scalar integer constant (with no kind parameter). If it is a named constant, it must have been declared previously in the scoping unit or made accessible through use or host association. If r is omitted, it is assumed to be 1.

Rules and Behavior

A variable can be initialized only once in an executable program. A variable that appears in a DATA statement and is typed implicitly can appear in a subsequent type declaration only if that declaration confirms the implicit typing.

The number of constants in c-list must equal the number of variables in var-list. The constants are assigned to the variables in the order in which they appear (from left to right).

The following objects cannot be initialized in a DATA statement:

  • A dummy argument
  • A function
  • A function result
  • An automatic object
  • An allocatable array
  • A variable that is accessible by use or host association
  • A variable in a named common block (unless the DATA statement is in a block data program unit)
  • A variable in blank common

Except for variables in named COMMON blocks, a named variable has the SAVE attribute if any part of it is initialized in a DATA statement. You can confirm this property by specifying the variable in a SAVE statement or a type declaration statement containing the SAVE attribute.

When an unsubscripted array name appears in a DATA statement, values are assigned to every element of that array in the order of subscript progression. The associated constant list must contain enough values to fill the array.

Array element values can be initialized in three ways: by name, by element, or by an implied-do list (interpreted in the same way as a DO construct).

The following conversion rules and restrictions apply to variable and constant list items:

  • If the constant and the variable are both of numeric type, the following conversion occurs:

    • The constant value is converted to the data type of the variable being initialized, if necessary.

    • When a binary, octal, or hexadecimal constant is assigned to a variable or array element, the number of digits that can be assigned depends on the data type of the data item. If the constant contains fewer digits than the capacity of the variable or array element, the constant is extended on the left with zeros. If the constant contains more digits than can be stored, the constant is truncated on the left.

  • If the constant and the variable are both of character type, the following conversion occurs:

    • If the length of the constant is less than the length of the variable, the rightmost character positions of the variable are initialized with blank characters.

    • If the length of the constant is greater than the length of the variable, the character constant is truncated on the right.

  • If the constant is of numeric type and the variable is of character type, the following restrictions apply:

    • The character variable must have a length of one character.

    • The constant must be an integer, binary, octal, or hexadecimal constant, and must have a value in the range 0 through 255.

    When the constant and variable conform to these restrictions, the variable is initialized with the character that has the ASCII code specified by the constant. (This lets you initialize a character object to any 8-bit ASCII code.)

  • If the constant is a Hollerith or character constant, and the variable is a numeric variable or numeric array element, the number of characters that can be assigned depends on the data type of the data item.

    If the Hollerith or character constant contains fewer characters than the capacity of the variable or array element, the constant is extended on the right with blank characters. If the constant contains more characters than can be stored, the constant is truncated on the right.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: CHARACTER, INTEGER, REAL, COMPLEX, COMMON, Data Types, Constants, and Variables, I/O Lists

Examples

The following example shows the three ways that DATA statements can initialize array element values:

  DIMENSION A(10,10)
  DATA A/100*1.0/    ! initialization by name
  DATA A(1,1), A(10,1), A(3,3) /2*2.5, 2.0/ ! initialization by element
  DATA ((A(I,J), I=1,5,2), J=1,5) /15*1.0/  ! initialization by implied-do list

The following example shows DATA statements containing structure components:

  TYPE EMPLOYEE
    INTEGER ID
    CHARACTER(LEN=40) NAME
  END TYPE EMPLOYEE
  TYPE(EMPLOYEE) MAN_NAME, CON_NAME
  DATA MAN_NAME / EMPLOYEE(417, 'Henry Adams') /
  DATA CON_NAME%ID, CON_NAME%NAME /891, "David James"/

In the following example, the first DATA statement assigns zero to all 10 elements of array A, and four asterisks followed by two blanks to the character variable STARS:

  INTEGER A(10), B(10)
  CHARACTER BELL, TAB, LF, FF, STARS*6
  DATA A,STARS /10*0,'****'/
  DATA BELL,TAB,LF,FF /7,9,10,12/
  DATA (B(I), I=1,10,2) /5*1/

In this case, the second DATA statement assigns ASCII control character codes to the character variables BELL, TAB, LF, and FF. The last DATA statement uses an implied-do list to assign the value 1 to the odd-numbered elements in the array B.

The following shows another example:

    INTEGER n, order, alpha, list(100)
    REAL coef(4), eps(2),
    pi(5), x(5,5)
    CHARACTER*12 help
    COMPLEX*8 cstuff
    DATA  n /0/, order /3/
    DATA  alpha /'A'/
    DATA  coef /1.0, 2*3.0, 1.0/, eps(1) /.00001/
    DATA  cstuff /(-1.0, -1.0)/
!    The following example initializes diagonal and below in
!    a 5x5 matrix:
    DATA  ((x(j,i), i=1,j), j=1,5) / 15*1.0 /
    DATA  pi / 5*3.14159 /
    DATA  list / 100*0 /
    DATA  help(1:4), help(5:8), help(9:12) /3*'HELP'/

Consider the following:

 CHARACTER (LEN = 10) NAME
 INTEGER, DIMENSION (0:9) :: MILES
 REAL, DIMENSION (100, 100) :: SKEW
 TYPE (MEMBER) MYNAME, YOURS
 DATA NAME / 'JOHN DOE' /, miles / 10*0 /
 DATA ((SKEW (k, j), j = 1, k), k = 1, 100) / 5050*0.0 /
 DATA ((SKEW (k, j), j = k + 1, 100), k = 1, 99) / 4950*1.0 /
 DATA MYNAME / MEMBER (21, 'JOHN SMITH') /
 DATA YOURS % age, YOURS % name / 35, 'FRED BROWN' /

In this example, the character variable NAME is initialized with the value JOHN DOE with two trailing blanks to fill out the declared length of the variable. The ten elements of MILES are initialized to zero. The two-dimensional array SKEW is initialized so that its lower triangle is zero and its upper triangle is one. The structures MYNAME and YOURS are declared using the derived type MEMBER from Derived Type. The derived-type variable MYNAME is initialized by a structure constructor. The derived-type variable YOURS is initialized by supplying a separate value for each component.

The first DATA statement in the previous example could also be written as:

 DATA name / 'JOHN DOE' /
 DATA miles / 10*0 /

As a Fortran 95 feature, a pointer can be initialized as disassociated by using a DATA statement. For example:

 INTEGER, POINTER :: P
 DATA P/NULL( )/
 END


DATE

DATE can be used as an intrinsic subroutine or as a portability routine.

Warning: The two-digit year return value may cause problems with the year 2000. Use DATE_AND_TIME instead.

DATE Intrinsic Subroutine

Intrinsic Subroutine: Returns the current date as set within the system.

Syntax

CALL DATE (buf)

buf
Is a 9-byte variable, array, array element, or character substring.

The date is returned as a 9-byte ASCII character string taking the form dd-mmm-yy, where:

dd is the 2-digit date
mmm is the 3-letter month
yy is the last two digits of the year

If buf is of numeric type and smaller than 9 bytes, data corruption can occur.

If buf is of character type, its associated length is passed to the subroutine. If buf is smaller than 9 bytes, the subroutine truncates the date to fit in the specified length. If an array of type character is passed, the subroutine stores the date in the first array element, using the element length, not the length of the entire array.

Example

CHARACTER*1 DAY(9)
...
CALL DATE (DAY)

The length of the first array element in CHARACTER array DAY is passed to the DATE subroutine. The subroutine then truncates the date to fit into the 1-character element, producing an incorrect result.

DATE Portability Routine

Portability Subroutine and Function: Returns the current system date.

Module: USE DFPORT

Subroutine Syntax:

CALL DATE (string)

Function Syntax:

result = DATE( )

string
(Output) CHARACTER. Variable or array containing at least nine bytes of storage.

DATE in its function form returns a CHARACTER string of length 8 in the form mm/dd/yy, where mm, dd, and yy are two-digit representations of the month, day, and year, respectively.

DATE in its subroutine form returns string in the form dd-mmm-yy, where dd is a two-digit representation of the current day of the month, mmm is a three-character abbreviation for the current month (for example, Jan) and yy are the last two digits of the current year.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

USE DFPORT
!If today's date is March 02, 2000, the following
!code prints "02-Mar-00"
CHARACTER(9) TODAY
CALL DATE(TODAY)
PRINT *, TODAY
!The next line prints "03/02/00"
PRINT *, DATE( )


DATE_AND_TIME

Intrinsic Subroutine: Returns character data on the real-time clock and date in a form compatible with the representations defined in Standard ISO 8601:1988.

Syntax

CALL DATE_AND_TIME ( [date] [, time] [, zone] [, values] )

date
(Optional; output) Must be scalar and of type default character; its length must be at least 8 to contain the complete value. Its leftmost 8 characters are set to a value of the form CCYYMMDD, where:

CC | Is the century
YY | Is the year within the century
MM | Is the month within the year
DD | Is the day within the month

time
(Optional; output) Must be scalar and of type default character; its length must be at least 10 to contain the complete value. Its leftmost 10 characters are set to a value of the form hhmmss.sss, where:

hh | Is the hour of the day
mm | Is the minutes of the hour
ss.sss | Is the seconds and milliseconds of the minute

zone
(Optional; output) Must be scalar and of type default character; its length must be at least 5 to contain the complete value. Its leftmost 5 characters are set to a value of the form hhmm, where hh and mm are the time difference with respect to Coordinated Universal Time (UTC) in hours and parts of an hour expressed in minutes, respectively.

UTC (also known as Greenwich Mean Time) is defined by CCIR Recommendation 460-2.

values
(Optional; output) Must be of type default integer. One-dimensional array with size of at least 8. The values returned in values are as follows:

values (1) | The 4-digit year
values (2) | The month of the year
values (3) | The day of the month
values (4) | The time difference with respect to Coordinated Universal Time (UTC) in minutes
values (5) | The hour of the day (range 0 to 23) - local time
values (6) | The minutes of the hour (range 0 to 59) - local time
values (7) | The seconds of the minute (range 0 to 59) - local time
values (8) | The milliseconds of the second (range 0 to 999) - local time

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETDAT, GETTIM, IDATE, FDATE, TIME, ITIME, RTC, CLOCK

Example

Consider the following example executed on 2000 March 28 at 11:04:14.5:

  INTEGER DATE_TIME (8)
  CHARACTER (LEN = 12) REAL_CLOCK (3)
  CALL DATE_AND_TIME (REAL_CLOCK (1), REAL_CLOCK (2), &
                      REAL_CLOCK (3), DATE_TIME)

This assigns the value "20000328" to REAL_CLOCK (1), the value "110414.500" to REAL_CLOCK (2), and the value "-0500" to REAL_CLOCK (3). The following values are assigned to DATE_TIME: 2000, 3, 28, -300, 11, 4, 14, and 500.

The following shows another example:

CHARACTER(10) t
CHARACTER(5) z
CALL DATE_AND_TIME(TIME = t, ZONE = z)


DBESJ0, DBESJ1, DBESJN, DBESY0, DBESY1, DBESYN

Portability Functions: Compute the double-precision values of Bessel functions of the first and second kinds.

Module: USE DFPORT

Syntax

result = DBESJ0 (posvalu)
result = DBESJ1 (posvalu)
result = DBESJN (n, posvalu)
result = DBESY0 (posvalu)
result = DBESY1 (posvalu)
result = DBESYN (n, posvalu)

posvalue
(Input) REAL(8). Independent variable for a Bessel function. Must be greater than or equal to zero.

n
(Input) Integer. Specifies the order of the selected Bessel function computation.

Results:

DBESJ0, DBESJ1, and DBESJN return Bessel functions of the first kind, orders 0, 1, and n, respectively, with the independent variable posvalue.

DBESY0, DBESY1, and DBESYN return Bessel functions of the second kind, orders 0, 1, and n, respectively, with the independent variable posvalue.

Negative arguments cause DBESY0, DBESY1, and DBESYN to return a huge negative value.

Bessel functions are explained more fully in most mathematics reference books, such as the Handbook of Mathematical Functions (Abramowitz and Stegun. Washington: U.S. Government Printing Office, 1964). These functions are commonly used in the mathematics of electromagnetic wave theory.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BESJ0, BESJ1, BESJN, BESY0, BESY1, BESYN

Example

    USE DFPORT
    real(8) besnum, besout
10  read *, besnum
    besout = dbesj0(besnum)
    print *, 'result is ',besout
    goto 10
    end


DBLE

Elemental Intrinsic Function (Generic): Converts a number to double-precision real type.

Syntax

result = DBLE (a)

a
(Input) Must be of type integer, real, or complex.

Results:

The result is of type double precision real (REAL(8) or REAL*8). Functions that cause conversion of one data type to another type have the same effect as the implied conversion in assignment statements.

If a is of type double precision, the result is the value of the a with no conversion (DBLE(a) = a).

If a is of type integer or real, the result has as much precision of the significant part of a as a double precision value can contain.

If a is of type complex, the result has as much precision of the significant part of the real part of a as a double precision value can contain.

Specific Name 1 | Argument Type | Result Type
 | INTEGER(1) | REAL(8)
 | INTEGER(2) | REAL(8)
 | INTEGER(4) | REAL(8)
 | INTEGER(8) | REAL(8)
DBLE 2 | REAL(4) | REAL(8)
 | REAL(8) | REAL(8)
DBLEQ 3 | REAL(16) | REAL(8)
 | COMPLEX(4) | REAL(8)
 | COMPLEX(8) | REAL(8)
 | COMPLEX(16) | REAL(8)
1 These specific functions cannot be passed as actual arguments. 2 For compatibility with older versions of Fortran, DBLE can also be specified as a specific function. 3 VMS, U*X

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: FLOAT, SNGL, REAL, CMPLX

Examples

DBLE (4) has the value 4.0.

DBLE ((3.4, 2.0)) has the value 3.4.


DCMPLX

Elemental Intrinsic Function (Generic): Converts the argument to double complex type. This function must not be specified as an actual argument.

Syntax

result = DCMPLX (x [, y])

x
(Input) Must be of type integer, real, or complex.

y
(Optional; input) Must be of type integer or real. It must not be present if x is of type complex.

Results:

The result is of type double complex (COMPLEX(8) or COMPLEX*16).

If only one noncomplex argument appears, it is converted into the real part of the result value and zero is assigned to the imaginary part. If y is not specified and x is complex, the result value is CMPLX(REAL(x), AIMAG(x)).

If two noncomplex arguments appear, the complex value is produced by converting the first argument into the real part of the value, and converting the second argument into the imaginary part.

DCMPLX(x, y) has the complex value whose real part is REAL(x, kind=8) and whose imaginary part is REAL(y, kind=8).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: CMPLX, FLOAT, INT, IFIX, REAL, SNGL

Examples

DCMPLX (-3) has the value (-3.0, 0.0).

DCMPLX (4.1, 2.3) has the value (4.1, 2.3).


DEALLOCATE

Statement: Frees the storage allocated for allocatable arrays and pointer targets (and causes the pointers to become disassociated).

Syntax

DEALLOCATE (object [, object] ...[, STAT=sv])

object
Is a structure component or the name of a variable, and must be a pointer or allocatable array.

sv
Is a scalar integer variable in which the status of the deallocation is stored.

Rules and Behavior

If a STAT variable is specified, it must not be deallocated in the DEALLOCATE statement in which it appears. If the deallocation is successful, the variable is set to zero. If the deallocation is not successful, an error condition occurs, and the variable is set to a positive integer value (representing the run-time error). If no STAT variable is specified and an error condition occurs, program execution terminates.

It is recommended that all explicitly allocated storage be explicitly deallocated when it is no longer needed.

To disassociate a pointer that was not associated with the ALLOCATE statement, use the NULLIFY statement.

For a list of run-time errors, see Visual Fortran Run-Time Errors in Error Messages.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ALLOCATE, NULLIFY, Arrays

Examples

The following example shows deallocation of an allocatable array:

INTEGER ALLOC_ERR
REAL, ALLOCATABLE :: A(:), B(:,:)
...
ALLOCATE (A(10), B(-2:8,1:5))
...
DEALLOCATE(A, B, STAT = ALLOC_ERR)

The following shows another example:

INTEGER, ALLOCATABLE :: dataset(:,:,:)
INTEGER reactor, level, points, error
DATA reactor, level, points / 10, 50, 10 /
ALLOCATE (dataset(1:reactor,1:level,1:points), STAT = error)
DEALLOCATE (dataset, STAT = error)


DECLARE and NODECLARE

General Compiler Directives: DECLARE generates warnings for variables that have been used but have not been declared (like the IMPLICIT NONE statement). NODECLARE (the default) disables these warnings.

Syntax

c DEC$ DECLARE
c DEC$ NODECLARE

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

The DECLARE directive is primarily a debugging tool that locates variables that have not been properly initialized, or that have been defined but never used.

The following forms are also allowed: !MS$DECLARE and !MS$NODECLARE

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: IMPLICIT, General Compiler Directives


DECODE

Statement: Translates data from character to internal form. It is comparable to using internal files in formatted sequential READ statements.

Syntax

DECODE (c, f, b [, IOSTAT=i-var] [, ERR=label]) [io-list]

c
Is a scalar integer expression. It is the number of characters to be translated to internal form.

f
Is a format identifier. An error occurs if more than one record is specified.

b
Is a scalar or array reference. If b is an array reference, its elements are processed in the order of subscript progression.
b contains the characters to be translated to internal form.

i-var
Is a scalar integer variable that is defined as a positive integer if an error occurs and as zero if no error occurs.

label
Is the label of an executable statement that receives control if an error occurs.

io-list
Is an I/O list. An I/O list is either an implied-do list or a simple list of variables (except for assumed-size arrays). The list receives the data after translation to internal form.

The interaction between the format specifier and the I/O list is the same as for a formatted I/O statement.

Rules and Behavior

The number of characters that the DECODE statement can translate depends on the data type of b. For example, an INTEGER(2) array can contain two characters per element, so that the maximum number of characters is twice the number of elements in that array.

The maximum number of characters a character variable or character array element can contain is the length of the character variable or character array element.

The maximum number of characters a character array can contain is the length of each element multiplied by the number of elements.

See Also: READ, WRITE, ENCODE

Examples

In the following example, the DECODE statement translates the 12 characters in A to integer form (as specified by the FORMAT statement):

     DIMENSION K(3)
     CHARACTER*12 A,B
     DATA A/'123456789012'/
     DECODE(12,100,A) K
100  FORMAT(3I4)
     ENCODE(12,100,B) K(3), K(2), K(1)

The 12 characters are stored in array K:

K(1) = 1234
K(2) = 5678
K(3) = 9012


DEFAULT (TU*X only)

Parallel Directive Clause: Lets you specify a scope for all variables in the lexical extent of a parallel region.

Syntax

DEFAULT ( PRIVATE | SHARED | NONE )

The specifications have the following effects:

  • PRIVATE - Makes all named objects in the lexical extent of the parallel region, including common block variables but excluding THREADPRIVATE (or TASKCOMMON) variables, private to a thread as if you explicitly listed each variable in a PRIVATE clause.

  • SHARED - Makes all named objects in the lexical extent of the parallel region shared among the threads in a team, as if you explicitly listed each variable in a SHARED clause. If you do not specify a DEFAULT clause, this is the default.

  • NONE - Specifies that there is no implicit default as to whether variables are PRIVATE or SHARED. In this case, you must specify the PRIVATE, SHARED, FIRSTPRIVATE, LASTPRIVATE, or REDUCTION property of each variable you use in the lexical extent of the parallel region.

You can specify only one DEFAULT clause in a PARALLEL directive. You can exclude variables from a defined default by using the PRIVATE, SHARED, FIRSTPRIVATE, LASTPRIVATE, or REDUCTION clauses.

Variables in THREADPRIVATE (or TASKCOMMON) common blocks are not affected by this clause.


DEFINE and UNDEFINE

General Compiler Directives: DEFINE creates a symbolic variable whose existence or value can be tested during conditional compilation. UNDEFINE removes a defined symbol.

Syntax

c DEC$ DEFINE name [ = val]

c DEC$ UNDEFINE name

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

name
Is the name of the variable.

val
(Input) INTEGER(4). The value assigned to name.

Rules and Behavior

DEFINE and UNDEFINE create and remove symbols for use with the IF (or IF DEFINED) compiler directive. Symbols defined with DEFINE directive are local to the directive. They cannot be declared in the Fortran program.

Because Fortran programs cannot access the named variables, the names can duplicate Fortran keywords, intrinsic functions, or user-defined names without conflict.

To test whether a symbol has been defined, use the IF DEFINED (name) directive. You can assign an integer value to a defined symbol. To test the assigned value of name, use the IF directive. IF test expressions can contain most logical and arithmetic operators.

Attempting to undefine a symbol that has not been defined produces a compiler warning.

The DEFINE and UNDEFINE directives can appear anywhere in a program, enabling and disabling symbol definitions.

The following forms are also allowed: !MS$DEFINE name[=val] and !MS$UNDEFINE name

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: IF Directive Construct, General Compiler Directives, /define compiler option

Example

!DEC$ DEFINE testflag
!DEC$ IF DEFINED (testflag)
   write (*,*) 'Compiling first line'
!DEC$ ELSE
   write (*,*) 'Compiling second line'
!DEC$ ENDIF
!DEC$ UNDEFINE testflag


DEFINE FILE

Statement: Establishes the size and structure of files with relative organization and associates them with a logical unit number.

Syntax

DEFINE FILE u(m, n, U, asv) [, u(m, n, U, asv)] ...

u
Is a scalar integer constant or variable that specifies the logical unit number.

m
Is a scalar integer constant or variable that specifies the number of records in the file.

n
Is a scalar integer constant or variable that specifies the length of each record in 16-bit words (2 bytes).

U
Specifies that the file is unformatted (binary); this is the only acceptable entry in this position.

asv
Is a scalar integer variable, called the associated variable of the file. At the end of each direct access I/O operation, the record number of the next higher numbered record in the file is assigned to asv; asv must not be a dummy argument.

Rules and Behavior

The DEFINE FILE statement is comparable to the OPEN statement. In situations where you can use the OPEN statement, OPEN is the preferable mechanism for creating and opening files.

The DEFINE FILE statement specifies that a file containing m fixed-length records, each composed of n 16-bit words, exists (or will exist) on the specified logical unit. The records in the file are numbered sequentially from 1 through m.

A DEFINE FILE statement does not itself open a file. However, the statement must be executed before the first direct access I/O statement referring to the specified file. The file is opened when the I/O statement is executed.

If this I/O statement is a WRITE statement, a direct access sequential file is opened, or created if necessary.
If the I/O statement is a READ or FIND statement, an existing file is opened, unless the specified file does not exist. If a file does not exist, an error occurs.

The DEFINE FILE statement establishes the variable asv as the associated variable of a file. At the end of each direct access I/O operation, the Fortran I/O system places in asv the record number of the record immediately following the one just read or written.

The associated variable always points to the next sequential record in the file (unless the associated variable is redefined by an assignment, input, or FIND statement). So, direct access I/O statements can perform sequential processing on the file by using the associated variable of the file as the record number specifier.

Examples

  DEFINE FILE 3(1000,48,U,NREC)

In this example, the DEFINE FILE statement specifies that the logical unit 3 is to be connected to a file of 1000 fixed-length records; each record is forty-eight 16-bit words long. The records are numbered sequentially from 1 through 1000 and are unformatted.

After each direct access I/O operation on this file, the integer variable NREC will contain the record number of the record immediately following the record just processed.


DELDIRQQ

Run-Time Function: Deletes a specified directory.

Module: USE DFLIB

Syntax

result = DELDIRQQ (dir)

dir
(Input) Character*(*). String containing the path of the directory to be deleted.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

The directory to be deleted must be empty. It cannot be the current directory, the root directory, or a directory currently in use by another process.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETDRIVEDIRQQ, MAKEDIRQQ, CHANGEDIRQQ, CHANGEDRIVEQQ, UNLINK

Example

See the example for GETDRIVEDIRQQ.


DELETE

Statement: Deletes a record from a relative file.

Syntax

DELETE ([UNIT=]io-unit, REC=r [, ERR=label] [, IOSTAT=i-var])

io-unit
Is an external unit specifier.

r
Is a scalar numeric expression indicating the record number to be deleted.

label
Is the label of the branch target statement that receives control if an error occurs.

i-var
Is a scalar integer variable that is defined as a positive integer if an error occurs and zero if no error occurs.

Rules and Behavior

In a relative file, the DELETE statement deletes the direct access record specified by r. If REC=r is omitted, the current record is deleted. When the direct access record is deleted, any associated variable is set to the next record number.

The DELETE statement logically removes the appropriate record from the specified file by locating the record and marking it as a deleted record. It then frees the position formerly occupied by the deleted record so that a new record can be written at that position.

Note: You must use the /vms compiler option for READs to detect that a record has been deleted.

See Also: Data Transfer I/O Statements, Branch Specifiers

Examples

The following statement deletes the fifth record in the file connected to I/O unit 10:

  DELETE (10, REC=5)

Suppose the following statement is specified:

  DELETE (UNIT=9, REC=10, IOSTAT=IOS, ERR=20)

The tenth record in the file connected to unit 9 is deleted. If an error occurs, control is transferred to the statement labeled 20, and a positive integer is stored in the variable IOS.


DELETEMENUQQ

QuickWin Function: Deletes a menu item from a QuickWin menu.

Module: USE DFLIB

Syntax

result = DELETEMENUQQ (menuID, itemID)

menuID
(Input) INTEGER(4). Identifies the menu that contains the menu item to be deleted, starting with 1 as the leftmost menu.

itemID
(Input) INTEGER(4). Identifies the menu item to be deleted, starting with 0 as the top menu item.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

Compatibility

QUICKWIN GRAPHICS LIB

See Also: Using QuickWin, APPENDMENUQQ, INSERTMENUQQ, MODIFYMENUFLAGSQQ, MODIFYMENUROUTINEQQ, MODIFYMENUSTRINGQQ

Example

USE DFLIB
LOGICAL(4) result
CHARACTER(25) str
str = 'Add to EDIT Menu'C   ! Append to 2nd menu
result = APPENDMENUQQ(2, $MENUENABLED, str, WINSTATUS)
! Delete third item (EXIT) from menu 1 (FILE)
result = DELETEMENUQQ(1, 3)
! Delete entire fifth menu (WINDOW)
result = DELETEMENUQQ(5,0)
END


DELFILESQQ

Run-Time Function: Deletes all files matching the name specification, which can contain wildcards (* and ?).

Module: USE DFLIB

Syntax

result = DELFILESQQ (files)

files
(Input) Character*(*). File(s) to be deleted. Can contain wildcards (* and ?).

Results:

The result is of type INTEGER(2). The result is the number of files deleted.

You can use wildcards to delete more than one file at a time. DELFILESQQ does not delete directories or system, hidden, or read-only files. Use this function with caution because it can delete many files at once. If a file is in use by another process (for example, if it is open in another process), it cannot be deleted.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: FINDFILEQQ

Example

USE DFLIB
INTEGER(4) len, count
CHARACTER(80) file
CHARACTER(1) ch
WRITE(*,*) "Enter names of files to delete: "
len = GETSTRQQ(file)
IF (file(1:len) .EQ. '*.*') THEN
   WRITE(*,*) "Are you sure (Y/N)?"
   ch = GETCHARQQ()
   IF ((ch .NE. 'Y') .AND. (ch .NE. 'y')) STOP
END IF
count = DELFILESQQ(file)
WRITE(*,*) "Deleted ", count, " files."
END


Derived Type

Statement: Specifies the name of a user-defined type and the types of its components.

Syntax

TYPE [[, access] :: ] name
component-definition
[component-definition]. . .
END TYPE [ name ]

access
Is the PUBLIC or PRIVATE keyword. The keyword can only be specified if the derived-type definition is in the specification part of a module.

name
Is the name of the derived data type. It must not be the same as the name of any intrinsic type, or the same as the name of a derived type that can be accessed from a module.

component-definition
Is one or more type declaration statements defining the component of derived type.

The first component definition can be preceded by an optional PRIVATE or SEQUENCE statement. (Only one PRIVATE or SEQUENCE statement can appear in a given derived-type definition.)

If SEQUENCE is present, all derived types specified in component definitions must be sequence types.

A component definition takes the following form:

type [ [, attr ] :: ] component [(a-spec)] [*char-len] [init-ex]

type
Is a type specifier. It can be an intrinsic type or a previously defined derived type. (If the POINTER attribute follows this specifier, the type can also be any accessible derived type, including the type being defined.)

attr
Is an optional POINTER attribute for a pointer component, or an optional DIMENSION attribute for an array component. You can specify one or both attributes. If DIMENSION is specified, it can be followed by an array specification.

The POINTER or DIMENSION attribute can only appear once in a given component-definition.

component
Is the name of the component being defined.

a-spec
Is an optional array specification, enclosed in parentheses. If POINTER is specified, the array is deferred shape; otherwise, it is explicit shape. In an explicit-shape specification, each bound must be a constant scalar integer expression.

If the array bounds are not specified here, they must be specified following the DIMENSION attribute.

char-len
Is an optional scalar integer literal constant; it must be preceded by an asterisk (*). This parameter can only be specified if the component is of type CHARACTER.

init-ex
Is an initialization expression, or for pointer components, => NULL( ). This is a Fortran 95 feature.

If init-ex is specified, a double colon must appear in the component definition. The equals assignment symbol (=) can only be specified for nonpointer components.

The initialization expression is evaluated in the scoping unit of the type definition.

Rules and Behavior

If a name is specified following the END TYPE statement, it must be the same name that follows TYPE in the derived type statement.

A derived type can be defined only once in a scoping unit. If the same derived-type name appears in a derived-type definition in another scoping unit, it is treated independently.

A component name has the scope of the derived-type definition only. Therefore, the same name can be used in another derived-type definition in the same scoping unit.

Two data entities have the same type if they are both declared to be of the same derived type (the derived-type definition can be accessed from a module or a host scoping unit).

If the entities are in different scoping units, they can also have the same derived type if they are declared with reference to different derived-type definitions, and if both derived-type definitions have all of the following:

  • The same name

  • A SEQUENCE statement (they both have sequence type)

  • Components that agree in name, order, and attributes; components cannot be private

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DIMENSION, MAP...END MAP, PRIVATE, PUBLIC, RECORD, SEQUENCE, STRUCTURE...END STRUCTURE, Derived Types, Default Initialization, Structure Components Structure Constructors

Examples

TYPE mem_name
  SEQUENCE
  CHARACTER (LEN = 20) lastn
  CHARACTER (LEN = 20) firstn
  CHARACTER (len = 3) cos   ! this works because COS is a component name
END TYPE mem_name
TYPE member
    TYPE (mem_name) :: name
    SEQUENCE
    INTEGER age
    CHARACTER (LEN = 20) specialty
END TYPE member

In the following example, a and b are both variable arrays of derived type pair:

 TYPE (pair)
   INTEGER i, j
 END TYPE
 TYPE (pair), DIMENSION (2, 2) :: a, b(3)

The following example shows how you can use derived-type objects as components of other derived-type objects:

 TYPE employee_name
   CHARACTER(25) last_name
   CHARACTER(15) first_name
 END TYPE
 TYPE employee_addr
   CHARACTER(20) street_name
   INTEGER(2) street_number
   INTEGER(2) apt_number
   CHARACTER(20) city
   CHARACTER(2) state
   INTEGER(4) zip
 END TYPE

Objects of these derived types can then be used within a third derived-type specification, such as:

 TYPE employee_data
   TYPE (employee_name) :: name
   TYPE (employee_addr) :: addr
   INTEGER(4) telephone
   INTEGER(2) date_of_birth
   INTEGER(2) date_of_hire
   INTEGER(2) social_security(3)
   LOGICAL(2) married
   INTEGER(2) dependents
 END TYPE


%DESCR (VMS only)

Built-in Function: Changes the form of an actual argument. It passes an argument by descriptor.

Syntax

result = %DESCR (a)

a
(Input) An expression, record name, procedure name, array, character array section, or array element.

You must specify %DESCR in the actual argument list of a CALL statement or function reference. You cannot use it in any other context.

The following table lists the Compaq Fortran defaults for argument passing, and the allowed uses of %DESCR:

Actual Argument Data Type | Default | %DESCR
Expressions:
Logical | REF | Yes
Integer | REF | Yes
REAL(4) | REF | Yes
REAL(8) | REF | Yes
REAL(16) 1 | REF | Yes
COMPLEX(4) | REF | Yes
COMPLEX(8) | REF | Yes
COMPLEX(16) 1 | REF | Yes
Character | DESCR 2 | Yes
Hollerith | REF | No
Aggregate 2 | REF | No
Derived | REF | No
Array Name:
Numeric | REF | Yes
Character | DESCR 2 | Yes
Aggregate 3 | REF | No
Derived | REF | No
Procedure Name:
Numeric | REF | Yes
Character | DESCR 2 | Yes
1 VMS, U*X 2 On Tru64 UNIX, Linux, and Windows systems, a character argument is passed by address and hidden length. 3 In Compaq Fortran record structures

The %DESCR, %VAL, and %REF functions override related cDEC$ ATTRIBUTE settings.

See Also: CALL, %VAL, %REF


DFLOAT

Elemental Intrinsic Function (Generic): Converts an integer to double precision type.

Syntax

result = DFLOAT (a)

a
(Input) Must be of type integer.

Results:

The result is of type double precision real (REAL(8) or REAL*8). Functions that cause conversion of one data type to another type have the same effect as the implied conversion in assignment statements.

Specific Name 1 | Argument Type | Result Type
 | INTEGER(1) | REAL(8)
DFLOTI | INTEGER(2) | REAL(8)
DFLOTJ | INTEGER(4) | REAL(8)
DFLOTK | INTEGER(8) | REAL(8)
1 These specific functions cannot be passed as actual arguments.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: REAL

Examples

DFLOAT (-4) has the value -4.0.


DIGITS

Inquiry Intrinsic Function (Generic): Returns the number of significant digits for numbers of the same type and kind parameters as the argument.

Syntax

result = DIGITS (x)

x
(Input) Must be of type integer or real; it can be scalar or array valued.

Results:

The result is a scalar of type default integer.

The result has the value q if x is of type integer; it has the value p if x is of type real. Integer parameter q is defined in Model for Integer Data; real parameter p is defined in Model for Real Data.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: EXPONENT, RADIX, FRACTION, Data Representation Models

Examples

If x is of type REAL(4), DIGITS(x) has the value 24.


DIM

Elemental Intrinsic Function (Generic): Returns the difference between two numbers (if the difference is positive).

Syntax

result = DIM (x, y )

x
(Input) Must be of type integer or real.

y
(Input) Must have the same type and kind parameters as x.

Results:

The result type is the same as x. The value of the result is x - y if x is greater than y; otherwise, the value of the result is zero.

Specific Name | Argument type | Result Type
 | INTEGER(1) | INTEGER(1)
IIDIM | INTEGER(2) | INTEGER(2)
IDIM 1 | INTEGER(4) | INTEGER(4)
KIDIM | INTEGER(8) | INTEGER(8)
DIM | REAL(4) | REAL(4)
DDIM | REAL(8) | REAL(8)
QDIM 2 | REAL(16) | REAL(16)
1 Or JIDIM. 2 VMS and U*X

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Examples

DIM (6, 2) has the value 4.

DIM (-4.0, 3.0) has the value 0.0.

The following shows another example:

  INTEGER i
  REAL r
  REAL(8) d
  i = IDIM(10, 5)            ! returns 5
  r = DIM (-5.1, 3.7)        ! returns 0.0
  d = DDIM (10.0D0, -5.0D0)  ! returns 15.0D0


DIMENSION

Statement and Attribute: Specifies that an object is an array, and defines the shape of the array.

The DIMENSION attribute can be specified in a type declaration statement or a DIMENSION statement, and takes one of the following forms:

Syntax

Type Declaration Statement:

type, [att-ls,] DIMENSION (a-spec) [, att-ls] :: a[(a-spec)] [, a[(a-spec)] ] ...

Statement:

DIMENSION [::] a(a-spec) [, a(a-spec) ] ...

type
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

a-spec
Is an array specification. It can be any of the following:

  • An explicit-shape specification; for example, a(10,10)
  • An assumed-shape specification; for example, a(:)
  • A deferred-shape specification; for example, a(:,:)
  • An assumed-size specification; for example, a(10,*)

For more information on array specifications, see Declaration Statements for Arrays.

In a type declaration statement, any array specification following an array overrides any array specification following DIMENSION.

a
Is the name of the array being declared.

Rules and Behavior

The DIMENSION attribute allocates a number of storage elements to each array named, one storage element to each array element in each dimension. The size of each storage element is determined by the data type of the array.

The total number of storage elements assigned to an array is equal to the number produced by multiplying together the number of elements in each dimension in the array specification. For example, the following statement defines ARRAY as having 16 real elements of 4 bytes each and defines MATRIX as having 125 integer elements of 4 bytes each:

  DIMENSION ARRAY(4,4), MATRIX(5,5,5)

An array can also be declared in the following statements: ALLOCATABLE, POINTER, TARGET, and COMMON.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ALLOCATE, Declaration Statements for Arrays, Arrays

Examples

The following examples show type declaration statements specifying the DIMENSION attribute:

  REAL, DIMENSION(10, 10) :: A, B, C(10, 15)  ! Specification following C
                                              ! overrides the one following
                                              ! DIMENSION
  REAL(8), DIMENSION(5,-2:2) :: A,B,C

The following are examples of the DIMENSION statement:

  DIMENSION BOTTOM(12,24,10)
  DIMENSION X(5,5,5), Y(4,85), Z(100)
  DIMENSION MARK(4,4,4,4)

  SUBROUTINE APROC(A1,A2,N1,N2,N3)
  DIMENSION A1(N1:N2), A2(N3:*)

  CHARACTER(LEN = 20) D
  DIMENSION A(15), B(15, 40), C(-5:8, 7), D(15)

You can also declare arrays by using type and ALLOCATABLE statements, for example:

  INTEGER A(2,0:2)
  COMPLEX F
  ALLOCATABLE F(:,:)
  REAL(8), ALLOCATABLE, DIMENSION( :, :, : ) :: E

You can specify both the upper and lower dimension bounds. If, for example, one array contains data from experiments numbered 28 through 112, you could dimension the array as follows:

  DIMENSION experiment(28:112)

Then, to refer to the data from experiment 72, you would reference experiment(72).

Array elements are stored in column-major order: the leftmost subscript is incremented first when the array is mapped into contiguous memory addresses. For example, consider the following statements:

  INTEGER(2) a(2, 0:2)
  DATA a /1, 2, 3, 4, 5, 6/

These are equivalent to:

  INTEGER(2) a
  DIMENSION a(2, 0:2)
  DATA a /1, 2, 3, 4, 5, 6/

If a is placed at location 1000 in memory, the preceding DATA statement produces the following mapping.

Array element | Address | Value
a(1,0) | 1000 | 1
a(2,0) | 1002 | 2
a(1,1) | 1004 | 3
a(2,1) | 1006 | 4
a(1,2) | 1008 | 5
a(2,2) | 100A | 6

The following DIMENSION statement defines an assumed-size array in a subprogram:

  DIMENSION data (19,*)

At execution time, the array data is given the size of the corresponding array in the calling program.

The following program fragment dimensions two arrays:

   ...
   SUBROUTINE Subr (matrix, rows, vector)
   REAL MATRIX, VECTOR
   INTEGER ROWS
   DIMENSION MATRIX (ROWS,*), VECTOR (10),
  +  LOCAL (2,4,8)
   MATRIX (1,1) = VECTOR (5)
   ...


DISPLAYCURSOR

Graphics Function: Controls cursor visibility.

Module: USE DFLIB

Syntax

result = DISPLAYCURSOR (toggle)

toggle
(Input) INTEGER(2). Constant that defines the cursor state. Has two possible values:

  • $GCURSOROFF - Makes the cursor invisible regardless of its current shape and mode.
  • $GCURSORON - Makes the cursor always visible in graphics mode.

Results:

The result is of type INTEGER(2). The result is the previous value of toggle.

Cursor settings hold only for the currently active child window. You need to call DISPLAYCURSOR for each window in which you want the cursor to be visible.

A call to SETWINDOWCONFIG turns off the cursor.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETTEXTCURSOR


DLGEXIT

Run-Time Subroutine: Closes an open dialog box.

Module: USE DFLOGM

Syntax

CALL DLGEXIT (dlg)

dlg
(Input) Derived type DIALOG. Contains dialog box parameters. The components of the type DIALOG are defined with the PRIVATE attribute, and cannot be changed or individually accessed by the user.

If you want to exit a dialog box on a condition other than the user selecting the OK or Cancel button, you need to include a call to DLGEXIT from within your callback routine. DLGEXIT saves the data associated with the dialog box controls and then closes the dialog box. The dialog box is exited after DLGEXIT has returned control back to the dialog manager, not immediately after the call to DLGEXIT.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DLGSETRETURN, DLGINIT, DLGMODAL, DLGMODELESS

Example

SUBROUTINE EXITSUB (dlg, exit_button_id, callbacktype)
USE DFLOGM
TYPE (DIALOG) dlg
INTEGER exit_button_id, callbacktype
...
  CALL DLGEXIT (dlg)


DLGFLUSH

Run-Time Subroutine: Updates the display of a dialog box.

Module: USE DFLOGM

Syntax

CALL DLGFLUSH (dlg [, flushall])

dlg
(Input) Derived type DIALOG. Contains dialog box parameters. The components of the type DIALOG are defined with the PRIVATE attribute, and cannot be changed or individually accessed by the user.

flushall
(Input; optional) Logical. If .FALSE. (the default), then only the controls that the dialog routines have marked as changed are updated. If .TRUE., all controls are updated with the state of the controls as known by the dialog routines. Normally, you would not set flushall to .TRUE..

When your application calls DLGSET to change a property of a control in a dialog box, the change is not immediately reflected in the displayed dialog box. Changes are applied when the dialog box is first displayed, and then after every dialog callback to the user's code.

This design expects that, after a call to DLGMODAL or DLGMODELESS, every call to DLGSET will be made from within a callback routine, and that the callback routine finishes quickly. This is true most of the time and so is not an issue.

However, there may be cases where you want to change a control outside of a dialog callback, or from within a loop in a dialog callback. In these cases, DLGFLUSH is required, but not always sufficient, to update the dialog display. DLGFLUSH sends pending Windows system messages to the dialog box and the controls that it contains. However, many display changes do not appear until after the program reads and processes the messages that the Windows system has sent to the program as the result of the messages sent by DLGFLUSH. A loop that processes the pending messages is often required; for example:

use DFWINTY
use USER32

logical lNotQuit, lret
integer iret
TYPE (T_MSG) mesg

lNotQuit = .TRUE.
do while (lNotQuit .AND. (PeekMessage(mesg, 0, 0, 0, PM_NOREMOVE) <> 0))
  lNotQuit = GetMessage(mesg, NULL, 0, 0)
    if (lNotQuit) then
      if (DLGISDLGMESSAGE(mesg) .EQV. .FALSE) then
         lret = TranslateMessage(mesg)
         iret = DispatchMessage(mesg)
      end if
    end if
end do

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DLGINIT, DLGMODAL, DLGMODELESS, DLGSET, DLGSETSUB


DLGGET, DLGGETINT, DLGGETLOG, DLGGETCHAR

Run-Time Functions: Retrieve the state of the dialog control variable.

Module: USE DFLOGM

Syntax

result = DLGGET (dlg, controlid, value [, index])
result = DLGGETINT (dlg, controlid, value [, index])
result = DLGGETLOG (dlg, controlid, value [, index])
result = DLGGETCHAR (dlg, controlid, value [, index])

dlg
(Input) Derived type DIALOG. Contains dialog box parameters. The components of the type DIALOG are defined with the PRIVATE attribute, and cannot be changed or individually accessed by the user.

controlid
(Input) Integer. Specifies the identifier of a control within the dialog box. Can be either the symbolic name for the control or the identifier number, both listed in the Include file (with extension .FD).

value
(Output) Integer, logical, or character. The value of the control's variable.

index
(Input; optional) Integer. Specifies the control variable whose value is retrieved. Necessary if the control has more than one variable of the same data type and you do not want to get the value of the default for that type.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, the result is .FALSE..

Use the DLGGET functions to retrieve the values of variables associated with your dialog box controls. Each control has at least one of the integer, logical, or character variable associated with it, but not necessarily all. The control variables are listed in the table in Control Indexes in the Programmer's Guide. The types of controls they are associated with are listed in the table in Available Indexes for Each Dialog Control in the Programmer's Guide.

You can use DLGGET to retrieve the value of any variable. You can also use DLGGETINT to retrieve an integer value, or DLGGETLOG and DLGGETCHAR to retrieve logical and character values, respectively. If you use DLGGET, you do not have to worry about matching the function to the variable type. If you use the wrong function type for a variable or try to retrieve a variable type that is not available, the DLGGET functions return .FALSE..

If two or more controls have the same controlid, you cannot use these controls in a DLGGET operation. In this case the function returns .FALSE..

The dialog box does not need to be open to access its control variables.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DLGSET, DLGSETSUB, DLGINIT, DLGMODAL, DLGMODELESS

Example

USE DFLOGM
INCLUDE "THISDLG.FD"
TYPE (DIALOG)  dlg
INTEGER        val
LOGICAL        retlog, is_checked
CHARACTER(256) text
...
retlog = DLGGET (dlg, IDC_CHECKBOX1, is_checked, dlg_status)
retlog = DLGGET (dlg, IDC_SCROLLBAR2, val, dlg_range)
retlog = DLGGET (dlg, IDC_STATIC_TEXT1, text, dlg_title)
...


DLGINIT, DLGINITWITHRESOURCEHANDLE

Run-Time Functions: Initialize a dialog box.

Module: USE DFLOGM

Syntax

result = DLGINIT (id, dlg)
result = DLGINITWITHRESOURCEHANDLE (id, hinst, dlg)

id
(Input) INTEGER(4). Dialog identifier. Can be either the symbolic name for the dialog or the identifier number, both listed in the Include file (with extension .FD).

dlg
(Output) Derived type DIALOG. Contains dialog box parameters.

hinst
(Input) INTEGER(4). Module instance handle in which the dialog resource can be found.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, the result is .FALSE..

DLGINIT must be called to initialize a dialog box before it can be used with DLGMODAL, DLGMODELESS, or any other dialog function.

DLGINIT will only search for the dialog box resource in the main application. For example, it will not find a dialog box resource that has been built into a dynamic link library.

DLGINITWITHRESOURCEHANDLE can be used when the dialog resource is not in the main application. If the dialog resource is in a dynamic link library (DLL), hinst must be the value passed as the first argument to the DLLMAIN procedure.

Dialogs can be used from any application, including console, QuickWin, and Windows.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DLGEXIT, DLGMODAL, DLGMODELESS, DLGUNINIT

Example

USE DFLOGM
INCLUDE 'DLG1.FD'
LOGICAL retlog
TYPE (DIALOG) thisdlg
...
retlog = DLGINIT (IDD_DLG3, thisdlg)
IF (.not. retlog) THEN
  WRITE (*,*) 'ERROR: dialog not found'
ELSE
...


DLGISDLGMESSAGE, DLGISDLGMESSAGEWITHDLG

Run-Time Functions: Determine whether the specified message is intended for one of the currently displayed modeless dialog boxes, or a specific dialog box.

Module: USE DFLOGM

Syntax

result = DLGISDLGMESSAGE (mesg)
result = DLGISDLGMESSAGEWITHDLG (mesg, dlg)

mesg
(Input) Derived type T_MSG. Contains a Windows message.

dlg
(Input) Derived type DIALOG. Contains dialog box parameters. The components of the type DIALOG are defined with the PRIVATE attribute, and cannot be changed or individually accessed by the user.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if the message is processed by the dialog box. Otherwise, the result is .FALSE. and the message should be further processed.

DLGISDLGMESSAGE must be called in the message loop of Windows applications that display a modeless dialog box using DLGMODELESS. DLGISDGMESSAGE determines whether the message is intended for one of the currently displayed modeless dialog boxes. If it is, it passes the message to the dialog box to be processed.

DLGISDLGMESSAGEWITHDLG specifies a particular dialog box to check. Use DLGISDLGMESSAGEWITHDLG when the message loop is in a main application and the currently active modeless dialog box was created by a DLL.

Compatibility

WINDOWS

See Also: DLGMODELESS, Using a Modeless Dialog Routine

Example

  use dflogm
  include 'resource.fd'
  type (DIALOG)	dlg
  type (T_MSG)    mesg
  integer*4	ret
  logical*4	lret
  ...
  ! Create the main dialog box and set up the controls and callbacks
  lret = DlgInit(IDD_THERM_DIALOG, dlg)
  lret = DlgSetSub(dlg, IDD_THERM_DIALOG, ThermSub)
  ...
  lret = DlgModeless(dlg, nCmdShow)
  ...
  ! Read and process messsages
  do while( GetMessage (mesg, NULL, 0, 0) )
     ! Note that DlgIsDlgMessage must be called in order to give
     ! the dialog box first chance at the message.
     if ( DlgIsDlgMessage(mesg) .EQV. .FALSE. ) then
        lret = TranslateMessage( mesg )
        ret  = DispatchMessage( mesg )
     end if
  end do
  ! Cleanup dialog box memory and exit the application
  call DlgUninit(dlg)
  WinMain = mesg%wParam
  return


DLGMODAL, DLGMODALWITHPARENT

Run-Time Functions: Display a dialog box and process user control selections made within the box.

Module: USE DFLOGM

Syntax

result = DLGMODAL (dlg)
result = DLGMODALWITHPARENT (dlg, hwndParent)

dlg
(Input) Derived type DIALOG. Contains dialog box parameters. The components of the type DIALOG are defined with the PRIVATE attribute, and cannot be changed or individually accessed by the user.

hwndParent
(Input) Integer. Specifies the parent window for the dialog box. If omitted, the value is determined in this order:

  1. If DLGMODAL is called from the callback of a modal or modeless dialog box, then that dialog box is the parent window.
  2. If it is a QuickWin or Standard Graphics application, then the frame window is the parent window.
  3. The Windows desktop window is the parent window.

Results:

The result is of type INTEGER(4). By default, if successful, it returns the identifier of the control that caused the dialog to exit; otherwise, it returns -1. The return value can be changed with the DLGSETRETURN subroutine.

During execution, DLGMODAL displays a dialog box and then waits for user control selections. When a control selection is made, the callback routine, if any, of the selected control (set with DLGSETSUB) is called.

The dialog remains active until an exit control is executed: either the default exit associated with the OK and Cancel buttons, or DLGEXIT within your own control callbacks. DLGMODAL does not return a value until the dialog box is exited.

The default return value for DLGMODAL is the identifier of the control that caused it to exit (for example, IDOK for the OK button and IDCANCEL for the Cancel button). You can specify your own return value with DLGSETRETURN from within one of your dialog control callback routines. You should not specify -1 as your return value, because this is the error value DLGMODAL returns if it cannot open the dialog.

Use DLGMODALWITHPARENT when you want the parent window to be other than the default value (see hwndParent above). In particular, in an SDI or MDI Windows application, you may want the parent window to be the main application window. The parent window is disabled for user input while the modal dialog box is displayed.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DLGSETRETURN, DLGSETSUB, DLGINIT, DLGEXIT

Example

USE DFLOGM
INCLUDE "MYDLG.FD"
INTEGER return
TYPE (DIALOG) mydialog
...
return = DLGMODAL (mydialog)
...


DLGMODELESS

Run-Time Function: Displays a modeless dialog box.

Module: USE DFLOGM

Syntax

result = DLGMODELESS (dlg [, nCmdShow, hwndParent])

dlg
(Input) Derived type DIALOG. Contains dialog box parameters. The components of the type DIALOG are defined with the PRIVATE attribute, and cannot be changed or individually accessed by the user. The variable passed to this function must remain in memory for the duration of the dialog box, that is from the DLGINIT call through the DLGUNINIT call.

The variable can be declared as global data in a module, as a variable with the STATIC attribute, or in a calling procedure that is active for the duration of the dialog box. It must not be an AUTOMATIC variable in the procedure that calls DLGMODELESS.

nCmdShow
(Input) Integer. Specifies how the dialog box is to be shown. It must be one of the following values:

Value | Description
SW_HIDE | Hides the dialog box.
SW_MINIMIZE | Minimizes the dialog box.
SW_RESTORE | Activates and displays the dialog box. If the dialog box is minimized or maximized, the Windows system restores it to its original size and position.
SW_SHOW | Activates the dialog box and displays it in its current size and position.
SW_SHOWMAXIMIZED | Activates the dialog box and displays it as a maximized window.
SW_SHOWMINIMIZED | Activates the dialog box and displays it as an icon.
SW_SHOWMINNOACTIVE | Displays the dialog box as an icon. The window that is currently active remains active.
SW_SHOWNA | Displays the dialog box in its current state. The window that is currently active remains active.
SW_SHOWNOACTIVATE | Displays the dialog box in its most recent size and position. The window that is currently active remains active.
SW_SHOWNORMAL | Activates and displays the dialog box. If the dialog box is minimized or maximized, the Windows system restores it to its original size and position.

The default value is SW_SHOWNORMAL.

hwndParent
(Input) Integer. Specifies the parent window for the dialog box. The default value is determined in this order:

  1. If DLGMODELESS is called from a callback of a modeless dialog box, then that dialog box is the parent window.
  2. The Windows desktop window is the parent window.

Results:

The result is of type LOGICAL(4). The value is .TRUE. if the function successfully displays the dialog box. Otherwise the result is .FALSE..

During execution, DLGMODELESS displays a modeless dialog box and returns control to the calling application. The dialog box remains active until DLGEXIT is called, either explicitly or as the result of the invocation of a default button callback.

DLGMODELESS is typically used in a Windows application. The application must contain a message loop that processes Windows messages. The message loop must call DLGISDLGMESSAGE for each message. See the example below. Multiple modeless dialog boxes can be displayed at the same time. A modal dialog box can be displayed from a modeless dialog box by calling DLGMODAL from a modeless dialog callback. However, DLGMODELESS cannot be called from a modal dialog box callback.

DLGMODELESS also can be used in a Console, DLL, or LIB project. However, the requirements remain that the application must contain a message loop and must call DLGISDLGMESSAGE for each message. For an example of calling DLGMODELESS in a DLL project, see the Dllprgrs sample in the ...\SAMPLES\DIALOG folder.

Use the DLG_INIT callback with DLGSETSUB to perform processing immediately after the dialog box is created and before it is displayed, and to perform processing immediately before the dialog box is destroyed.

Compatibility

WINDOWS CONSOLE DLL LIB

See Also: DLGSETSUB, DLGINIT, DLGEXIT, DLGISDLGMESSAGE, Using a Modeless Dialog Routine

Example

    use dflogm
    include 'resource.fd'
    type (DIALOG)	dlg
    type (T_MSG)    mesg
    integer*4	ret
    logical*4	lret
    ...
    ! Create the main dialog box and set up the controls and callbacks
    lret = DlgInit(IDD_THERM_DIALOG, dlg)
    lret = DlgSetSub(dlg, IDD_THERM_DIALOG, ThermSub)
    ...
    lret = DlgModeless(dlg, nCmdShow)
    ...
    ! Read and process messsages
    do while( GetMessage (mesg, NULL, 0, 0) )
       ! Note that DlgIsDlgMessage must be called in order to give
       ! the dialog box first chance at the message.
       if ( DlgIsDlgMessage(mesg) .EQV. .FALSE. ) then
         lret = TranslateMessage( mesg )
         ret  = DispatchMessage( mesg )
       end if
    end do
        ! Cleanup dialog box memory and exit the application
    call DlgUninit(dlg)
    WinMain = mesg%wParam
    return


DLGSENDCTRLMESSAGE

Run-Time Function: Sends a Windows message to a dialog box control.

Module: USE DFLOGM

Syntax

result = DLGSENDCTRLMESSAGE (dlg, controlid, msg, wparam, lparam)

dlg
(Input) Derived-type DIALOG. Contains dialog box parameters. The components of the type DIALOG are defined with the PRIVATE attribute, and cannot be changed or individually accessed by the user.

controlid
(Input) Integer. Specifies the identifier of the control within the dialog box. Can be either the symbolic name for the control or the identifier number, both listed in the Include file (with extension .FD).

msg
(Input) Integer. Derived type T_MSG. Specifies the message to be sent.

wparam
(Input) Integer. Specifies additional message specific information.

lparam
(Input) Integer. Specifies additional message specific information.

Results:

The result is of type INTEGER(4). The value specifies the result of the message processing and depends upon the message sent.

The dialog box must be currently active by a call to DLGMODAL or DLGMODELESS. This function does not return until the message has been processed by the control.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DLGINIT, DLGSETSUB, DLGMODAL, DLGMODELESS

Example

use dfwin
use dflogm
include 'resource.fd'
type (dialog)    dlg
integer          callbacktype
integer          cref
integer          iret

if (callbacktype == dlg_init) then
    ! Change the color of the Progress bar to red
    ! NOTE:  The following message succeeds only if Internet Explorer 4.0
    !        or later is installed
        cref = #FF	! Red
        iret = DlgSendCtrlMessage(dlg, IDC_PROGRESS1, PBM_SETBARCOLOR, 0, cref)
endif


DLGSET, DLGSETINT, DLGSETLOG, DLGSETCHAR

Run-Time Functions: Set the values of dialog control variables.

Module: USE DFLOGM

Syntax

result = DLGSET (dlg, controlid, value [, index])
result = DLGSETINT (dlg, controlid, value [, index])
result = DLGSETLOG (dlg, controlid, value [, index])
result = DLGSETCHAR (dlg, controlid, value [, index])

dlg
(Input) Derived-type DIALOG. Contains dialog box parameters. The components of the type DIALOG are defined with the PRIVATE attribute, and cannot be changed or individually accessed by the user.

controlid
(Input) Integer. Specifies the identifier of a control within the dialog box. Can be either the symbolic name for the control or the identifier number, both listed in the Include file (with extension .FD).

value
(Input) Integer, logical, or character. The value of the control's variable.

index
(Input; optional) Integer. Specifies the control variable whose value is set. Necessary if the control has more than one variable of the same data type and you do not want to set the value of the default for that type.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, the result is .FALSE..

Use the DLGSET functions to set the values of variables associated with your dialog box controls. Each control has at least one of the integer, logical, or character variables associated with it, but not necessarily all. The control variables are listed in the table in Control Indexes in the Programmer's Guide. The types of controls they are associated with are listed in the table in Available Indexes for Each Dialog Control in the Programmer's Guide.

You can use DLGSET to set any control variable. You can also use DLGSETINT to set an integer variable, or DLGSETLOG and DLGSETCHAR to set logical and character values, respectively. If you use DLGSET, you do not have to worry about matching the function to the variable type. If you use the wrong function type for a variable or try to set a variable type that is not available, the DLGSET functions return .FALSE..

Calling DLGSET does not cause a callback routine to be called for the changing value of a control. In particular, when inside a callback, performing a DLGSET on a control does not cause the associated callback for that control to be called. Callbacks are invoked automatically only by user action on the controls in the dialog box. If the callback routine needs to be called, you can call it manually after the DLGSET is executed.

If two or more controls have the same controlid, you cannot use these controls in a DLGSET operation. In this case the function returns .FALSE..

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DLGSETSUB, DLGGET, Using Dialogs, Dialog Functions, and Dialog Controls

Example

USE DFLOGM
INCLUDE "DLGRADAR.FD"
TYPE (DIALOG)  dlg
LOGICAL        retlog
...
retlog = DLGSET (dlg, IDC_SCROLLBAR1, 400, dlg_range)
retlog = DLGSET (dlg, IDC_CHECKBOX1, .FALSE., dlg_status)
retlog = DLGSET (dlg, IDC_RADIOBUTTON1, "Hot Button", dlg_title)
...


DLGSETCTRLEVENTHANDLER

Run-Time Function: Assigns user-written event handlers to ActiveX controls in a dialog box.

Module: USE DFLOGM

Syntax

result = DLGSETCTRLEVENTHANDLER (dlg, controlid, handler, dispid [, iid])

dlg
(Input) Derived type DIALOG. Contains dialog box parameters. The components of the type DIALOG are defined with the PRIVATE attribute, and cannot be changed or individually accessed by the user.

controlid
(Input) Integer. Specifies the identifier of a control within the dialog box. Can be the symbolic name for the control or the identifier number, both listed in the include (with extension .FD) file.

handler
(Input) Name of the routine to be called when the event occurs. It must be declared EXTERNAL.

dispid
(Input) Integer. Specifies the member id of the method in the event interface that identifies the event.

iid
(Input; optional) Derived type GUID, which is defined in the DFWINTY module. Specifies the interface identifier of the source (event) interface. If omitted, the default source interface of the ActiveX control is used.

Results:

The result is of type INTEGER(4). The result is an HRESULT describing the status of the operation.

When the ActiveX control event occurs, the handler associated with the event is called. You call DLGSETCTRLEVENTHANDLER to specify the handler to be called.

The events supported by an ActiveX control and the interfaces of the handlers are determined by the ActiveX control.

You can find this information in one of the following ways:

  • By reading the documentation of the ActiveX control.

  • By using a tool that lets you examine the type information of the ActiveX control, The OLE-COM Object Viewer in the Visual Fortran folder is one such tool.

  • By using the Fortran Module Wizard to generate a module that contains Fortran interfaces to the ActiveX control, and examining the generated module.

The handler that you define in your application must have the interface that the ActiveX control expects, including calling convention and parameter passing mechanisms. Otherwise, your application will likely crash in unexpected ways because of the application's stack getting corrupted.

Note that an object is always the first parameter in an event handler. This object value is a pointer to the control's source (event) interface, not the IDispatch pointer of the control. You can use DLGGET with the DLG_IDISPATCH index to retrieve the control's IDispatch pointer.

For more information, see Using ActiveX Controls in the Programmer's Guide.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DLGINIT, DLGGET, DLGMODAL, DLGMODELESS, DLGSETSUB

Example

ret = DlgSetCtrlEventHandler(  	   &
      dlg,                         &
      IDC_ACTIVEMOVIECONTROL1,     & ! Identifies the control
      ReadyStateChange,            & ! Name of the event handling routine
      -609,                        & ! Member id of the ActiveMovie's
                                   & !   control ReadyStateChange event.
      IID_DActiveMovieEvents2 )      ! Identifer of the source (event)
                                   !   interface.


DLGSETRETURN

Run-Time Subroutine: Sets the return value for the DLGMODAL function from within a callback subroutine.

Module: USE DFLOGM

Syntax

CALL DLGSETRETURN (dlg, retval)

dlg
(Input) Derived type DIALOG. Contains dialog box parameters. The components of the type DIALOG are defined with the PRIVATE attribute, and cannot be changed or individually accessed by the user.

retval
(Input) Integer. Specifies the return value for DLGMODAL upon exiting.

DLGSETRETURN overrides the default return value with retval. You can set your own value as a means of determining the condition under which the dialog box was closed. The default return value for an error condition is -1, so you should not use -1 as your return value.

DLGSETRETURN should be called from within a callback routine, and is generally used with DLGEXIT, which causes the dialog box to be exited from a control callback rather than the user selecting the OK or Cancel button.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DLGEXIT, DLGMODAL

Example

SUBROUTINE SETRETSUB (dlg, button_id, callbacktype)
USE DFLOGM
INCLUDE "MYDLG.FD"
TYPE (DIALOG) dlg
LOGICAL     is_checked, retlog
INTEGER     return, button_id, callbacktype
...
retlog = DLGGET(dlg, IDC_CHECKBOX4, is_checked, dlg_state)
IF (is_checked) THEN
   return = 999
ELSE
   return = -999
END IF
CALL DLGSETRETURN (dlg, return)
CALL DLGEXIT (dlg)
END SUBROUTINE SETRETSUB


DLGSETSUB

Run-Time Function: Assigns your own callback subroutines to dialog controls and to the dialog box.

Module: USE DFLOGM

Syntax

result = DLGSETSUB (dlg, controlid, value [, index])

dlg
(Input) Derived type DIALOG. Contains dialog box parameters. The components of the type DIALOG are defined with the PRIVATE attribute, and cannot be changed or individually accessed by the user.

controlid
(Input) Integer. Specifies the identifier of a control within the dialog box. Can be the symbolic name for the control or the identifier number, both listed in the include (with extension .FD) file, or it can be the identifier of the dialog box.

value
(Input) EXTERNAL. Name of the routine to be called when the callback event occurs.

index
(Input; optional) Integer. Specifies which callback routine is executed when the callback event occurs. Necessary if the control has more than one callback routine.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, the result is .FALSE..

When a callback event occurs (for example, when you select a check box), the callback routine associated with that callback event is called. You use DLGSETSUB to specify the subroutine to be called. All callback routines should have the following interface:

SUBROUTINE callbackname (dlg, control_id, callbacktype)
!DEC$ ATTRIBUTES DEFAULT :: callbackname

callbackname
Is the name of the callback routine.

dlg
Refers to the dialog box and allows the callback to change values of the dialog controls.

control_id
Is the name of the control that caused the callback.

callbacktype
Indicates what callback is occurring (for example, DLG_CLICKED, DLG_CHANGE, or DLG_DBLCLICK).

The control_id and callbacktype parameters let you write a single subroutine that can be used with multiple callbacks from more than one control. Typically, you do this for controls comprising a logical group. You can also associate more than one callback routine with the same control, but you must use then use index parameter to indicate which callback routine to use.

The control_id can also be the identifier of the dialog box. The dialog box supports two callbacktypes, DLG_INIT and DLG_SIZECHANGE. The DLG_INIT callback is executed immediately after the dialog box is created with callbacktype DLG_INIT, and immediately before the dialog box is destroyed with callbacktype DLG_DESTROY. DLG_SIZECHANGE is called when the size of a dialog is changed.

Callback routines for a control are called after the value of the control has been updated based on the user's action.

If two or more controls have the same controlid, you cannot use these controls in a DLGSETSUB operation. In this case, the function returns .FALSE..

For more information, see Dialog Callback Routines in the Programmer's Guide.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DLGSET, DLGGET

Example

PROGRAM DLGPROG
USE DFLOGM
INCLUDE "MYDLG.FD"
TYPE (dialog) mydialog
LOGICAL retlog
INTEGER return
EXTERNAL RADIOSUB
retlog = DLGINIT(IDD_mydlg, dlg)
retlog = DLGSETSUB (mydialog, IDC_RADIO_BUTTON1, RADIOSUB)
retlog = DLGSETSUB (mydialog, IDC_RADIO_BUTTON2, RADIOSUB)
return = DLGMODAL(dlg)
END
SUBROUTINE RADIOSUB( dlg, id, callbacktype )
!DEC$ ATTRIBUTES DEFAULT :: callbackname
  USE DFLOGM
  TYPE (dialog) dlg
  INTEGER id, callbacktype
  INCLUDE 'MYDLG.FD'
  CHARACTER(256) text
  INTEGER cel, far, retint
  LOGICAL retlog
  SELECT CASE (id)
    CASE (IDC_RADIO_BUTTON1)
    ! Radio button 1 selected by user so
    ! change text accordingly
      text = 'Statistics Package A'
      retlog = DLGSET( dlg, IDC_STATICTEXT1, text )
    CASE (IDC_RADIO_BUTTON2)
    ! Radio button 2 selected by user so
    ! change text accordingly
      text = 'Statistics Package B'
      retlog = DLGSET( dlg, IDC_STATICTEXT1, text )
  END SELECT
END SUBROUTINE RADIOSUB


DLGSETTITLE

Run-Time Subroutine: Sets the title of a dialog box.

Module: USE DFLOGM

Syntax

CALL DLGSETTITLE (dlg, title)

dlg
(Input) Derived type DIALOG. Contains dialog box parameters. The components of the type DIALOG are defined with the PRIVATE attribute, and cannot be changed or individually accessed by the user.

title
(Input) Character*(*). Specifies text to be the title of the dialog box.

Use this routine when you want to specify the title for a dialog box.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DLGINIT, DLGMODAL, DLGMODELESS

Example

USE DFLOGM
INCLUDE "MYDLG.FD"
TYPE (DIALOG) mydialog
LOGICAL retlog
...
retlog = DLGINIT(IDD_mydlg, mydialog)
...
CALL DLGSETTITLE(mydialog, "New Title")
...


DLGUNINIT

Run-Time Subroutine: Deallocates memory associated with an initialized dialog.

Module: USE DFLOGM

Syntax

CALL DLGUNINIT (dlg)

dlg
(Input) Derived type DIALOG. Contains dialog box parameters. The components of the type DIALOG are defined with the PRIVATE attribute, and cannot be changed or individually accessed by the user.

You should call DLGUNINIT when a dialog that was successfully initialized by DLGINIT is no longer needed. DLGUNINIT should only be called on a dialog initialized with DLGINIT. If it is called on an uninitialized dialog or one that has already been deallocated with DLGUNINIT, the result is undefined.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DLGINIT, DLGMODAL, DLGMODELESS, DLGEXIT

Example

USE DFLOGM
INCLUDE "MYDLG.FD"
TYPE (DIALOG)  mydialog
LOGICAL        retlog
...
retlog = DLGINIT(IDD_mydlg, mydialog)
...
CALL DLGUNINIT (mydialog)
END


DO

Statement: Marks the beginning of a DO construct. The DO construct controls the repeated execution of a block of statements or constructs. (This repeated execution is called a loop.)

A DO construct takes one of the following forms:

Syntax

Block Form:

[name:] DO [label[, ] ] [loop-control]
block
[label] term-stmt

Nonblock Form:

DO label[,] [loop-control]

name
(Optional) Is the name of the DO construct.

label
(Optional) Is a statement label identifying the terminal statement.

loop-control
Is a DO iteration (see Iteration Loop Control) or a DO WHILE statement.

block
Is a sequence of zero or more statements or constructs.

term-stmt
Is the terminal statement for the construct.

Rules and Behavior

A block DO construct is terminated by an END DO or CONTINUE statement. If the block DO statement contains a label, the terminal statement must be identified with the same label. If no label appears, the terminal statement must be an END DO statement.

If a construct name is specified in a block DO statement, the same name must appear in the terminal END DO statement. If no construct name is specified in the block DO statement, no name can appear in the terminal END DO statement.

A nonblock DO construct is terminated by an executable statement (or construct) that is identified by the label specified in the nonblock DO statement. A nonblock DO construct can share a terminal statement with another nonblock DO construct. A block DO construct cannot share a terminal statement.

The following cannot be terminal statements for nonblock DO constructs:

  • CONTINUE (allowed if it is a shared terminal statement)
  • CYCLE
  • END (for a program or subprogram)
  • EXIT
  • GO TO (unconditional or assigned)
  • Arithmetic IF
  • RETURN
  • STOP

The nonblock DO construct is an obsolescent feature in Fortran 95 and Fortran 90.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: CONTINUE, CYCLE, EXIT, DO WHILE, Execution Control, DO Constructs

Examples

The following example shows a simple block DO construct (contains no iteration count or DO WHILE statement):

  DO
    READ *, N
    IF (N == 0) STOP
    CALL SUBN
  END DO

The DO block executes repeatedly until the value of zero is read. Then the DO construct terminates.

The following example shows a named block DO construct:

  LOOP_1: DO I = 1, N
            A(I) = C * B(I)
          END DO LOOP_1

The following example shows a nonblock DO construct with a shared terminal statement:

     DO 20 I = 1, N
     DO 20 J = 1 + I, N
  20 RESULT(I,J) = 1.0 / REAL(I + J)

The following two program fragments are also examples of DO statements:

  C   Initialize the even elements of a 20-element real array
  C
      DIMENSION array(20)
      DO j = 2, 20, 2
        array(j) = 12.0
      END DO
  C
  C   Perform a function 11 times
  C
      DO k = -30, -60, -3
        int = j / 3
        isb = -9 - k
        array(isb) = MyFunc (int)
      END DO

The following shows the final value of a DO variable (in this case 11):

    DO j = 1, 10
      WRITE (*, '(I5)') j
    END DO
    WRITE (*, '(I5)') j


DO Directive (TU*X only)

OpenMP Parallel Compiler Directive: Specifies that the iterations of the immediately following DO loop must be executed in parallel.

Syntax

c$OMP DO [clause[[,] clause] ... ]
do_loop
[c$OMP END DO [NOWAIT]]

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

clause
Is one of the following:

  • FIRSTPRIVATE (list)

  • LASTPRIVATE (list)

  • ORDERED

    Must be used if ordered sections are contained in the dynamic extent of the DO directive. For more information about ordered sections, see the ORDERED directive.

  • PRIVATE (list)

  • REDUCTION( operator | intrinsic : list)

  • SCHEDULE (type[, chunk])

    Specifies how iterations of the DO loop are divided among the threads of the team. chunk must be a scalar integer expression. The following four types are permitted, three of which allow the optional parameter chunk:

    Type | Effect
    STATIC Divides iterations into contiguous pieces by dividing the number of iterations by the number of threads in the team. Each piece is then dispatched to a thread before loop execution begins.

    If chunk is specified, iterations are divided into pieces of a size specified by chunk. The pieces are statically dispatched to threads in the team in a round-robin fashion in the order of the thread number.
    DYNAMIC Can be used to get a set of iterations dynamically. It defaults to 1 unless chunk is specified.

    If chunk is specified, the iterations are broken into pieces of a size specified by chunk. As each thread finishes a piece of the iteration space, it dynamically gets the next set of iterations.
    GUIDED Can be used to specify a minimum number of iterations. It defaults to 1 unless chunk is specified.

    If chunk is specified, the chunksize is reduced exponentially with each succeeding dispatch. The chunk specifies the minimum number of iterations to dispatch each time. If there are less than chunk iterations remaining, the rest are dispatched.
    RUNTIME1 | Defers the scheduling decision until run time. You can choose a schedule type and chunksize at run time by using the environment variable OMP_SCHEDULE.
    1 No chunk is permitted for this type.

    If the SCHEDULE clause is not used, the default schedule type is STATIC.

do_loop
Is a DO iteration (an iterative DO loop). It cannot be a DO WHILE or a DO loop without loop control. The DO loop iteration variable must be of type integer.

The iterations of the DO loop are distributed across the existing team of threads. The values of the loop control parameters of the DO loop associated with a DO directive must be the same for all the threads in the team.

You cannot branch out of a DO loop associated with a DO directive.

Rules and Behavior

If used, the END DO directive must appear immediately after the end of the loop. If you do not specify an END DO directive, an END DO directive is assumed at the end of the DO loop.

If you specify NOWAIT in the END DO directive, threads do not synchronize at the end of the parallel loop. Threads that finish early proceed straight to the instruction following the loop without waiting for the other members of the team to finish the DO directive.

Parallel DO loop control variables are block-level entities within the DO loop. If the loop control variable also appears in the LASTPRIVATE list of the parallel DO, it is copied out to a variable of the same name in the enclosing PARALLEL region. The variable in the enclosing PARALLEL region must be SHARED if it is specified in the LASTPRIVATE list of a DO directive.

Only a single SCHEDULE clause and ORDERED clause can appear in a DO directive.

DO directives must be encountered by all threads in a team or by none at all. It must also be encountered in the same order by all threads in a team.

See Also: Parallel Directives for Tru64 UNIX Systems, OpenMP Fortran API Compiler Directives (TU*X only), Compaq Fortran Parallel Compiler Directives (TU*X only)

Examples

In the following example, the loop iteration variable is private by default, and it is not necessary to explicitly declare it. The END DO directive is optional:

  c$OMP PARALLEL
  c$OMP DO
        DO I=1,N
          B(I) = (A(I) + A(I-1)) / 2.0
        END DO
  c$OMP END DO
  c$OMP END PARALLEL

If there are multiple independent loops within a parallel region, you can use the NOWAIT keyword to avoid the implied BARRIER at the end of the DO directive, as follows:

  c$OMP PARALLEL
  c$OMP DO
        DO I=2,N
          B(I) = (A(I) + A(I-1)) / 2.0
        END DO
  c$OMP END DO NOWAIT
  c$OMP DO
        DO I=1,M
          Y(I) = SQRT(Z(I))
        END DO
  c$OMP END DO NOWAIT
  c$OMP END PARALLEL

Correct execution sometimes depends on the value that the last iteration of a loop assigns to a variable. Such programs must list all such variables as arguments to a LASTPRIVATE clause so that the values of the variables are the same as when the loop is executed sequentially, as follows:

  c$OMP PARALLEL
  c$OMP DO LASTPRIVATE(I)
        DO I=1,N
          A(I) = B(I) + C(I)
        END DO
  c$OMP END PARALLEL
        CALL REVERSE(I)

In this case, the value of I at the end of the parallel region equals N+1, as in the sequential case.

Ordered sections are useful for sequentially ordering the output from work that is done in parallel. Assuming that a reentrant I/O library exists, the following program prints out the indexes in sequential order:

  c$OMP DO ORDERED SCHEDULE(DYNAMIC)
        DO I=LB,UB,ST
          CALL WORK(I)
        END DO
        ...
        SUBROUTINE WORK(K)
  c$OMP ORDERED
        WRITE(*,*) K
  c$OMP END ORDERED


DO WHILE

Statement: Executes the range of a DO construct while a specified condition remains true.

Syntax

DO [label[, ] ] WHILE (expr)

label
(Optional) Is a label specifying an executable statement in the same program unit.

expr
Is a scalar logical (test) expression enclosed in parentheses.

Rules and Behavior

Before each execution of the DO range, the logical expression is evaluated. If it is true, the statements in the body of the loop are executed. If it is false, the DO construct terminates and control transfers to the statement following the loop.

If no label appears in a DO WHILE statement, the DO WHILE loop must be terminated with an END DO statement.

You can transfer control out of a DO WHILE loop but not into a loop from elsewhere in the program.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB

See Also: CONTINUE, CYCLE, EXIT, DO, Execution Control, DO Constructs

Examples

The following example shows a DO WHILE statement:

  CHARACTER*132 LINE
  ...
  I = 1
  DO WHILE (LINE(I:I) .EQ. ' ')
    I = I + 1
  END DO

The following examples show required and optional END DO statements:

  Required                 Optional
  DO WHILE (I .GT. J)         DO 10 WHILE (I .GT. J)
    ARRAY(I,J) = 1.0            ARRAY(I,J) = 1.0
    I = I - 1                   I = I - 1
  END DO                   10 END DO

The following shows another example:

  CHARACTER(1) input
  input = ' '
  DO WHILE ((input .NE. 'n') .AND. (input .NE. 'y'))
     WRITE (*, '(A)') 'Enter y or n: '
     READ (*, '(A)') input
  END DO


DOT_PRODUCT

Transformational Intrinsic Function (Generic): Performs dot-product multiplication of numeric or logical vectors (rank-one arrays).

Syntax

result = DOT_PRODUCT (vector_a, vector_b)

vector_a
(Input) Must be a rank-one array of numeric (integer, real, or complex) or logical type.

vector_b
(Input) Must be a rank-one array of numeric type if vector_a is of numeric type, or of logical type if vector_a is of logical type. It must be the same size as vector_a.

Results:

The result is a scalar whose type depends on the types of vector_a and vector_b.

If vector_a is of type integer or real, the result value is SUM (vector_a*vector_b).

If vector_a is of type complex, the result value is SUM (CONJG (vector_a)*vector_b).

If vector_a is of type logical, the result has the value ANY (vector_a .AND. vector_b).

If either rank-one array has size zero, the result is zero if the array is of numeric type, and false if the array is of logical type.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: PRODUCT, MATMUL, TRANSPOSE

Examples

DOT_PRODUCT ((/1, 2, 3/), (/3, 4, 5/)) has the value 26 (calculated as follows: ((1 x 3) + (2 x 4) + (3 x 5)) = 26 ).

DOT_PRODUCT ((/ (1.0, 2.0), (2.0, 3.0) /), (/ (1.0, 1.0), (1.0, 4.0) /)) has the value (17.0, 4.0).

DOT_PRODUCT ((/ .TRUE., .FALSE. /), (/ .FALSE., .TRUE. /)) has the value false.

The following shows another example:

  I = DOT_PRODUCT((/1,2,3/), (/4,5,6/)) ! returns
                                        !  the value 32


DOUBLE COMPLEX

Statement: Specifies the DOUBLE COMPLEX data type.

A COMPLEX(8) or DOUBLE COMPLEX constant is a pair of constants that represents a complex number. One of the pair must be a double-precision real constant, the other can be an integer, single-precision real, or double-precision real constant.

A COMPLEX(8) or DOUBLE COMPLEX constant occupies 16 bytes of memory and is interpreted as a complex number.

The rules for DOUBLE PRECISION (REAL(8)) constants also apply to the double precision portion of COMPLEX(KIND=8) or DOUBLE COMPLEX constants. (See REAL and DOUBLE PRECISION for more information.)

The DOUBLE PRECISION constants in a COMPLEX(8) or DOUBLE COMPLEX constant have IEEE® T_floating format.

For more information, see General Rules for Complex Constants.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB

See Also: COMPLEX, Complex Data Types, DOUBLE PRECISION, REAL

Examples

DOUBLE COMPLEX vector, arrays(7,29)
DOUBLE COMPLEX pi, pi2 /3.141592654,6.283185308/

The following examples demonstrate valid and invalid COMPLEX(KIND=8) or DOUBLE COMPLEX constants:

Valid |
(1.7039,-1.7039D0) |
(547.3E0_8,-1.44_8) |
(1.7039E0,-1.7039D0) |
(+12739D3,0.D0) |
Invalid | Explanation
(1.23D0,) | Second constant missing.
(1D1,2H12) | Hollerith constants not allowed.
(1,1.2) | Neither constant is DOUBLE PRECISION; this is a valid single-precision real constant.


DOUBLE PRECISION

A REAL(8) or DOUBLE PRECISION constant has more than twice the accuracy of a REAL(4) number, and greater range.

A REAL(8) or DOUBLE PRECISION constant occupies eight bytes of memory. The number of digits that precede the exponent is unlimited, but typically only the leftmost 15 digits are significant.

IEEE® T_floating format is used.

For more information, see General Rules for Real Constants.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: REAL, REAL(8) or DOUBLE PRECISION Constants, Data Types, Constants, and Variables

Examples

DOUBLE PRECISION varnam
DOUBLE PRECISION,PRIVATE :: zz

The following examples show valid and invalid REAL(8) or DOUBLE PRECISION constants:

Valid |
123456789D+5 |
123456789E+5_8 |
+2.7843D00 |
-.522D-12 |
2E200_8 |
2.3_8 |
3.4E7_8 |
Invalid | Explanation
-.25D0_2 | 2 is not a valid kind type for reals.
+2.7182812846182 | No D exponent designator is present; this is a valid single-precision constant.
1234567890D45 | Too large for D_floating format; valid for G_floating and T_floating format.
123456789.D400 | Too large for any double-precision format.
123456789.D-400 | Too small for any double-precision format.


DPROD

Elemental Intrinsic Function (Specific): Produces a higher precision product. This is a specific function that has no generic function associated with it. It must not be passed as an actual argument.

Syntax

result = DPROD (x, y)

x
(Input) Must be of type REAL(4) or REAL(8).

y
(Input) Must have the same type and kind parameters as x.

Results:

If x and y are of type REAL(4), the result type is double precision real. If x and y are of type REAL(8), the result type is REAL(16). The result value is equal to x * y.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Examples

DPROD (2.0, -4.0) has the value -8.00D0.

DPROD (5.0D0, 3.0D0) has the value 15.00Q0.

The following shows another example:

  REAL(4) e
  REAL(8) d
  e = 123456.7
  d = 123456.7D0
  ! DPROD (e,e) returns 15241557546.4944
  ! DPROD (d,d) returns 15241556774.8899992813874268904328


DRAND, DRANDM

Portability Functions: Return double-precision random numbers in the range 0.0 through 1.0.

Module: USE DFPORT

Syntax

result = DRAND (iflag)
result = DRANDM (iflag)

iflag
(Input) INTEGER(4). Controls the way the random number is selected.

Results:

The result is of type REAL(8). Return values are:

Value of iflag | Selection process
1 | The generator is restarted and the first random value is selected.
0 | The next random number in the sequence is selected.
Otherwise | The generator is reseeded using iflag, then restarted, and the first random value is selected.

There is no difference between DRAND and DRANDM. Both functions are included to insure portability of existing code that references one or both of them.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RANDOM_NUMBER, RANDOM_SEED

Example

USE DFPORT
REAL(8) num
INTEGER(4) f
f=1
CALL print_rand
f=0
CALL print_rand
f=22
CALL print_rand
CONTAINS
SUBROUTINE print_rand
num = drand(f)
print *, 'f= ',f,':',num
END SUBROUTINE
END


DREAL

Elemental Intrinsic Function (Specific): Converts the real part of a double complex argument to double precision type. This is a specific function that has no generic function associated with it. It must not be passed as an actual argument.

Syntax

result = DREAL (a)

a
(Input) Must be of type double complex (COMPLEX(8) or COMPLEX*16).

Results:

The result type is double precision real (REAL(8) or REAL*8).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: REAL

Examples

DREAL ((2.0d0, 3.0d0)) has the value 2.0d0.


DTIME (WNT only)

Portability Function: Returns the elapsed CPU time since the start of program execution when first called, and the elapsed execution time since the last call to DTIME thereafter. This function is currently restricted to WNT systems.

Module: USE DFPORT

Syntax

result = DTIME (tarray)

tarray
(Output) REAL(4). Must be a rank one array with two elements:

  • tarray(1) Elapsed user time, which is time spent executing user code. This value includes time running protected Windows subsystem code.

  • tarray(2) Elapsed system time, which is time spent executing privileged code (code in the Windows Executive).

Results:

The result type is REAL(4). The result is the total CPU time, which is the sum of tarray(1) and tarray(2).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE_AND_TIME

Example

 REAL(4) I, TA(2)
 I = DTIME(TA)
 write(*,*) 'Program has been running for', I, 'seconds.'
 write(*,*) ' This includes', TA(1), 'seconds of user time and', &
& TA(2), 'seconds of system time.'


ELEMENTAL

Keyword: Asserts that a user-defined procedure is a restricted form of pure procedure. This is a Fortran 95 feature.

To specify an elemental procedure, use this keyword in a FUNCTION or SUBROUTINE statement.

An explicit interface must be visible to the caller of an ELEMENTAL procedure.

An elemental procedure can be passed an array, which is acted upon one element at a time.

For functions, the result must be scalar; it cannot have the POINTER attribute.

Dummy arguments have the following restrictions:

  • They must be scalar.
  • They cannot have the POINTER attribute.
  • They (or their subobjects) cannot appear in a specification expression except as an argument to one of the intrinsic functions BIT_SIZE, LEN, KIND, or the numeric inquiry functions.
  • They cannot be *.
  • They cannot be dummy procedures.

If the actual arguments are all scalar, the result is scalar. If the actual arguments are array valued, the values of the elements (if any) of the result are the same as if the function or subroutine had been applied separately, in any order, to corresponding elements of each array actual argument.

Elemental procedures are pure procedures and all rules that apply to pure procedures also apply to elemental procedures.

See Also: FUNCTION, SUBROUTINE, Determining When Procedures Require Explicit Interfaces, Optional Arguments

Examples

Consider the following:

  MIN (A, 0, B)             ! A and B are arrays of shape (S, T)

In this case, the elemental reference to the MIN intrinsic function is an array expression whose elements have the following values:

  MIN (A(I,J), 0, B(I,J)), I = 1, 2, ..., S, J = 1, 2, ..., T


ELLIPSE, ELLIPSE_W

Graphics Function: Draws a circle or an ellipse using the current graphics color.

Module: USE DFLIB

Syntax

result = ELLIPSE (control, x1, y1, x2, y2)
result = ELLIPSE_W (control, wx1, wy1, wx2, wy2)

control
(Input) INTEGER(2). Fill flag. Can be one of the following symbolic constants:

  • $GFILLINTERIOR - Fills the figure using the current color and fill mask.
  • $GBORDER - Does not fill the figure.

x1, y1
(Input) INTEGER(2). Viewport coordinates for upper-left corner of bounding rectangle.

x2, y2
(Input) INTEGER(2). Viewport coordinates for lower-right corner of bounding rectangle.

wx1, wy1
(Input) REAL(8). Window coordinates for upper-left corner of bounding rectangle.

wx2, wy2
(Input) REAL(8). Window coordinates for lower-right corner of bounding rectangle.

Results:

The result is of type INTEGER(2). The result is nonzero if successful; otherwise, 0. If the ellipse is clipped or partially out of bounds, the ellipse is considered successfully drawn, and the return is 1. If the ellipse is drawn completely out of bounds, the return is 0.

The border is drawn in the current color and line style.

When you use ELLIPSE, the center of the ellipse is the center of the bounding rectangle defined by the viewport-coordinate points (x1, y1) and (x2, y2). When you use ELLIPSE_W, the center of the ellipse is the center of the bounding rectangle defined by the window-coordinate points (wx1, wy1) and (wx2, wy2). If the bounding-rectangle arguments define a point or a vertical or horizontal line, no figure is drawn.

The control option given by $GFILLINTERIOR is equivalent to a subsequent call to the FLOODFILLRGB function using the center of the ellipse as the start point and the current color (set by SETCOLORRGB) as the boundary color.

Note: The ELLIPSE routine described here is a QuickWin routine. If you are trying to use the Win32 SDK version of the Ellipse routine by including the DFWIN module, you need to specify the routine name as MSFWIN$Ellipse. For more information, see Special Naming Convention for Certain QuickWin and Win32 Graphics Routines in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: ARC, FLOODFILLRGB, GRSTATUS, LINETO, PIE, POLYGON, RECTANGLE, SETCOLORRGB, SETFILLMASK

Example

This program draws the shape shown below.

! compile as QuickWin or Standard Graphics application
 USE DFLIB
 INTEGER(2) dummy, x1, y1, x2, y2
 x1 = 80;  y1 = 50
 x2 = 240; y2 = 150
 dummy = ELLIPSE( $GFILLINTERIOR, x1, y1, x2, y2 )
 END

Figure: Output of Program ELLIPSE.FOR


ELSE

See the IF Construct.


ELSE Directive

See the IF Directive Construct.


ELSEIF Directive

See the IF Directive Construct.


ELSE IF

See the IF Construct.


ELSEWHERE

Statement: Marks the beginning of an ELSEWHERE block within a WHERE construct.

Syntax

[name:] WHERE (mask-expr1)
[where-body-stmt] ...
[ELSEWHERE (mask-expr2) [name]
[where-body-stmt] ...]
[ELSEWHERE [name]
[where-body-stmt] ...]
END WHERE [name]

name
Is the name of the WHERE construct.

mask-expr1, mask-expr2
Are logical array expressions (called mask expressions).

where-body-stmt
Is one of the following:

  • An assignment statement of the form: array variable = array expression.

    The assignment can be a defined assignment only if the routine implementing the defined assignment is elemental.

  • A WHERE statement or construct

Rules and Behavior

Every assignment statement following the ELSEWHERE is executed as if it were a WHERE statement with ".NOT. mask-expr1". If ELSEWHERE specifies "mask-expr2", it is executed as "(.NOT. mask-expr1) .AND. mask-expr2" during the processing of the ELSEWHERE statement.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: WHERE

Example

WHERE (pressure <= 1.0)
  pressure = pressure + inc_pressure
  temp = temp - 5.0
ELSEWHERE
  raining = .TRUE.
END WHERE

The variables temp, pressure, and raining are all arrays.


ENCODE

Statement: Translates data from internal (binary) form to character form. It is comparable to using internal files in formatted sequential WRITE statements.

Syntax

ENCODE (c, f, b [, IOSTAT=i-var] [, ERR=label]) [io-list]

c
Is a scalar integer expression. It is the number of characters to be translated to internal form.

f
Is a format identifier. An error occurs if more than one record is specified.

b
Is a scalar or array reference. If b is an array reference, its elements are processed in the order of subscript progression.
b contains the characters to be translated to internal form.

i-var
Is a scalar integer variable that is defined as a positive integer if an error occurs and as zero if no error occurs.

label
Is the label of an executable statement that receives control if an error occurs.

io-list
Is an I/O list. An I/O list is either an implied-do list or a simple list of variables (except for assumed-size arrays). The list contains the data to be translated to character form.

The interaction between the format specifier and the I/O list is the same as for a formatted I/O statement.

Rules and Behavior

The number of characters that the ENCODE statement can translate depends on the data type of b. For example, an INTEGER(2) array can contain two characters per element, so that the maximum number of characters is twice the number of elements in that array.

The maximum number of characters a character variable or character array element can contain is the length of the character variable or character array element.

The maximum number of characters a character array can contain is the length of each element multiplied by the number of elements.

See Also: READ, WRITE, DECODE

Examples

Consider the following:

     DIMENSION K(3)
     CHARACTER*12 A,B
     DATA A/'123456789012'/
     ENCODE(12,100,A) K
100  FORMAT(3I4)
     ENCODE(12,100,B) K(3), K(2), K(1)

The 12 characters are stored in array K:

K(1) = 1234
K(2) = 5678
K(3) = 9012

The ENCODE statement translates the values K(3), K(2), and K(1) to character form and stores the characters in the character variable B.:

B = '901256781234'


END

Statement: Marks the end of a program unit. It takes one of the following forms:

Syntax

END [PROGRAM [program-name]]
END [FUNCTION [function-name]]
END [SUBROUTINE [subroutine-name]]
END [MODULE [module-name]]
END [BLOCK DATA [block-data-name]]

For internal procedures and module procedures, you must specify the FUNCTION and SUBROUTINE keywords in the END statement; otherwise, the keywords are optional.

In main programs, function subprograms, and subroutine subprograms, END statements are executable and can be branch target statements. If control reaches the END statement in these program units, the following occurs:

  • In a main program, execution of the program terminates.
  • In a function or subroutine subprogram, a RETURN statement is implicitly executed.

The END statement cannot be continued in a program unit, and no other statement in the program unit can have an initial line that appears to be the program unit END statement.

The END statements in a module or block data program unit are nonexecutable.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Program Units and Procedures, Branch Statements

Example

C   An END statement must be the last statement in a program
C   unit:
    PROGRAM MyProg
    WRITE (*, '("Hello, world!")')
    END
C
C   An example of a named subroutine
C
    SUBROUTINE EXT1 (X,Y,Z)
      Real, Dimension (100,100) :: X, Y, Z
    END SUBROUTINE EXT1


END DO

Statement: Marks the end of a DO or DO WHILE loop.

Syntax

END DO

Rules and Behavior

There must be a matching END DO statement for every DO or DO WHILE statement that does not contain a label reference.

An END DO statement can terminate only one DO or DO WHILE statement. If you name the DO or DO WHILE statement, the END DO statement can specify the same name.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DO, DO WHILE, CONTINUE

Example

The following examples both produce the same output:

  DO ivar = 1, 10
    PRINT ivar
  END DO
  ivar = 0

do2: DO WHILE (ivar .LT. 10)
        ivar = ivar + 1
        PRINT ivar
     END DO do2


ENDIF Directive

See the IF Directive Construct.


END IF

See the IF Construct.


ENDFILE

Statement: For sequential files, writes an end-of-file record to the file and positions the file after this record (the terminal point). For direct access files, truncates the file after the current record.

It can have either of the following forms:

Syntax

ENDFILE ([UNIT=]io-unit [, ERR=label] [, IOSTAT=i-var])
ENDFILE io-unit

io-unit
(Input) Is an external unit specifier.

label
Is the label of the branch target statement that receives control if an error occurs.

i-var
(Output) Is a scalar integer variable that is defined as a positive integer if an error occurs and zero if no error occurs.

Rules and Behavior

If the unit specified in the ENDFILE statement is not open, the default file is opened for unformatted output.

An end-of-file record can be written only to files with sequential organization that are accessed as formatted-sequential or unformatted-segmented sequential files. An ENDFILE performed on a direct access file always truncates the file.

End-of-file records should not be written in files that are read by programs written in a language other than Fortran.

Note: If you use the /vms compiler option and an ENDFILE is performed on a sequential unit, an actual one byte record containing a Ctrl/Z is written to the file. If this option is not specified, an internal ENDFILE flag is set and the file is truncated. The option does not affect ENDFILE on relative files; such files are truncated.

If a parameter of the ENDFILE statement is an expression that calls a function, that function must not cause an I/O statement or the EOF intrinsic function to be executed, because unpredictable results can occur.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BACKSPACE, REWIND, Data Transfer I/O Statements, Branch Specifiers

Examples

The following statement writes an end-of-file record to I/O unit 2:

  ENDFILE 2

Suppose the following statement is specified:

  ENDFILE (UNIT=9, IOSTAT=IOS, ERR=10)

An end-of-file record is written to the file connected to unit 9. If an error occurs, control is transferred to the statement labeled 10, and a positive integer is stored in variable IOS.

The following shows another example:

  WRITE (6, *) x
  ENDFILE 6
  REWIND 6
  READ (6, *) y


END FORALL

Statement: Marks the end of a FORALL construct. For more information, see FORALL.


END INTERFACE

Statement: Marks the end of an INTERFACE block. For more information, see INTERFACE.


END WHERE

Statement: Marks the end of a WHERE block. For more information, see WHERE.

Example

  WHERE (pressure <= 1.0)
    pressure = pressure + inc_pressure
    temp = temp - 5.0
  ELSEWHERE
    raining = .TRUE.
  END WHERE

Note that the variables temp, pressure, and raining are all arrays.


ENTRY

Statement: Provides one or more entry points within a subprogram. It is not executable and must precede any CONTAINS statement (if any) within the subprogram.

Syntax

ENTRY name [ ( [d-arg [, d-arg ] ...] ) [RESULT (r-name)] ]

name
Is the name of an entry point. If RESULT is specified, this entry name must not appear in any specification statement in the scoping unit of the function subprogram.

d-arg
(Optional) Is a dummy argument. The dummy argument can be an alternate return indicator (*) if the ENTRY statement is within a subroutine subprogram.

r-name
(Optional) Is the name of a function result. This name must not be the same as the name of the entry point, or the name of any other function or function result. This parameter can only be specified for function subprograms.

Rules and Behavior

ENTRY statements can only appear in external procedures or module procedures.

An ENTRY statement must not appear in a CASE, DO, IF, FORALL, or WHERE construct, or a nonblock DO loop.

When the ENTRY statement appears in a subroutine subprogram, it is referenced by a CALL statement. When the ENTRY statement appears in a function subprogram, it is referenced by a function reference.

An entry name within a function subprogram can appear in a type declaration statement.

Within the subprogram containing the ENTRY statement, the entry name must not appear as a dummy argument in the FUNCTION or SUBROUTINE statement, and it must not appear in an EXTERNAL or INTRINSIC statement. For example, neither of the following are valid:

(1)  SUBROUTINE SUB(E)
     ENTRY E
     ...

(2)  SUBROUTINE SUB
     EXTERNAL E
     ENTRY E
     ...

An ENTRY statement can reference itself if the function or subroutine subprogram was defined as RECURSIVE.

Dummy arguments can be used in ENTRY statements even if they differ in order, number, type and kind parameters, and name from the dummy arguments used in the FUNCTION, SUBROUTINE, and other ENTRY statements in the same subprogram. However, each reference to a function, subroutine, or entry must use an actual argument list that agrees in order, number, and type with the dummy argument list in the corresponding FUNCTION, SUBROUTINE, or ENTRY statement.

Dummy arguments can be referred to only in executable statements that follow the first SUBROUTINE, FUNCTION, or ENTRY statement in which the dummy argument is specified. If a dummy argument is not currently associated with an actual argument, the dummy argument is undefined and cannot be referenced. Arguments do not retain their association from one reference of a subprogram to another.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Program Units and Procedures, ENTRY Statements in Function Subprograms, ENTRY Statements in Subroutine Subprograms

Example

C  This fragment writes a message indicating
C  whether num is positive or negative
   IF (num .GE. 0) THEN
     CALL Sign
   ELSE
     CALL Negative
   END IF
   ...
   END

SUBROUTINE Sign
   WRITE (*, *) 'It''s positive.'
   RETURN
   ENTRY Negative
   WRITE (*, *) 'It''s negative.'
   RETURN
END SUBROUTINE


EOF

Inquiry Intrinsic Function (Specific): Checks whether a file is at or beyond the end-of-file record. This is a specific function that has no generic function associated with it. It must not be passed as an actual argument.

Syntax

result = EOF (a)

a
(Input) Must be of type integer. It represents a unit specifier corresponding to an open file. It cannot be zero unless you have reconnected unit zero to a unit other than the screen or keyboard.

Results:

The result is of type logical. The value of the result is .TRUE. if the file connected to a is at or beyond the end-of-file record; otherwise, .FALSE..

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ENDFILE, BACKSPACE, REWIND

Example

!  Creates a file of random numbers, reads them back
       REAL x, total
       INTEGER count
       OPEN (1, FILE = 'TEST.DAT')
       DO I = 1, 20
         CALL RANDOM_NUMBER(x)
         WRITE (1, '(F6.3)') x * 100.0
       END DO
       CLOSE(1)
       OPEN (1, FILE = 'TEST.DAT')
       DO WHILE (.NOT. EOF(1))
         count = count + 1
         READ (1, *) value
         total = total + value
       END DO
100    IF ( count .GT. 0) THEN
         WRITE (*,*) 'Average is: ', total / count
       ELSE
         WRITE (*,*) 'Input file is empty '
       END IF
    STOP
       END


EOSHIFT

Transformational Intrinsic Function (Generic): Performs an end-off shift on a rank-one array, or performs end-off shifts on all the complete rank-one sections along a given dimension of an array of rank two or greater.

Elements are shifted off at one end of a section and copies of a boundary value are filled in at the other end. Different sections can have different boundary values and can be shifted by different amounts and in different directions.

Syntax

result = EOSHIFT (array, shift [, boundary][, dim])

array
(Input) Must be an array (of any data type).

shift
(Input) Must be a scalar integer or an array with a rank that is one less than array, and shape (d1, d2, ..., ddim-1, ddim+1, ..., dn), where (d1, d2, ..., dn) is the shape of array.

boundary
(Optional; input) Must have the same type and kind parameters as array. It must be a scalar or an array with a rank that is one less than array, and shape (d1, d2, ..., ddim-1, ddim+1, ..., dn). The boundary specifies a value to replace spaces left by the shifting procedure.

If boundary is not specified, it is assumed to have the following default values (depending on the data type of array):

  array Type        boundary Value
  Integer           0
  Real              0.0
  Complex           (0.0, 0.0)
  Logical           false
  Character(len)    len blanks
dim
(Optional; input) Must be a scalar integer with a value in the range 1 to n, where n is the rank of array. If dim is omitted, it is assumed to be 1.

Results:

The result is an array with the same type and kind parameters, and shape as array.

If array has rank one, the same shift is applied to each element. If an element is shifted off one end of the array, the boundary value is placed at the other end the array.

If array has rank greater than one, each section (s1, s2, ..., sdim-1, :, sdim+1, ..., sn) of the result is shifted as follows:

  • By the value of shift, if shift is scalar

  • According to the corresponding value in shift(s1, s2, ..., sdim-1, sdim+1, ..., sn), if shift is an array

If an element is shifted off one end of a section, the boundary value is placed at the other end of the section.

The value of shift determines the amount and direction of the end- off shift. A positive shift value causes a shift to the left (in rows) or up (in columns). A negative shift value causes a shift to the right (in rows) or down (in columns).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: CSHIFT, ISHFT, ISHFTC, TRANSPOSE

Examples

V is the array (1, 2, 3, 4, 5, 6).

EOSHIFT (V, SHIFT=2) shifts the elements in V to the left by 2 positions, producing the value (3, 4, 5, 6, 0, 0). 1 and 2 are shifted off the beginning and two elements with the default BOUNDARY value are placed at the end.

EOSHIFT (V, SHIFT= -3, BOUNDARY= 99) shifts the elements in V to the right by 3 positions, producing the value (99, 99, 99, 1, 2, 3). 4, 5, and 6 are shifted off the end and three elements with BOUNDARY value 99 are placed at the beginning.

M is the array

  [ 1  2  3 ]
  [ 4  5  6 ]
  [ 7  8  9 ].
EOSHIFT (M, SHIFT = 1, BOUNDARY = '*', DIM = 2) produces the result
  [ 2  3  * ]
  [ 5  6  * ]
  [ 8  9  * ].

Each element in rows 1, 2, and 3 is shifted to the left by 1 position. This causes the first element in each row to be shifted off the beginning, and the BOUNDARY value to be placed at the end.

EOSHIFT (M, SHIFT = -1, DIM = 1) produces the result

  [ 0  0  0 ]
  [ 1  2  3 ]
  [ 4  5  6 ].

Each element in columns 1, 2, and 3 is shifted down by 1 position. This causes the last element in each column to be shifted off the end and the BOUNDARY value to be placed at the beginning.

EOSHIFT (M, SHIFT = (/1, -1, 0/), BOUNDARY = (/ '*', '?', '/' /), DIM = 2) produces the result

  [ 2  3  * ]
  [ ?  4  5 ]
  [ 7  8  9 ].

Each element in row 1 is shifted to the left by 1 position, causing the first element to be shifted off the beginning and the BOUNDARY value * to be placed at the end. Each element in row 2 is shifted to the right by 1 position, causing the last element to be shifted off the end and the BOUNDARY value ? to be placed at the beginning. No element in row 3 is shifted at all, so the specified BOUNDARY value is not used.

The following is another example:

INTEGER shift(3)
CHARACTER(1) array(3, 3), AR1(3, 3)
array = RESHAPE ((/'A', 'D', 'G', 'B', 'E', 'H', &
                   'C', 'F', 'I'/), (/3,3/))
!        array is A B C
!                 D E F
!                 G H I
shift = (/-1, 1, 0/)
AR1 = EOSHIFT (array, shift, BOUNDARY = (/'*','?','#'/), DIM= 2)
! returns         * A B
!                 E F ?
!                 G H I


EPSILON

Inquiry Intrinsic Function (Generic): Returns a positive model number that is almost negligible compared to unity in the model representing real numbers.

Syntax

result = EPSILON (x)

x
(Input) Must be of type real; it can be scalar or array valued.

Results:

The result is a scalar of the same type and kind parameters as x. The result has the value b1-p. Parameters b and p are defined in Model for Real Data.

EPSILON makes it easy to select a delta for algorithms (such as root locators) that search until the calculation is within delta of an estimate. If delta is too small (smaller than the decimal resolution of the data type), the algorithm might never halt. By scaling the value returned by EPSILON to the estimate, you obtain a delta that ensures search termination.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: PRECISION, TINY, Data Representation Models

Examples

If x is of type REAL(4), EPSILON (X) has the value 2-23.


EQUIVALENCE

Statement: Specifies that a storage area is shared by two or more objects in a program unit. This causes total or partial storage association of the objects that share the storage area.

Syntax

EQUIVALENCE (equiv-list) [, (equiv-list)] ...

equiv-list
Is a list of two or more variables, array elements, or substrings, separated by commas (also called an equivalence set). If an object of derived type is specified, it must be a sequence type. Objects cannot have the TARGET attribute.

Each expression in a subscript or a substring reference must be an integer initialization expression. A substring must not have a length of zero.

Rules and Behavior

The following objects cannot be specified in EQUIVALENCE statements:

  • A dummy argument
  • An allocatable array
  • A pointer
  • An object of nonsequence derived type
  • An object of sequence derived type containing a pointer in the structure
  • A function, entry, or result name
  • A named constant
  • A structure component
  • A subobject of any of the above objects

The EQUIVALENCE statement causes all of the entities in one parenthesized list to be allocated storage beginning at the same storage location.

Association of objects depends on their types, as follows:

Type of Object | Type of Associated Object
Intrinsic numeric 1 or numeric sequence | Can be of any of these types
Default character or character sequence | Can be of either of these types 2
Any other intrinsic type | Must have the same type and kind parameters
Any other sequence type | Must have the same type
1 Default integer, default real, double precision real, default complex, double complex, or default logical. 2 The lengths do not have to be equal.

So, objects can be associated if they are of different numeric type. For example, the following is valid:

  INTEGER A(20)
  REAL Y(20)
  EQUIVALENCE(A, Y)

Objects of default character do not need to have the same length. The following example associates character variable D with the last 4 (of the 6) characters of character array F:

  CHARACTER(LEN=4) D
  CHARACTER(LEN=3) F(2)
  EQUIVALENCE(D, F(1)(3:))

Entities having different data types can be associated because multiple components of one data type can share storage with a single component of a higher-ranked data type. For example, if you make an integer variable equivalent to a complex variable, the integer variable shares storage with the real part of the complex variable.

The same storage unit cannot occur more than once in a storage sequence, and consecutive storage units cannot be specified in a way that would make them nonconsecutive.

Visual Fortran lets you associate character and noncharacter entities, for example:

  CHARACTER*1 char1(10)
  REAL reala, realb
  EQUIVALENCE (reala, char1(1))
  EQUIVALENCE (realb, char1(2))

EQUIVALENCE statements require only the first subscript of a multidimensional array (unless the STRICT compiler directive is in effect). For example, the array declaration var(3,3), var(4) could appear in an EQUIVALENCE statement. The reference is to the fourth element of the array (var(1,2)), not to the beginning of the fourth row or column.

If you use the STRICT directive, the following rules apply to the kinds of variables and arrays that you can associate:

  • If an EQUIVALENCE object is default integer, default real, double-precision real, default complex, default logical, or a sequenced derived type of all numeric or logical components, all objects in the EQUIVALENCE statement must be one of these types, though it is not necessary that they be the same type.

  • If an EQUIVALENCE object is default character or a sequenced derived type of all character components, all objects in the EQUIVALENCE statement must be one of these types. The lengths do not need to be the same.

  • If an EQUIVALENCE object is a sequenced derived type that is not purely numeric or purely character, all objects in the EQUIVALENCE statement must be the same derived type.

  • If an EQUIVALENCE object is an intrinsic type other than the default (for example, INTEGER(1)), all objects in the EQUIVALENCE statement must be the same type and kind.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: EQUIVALENCE Statement, Initialization Expressions, Derived Data Types, Storage Association, STRICT Directive

Examples

The following EQUIVALENCE statement is invalid because it specifies the same storage unit for X(1) and X(2):

  REAL, DIMENSION(2), :: X
  REAL :: Y
  EQUIVALENCE(X(1), Y), (X(2), Y)

The following EQUIVALENCE statement is invalid because because A(1) and A(2) will not be consecutive:

  REAL A(2)
  DOUBLE PRECISION D(2)
  EQUIVALENCE(A(1), D(1)), (A(2), D(2))

In the following example, the EQUIVALENCE statement causes the four elements of the integer array IARR to share the same storage as that of the double-precision variable DVAR:

  DOUBLE PRECISION DVAR
  INTEGER(KIND=2) IARR(4)
  EQUIVALENCE(DVAR, IARR(1))

In the following example, the EQUIVALENCE statement causes the first character of the character variables KEY and STAR to share the same storage location. The character variable STAR is equivalent to the substring KEY(1:10).

  CHARACTER KEY*16, STAR*10
  EQUIVALENCE(KEY, STAR)

The following shows another example:

  CHARACTER name, first, middle, last
  DIMENSION name(60), first(20), middle(20), last(20)
  EQUIVALENCE (name(1), first(1)), (name(21), middle(1))
  EQUIVALENCE (name(41), last(1))

Consider the following:

  CHARACTER (LEN = 4) :: a, b
  CHARACTER (LEN = 3) :: c(2)
  EQUIVALENCE (a, c(1)), (b, c(2))

This causes the following alignment:

   1          2          3          4          5          6          7
 a(1:1)     a(2:2)     a(3:3)     a(4:4)
                                  b(1:1)     b(2:2)     b(3:3)     b(4:4)
 c(1)(1:1)  c(1)(2:2)  c(1)(3:3)  c(2)(1:1)  c(2)(2:2)  c(2)(3:3)

Note that the fourth element of a, the first element of b, and the first element of c(2) share the same storage unit.


ERRSNS

Intrinsic Subroutine: Returns information about the most recently detected I/O system error condition.

Syntax

ERRSNS ([io_err] [, sys_err] [, stat] [, unit] [, cond])

io_err
(Optional) Is an integer variable or array element that stores the most recent Compaq Fortran Run-Time Library error number that occurred during program execution. (For a listing of error numbers, see Visual Fortran Run-Time Errors in Error Messages.)

A zero indicates no error has occurred since the last call to ERRSNS or since the start of program execution.

sys_err
(Optional) Is an integer variable or array element that stores the most recent system error number associated with io_err. This code is one of the following:

  • On Windows systems, it is the value returned by GETLASTERROR( ) at the time of the error.
  • On OpenVMS systems, it is an RMS STS value.
  • On Tru64 UNIX and Linux systems, it is an errno value. (See errno(2).)

stat
(Optional) Is an integer variable or array element that stores a status value that occurred during program execution. This value is one of the following:

  • On Windows, Tru64 UNIX, and Linux systems, the value is zero.
  • On OpenVMS systems, it is an RMS STV value.

unit
(Optional) Is an integer variable or array element that stores the logical unit number, if the last error was an I/O error.

cond
(Optional) Is an integer variable or array element that stores the actual processor value. This value is always zero.

If you specify INTEGER(2) arguments, only the low-order 16 bits of information are returned or adjacent data can be overwritten. Because of this, it is best to use INTEGER(4) arguments.

The saved error information is set to zero after each call to ERRSNS.

Examples

Any of the arguments can be omitted. For example, the following is valid:

CALL ERRSNS (SYS_ERR, STAT, , UNIT)


ETIME (WNT only)

Portability Function: Returns the elapsed CPU time, in seconds, of the process that calls it. This function is currently restricted to WNT systems.

Module: USE DFPORT

Syntax

result = ETIME (array)

array
(Output) REAL(4). Must be a rank one array with two elements:

  • array(1) Elapsed user time, which is time spent executing user code. This value includes time running protected Windows subsystem code.

  • array(2) Elapsed system time, which is time spent executing privileged code (code in the Windows Executive).

Results:

The result is of type REAL(4). The result is the total CPU time, which is the sum of array(1) and array(2).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE_AND_TIME

Example

REAL(4) I, TA(2)
I = ETIME(TA)
write(*,*) 'Program has used', I, 'seconds of CPU time.'
write(*,*) '  This includes', TA(1), 'seconds of user time and',  &
& TA(2), 'seconds of system time.'


EXIT

Statement: Terminates execution of a DO construct.

Syntax

EXIT [name]

name
(Optional) Is the name of the DO construct.

Rules and Behavior

The EXIT statement causes execution of the named (or innermost) DO construct to be terminated.

If a DO construct name is specified, the EXIT statement must be within the range of that construct.

Any DO variable present retains its last defined value.

An EXIT statement can be labeled, but it cannot be used to terminate a DO construct.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DO, DO WHILE

Example

The following example shows an EXIT statement:

LOOP_A : DO I = 1, 15
  N = N + 1
  IF (N > I) EXIT LOOP_A
END DO LOOP_A

The following shows another example:

CC  See CYCLE.F90 in the /DF98/SAMPLES/TUTORIAL for an example of EXIT in nested
CC  DO loops
CC  Loop terminates early if one of the data points is zero:
CC
    INTEGER numpoints, point
    REAL datarray(1000), sum
    sum = 0.0
    DO point = 1, 1000
      sum = sum + datarray(point)
      IF (datarray(point+1) .EQ. 0.0) EXIT
    END DO


EXIT Subroutine

Intrinsic Subroutine: Terminates program execution, closes all files, and returns control to the operating system.

Syntax

CALL EXIT ( [status] )

status
(Optional; output) Is an integer argument you can use to specify the image exit-status value.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: END, ABORT

Example

    INTEGER(4) exvalue
! all is well, exit with 1
    exvalue = 1
    CALL EXIT(exvalue)
! all is not well, exit with diagnostic -4
    exvalue = -4
    CALL EXIT(exvalue)
! give no diagnostic, just exit
    CALL EXIT ( )


EXP

Elemental Intrinsic Function (Generic): Computes an exponential value.

Syntax

result = EXP (x)

x
(Input) Must be of type real or complex.

Results:

The result type is the same as x. The value of the result is ex. If x is of type complex, its imaginary part is regarded as a value in radians.

Specific Name | Argument Type | Result Type
EXP | REAL(4) | REAL(4)
DEXP | REAL(8) | REAL(8)
QEXP 1 | REAL(16) | REAL(16)
CEXP 2 | COMPLEX(4) | COMPLEX(4)
CDEXP 3 | COMPLEX(8) | COMPLEX(8)
CQEXP 1 | COMPLEX(16) | COMPLEX(16)
1 VMS and U*X 2 The setting of compiler option /real_size can affect CEXP. 3 This function can also be specified as ZEXP.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LOG

Examples

EXP (2.0) has the value 7.389056.

EXP (1.3) has the value 3.669297.

The following shows another example:

!  Given initial size and growth rate,
!  calculates the size of a colony at a given time.
     REAL sizei, sizef, time, rate
     sizei = 10000.0
     time = 40.5
     rate = 0.0875
     sizef = sizei * EXP (rate * time)
     WRITE (*, 100) sizef
100  FORMAT (' The final size is ', E12.6)
     END


EXPONENT

Elemental Intrinsic Function (Generic): Returns the exponent part of the argument when represented as a model number.

Syntax

result = EXPONENT (x)

x
(Input) must be of type real.

Results:

The result is of type default integer. If x is not equal to zero, the result value is the exponent part of x. The exponent must be within default integer range; otherwise, the result is undefined.

If x is zero, the exponent of x is zero. For more information on the exponent part (e) in the real model, see Model for Real Data.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB

See Also: DIGITS, RADIX, FRACTION, MAXEXPONENT, MINEXPONENT, Data Representation Models

Examples

EXPONENT (2.0) has the value 2.

If 4.1 is a REAL(4) value, EXPONENT (4.1) has the value 3.

The following shows another example:

  REAL(4) r1, r2
  REAL(8) r3, r4
  r1 = 1.0
  r2 = 123456.7
  r3 = 1.0D0
  r4 = 123456789123456.7
  write(*,*) EXPONENT(r1) ! prints 1
  write(*,*) EXPONENT(r2) ! prints 17
  write(*,*) EXPONENT(r3) ! prints 1
  write(*,*) EXPONENT(r4) ! prints 47
  END


EXTERNAL

Statement and Attribute: Allows an external or dummy procedure to be used as an actual argument. (To specify intrinsic procedures as actual arguments, use the INTRINSIC attribute.)

The EXTERNAL attribute can be specified in a type declaration statement or an EXTERNAL statement, and takes one of the following forms:

Syntax

Type Declaration Statement:

type, [att-ls,] EXTERNAL [, att-ls] :: ex-pro [, ex-pro] ...

Statement:

EXTERNAL ex-pro [, ex-pro ] ...

type
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

ex-pro
Is the name of an external (user-supplied) procedure or dummy procedure.

Rules and Behavior

In a type declaration statement, only functions can be declared EXTERNAL. However, you can use the EXTERNAL statement to declare subroutines and block data program units, as well as functions, to be external.

The name declared EXTERNAL is assumed to be the name of an external procedure, even if the name is the same as that of an intrinsic procedure. For example, if SIN is declared with the EXTERNAL attribute, all subsequent references to SIN are to a user-supplied function named SIN, not to the intrinsic function of the same name.

You can include the name of a block data program unit in the EXTERNAL statement to force a search of the object module libraries for the block data program unit at link time. However, the name of the block data program unit must not be used in a type declaration statement.

If you want to describe a routine with greater detail, use the INTERFACE statement. This statement automatically declares a routine as EXTERNAL, and provides information on result types and argument types.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Program Units and Procedures, Type Declarations, INTRINSIC, Compatible attributes, FORTRAN-66 Interpretation of the External Statement

Examples

The following example shows type declaration statements specifying the EXTERNAL attribute:

PROGRAM TEST
...
INTEGER, EXTERNAL :: BETA
LOGICAL, EXTERNAL :: COS
...
CALL SUB(BETA)       ! External function BETA is an actual argument

You can use a name specified in an EXTERNAL statement as an actual argument to a subprogram, and the subprogram can then use the corresponding dummy argument in a function reference or a CALL statement; for example:

EXTERNAL FACET
CALL BAR(FACET)

SUBROUTINE BAR(F)
EXTERNAL F
CALL F(2)

Used as an argument, a complete function reference represents a value, not a subprogram; for example, FUNC(B) represents a value in the following statement:

CALL SUBR(A, FUNC(B), C)

The following shows another example:

EXTERNAL MyFunc, MySub
C   MyFunc and MySub are arguments to Calc
    CALL Calc (MyFunc, MySub)
C   Example of a user-defined function replacing an
C   intrinsic
    EXTERNAL SIN
    x = SIN (a, 4.2, 37)


FDATE

Portability Function and Subroutine: Returns the current date and time as an ASCII string.

Module: USE DFPORT

Syntax

Subroutine:

CALL FDATE ( [string] )

Function:

result = FDATE ( )

string
(Optional; Output) Character*(*). When FDATE is called as a subroutine, string is returned as a 24-character string in the form:
  Mon Jan 31 04:37:23 2001

Results:

The result of the function FDATE and the value of string returned by the subroutine FDATE(string) are identical. Newline and NULL are not included in the string.

When you use FDATE as a function, declare it as:

  CHARACTER*24 FDATE

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE_AND_TIME

Example

USE DFPORT
CHARACTER*24 today
!
CALL FDATE(today)
write (*,*), 'Today is ', today
!
write (*,*), 'Today is ', fdate()


FGETC

Portability Function: Reads the next available character from a file specified by a Fortran unit number.

Module: USE DFPORT

Syntax

result = FGETC (lunit, char)

lunit
(Input) INTEGER(4). Unit number of a file.

char
(Output) CHARACTER*1. Next available character in the file. If lunit is connected to a console device, then no characters are returned until the Enter key is pressed.

Results:

The result is of type INTEGER(4). The result is zero if the read is successful, or -1 if an end-of-file is detected. A positive value is either a system error code or a Fortran I/O error code, such as:

EINVAL: The specified unit is invalid (either not already open, or an invalid unit number).

If you use WRITE, READ, or any other Fortran I/O statements with lunit, be sure to read Input and Output With Portability Routines in the Programmer's Guide.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETCHARQQ, READ

Example

USE dfport
CHARACTER inchar
INTEGER istatus
istatus = FGETC(5,inchar)
PRINT *, inchar
END


FIND

Statement: Positions a direct access file at a particular record and sets the associated variable of the file to that record number. It is comparable to a direct access READ statement with no I/O list, and it can open an existing file. No data transfer takes place.

Syntax

FIND ([UNIT=]io-unit, REC=r [, ERR=label] [, IOSTAT=i-var])
FIND (io-unit'rec [, ERR=label] [, IOSTAT=i-var])

io-unit
Is a logical unit number. It must refer to a relative organization file (see Unit Specifier).

r
Is the direct access record number. It cannot be less than one or greater than the number of records defined for the file (see Record Specifier).

label
Is the label of the executable statement that receives control if an error occurs.

i-var
Is a scalar integer variable that is defined as a positive integer if an error occurs, and as zero if no error occurs (see I/O Status Specifier).

See Also: Forms for Direct-Access READ Statements, I/O Control List

Example

In the following example, the FIND statement positions logical unit 1 at the first record in the file. The file's associated variable is set to one:

  FIND(1, REC=1)

In the following example, the FIND statement positions the file at the record identified by the content of INDX. The file's associated variable is set to the value of INDX:

  FIND(4, REC=INDX)


FINDFILEQQ

Run-Time Function: Searches for a specified file in the directories listed in the path contained in the environment variable.

Module: USE DFLIB

Syntax

result = FINDFILEQQ (filename, varname, pathbuf)

filename
(Input) Character*(*). Name of the file to be found.

varname
(Input) Character*(*). Name of an environment variable containing the path to be searched.

pathbuf
(Output) Character*(*). Buffer to receive the full path of the file found.

Results:

The result is of type INTEGER(4). The result is the length of the string containing the full path of the found file returned in pathbuf, or 0 if no file is found.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: FULLPATHQQ, GETFILEINFOQQ, SPLITPATHQQ

Example

USE DFLIB
CHARACTER(256) pathname
INTEGER(4) pathlen
pathlen = FINDFILEQQ("libfmt.lib", "LIB", pathname)
WRITE (*,*) pathname
END


FIRSTPRIVATE (TU*X only)

Parallel Directive Clause: Provides a superset of the functionality provided by the PRIVATE clause; objects are declared PRIVATE and they are initialized with certain values.

Syntax

FIRSTPRIVATE (list)

list
Is the name of one or more variables or common blocks that are accessible to the scoping unit. Subobjects cannot be specified. Each name must be separated by a comma, and a named common block must appear between slashes (/ /).

Variables that appear in a FIRSTPRIVATE list are subject to PRIVATE clause semantics. In addition, private (local) copies of each variable in the different threads are initialized to the value the variable had before the parallel region started.


FIXEDFORMLINESIZE

General Compiler Directive: Sets the line length for fixed-form Fortran source code.

Syntax

c DEC$ FIXEDFORMLINESIZE:{72 | 80 | 132}

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

You can set FIXEDFORMLINESIZE to 72 (the default), 80, or 132 characters. The FIXEDFORMLINESIZE setting remains in effect until the end of the file, or until it is reset.

The FIXEDFORMLINESIZE directive sets the source-code line length in include files, but not in USE modules, which are compiled separately. If an include file resets the line length, the change does not affect the host file.

This directive has no effect on free-form source code.

The following form is also allowed: !MS$FIXEDFORMLINESIZE:{72|80|132}

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: FREEFORM and NOFREEFORM, /fixed, Source Forms, General Compiler Directives

Example

  cDEC$ NOFREEFORM
  cDEC$ FIXEDFORMLINESIZE:132
  WRITE (*,*) 'Sentence that goes beyond the 72nd column without continuation.'


FLOAT

Elemental Intrinsic Function (Generic): Converts an integer to REAL(4). For more information, see REAL.


FLOODFILL, FLOODFILL_W

Graphics Function: Fills an area using the current color index and fill mask.

Module: USE DFLIB

Syntax

result = FLOODFILL (x, y, bcolor)
result = FLOODFILL_W (wx, wy, bcolor)

x, y
(Input) INTEGER(2). Viewport coordinates for fill starting point.

wx, wy
(Input) REAL(8). Window coordinates for fill starting point.

bcolor
(Input) INTEGER(2). Color index of the boundary color.

Results:

The result is of type INTEGER(2). The result is a nonzero value if successful; otherwise, 0 (occurs if the fill could not be completed, or if the starting point lies on a pixel with the boundary color bcolor, or if the starting point lies outside the clipping region).

FLOODFILL begins filling at the viewport-coordinate point (x, y). FLOODFILL_W begins filling at the window-coordinate point (wx, wy). The fill color used by FLOODFILL and FLOODFILL_W is set by SETCOLOR. You can obtain the current fill color index by calling GETCOLOR. These functions allow access only to the colors in the palette (256 or less). To access all available colors on a VGA (262,144 colors) or a true color system, use the RGB functions FLOODFILLRGB and FLOODFILLRGB_W.

If the starting point lies inside a figure, the interior is filled; if it lies outside a figure, the background is filled. In both cases, the fill color is the current graphics color index set by SETCOLOR. The starting point must be inside or outside the figure, not on the figure boundary itself. Filling occurs in all directions, stopping at pixels of the boundary color bcolor.

Note: The FLOODFILL routine described here is a QuickWin routine. If you are trying to use the Win32 SDK version of the FloodFill routine by including the DFWIN module, you need to specify the routine name as MSFWIN$FloodFill. For more information, see Special Naming Convention for Certain QuickWin and Win32 Graphics Routines in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: FLOODFILLRGB, FLOODFILLRGB_W, ELLIPSE, GETCOLOR, GETFILLMASK, GRSTATUS, PIE, SETCLIPRGN, SETCOLOR, SETFILLMASK

Example

USE DFLIB
INTEGER(2) status, bcolor, red, blue
INTEGER(2) x1, y1, x2, y2, xinterior, yinterior
x1 = 80; y1 = 50
x2 = 240; y2 = 150
red = 4
blue = 1
status = SETCOLOR(red)
status = RECTANGLE( $GBORDER, x1, y1, x2, y2 )
bcolor = GETCOLOR()
status = SETCOLOR (blue)
xinterior = 160; yinterior = 100
status = FLOODFILL (xinterior, yinterior, bcolor)
END


FLOODFILLRGB, FLOODFILLRGB_W

Graphics Function: Fills an area using the current Red-Green-Blue (RGB) color and fill mask.

Module: USE DFLIB

Syntax

result = FLOODFILLRGB (x, y, color)
result = FLOODFILLRGB_W (wx, wy, color)

x, y
(Input) INTEGER(2). Viewport coordinates for fill starting point.

wx, wy
(Input) REAL(8). Window coordinates for fill starting point.

color
(Input) INTEGER(4). RGB value of the boundary color.

Results:

The result is of type INTEGER(4). The result is a nonzero value if successful; otherwise, 0 (occurs if the fill could not be completed, or if the starting point lies on a pixel with the boundary color color, or if the starting point lies outside the clipping region).

FLOODFILLRGB begins filling at the viewport-coordinate point (x, y). FLOODFILLRGB_W begins filling at the window-coordinate point (wx, wy). The fill color used by FLOODFILLRGB and FLOODFILLRGB_W is set by SETCOLORRGB. You can obtain the current fill color by calling GETCOLORRGB.

If the starting point lies inside a figure, the interior is filled; if it lies outside a figure, the background is filled. In both cases, the fill color is the current color set by SETCOLORRGB. The starting point must be inside or outside the figure, not on the figure boundary itself. Filling occurs in all directions, stopping at pixels of the boundary color color.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: ELLIPSE, FLOODFILL, GETCOLORRGB, GETFILLMASK, GRSTATUS, PIE, SETCLIPRGN, SETCOLORRGB, SETFILLMASK

Example

! Build as a QuickWin or Standard Graphics App.
USE DFLIB
INTEGER(2) status
INTEGER(4) result, bcolor
INTEGER(2) x1, y1, x2, y2, xinterior, yinterior
x1 = 80; y1 = 50
x2 = 240; y2 = 150
result = SETCOLORRGB(#008080) ! red
status = RECTANGLE( $GBORDER, x1, y1, x2, y2 )
bcolor = GETCOLORRGB( )
result = SETCOLORRGB (#FF0000) ! blue
xinterior = 160; yinterior = 100
result = FLOODFILLRGB (xinterior, yinterior, bcolor)
END


FLOOR

Elemental Intrinsic Function (Generic): Returns the greatest integer less than or equal to its argument.

Syntax

result = FLOOR (a [, kind])

a
(Input) Must be of type real.

kind
(Optional; input) Must be a scalar integer initialization expression. This argument is a Fortran 95 feature.

Results:

The result is of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

The value of the result is equal to the greatest integer less than or equal to a.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: CEILING

Examples

FLOOR (4.8) has the value 4.

FLOOR (-5.6) has the value -6.

The following shows another example:

I = FLOOR(3.1)  ! returns 3
I = FLOOR(-3.1) ! returns -4


FLUSH

Portability Subroutine: Flushes the contents of an external unit buffer into its associated file.

Module: USE DFPORT

Syntax

CALL FLUSH (lunit)

lunit
(Input) INTEGER(4). Number of the external unit to be flushed.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: COMMITQQ


FLUSH Directive (TU*X only)

OpenMP Parallel Compiler Directive: Identifies synchronization points at which the implementation must provide a consistent view of memory.

Syntax

c$OMP FLUSH [(list)]

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

list
Is the name of one or more variables to be flushed. Names must be separated by commas.

Rules and Behavior

The FLUSH directive must appear at the precise point in the code at which the synchronization is required. To avoid flushing all variables, specify a list.

Thread-visible variables are written back to memory at the point at which this directive appears. Modifications to thread-visible variables are visible to all threads after this point. Subsequent reads of thread-visible variables fetch the latest copy of the data.

Thread-visible variables include the following data items:

  • Globally visible variables (common blocks and modules)
  • Local variables that do not have the SAVE attribute but have had their address taken and saved or have had their address passed to another subprogram
  • Local variables that do not have the SAVE attribute that are declared shared in a parallel region within the subprogram
  • Dummy arguments
  • All pointer dereferences

The FLUSH directive is implied for the following directives (unless the NOWAIT keyword is used):

  • BARRIER
  • CRITICAL and END CRITICAL
  • END DO
  • END PARALLEL
  • END SECTIONS
  • END SINGLE
  • ORDERED and END ORDERED

See Also: Parallel Directives for Tru64 UNIX Systems, OpenMP Fortran API Compiler Directives (TU*X only), Compaq Fortran Parallel Compiler Directives (TU*X only)

Examples

The following example uses the FLUSH directive for point-to-point synchronization between pairs of threads:

  c$OMP PARALLEL DEFAULT(PRIVATE) SHARED(ISYNC)
        IAM = OMP_GET_THREAD_NUM( )
        ISYNC(IAM) = 0
  c$OMP BARRIER
        CALL WORK( )
  C I AM DONE WITH MY WORK, SYNCHRONIZE WITH MY NEIGHBOR
        ISYNC(IAM) = 1
  c$OMP FLUSH(ISYNC)
  C WAIT TILL NEIGHBOR IS DONE
        DO WHILE (ISYNC(NEIGH) .EQ. 0)
  c$OMP FLUSH(ISYNC)
        END DO
  c$OMP END PARALLEL


FOCUSQQ

QuickWin Function: Sets focus to the window with the specified unit number.

Module: USE DFLIB

Syntax

result = FOCUSQQ (iunit)

unit
(Input) INTEGER(4). Unit number of the window to which the focus is set. Unit numbers 0, 5, and 6 refer to the default startup window.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, nonzero.

Units 0, 5, and 6 refer to the default window only if the program does not specifically open them. If these units have been opened and connected to windows, they are automatically reconnected to the console once they are closed.

Unlike SETACTIVEQQ, FOCUSQQ brings the specified unit to the foreground. Note that the window with the focus is not necessarily the active window (the one that receives graphical output). A window can be made active without getting the focus by calling SETACTIVEQQ.

A window has focus when it is given the focus by FOCUSQQ, when it is selected by a mouse click, or when an I/O operation other than a graphics operation is performed on it, unless the window was opened with IOFOCUS=.FALSE.. The IOFOCUS specifier determines whether a window receives focus when on I/O statement is executed on that unit. For example:

  OPEN (UNIT = 10, FILE = 'USER', IOFOCUS = .TRUE.)

By default IOFOCUS=.TRUE., except for child windows opened with as unit *. If IOFOCUS=.TRUE., the child window receives focus prior to each READ, WRITE, PRINT, or OUTTEXT. Calls to graphics functions (such as OUTGTEXT and ARC) do not cause the focus to shift.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: Using QuickWin, SETACTIVEQQ, INQFOCUSQQ


FOR_CHECK_FLAWED_PENTIUM

Run-Time Function: Checks the processor to determine if it shows characteristics of the Pentium® floating-point divide flaw.

This routine can be called from a C program. It is invoked by default from a Fortran program unless /check:noflawed_pentium is specified.

Module: USE DFLIB

Syntax

result = FOR_CHECK_FLAWED_PENTIUM( )

Results:

If the floating-point divide flaw is found, a severe forrtl error message is displayed and the calling program is terminated.

You can bypass this action by setting environment variable FOR_RUN_FLAWED_PENTIUM to the value TRUE.

For more information, see Intel Pentium Floating-Point Flaw in the Programmer's Guide.

Example

Consider the following C code:

  void __stdcall for_check_flawed_pentium ( void );
  for_check_flawed_pentium ( );

Consider the following Fortran code that checks for the divide flaw:

  USE DFLIB

  REAL*8 X, Y, Z

  X = 5244795.0
  Y = 3932159.0
  Z = X - (X/Y) * Y
  IF (Z .NE. 0) THEN           ! If flawed, Z will be 256
    PRINT *, " FDIV flaw detected on Pentium"
  ENDIF


FOR_GET_FPE

Run-Time Function: Returns the current settings of floating-point exception flags. This routine can be called from a C or Fortran program.

Module: USE DFLIB

Syntax

result = FOR_GET_FPE( )

Results:

The result is of type INTEGER(4). The return value represents the settings of the current floating-point exception flags. The meanings of the bits are defined in the DFLIB module file.

To set floating-point exception flags after program initialization, use FOR_SET_FPE.

Example

Consider the following:

  USE DFLIB

  INTEGER*4 FPE_FLAGS
  FPE_FLAGS = FOR_GET_FPE ( )


FOR_RTL_FINISH_

Run-Time Function: Cleans up the Fortran run-time environment; for example, flushing buffers and closing files. It also issues messages about floating-point exceptions, if any occur.

This routine should be called from a C main program; it is invoked by default from a Fortran main program.

Syntax

result = FOR_RTL_FINISH_ ( )

Results:

The result is an I/O status value. For information on these status values, see Using the IOSTAT Value and Fortran Exit Codes in the Programmer's Guide.

To initialize the Fortran run-time environment, use FOR_RTL_INIT_ .

Example

Consider the following C code:

  int io_status;
  int for_rtl_finish_ ( );
  io_status = for_rtl_finish_ ( );


FOR_RTL_INIT_

Run-Time Subroutine: Initializes the Fortran run-time environment. It establishes handlers and floating-point exception handling, so Fortran subroutines behave the same as when called from a Fortran main program.

This routine should be called from a C main program; it is invoked by default from a Fortran main program.

Syntax

CALL FOR_RTL_INIT_ (argcount, actarg)

argcount
Is a command-line parameter describing the argument count.

actarg
Is a command-line parameter describing the actual arguments.

To clean up the Fortran run-time environment, use FOR_RTL_FINISH_.

Example

Consider the following C code:

  int argc;
  char **argv;
  void for_rtl_init_ (int *, char **);
  for_rtl_init_ (&argc, argv);


FOR_SET_FPE

Run-Time Function: Sets the floating-point exception flags. This routine can be called from a C or Fortran program.

Module: USE DFLIB

Syntax

result = FOR_SET_FPE (a)

a
Must be of type INTEGER(4). It contains bit flags controlling floating-point exception trapping, reporting, and result handling.

Results:

The result is of type INTEGER(4). The return value represents the previous settings of the floating-point exception flags. The meanings of the bits are defined in the DFLIB module file.

To get the current settings of the floating-point exception flags, use FOR_GET_FPE.

Example

Consider the following:

  USE DFLIB

  INTEGER*4 OLD_FPE_FLAGS, NEW_FPE_FLAGS
  OLD_FPE_FLAGS = FOR_SET_FPE (NEW_FPE_FLAGS)


FOR_SET_REENTRANCY

Run-Time Function: Controls the type of reentrancy protection that the Fortran Run-Time Library (RTL) exhibits. This routine can be called from a C or Fortran program.

Module: USE DFLIB

Syntax

result = FOR_SET_REENTRANCY (mode)

mode
Must be of type INTEGER(4) and contain one of the following options:

  • FOR_K_REENTRANCY_NONE
    Tells the Fortran RTL to perform simple locking around critical sections of RTL code. This type of reentrancy should be used when the Fortran RTL will not be reentered due to asynchronous system traps (ASTs) or threads within the application.

  • FOR_K_REENTRANCY_ASYNCH
    Tells the Fortran RTL to perform simple locking and disables ASTs around critical sections of RTL code. This type of reentrancy should be used when the application contains AST handlers that call the Fortran RTL.

  • FOR_K_REENTRANCY_THREADED
    Tells the Fortran RTL to perform thread locking. This type of reentrancy should be used in multithreaded applications.

  • FOR_K_REENTRANCY_INFO
    Tells the Fortran RTL to return the current reentrancy mode.

Results:

The result is of type INTEGER(4). The return value represents the previous setting of the Fortran Run-Time Library reentrancy mode, unless the argument is FOR_K_REENTRANCY_INFO, in which case the return value represents the current setting.

You must be using an RTL that supports the level of reentrancy you desire. For example, FOR_SET_REENTRANCY ignores a request for thread protection (FOR_K_REENTRANCY_THREADED) if you do not build your program with the thread-safe RTL.

Example

Consider the following:

  PROGRAM SETREENT
  USE DFLIB

  INTEGER*4    MODE
  CHARACTER*10 REENT_TXT(3) /'NONE    ','ASYNCH  ','THREADED'/

  PRINT*,'Setting Reentrancy mode to ',REENT_TXT(MODE+1)
  MODE = FOR_SET_REENTRANCY(FOR_K_REENTRANCY_NONE)
  PRINT*,'Previous Reentrancy mode was ',REENT_TXT(MODE+1)

  MODE = FOR_SET_REENTRANCY(FOR_K_REENTRANCY_INFO)
  PRINT*,'Current Reentrancy mode is ',REENT_TXT(MODE+1)

  END


FORALL

Statement and Construct: The FORALL statement and construct is an element-by-element generalization of the Fortran 95/90 masked array assignment (WHERE statement and construct). It allows more general array shapes to be assigned, especially in construct form.

FORALL is a feature of Fortran 95.

Syntax

Statement:

FORALL (triplet-spec [,triplet-spec] ...[,mask-expr]) assignment-stmt

Construct:

[name:] FORALL (triplet-spec [,triplet-spec] ...[, mask-expr])
forall-body-stmt
[forall-body-stmt] ...
END FORALL [name]

triplet-spec
Is a triplet specification with the following form:

subscript-name = subscript-1 : subscript-2 [: stride]

The subscript-name is a scalar of type integer. It is valid only within the scope of the FORALL; its value is undefined on completion of the FORALL.
The subscripts and stride cannot contain a reference to any subscript-name in triplet-spec.
The stride cannot be zero. If it is omitted, the default value is 1.

Evaluation of an expression in a triplet specification must not affect the result of evaluating any other expression in another triplet specification.

mask-expr
Is a logical array expression (called the mask expression). If it is omitted, the value .TRUE. is assumed. The mask expression can reference the subscript name in triplet-spec.

assignment-stmt
Is an assignment statement or a pointer assignment statement. The variable being assigned to must be an array element or array section and must reference all subscript names included in all triplet-specs.

name
Is the name of the FORALL construct.

forall-body-stmt
Is one of the following:

  • An assignment-stmt
  • A WHERE statement or construct
    The WHERE statement and construct use a mask to make the array assignments.
  • A FORALL statement or construct

Rules and Behavior

If a construct name is specified in the FORALL statement, the same name must appear in the corresponding END FORALL statement.

A FORALL statement is executed by first evaluating all bounds and stride expressions in the triplet specifications, giving a set of values for each subscript name. The FORALL assignment statement is executed for all combinations of subscript name values for which the mask expression is true.

The FORALL assignment statement is executed as if all expressions (on both sides of the assignment) are completely evaluated before any part of the left side is changed. Valid values are assigned to corresponding elements of the array being assigned to. No element of an array can be assigned a value more than once.

A FORALL construct is executed as if it were multiple FORALL statements, with the same triplet specifications and mask expressions. Each statement in the FORALL body is executed completely before execution begins on the next FORALL body statement.

Any procedure referenced in the mask expression or FORALL assignment statement must be pure.
Pure functions can be used in the mask expression or called directly in a FORALL statement. Pure subroutines cannot be called directly in a FORALL statement, but can be called from other pure procedures.

Examples

The following example, which is not expressible using array syntax, sets diagonal elements of an array to 1:

  REAL, DIMENSION(N, N) :: A
  FORALL (I=1:N)  A(I, I) = 1

Consider the following:

  FORALL(I = 1:N, J = 1:N, A(I, J) .NE. 0.0) B(I, J) = 1.0 / A(I, J)

This statement takes the reciprocal of each nonzero element of array A(1:N, 1:N) and assigns it to the corresponding element of array B. Elements of A that are zero do not have their reciprocal taken, and no assignments are made to corresponding elements of B.

Every array assignment statement and WHERE statement can be written as a FORALL statement, but some FORALL statements cannot be written using just array syntax. For example, the preceding FORALL statement is equivalent to the following:

  WHERE(A /= 0.0) B = 1.0 / A

It is also equivalent to:

FORALL (I = 1:N, J = 1:N)
  WHERE(A(I, J) .NE. 0.0) B(I, J) = 1.0/A(I, J)
END FORALL

However, the following FORALL example cannot be written using just array syntax:

  FORALL(I = 1:N, J = 1:N) H(I, J) = 1.0/REAL(I + J - 1)

This statement sets array element H(I, J) to the value 1.0/REAL(I + J - 1) for values of I and J between 1 and N.

Consider the following:

TYPE MONARCH
  INTEGER, POINTER :: P
END TYPE MONARCH

TYPE(MONARCH), DIMENSION(8) :: PATTERN
INTEGER, DIMENSION(8), TARGET :: OBJECT
FORALL(J=1:8) PATTERN(J)%P => OBJECT(1+IEOR(J-1,2))

This FORALL statement causes elements 1 through 8 of array PATTERN to point to elements 3, 4, 1, 2, 7, 8, 5, and 6, respectively, of OBJECT. IEOR can be referenced here because it is pure.

The following example shows a FORALL construct:

FORALL(I = 3:N + 1, J = 3:N + 1)
  C(I, J) = C(I, J + 2) + C(I, J - 2) + C(I + 2, J) + C(I - 2, J)
  D(I, J) = C(I, J)
END FORALL

The assignment to array D uses the values of C computed in the first statement in the construct, not the values before the construct began execution.


FORMAT

Statement: Specifies the form of data being transferred and the data conversion (editing) required to achieve that form.

Syntax

FORMAT (format-list)

format-list
Is a list of one or more of the following edit descriptors, separated by commas or slashes (/):
Data edit descriptors: I, B, O, Z, F, E, EN, ES, D, G, L, and A.
Control edit descriptors: T, TL, TR, X, S, SP, SS, BN, BZ, P, :, /, $, \, and Q.
String edit descriptors: H, 'c', and "c", where c is a character constant.

A comma can be omitted in the following cases:

  • Between a P edit descriptor and an immediately following F, E, EN, ES, D, or G edit descriptor

  • Before a slash (/) edit descriptor when the optional repeat specification is not present

  • After a slash (/) edit descriptor

  • Before or after a colon (:) edit descriptor

Edit descriptors can be nested and a repeat specification can precede data edit descriptors, the slash edit descriptor, or a parenthesized list of edit descriptors.

Rules and Behavior

A FORMAT statement must be labeled.

Named constants are not permitted in format specifications.

If the associated I/O statement contains an I/O list, the format specification must contain at least one data edit descriptor or the control edit descriptor Q.

Blank characters can precede the initial left parenthesis, and additional blanks can appear anywhere within the format specification. These blanks have no meaning unless they are within a character string edit descriptor.

When a formatted input statement is executed, the setting of the BLANK specifier (for the relevant logical unit) determines the interpretation of blanks within the specification. If the BN or BZ edit descriptors are specified for a formatted input statement, they supersede the default interpretation of blanks. (For more information on BLANK defaults, see the OPEN statement.

For formatted input, use the comma as an external field separator. The comma terminates the input of fields (for noncharacter data types) that are shorter than the number of characters expected. It can also designate null (zero-length) fields.

The first character of a record transmitted to a line printer or terminal is typically used for carriage control; it is not printed. The first character of such a record should be a blank, 0, 1, $, +, or ASCII NUL. Any other character is treated as a blank.

A format specification cannot specify more output characters than the external record can contain. For example, a line printer record cannot contain more than 133 characters, including the carriage control character.

Whenever an edit descriptor requires an integer constant, you can specify an integer expression in a FORMAT statement. The integer expression must be enclosed by angle brackets (< and >). The following examples are valid format specifications:

      WRITE(6,20) INT1
  20  FORMAT(I<MAX(20,5)>)

      WRITE(6,FMT=30) INT2, INT3
  30  FORMAT(I<J+K>, I<2*M>)

The integer expression can be any valid Fortran expression, including function calls and references to dummy arguments, with the following restrictions:

  • Expressions cannot be used with the H edit descriptor.
  • Expressions cannot contain graphical relational operators (such as > and <).

The value of the expression is reevaluated each time an input/output item is processed during the execution of the READ, WRITE, or PRINT statement.

The following table summarizes the edit descriptors:

Data Edit Descriptors
Code | Form 1 | Effect
A | A[w] | Transfers character or Hollerith values.
B | Bw[.m] | Transfers binary values.
D | Dw.d | Transfers real values with D exponents.
E | Ew.d[Ee] | Transfers real values with E exponents.
EN | ENw.d[Ee] | Transfers real values with engineering notation.
ES | ESw.d[Ee] | Transfers real values with scientific notation.
F | Fw.d | Transfers real values with no exponent.
G | Gw.d[Ee] | Transfers values of all intrinsic types.
I | Iw[.m] | Transfers decimal integer values.
L | Lw | Transfers logical values: on input, transfers characters; on output, transfers T or F.
O | Ow[.m] | Transfers octal values.
Z | Zw[.m] | Transfers hexadecimal values.
1 w is the field width m is the minimum number of digits that must be in the field (including zeros). d is the number of digits to the right of the decimal point E is the exponent field e is the number of digits in the exponent
Control Edit Descriptors
Code | Form | Effect
BN | BN | Ignores embedded and trailing blanks in a numeric input field.
BZ | BZ | Treats embedded and trailing blanks in a numeric input field as zeros.
P | kP | Interprets certain real numbers with a specified scale factor.
Q | Q | Returns the number of characters remaining in an input record.
S | S | Reinvokes optional plus sign (+) in numeric output fields; counters the action of SP and SS.
SP | SP | Writes optional plus sign (+) into numeric output fields.
SS | SS | Suppresses optional plus sign (+) in numeric output fields.
T | Tn | Tabs to specified position.
TL | TLn | Tabs left the specified number of positions.
TR | TRn | Tabs right the specified number of positions.
X | nX | Skips the specified number of positions.
$ | $ | Suppresses trailing carriage return during interactive I/O.
: | : | Terminates format control if there are no more items in the I/O list.
/ | [r]/ | Terminates the current record and moves to the next record.
\ | \ | Continues the same record; same as $.
String Edit Descriptors
Code | Form | Effect
H | nHch[ch...] | Transfers characters following the H edit descriptor to an output record.
'c' 2 | 'c' | Transfers the character literal constant (between the delimiters) to an output record.
2 These delimiters can also be quotation marks (").

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: I/O Formatting, Format Specifications, Data Edit Descriptors

Example

   INTEGER width, value
   width = 2
   read (*,1) width, value
!  if the input is 3123, prints 123, not 12
1  format ( i1, i<width>)
   print *, value
   END


FP_CLASS

Elemental Intrinsic Function (Generic): Returns the class of an IEEE® real (S_floating, T_floating, or X_floating) argument.

Syntax

result = FP_CLASS (x)

x
(Input) Must be of type real.

Results:

The result is of type default integer. The return value is one of the following:

Class of Argument | Return Value
Signaling NaN | FOR_K_FP_SNAN
Quiet NaN | FOR_K_FP_QNAN
Positive Infinity | FOR_K_FP_POS_INF
Negative Infinity | FOR_K_FP_NEG_INF
Positive Normalized Number | FOR_K_FP_POS_NORM
Negative Normalized Number | FOR_K_FP_NEG_NORM
Positive Denormalized Number | FOR_K_FP_POS_DENORM
Negative Denormalized Number | FOR_K_FP_NEG_DENORM
Positive Zero | FOR_K_FP_POS_ZERO
Negative Zero | FOR_K_FP_NEG_ZERO

The preceding return values are defined in file fordef.for in \DF98\INCLUDE on Windows systems; file fordef.f on Tru64 UNIX and Linux systems; and module FORSYSDEF on OpenVMS systems.

Example

FP_CLASS (4.0_8) has the value 4 (FOR_K_FP_POS_NORM).


FPUTC

Portability Function: Writes a character to the file specified by a Fortran external unit, bypassing normal Fortran input/output.

Module: USE DFPORT

Syntax

result = FPUTC (lunit, char)

lunit
(Input) INTEGER(4). Unit number of a file.

char
(Output) Character*(*). Variable whose value is to be written to the file corresponding to lunit.

Results:

The result is of type INTEGER(4). The result is zero if the write was successful; otherwise, an error code, such as:

EINVAL - The specified unit is invalid (either not already open, or an invalid unit number)

If you use WRITE, READ, or any other Fortran I/O statements with lunit, be sure to read Input and Output With Portability Routines in the Programmer's Guide.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: I/O Formatting, Files, Devices, and Input/Output Hardware

Example

use dfport
integer*4 lunit, i4
character*26 string
character*1 char1
lunit = 1
open (lunit,file = 'fputc.dat')
do i = 1,26
  char1 = char(123-i)
  i4 = fputc(1,char1)        !make valid writes
  if (i4.ne.0) iflag = 1
enddo
rewind (1)
read (1,'(a)') string
print *, string


FRACTION

Elemental Intrinsic Function (Generic): Returns the fractional part of the model representation of the argument value.

Syntax

result = FRACTION (x)

x
(Input) Must be of type real.

Results:

The result type is the same as x. The result has the value x x be. Parameters b and e are defined in Model for Real Data. If x has the value zero, the result has the value zero.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DIGITS, RADIX, EXPONENT, Data Representation Models

Examples

If 3.0 is a REAL(4) value, FRACTION (3.0) has the value 0.75.

The following shows another example:

REAL result
result = FRACTION(3.0) ! returns 0.75
result = FRACTION(1024.0) ! returns 0.5


FREE

Intrinsic Subroutine: Frees a block of memory that is currently allocated.

Syntax

CALL FREE (i)

i
(Input) Must be of type INTEGER(4) on ia32 processors; INTEGER(8) on Alpha and ia64 processors. This value is the starting address of the memory block to be freed, previously allocated by MALLOC.

If the freed address was not previously allocated by MALLOC, or if an address is freed more than once, results are unpredictable.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

  INTEGER(4) addr, size
  size = 1024            ! size in bytes
  addr = MALLOC(size)    ! allocate the memory
  CALL FREE(addr)        ! free it
  END


FREEFORM and NOFREEFORM

General Compiler Directives: FREEFORM specifies that source code is in free-form format. NOFREEFORM specifies that source code is in fixed-form format.

Syntax

c DEC$ FREEFORM
c DEC$ NOFREEFORM

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

When the FREEFORM or NOFREEFORM directives are used, they remain in effect for the remainder of the file, or until the opposite directive is used. When in effect, they apply to include files, but do not affect USE modules, which are compiled separately.

The following forms are also allowed: !MS$FREEFORM and !MS$NOFREEFORM

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Source Forms, General Compiler Directives, /free


FSEEK

Portability Function: Repositions a file specified by a Fortran external unit.

Module: USE DFPORT

Syntax

result = FSEEK (lunit, offset, from)

lunit
(Input) INTEGER(4). External unit number of a file.

offset
(Input) INTEGER(4). Offset in bytes, relative to from, that is to be the new location of the file marker.

from
(Input) INTEGER(4). A position in the file. Portability defines the following parameters:
SEEK_SET = 0 | Beginning of the file
SEEK_CUR = 1 | Current position
SEEK_END = 2 | End of the file

Results:

The result is of type INTEGER(4). The result is zero if the repositioning was successful; otherwise, an error code, such as:

EINVAL: The specified unit is invalid (either not already open, or an invalid unit number), or the from parameter is invalid.

The file specified in lunit must be open.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

USE DFPORT
integer(4) istat, offset, ipos
character ichar
OPEN (unit=1,file='datfile.dat')
offset = 5
ipos = 0
istat=fseek(1,offset,ipos)
if (.NOT. stat) then
  istat=fgetc(1,ichar)
  print *, 'data is ',ichar
end if


FSTAT

Portability Function: Returns detailed information about a file specified by a external unit number.

Module: USE DFPORT

Syntax

result = FSTAT (lunit, statb)

lunit
(Input) INTEGER(4). External unit number of the file to examine.

statb
(Output) INTEGER(4). One-dimensional array with a size of 12. The following table describes the elements of the array:

statb element | Return value
statb(1) | Device the file resides on (always 0)
statb(2) | Inode number (always 0)
statb(3) | File type, attributes, and access control information (see the following table)
statb(4) | Number of links (always 1)
statb(5) | User ID of owner (always 1)
statb(6) | Group ID of owner (always 1)
statb(7) | Raw device file resides on (always 1)
statb(8) | The size of the file in bytes
statb(9) | The time of last access (only available on non-FAT file systems; same as statb(10) on FAT systems.
statb(10) | The time of last modification
statb(11) | The time of last status change (same as statb(10))
statb(12) | Block size (always 1)

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, returns an error code equal to EINVAL (lunit is not a valid unit number, or is not open).

Mode is a bitmap consisting of an IOR of the following constants (the module DFPORT supplies parameters with the symbolic names given):

Symbolic name | Constant | Description | Notes
S_IFMT O'0170000' Type of file
S_IFDIR O'0040000' Directory
S_IFCHR | O'0020000' | Character special | Never set
S_IFBLK | O'0060000' | Block special | Never set
S_IFREG O'0100000' Regular
S_IFLNK | O'0120000' | Symbolic link | Never set
S_IFSOCK | O'0140000' | Socket | Never set
S_ISUID | O'0004000' | Set user ID on execution | Never set
S_ISGID | O'0002000' | Set group ID on execution | Never set
S_ISVTX | O'0001000' | Save swapped text | Never set
S_IRWXU O'0000700' Owner's file permissions
S_IRUSR, S_IREAD | O'0000400' | Owner read permission | Always true
S_IWUSR, S_IWRITE O'0000200' Owner write permission
S_IXUSR, S_IEXEC | O'0000100' | Owner execute permission | Set if S_IREAD is set
S_IRWXG | O'0000070' | Group's file permissions | Same as S_IRWXU
S_IRGRP | O'0000040' | Group read permission | Same as S_IRUSR
S_IWGRP | O'0000020' | Group write permission | Same as S_IWUSR
S_IXGRP | O'0000010' | Group execute permission | Same as S_IXUSR
S_IRWXO | O'0000007' | Other's file permissions | Same as S_IRWXU
S_IROTH | O'0000004' | Other's read permission | Same as S_IRUSR
S_IWOTH | O'0000002' | Other write permission | Same as S_IWUSR
S_IXOTH | O'0000001' | Other execute permission | Same as S_IXUSR

Time values are returned as number of seconds since 0:00:00 Greenwich mean time, January 1, 1970.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: INQUIRE

Example

USE DFPORT
integer(4) statarray(12), istat
OPEN (unit=1,file='datfile.dat')
ISTAT = FSTAT (1, statarray)
if (.NOT. istat) then
    print *, statarray
end if


FTELL

Portability Function: Returns the current position of a file.

Module: USE DFPORT

Syntax

result = FTELL (lunit)

lunit
(Input) INTEGER(4). External unit number of a file.

Results:

The result is of type INTEGER(4). The result is the offset, in bytes, from the beginning of the file. A negative value indicates an error, which is the negation of the IERRNO error code. The following is an example of an error code:

EINVAL: lunit is not a valid unit number, or is not open.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB


FULLPATHQQ

Run-Time Function: Returns the full path for a specified file or directory.

Module: USE DFLIB

Syntax

result = FULLPATHQQ (name, pathbuf)

name
(Input) Character*(*). Item for which you want the full path. Can be the name of a file in the current directory, a relative directory or filename, or a network uniform naming convention (UNC) path.

pathbuf
(Output) Character*(*). Buffer to receive full path of the item specified in name.

Results:

The result is of type INTEGER(4). The result is the length of the full path in bytes, or 0 if the function fails (usually for an invalid name).

The length of the full path depends upon how deeply the directories are nested on the drive you are using. If the full path is longer than the character buffer provided to return it (pathbuf), FULLPATHQQ returns only that portion of the path that fits into the buffer.

Check the length of the path before using the string returned in pathbuf. If the longest full path you are likely to encounter does not fit into the buffer you are using, allocate a larger character buffer. You can allocate the largest possible path buffer with the following statements:

  USE DFLIB
  CHARACTER($MAXPATH) pathbuf

$MAXPATH is a symbolic constant defined in module DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as 260.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPLITPATHQQ

Example

     USE DFLIB
     CHARACTER($MAXPATH) buf
     CHARACTER(3)        drive
     CHARACTER(256)      dir
     CHARACTER(256)      name
     CHARACTER(256)      ext
     CHARACTER(256)      file

     INTEGER(4)          len

     DO WHILE (.TRUE.)
       WRITE (*,*)
       WRITE (*,'(A, \)') ' Enter filename (Hit &
                            RETURN to exit): '
       len = GETSTRQQ(file)
       IF (len .EQ. 0) EXIT
       len = FULLPATHQQ(file, buf)
       IF (len .GT. 0) THEN
         WRITE (*,*) buf(:len)
       ELSE
         WRITE (*,*) 'Can''t get full path'
         EXIT
       END IF
!
!      Split path
       WRITE (*,*)
       len = SPLITPATHQQ(buf, drive, dir, name, ext)
       IF (len .NE. 0) THEN
         WRITE (*, 900) ' Drive: ', drive
         WRITE (*, 900) ' Directory: ', dir(1:len)
         WRITE (*, 900) ' Name: ', name
         WRITE (*, 900) ' Extension: ', ext
       ELSE
         WRITE (*, *) 'Can''t split path'
       END IF
     END DO
900  FORMAT (A, A)
     END


FUNCTION

Statement: The initial statement of a function subprogram. A function subprogram is invoked in an expression and returns a single value (a function result) that is used to evaluate the expression.

Syntax

[prefix] FUNCTION name ([d-arg-list]) [RESULT (r-name)]

prefix
(Optional) Is one of the following:

type [keyword]
keyword [type]

type
Is a data type specifier.

keyword
Is one of the following:

Keyword | Meaning
RECURSIVE | Permits direct recursion to occur. If a function is directly recursive and array valued, RESULT must also be specified.
PURE | Asserts that the procedure has no side effects.
ELEMENTAL | Restricted form of pure procedure that acts on one array element at a time.

name
Is the name of the function. If RESULT is specified, the function name must not appear in any specification statement in the scoping unit of the function subprogram.

The function name can be followed by the length of the data type. The length is specified by an asterisk (*) followed by any unsigned, nonzero integer that is a valid length for the function's type. For example, REAL FUNCTION LGFUNC*8 (Y, Z) specifies the function result as REAL(8) (or REAL*8).

This optional length specification is not permitted if the length has already been specified following the keyword CHARACTER.

d-arg-list
(Optional) Is a list of one or more dummy arguments.

r-name
(Optional) Is the name of the function result. This name must not be the same as the function name.

Rules and Behavior

The type and kind parameters (if any) of the function's result can be defined in the FUNCTION statement or in a type declaration statement within the function subprogram, but not both. If no type is specified, the type is determined by implicit typing rules in effect for the function subprogram.

Execution begins with the first executable construct or statement following the FUNCTION statement. Control returns to the calling program unit once the END statement (or a RETURN statement) is executed.

If you specify CHARACTER*(*), the function assumes the length declared for it in the program unit that invokes it. This type of character function can have different lengths when it is invoked by different program units; it is an obsolescent feature in Fortran 95.

If the length is specified as an integer constant, the value must agree with the length of the function specified in the program unit that invokes the function. If no length is specified, a length of 1 is assumed.

If the function is array-valued or a pointer, the declarations within the function must state these attributes for the function result name. The specification of the function result attributes, dummy argument attributes, and the information in the procedure heading collectively define the interface of the function.

The value of the result variable is returned by the function when it completes execution. Certain rules apply depending on whether the result is a pointer, as follows:

  • If the result is a pointer, its allocation status must be determined before the function completes execution. (The function must associate a target with the pointer, or cause the pointer to be explicitly disassociated from a target.)

    The shape of the value returned by the function is determined by the shape of the result variable when the function completes execution.

  • If the result is not a pointer, its value must be defined before the function completes execution. If the result is an array, all the elements must be defined; if the result is a derived-type structure, all the components must be defined.

A function subprogram cannot contain a SUBROUTINE statement, a BLOCK DATA statement, a PROGRAM statement, or another FUNCTION statement. ENTRY statements can be included to provide multiple entry points to the subprogram.

You can use a CALL statement to invoke a function as long as the function is not one of the following types:

  • REAL(8)
  • REAL(16) (VMS, U*X)
  • COMPLEX(8)
  • COMPLEX(16) (VMS, U*X)
  • CHARACTER

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ENTRY, SUBROUTINE, PURE, ELEMENTAL, RESULT keyword, Function References, Program Units and Procedures, General Rules for Function and Subroutine Subprograms

Examples

The following example uses the Newton-Raphson iteration method (F(X) = cosh(X) + cos(X) - A = 0) to get the root of the function:

  FUNCTION ROOT(A)
    X  = 1.0
    DO
      EX = EXP(X)
      EMINX = 1./EX
      ROOT  = X - ((EX+EMINX)*.5+COS(X)-A)/((EX-EMINX)*.5-SIN(X))
      IF (ABS((X-ROOT)/ROOT) .LT. 1E-6) RETURN
      X  = ROOT
    END DO
  END
In the preceding example, the following formula is calculated repeatedly until the difference between Xi and Xi+1 is less than 1.0E-6:
cosh(Xi) + cos(Xi) - A
Xi+1 = Xi -
sinh(Xi) - sin(Xi)
The following example shows an assumed-length character function:
  CHARACTER*(*) FUNCTION REDO(CARG)
    CHARACTER*1 CARG
    DO I=1,LEN(REDO)
      REDO(I:I) = CARG
    END DO
    RETURN
  END FUNCTION

This function returns the value of its argument, repeated to fill the length of the function.

Within any given program unit, all references to an assumed-length character function must have the same length. In the following example, the REDO function has a length of 1000:

  CHARACTER*1000 REDO, MANYAS, MANYZS
  MANYAS = REDO('A')
  MANYZS = REDO('Z')

Another program unit within the executable program can specify a different length. For example, the following REDO function has a length of 2:

  CHARACTER HOLD*6, REDO*2
  HOLD = REDO('A')//REDO('B')//REDO('C')

The following example shows a dynamic array-valued function:

  FUNCTION SUB (N)
    REAL, DIMENSION(N) :: SUB
    ...
  END FUNCTION

The following shows another example:

      INTEGER Divby2
10   PRINT *, 'Enter a number'
      READ *, i
      Print *, Divby2(i)
      GOTO 10
      END
C
C     This is the function definition
C
      INTEGER FUNCTION Divby2 (num)
      Divby2=num / 2
      END FUNCTION


GERROR

Portability Subroutine: Returns a message for the last error detected by a Fortran run-time routine.

Syntax

CALL GERROR (string)

string
(Output) Character*(*). Message corresponding to the last detected error.

The last detected error does not necessarily correspond to the most recent function call. Visual Fortran resets string only when another error occurs.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: PERROR, IERRNO

Example

USE DFPORT
character*40 errtext
character char1
integer*4 iflag, i4
. . .!Open unit 1 here
i4=fgetc(1,char1)
if (i4) then
  iflag = 1
  Call GERROR (errtext)
  print *, errtext
end if


GETACTIVEQQ

QuickWin Function: Returns the unit number of the currently active child window.

Module: USE DFLIB

Syntax

result = GETACTIVEQQ( )

Results:

The result is of type INTEGER(4). The result is the unit number of the currently active window. Returns the parameter QWIN$NOACTIVEWINDOW (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory) if no child window is active.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: SETACTIVEQQ, GETHWNDQQ, Using QuickWin


GETARCINFO

Graphics Function: Determines the endpoints (in viewport coordinates) of the most recently drawn arc or pie.

Module: USE DFLIB

Syntax

result = GETARCINFO (pstart, pend, ppaint)

pstart
(Output) Derived type xycoord. Viewport coordinates of the starting point of the arc.

pend
(Output) Derived type xycoord. Viewport coordinates of the end point of the arc.

ppaint
(Output) Derived type xycoord. Viewport coordinates of the point at which the fill begins.

Results:

The result is of type INTEGER(2). The result is nonzero if successful. The result is zero if neither the ARC nor the PIE function has been successfully called since the last time CLEARSCREEN or SETWINDOWCONFIG was successfully called, or since a new viewport was selected.

GETARCINFO updates the pstart and pend xycoord derived types to contain the endpoints (in viewport coordinates) of the arc drawn by the most recent call to the ARC or PIE functions. The xycoord derived type, defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory), is:

TYPE xycoord
  INTEGER(2) xcoord
  INTEGER(2) ycoord
END TYPE xycoord

The returned value in ppaint specifies a point from which a pie can be filled. You can use this to fill a pie in a color different from the border color. After a call to GETARCINFO, change colors using SETCOLORRGB. Use the new color, along with the coordinates in ppaint, as arguments for the FLOODFILLRGB function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: ARC, FLOODFILLRGB, GETCOLORRGB, GRSTATUS, PIE, SETCOLORRGB

Example

USE DFLIB
INTEGER(2) status, x1, y1, x2, y2, x3, y3, x4, y4
TYPE (xycoord) xystart, xyend, xyfillpt
x1 = 80; y1 = 50
x2 = 240; y2 = 150
x3 = 120; y3 = 80
x4 = 90; y4 = 180

status = ARC(x1, y1, x2, y2, x3, y3, x4, y4)
status = GETARCINFO(xystart, xyend, xyfillpt)
END


GETARG

Run-Time Subroutine: Returns the specified command-line argument (where the command itself is argument number 0).

Module: USE DFLIB

Syntax

CALL GETARG (n, buffer [, status])

n
(Input) INTEGER(2). Position of the command-line argument to retrieve. The command itself is argument number 0.

buffer
(Output) Character*(*). Command-line argument retrieved.

status
(Optional; output) INTEGER(2). If specified, returns the completion status. If there were no errors, status returns the number of characters in the retrieved command-line argument before truncation or blank-padding. (That is, status is the original number of characters in the command-line argument.) Errors return a value of -1. Errors include specifying an argument position less than 0 or greater than the value returned by NARGS.

GETARG can be used with two or three arguments. If you use module DFLIB.F90 in the \DF98\INCLUDE subdirectory (by including the statement USE DFLIB), you can mix calls to GETARG with two or three arguments. If you do not use DFLIB.F90, you can use either two-argument or three-argument calls to GETARG but only one type of call within a subprogram.

GETARG returns command-line arguments as they were entered. There is no case conversion.

If the command-line argument is shorter than buffer, GETARG pads buffer on the right with blanks. If the argument is longer than buffer, GETARG truncates the argument. If there is an error, GETARG fills buffer with blanks.

Assume a command-line invocation of ANOVA -g -c -a, and that buffer is at least five characters long. The following GETARG statements return the corresponding arguments in buffer:

Statement | String returned in buffer | Length returned in status
CALL GETARG (0, buffer, status) | ANOVA | 5
CALL GETARG (1, buffer) | -g | undefined
CALL GETARG (2, buffer, status) | -c | 2
CALL GETARG (3, buffer) | -a | undefined
CALL GETARG (4, buffer, status) | all blanks | -1

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NARGS, IARGC

Example

USE DFLIB
INTEGER(2) result
result = RUNQQ('prog', '-c -r')
END
! PROG.F90
USE DFLIB
INTEGER(2) n1, n2, status
CHARACTER(80) buf
n1 = 1
n2 = 2
CALL GETARG(n1, buf, status)
WRITE(*,*) buf
CALL GETARG(n2, buf )
WRITE (*,*) buf
END


GETBKCOLOR

Graphics Function: Gets the current background color index for both text and graphics output.

Module: USE DFLIB

Syntax

result = GETBKCOLOR( )

Results:

The result is of type INTEGER(4). The result is the current background color index.

GETBKCOLOR returns the current background color index for both text and graphics, as set with SETBKCOLOR. The color index of text over the background color is set with SETTEXTCOLOR and returned with GETTEXTCOLOR. The color index of graphics over the background color is set with SETCOLOR and returned with GETCOLOR. These non-RGB color functions use color indexes, not true color values, and limit the user to colors in the palette, at most 256. For access to all system colors, use SETBKCOLORRGB, SETCOLORRGB, and SETTEXTCOLORRGB.

Generally, INTEGER(4) color arguments refer to color values and INTEGER(2) color arguments refer to color indexes. The two exceptions are GETBKCOLOR and SETBKCOLOR. The default background index is 0, which is associated with black unless the user remaps the palette with REMAPPALETTERGB.

Note: The GETBKCOLOR routine described here is a QuickWin routine. If you are trying to use the Win32 SDK version of the GetBkColor routine by including the DFWIN module, you need to specify the routine name as MSFWIN$GetBkColor. For more information, see Special Naming Convention for Certain QuickWin and Win32 Graphics Routines in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETBKCOLORRGB, SETBKCOLOR, GETCOLOR, GETTEXTCOLOR, REMAPALLPALETTERGB, REMAPPALETTERGB

Example

USE DFLIB
INTEGER(4) bcindex
bcindex = GETBKCOLOR()


GETBKCOLORRGB

Graphics Function: Gets the current background Red-Green-Blue (RGB) color value for both text and graphics.

Module: USE DFLIB

Syntax

result = GETBKCOLORRGB( )

Results:

The result is of type INTEGER(4). The result is the RGB value of the current background color for both text and graphics.

In each RGB color value, each of the three colors, red, green, and blue, is represented by an eight-bit value (2 hex digits). In the value you retrieve with GETBKCOLORRGB, red is the rightmost byte, followed by green and blue. The RGB value's internal structure is as follows:

Larger numbers correspond to stronger color intensity with binary 1111111 (hex FF) the maximum for each of the three components. For example, #0000FF yields full-intensity red, #00FF00 full-intensity green, #FF0000 full-intensity blue, and #FFFFFF full-intensity for all three, resulting in bright white.

GETBKCOLORRGB returns the RGB color value of the current background for both text and graphics, set with SETBKCOLORRGB. The RGB color value of text over the background color (used by text functions such as OUTTEXT, WRITE, and PRINT) is set with SETTEXTCOLORRGB and returned with GETTEXTCOLORRGB. The RGB color value of graphics over the background color (used by graphics functions such as ARC, OUTGTEXT, and FLOODFILLRGB) is set with SETCOLORRGB and returned with GETCOLORRGB.

SETBKCOLORRGB (and the other RGB color selection functions SETCOLORRGB and SETTEXTCOLORRGB) sets the color to a value chosen from the entire available range. The non-RGB color functions (SETBKCOLOR, SETCOLOR, and SETTEXTCOLOR) use color indexes rather than true color values. If you use color indexes, you are restricted to the colors available in the palette, at most 256. Some display adapters (SVGA and true color) are capable of creating 262,144 (256K) colors or more. To access any available color, you need to specify an explicit RGB value with an RGB color function, rather than a palette index with a non-RGB color function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETCOLORRGB, GETTEXTCOLORRGB, SETBKCOLORRGB, GETBKCOLOR

Example

! Build as a QuickWin or Standard Graphics App.
USE DFLIB
INTEGER(4) back, fore, oldcolor
INTEGER(2) status, x1, y1, x2, y2
x1 = 80; y1 = 50
x2 = 240; y2 = 150
oldcolor = SETCOLORRGB(#FF) ! red
! reverse the screen
back = GETBKCOLORRGB()
fore = GETCOLORRGB()
oldcolor = SETBKCOLORRGB(fore)
oldcolor = SETCOLORRGB(back)
CALL CLEARSCREEN ($GCLEARSCREEN)
status = ELLIPSE($GBORDER, x1, y1, x2, y2)
END


GETC

Portability Function: Reads the next available character from external unit 5, which is normally connected to the console.

Module: USE DFPORT

Syntax

result = GETC (char)

char
(Output) Character*(*). First character typed at the keyboard after the call to GETC. If unit 5 is connected to a console device, then no characters are returned until the Enter key is pressed.

Results:

The result is of type INTEGER(4). The result is zero if successful, or -1 if an end-of-file was detected.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAHICS WINDOWS DLL LIB

See Also: GETCHARQQ, GETSTRQQ, Programmer's Guide: Portability Library

Example

    use dfport
    character ans,errtxt*40
    print *, 'Enter a character: '
    ISTAT = GETC (ans)

  if (istat) then
    call gerror(errtxt)
  end if


GETCHARQQ

Run-Time Function: Gets the next keystroke.

Module: USE DFLIB

Syntax

result = GETCHARQQ( )

Results:

The result is of type character with length 1. The result is the character representing the key that was pressed. The value can be any ASCII character.

If the key pressed is represented by a single ASCII character, GETCHARQQ returns the character. If the key pressed is a function or direction key, a hex #00 or #E0 is returned. If you need to know which function or direction was pressed, call GETCHARQQ a second time to get the extended code for the key.

If there is no keystroke waiting in the keyboard buffer, GETCHARQQ waits until there is one, and then returns it. Compare this to the function PEEKCHARQQ, which returns .TRUE. if there is a character waiting in the keyboard buffer, and .FALSE. if not. You can use PEEKCHARQQ to determine if GETCHARQQ should be called. This can prevent a program from hanging while GETCHARQQ waits for a keystroke that isn't there. Note that PEEKCHARQQ is only supported in console applications.

If your application is a QuickWin or Standard Graphics application, you may want to put a call to PASSDIRKEYSQQ in your program. This will enable the program to get characters that would otherwise be trapped. These extra characters are described in PASSDIRKEYSQQ.

Note that the GETCHARQQ routine used in a console application is a different routine than the one used in a QuickWin or Standard Graphics application. The GETCHARQQ used with a console application does not trap characters that are used in QuickWin for a special purpose, such as scrolling. Console applications do not need, and cannot use PASSDIRKEYSQQ.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: PEEKCHARQQ, GETSTRQQ, INCHARQQ, MBINCHARQQ, GETC, FGETC, PASSDIRKEYSQQ

Example

!  Program to demonstrate GETCHARQQ
USE DFLIB
CHARACTER(1) key / 'A' /
PARAMETER (ESC = 27)
PARAMETER (NOREP = 0)
WRITE (*,*) ' Type a key: (or q to quit)'
!  Read keys until ESC or q is pressed
DO WHILE (ICHAR (key) .NE. ESC)
   key = GETCHARQQ()
!  Some extended keys have no ASCII representation
   IF(ICHAR(key) .EQ. NOREP) THEN
     key = GETCHARQQ()
     WRITE (*, 900) 'Not ASCII. Char = NA'
     WRITE (*,*)
!  Otherwise, there is only one key
   ELSE
     WRITE (*,900) 'ASCII. Char = '
     WRITE (*,901) key
   END IF
   IF (key .EQ. 'q' ) THEN
     EXIT
   END IF
   END DO
900   FORMAT (1X, A, \)
901   FORMAT (A)
END


GETCOLOR

Graphics Function: Gets the current graphics color index.

Module: USE DFLIB

Syntax

result = GETCOLOR( )

Results:

The result is of type INTEGER(2). The result is the current color index, if successful; otherwise, -1.

GETCOLOR returns the current color index used for graphics over the background color as set with SETCOLOR. The background color index is set with SETBKCOLOR and returned with GETBKCOLOR. The color index of text over the background color is set with SETTEXTCOLOR and returned with GETTEXTCOLOR. These non-RGB color functions use color indexes, not true color values, and limit the user to colors in the palette, at most 256. For access to all system colors, use SETCOLORRGB, SETBKCOLORRGB, and SETTEXTCOLORRGB.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETCOLORRGB, GETBKCOLOR, GETTEXTCOLOR, SETCOLOR

Example

!  Program to demonstrate GETCOLOR
 PROGRAM COLORS
 USE DFLIB
 INTEGER(2) loop, loop1, status, color
 LOGICAL(4) winstat
 REAL rnd1, rnd2, xnum, ynum
 type (windowconfig) wc
 status = SETCOLOR(INT2(0))
!  Color random pixels with 15 different colors
 DO loop1 = 1, 15
   color = INT2(MOD(GETCOLOR() +1, 16))
   status = SETCOLOR (color) ! Set to next color
   DO loop = 1, 75
!  Set color of random spot, normalized to be on screen
     CALL RANDOM(rnd1)
     CALL RANDOM(rnd2)
     winstat = GETWINDOWCONFIG(wc)
     xnum = wc%numxpixels
     ynum = wc%numypixels
     status = &
     SETPIXEL(INT2(rnd1*xnum+1),INT2(rnd2*ynum))
     status = &
     SETPIXEL(INT2(rnd1*xnum),INT2(rnd2*ynum+1))
     status = &
     SETPIXEL(INT2(rnd1*xnum-1),INT2( rnd2*ynum))
     status = &
     SETPIXEL(INT2(rnd1*xnum),INT2( rnd2*ynum-1))
   END DO
 END DO
 END


GETCOLORRGB

Graphics Function: Gets the current graphics color Red-Green-Blue (RGB) value (used by graphics functions such as ARC, ELLIPSE, and FLOODFILLRGB).

Module: USE DFLIB

Syntax

result = GETCOLORRGB( )

Results:

The result is of type INTEGER(4). The result is the RGB value of the current graphics color.

In each RGB color value, each of the three colors, red, green, and blue, is represented by an eight-bit value (2 hex digits). In the value you retrieve with GETCOLORRGB, red is the rightmost byte, followed by green and blue. The RGB value's internal structure is as follows:

Larger numbers correspond to stronger color intensity with binary 1111111 (hex FF) the maximum for each of the three components. For example, #0000FF yields full-intensity red, #00FF00 full-intensity green, #FF0000 full-intensity blue, and #FFFFFF full-intensity for all three, resulting in bright white.

GETCOLORRGB returns the RGB color value of graphics over the background color (used by graphics functions such as ARC, ELLIPSE, and FLOODFILLRGB), set with SETCOLORRGB. GETBKCOLORRGB returns the RGB color value of the current background for both text and graphics, set with SETBKCOLORRGB. GETTEXTCOLORRGB returns the RGB color value of text over the background color (used by text functions such as OUTTEXT, WRITE, and PRINT), set with SETTEXTCOLORRGB.

SETCOLORRGB (and the other RGB color selection functions SETBKCOLORRGB and SETTEXTCOLORRGB) sets the color to a value chosen from the entire available range. The non-RGB color functions (SETCOLOR, SETBKCOLOR, and SETTEXTCOLOR) use color indexes rather than true color values. If you use color indexes, you are restricted to the colors available in the palette, at most 256. Some display adapters (SVGA and true color) are capable of creating 262,144 (256K) colors or more. To access any available color, you need to specify an explicit RGB value with an RGB color function, rather than a palette index with a non-RGB color function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETBKCOLORRGB, GETTEXTCOLORRGB, SETCOLORRGB, GETCOLOR

Example

! Build as a QuickWin or Standard Graphics App.
USE DFLIB
INTEGER(2) numfonts
INTEGER(4) fore, oldcolor

numfonts = INITIALIZEFONTS ( )
oldcolor = SETCOLORRGB(#FF)   ! set graphics
                              ! color to red
fore = GETCOLORRGB()
oldcolor = SETBKCOLORRGB(fore)  ! set background
                                ! to graphics color
CALL CLEARSCREEN($GCLEARSCREEN)
oldcolor = SETCOLORRGB (#FF0000) ! set graphics
                                 ! color to blue

CALL OUTGTEXT("hello, world")
END


GETCONTROLFPQQ (ia32 only)

Run-Time Subroutine: Returns the floating-point processor control word. This routine is only available on ia32 processors.

Module: USE DFLIB

Syntax

CALL GETCONTROLFPQQ (controlword)

controlword
(Output) INTEGER(2). Floating-point processor control word.

The floating-point control word is a bit flag that controls various modes of the floating-point coprocessor. The DFLIB.F90 module file (in the \DF98\INCLUDE subdirectory) contains constants defined for the control word as follows:

Parameter name | Hex value | Description
FPCW$MCW_IC | #1000 | Infinity control mask
FPCW$AFFINE | #1000 | Affine infinity
FPCW$PROJECTIVE | #0000 | Projective infinity
FPCW$MCW_PC | #0300 | Precision control mask
FPCW$64 | #0300 | 64-bit precision
FPCW$53 | #0200 | 53-bit precision
FPCW$24 | #0000 | 24-bit precision
FPCW$MCW_RC | #0C00 | Rounding control mask
FPCW$CHOP | #0C00 | Truncate
FPCW$UP | #0800 | Round up
FPCW$DOWN | #0400 | Round down
FPCW$NEAR | #0000 | Round to nearest
FPCW$MSW_EM | #003F | Exception mask
FPCW$INVALID | #0001 | Allow invalid numbers
FPCW$DENORMAL | #0002 | Allow denormals (very small numbers)
FPCW$ZERODIVIDE | #0004 | Allow divide by zero
FPCW$OVERFLOW | #0008 | Allow overflow
FPCW$UNDERFLOW | #0010 | Allow underflow
FPCW$INEXACT | #0020 | Allow inexact precision

The defaults for the floating-point control word are 53-bit precision, round to nearest, and the denormal, underflow and inexact precision exceptions disabled. An exception is disabled if its flag is set to 1 and enabled if its flag is cleared to 0. Exceptions can be disabled by setting the flags to 1 with SETCONTROLFPQQ.

If an exception is disabled, it does not cause an interrupt when it occurs. Instead, floating-point processes generate an appropriate special value (NaN or signed infinity), but the program continues.

You can find out which exceptions (if any) occurred by calling GETSTATUSFPQQ. If errors on floating-point exceptions are enabled (by clearing the flags to 0 with SETCONTROLFPQQ), the operating system generates an interrupt when the exception occurs. By default, these interrupts cause run-time errors, but you can capture the interrupts with SIGNALQQ and branch to your own error-handling routines.

You can use GETCONTROLFPQQ to retrieve the current control word and SETCONTROLFPQQ to change the control word. Most users do not need to change the default settings. For a full discussion of the floating-point control word, exceptions, and error handling, see The Floating-Point Environment in the Programmer's Guide.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SETCONTROLFPQQ, GETSTATUSFPQQ, SIGNALQQ, MATHERRQQ, CLEARSTATUSFPQQ

Example

USE DFLIB
INTEGER(2) control
CALL GETCONTROLFPQQ (control)
     !if not rounding down
IF (IAND(control, FPCW$DOWN) .NE. FPCW$DOWN) THEN
  control = IAND(control, NOT(FPCW$MCW_RC)) ! clear all
                                            !  rounding
  control = IOR(control, FPCW$DOWN)         !  set to
                                            !  round down
  CALL SETCONTROLFPQQ(control)
END IF
END


GETCWD

Portability Function: Retrieves the path of the current working directory.

Module: USE DFPORT

Syntax

result = GETCWD (dirname)

dirname
(Output) Character *(*). Name of the current working directory path, including drive letter.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, an error code.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETDRIVEDIRQQ

Example

    character*30 dirname
!   variable dirname must be long enough to hold entire string
    integer(4) istat
    ISTAT = GETCWD (dirname)
    IF (ISTAT == 0) write *, 'Current directory is ',dirname


GETCURRENTPOSITION, GETCURRENTPOSITION_W

Graphics Subroutines: Get the coordinates of the current graphics position.

Module: USE DFLIB

Syntax

CALL GETCURRENTPOSITION (t)
CALL GETCURRENTPOSITION_W (wt)

t
(Output) Derived type xycoord. Viewport coordinates of current graphics position. The derived type xycoord is defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory as follows:
TYPE xycoord
  INTEGER(2) xcoord   ! x-coordinate
  INTEGER(2) ycoord   ! y-coordinate
END TYPE xycoord
wt
(Output) Derived type wxycoord. Window coordinates of current graphics position. The derived type wxycoord is defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as follows:
TYPE wxycoord
  REAL(8) wx    ! x-coordinate
  REAL(8) wy    ! y-coordinate
END TYPE wxycoord

LINETO, MOVETO, and OUTGTEXT all change the current graphics position. It is in the center of the screen when a window is created.

Graphics output starts at the current graphics position returned by GETCURRENTPOSITION or GETCURRENTPOSITION_W. This position is not related to normal text output (from OUTTEXT or WRITE, for example), which begins at the current text position (see SETTEXTPOSITION). It does, however, affect graphics text output from OUTGTEXT.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: LINETO, MOVETO, OUTGTEXT, SETTEXTPOSITION, GETTEXTPOSITION

Example

! Program to demonstrate GETCURRENTPOSITION
USE DFLIB
TYPE (xycoord) position
INTEGER(2)     result
result = LINETO(INT2(300), INT2(200))
CALL GETCURRENTPOSITION( position )
IF (position%xcoord .GT. 50) THEN
  CALL MOVETO(INT2(50), position%ycoord, position)
  WRITE(*,*) "Text unaffected by graphics position"
END IF
result = LINETO(INT2(300), INT2(200))
END


GETDAT

Run-Time Subroutine: Returns the date.

Module: USE DFLIB

Syntax

CALL GETDAT (iyr, imon, iday)

iyr
(Output) INTEGER(2). Year (xxxx AD).

imon
(Output) INTEGER(2). Month (1-12).

iday
(Output) INTEGER(2). Day of the month (1-31).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB

See Also: GETTIM, SETDAT, SETTIM, DATE, FDATE, IDATE, JDATE

Example

! Program to demonstrate GETDAT and GETTIM
USE DFLIB
INTEGER(2) tmpday, tmpmonth, tmpyear
INTEGER(2) tmphour, tmpminute, tmpsecond, tmphund
CHARACTER(1) mer

CALL GETDAT(tmpyear, tmpmonth, tmpday)
CALL GETTIM(tmphour, tmpminute, tmpsecond, tmphund)
IF (tmphour .GT. 12) THEN
  mer = 'p'
  tmphour = tmphour - 12
ELSE
  mer = 'a'
END IF
WRITE (*, 900) tmpmonth, tmpday, tmpyear
900  FORMAT(I2, '/', I2.2, '/', I4.4)
WRITE (*, 901) tmphour,tmpminute,tmpsecond,tmphund,mer
901  FORMAT(I2, ':', I2.2, ':', I2.2, ':', I2.2, ' ',&
            A, 'm')
END


GETDRIVEDIRQQ

Run-Time Function: Gets the path of the current working directory on a specified drive.

Module: USE DFLIB

Syntax

result = GETDRIVEDIRQQ (drivedir)

drivedir
(Input; output) Character*(*). On input, drive whose current working directory path is to be returned. On output, string containing the current directory on that drive in the form d:\dir.

Results:

The result is of type INTEGER(4). The result is the length (in bytes) of the full path of the directory on the specified drive. Zero is returned if the path is longer than the size of the character buffer drivedir.

You specify the drive from which to return the current working directory by putting the drive letter into drivedir before calling GETDRIVEDIRQQ. To make sure you get information about the current drive, put the symbolic constant FILE$CURDRIVE (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory) into drivedir.

Because drives are identified by a single alphabetic character, GETDRIVEDIRQQ examines only the first letter of drivedir. For instance, if drivedir contains the path c:\fps90\bin, GETDRIVEDIRQQ (drivedir) returns the current working directory on drive C and disregards the rest of the path. The drive letter can be uppercase or lowercase.

The length of the path returned depends on how deeply the directories are nested on the drive specified in drivedir. If the full path is longer than the length of drivedir, GETDRIVEDIRQQ returns only the portion of the path that fits into drivedir. If you are likely to encounter a long path, allocate a buffer of size $MAXPATH ($MAXPATH = 260).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB

See Also: CHANGEDRIVEQQ, CHANGEDIRQQ, GETDRIVESIZEQQ, GETDRIVESQQ, GETLASTERRORQQ, SPLITPATHQQ

Example

!  Program to demonstrate GETDRIVEDIRQQ
USE DFLIB
CHARACTER($MAXPATH) dir
INTEGER(4) length

!  Get current directory
dir = FILE$CURDRIVE
length = GETDRIVEDIRQQ(dir)
IF (length .GT. 0) THEN
  WRITE (*,*) 'Current directory is: '
  WRITE (*,*) dir
ELSE
  WRITE (*,*) 'Failed to get current directory'
END IF
END


GETDRIVESIZEQQ

Run-Time Function: Gets the total size of the specified drive and space available on it.

Module: USE DFLIB

Syntax

result = GETDRIVESIZEQQ (drive, total, avail)

drive
(Input) Character*(*). String containing the letter of the drive to get information about.

total
(Output) INTEGER(4) or INTEGER(4),DIMENSION(2) or INTEGER(8). Total number of bytes on the drive.

avail
(Output) INTEGER(4) or INTEGER(4),DIMENSION(2) or INTEGER(8). Number of bytes of available space on the drive.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

The data types and dimension (if any) specified for the total and avail arguments must be the same. Specifying an array of two INTEGER(4) elements, or an INTEGER(8) argument, allows drive sizes larger than 2147483647 to be returned.

If an array of two INTEGER(4) elements is specified, the least-significant 32 bits are returned in the first element, the most-significant 32 bits in the second element. If an INTEGER(4) scalar is specified, the least-significant 32 bits are returned.

Because drives are identified by a single alphabetic character, GETDRIVESIZEQQ examines only the first letter of drive. The drive letter can be uppercase or lowercase. You can use the constant FILE$CURDRIVE (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory) to get the size of the current drive.

If GETDRIVESIZEQQ fails, use GETLASTERRORQQ to determine the reason.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETLASTERRORQQ, GETDRIVESQQ, GETDRIVEDIRQQ, CHANGEDRIVEQQ, CHANGEDIRQQ

Example

! Program to demonstrate GETDRIVESQQ and GETDRIVESIZEQQ
USE DFLIB
CHARACTER(26) drives
CHARACTER(1) adrive
LOGICAL(4) status
INTEGER(4) total, avail
INTEGER(2) i
! Get the list of drives
drives = GETDRIVESQQ()
WRITE (*,'(A, A)') ' Drives available: ', drives
!
!Cycle through them for free space and write to console
DO i = 1, 26
  adrive = drives(i:i)
  status = .FALSE.
  WRITE (*,'(A, A, A, \)') ' Drive ', CHAR(i + 64), ':'
  IF (adrive .NE. ' ') THEN
     status = GETDRIVESIZEQQ(adrive, total, avail)
  END IF
  IF (status) THEN
     WRITE (*,*) avail, ' of ', total, ' bytes free.'
  ELSE
     WRITE (*,*) 'Not available'
  END IF
END DO
END


GETDRIVESQQ

Run-Time Function: Reports which drives are available to the system.

Module: USE DFLIB

Syntax

result = GETDRIVESQQ( )

Results:

The result is of type character with length 26. It is the positional character string containing the letters of the drives available in the system.

The returned string contains letters for drives that are available, and blanks for drives that are not available. For example, on a system with A, C, and D drives, the string 'A CD ' is returned.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB

See Also: GETDRIVEDIRQQ, GETDRIVESIZEQQ, CHANGEDRIVEQQ

Example

See the example for GETDRIVESIZEQQ.


GETENV

Portability Subroutine: Retrieves the value of an environment variable.

Module: USE DFPORT

Syntax

CALL GETENV (ename, evalue)

ename
(Input) Character*(*). Environment variable to search for.

evalue
(Output) Character*(*). Value found for ename. Blank if ename is not found.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETENVQQ

Example

use dfport
character*40 libname
CALL GETENV ("LIB",libname)
TYPE *, "The LIB variable points to ",libname


GETENVQQ

Run-Time Function: Gets the value of a specified environment variable from the current environment.

Module: USE DFLIB

Syntax

result = GETENVQQ (varname, value)

varname
(Input) Character*(*). Name of environment variable.

value
(Output) Character*(*). Value of the specified environment variable, in uppercase.

Results:

The result is of type INTEGER(4). The result is the length of the string returned in value. Zero is returned if the given variable is not defined.

GETENVQQ searches the list of environment variables for an entry corresponding to varname. Environment variables define the environment in which a process executes. (For example, the LIB environment variable defines the default search path for libraries to be linked with a program.)

GETENVQQ uses the C runtime routine getenv and SETENVQQ uses the C runtime routine _putenv. From the C documentation:

getenv and _putenv use the copy of the environment pointed to by the global variable _environ to access the environment. getenv operates only on the data structures accessible to the run-time library and not on the environment segment created for the process by the operating system.

In a program that uses the main function, _environ is initialized at program startup to settings taken from the operating system's environment.

Changes made outside the program by the console SET command, for example, SET MY_VAR=ABCDE, will be reflected by GETENVQQ.

GETENVQQ and SETENVQQ will not work properly with the Win32 APIs GetEnvironmentVariable and SetEnvironmentVariable.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB

See Also: SETENVQQ, GETLASTERRORQQ

Example

!  Program to demonstrate GETENVQQ and SETENVQQ
USE DFLIB
INTEGER(4) lenv, lval
CHARACTER(80) env, val, enval

WRITE (*,900) ' Enter environment variable name to create, &
                modify, or delete: '
lenv = GETSTRQQ(env)
IF (lenv .EQ. 0) STOP
WRITE (*,900) ' Value of variable (ENTER to delete): '
lval = GETSTRQQ(val)
IF (lval .EQ. 0) val = ' '
enval = env(1:lenv) // '=' // val(1:lval)
IF (SETENVQQ(enval)) THEN
  lval = GETENVQQ(env(1:lenv), val)
  IF (lval .EQ. 0) THEN
    WRITE (*,*) 'Can''t get environment variable'
  ELSE IF (lval .GT. LEN(val)) THEN
    WRITE (*,*) 'Buffer too small'
  ELSE
    WRITE (*,*) env(:lenv), ': ', val(:lval)
    WRITE (*,*) 'Length: ', lval
  END IF
ELSE
  WRITE (*,*) 'Can''t set environment variable'
END IF
900  FORMAT (A, \)
END


GETEXCEPTIONPTRSQQ

Run-Time Function: Returns a pointer to C run-time exception information pointers appropriate for use in signal handlers established with SIGNALQQ or direct calls to the C rtl signal( ) routine.

Module: USE DFLIB

Syntax

result = GETEXCEPTIONPTRSQQ( )

Results:

The result is of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors. The return value is the address of a data structure whose members are pointers to exception information captured by the C runtime at the time of an exception. This result value can then be used as the EPTR argument to routine TRACEBACKQQ to generate a stack trace from a user-defined handler or to inspect the exception context record directly.

Calling GETEXCEPTIONPTRSQQ is only valid within a user-defined handler that was established with SIGNALQQ or a direct call to the C rtl signal( ) function.

For a full description of exceptions and error handling, see The Floating Point Environment in the Programmer's Guide.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB

See Also: TRACEBACKQQ, GETSTATUSFPQQ, CLEARSTATUSFPQQ, SETCONTROLFPQQ, GETCONTROLFPQQ, SIGNALQQ, MATHERRQQ

Example

   PROGRAM SIGTEST
   USE DFLIB
   ...
   R3 = 0.0E0
   STS = SIGNALQQ(MY_HANDLER)
   ! Cause a divide by zero exception
   R1 = 3.0E0/R3
   ...
   END

   INTEGER(4) FUNCTION MY_HANDLER(SIGNUM,EXCNUM)
   USE DFLIB
   ...
   EPTRS = GETEXCEPTIONPTRSQQ()
   ...
   CALL TRACEBACKQQ("Application SIGFPE error!",USER_EXIT_CODE=-1,EPTR=EPTRS)
   ...
   MY_HANDLER = 1
   END

A complete working example can be found in the online samples.


GETEXITQQ

QuickWin Function: Gets the setting for a QuickWin application's exit behavior.

Module: USE DFLIB

Syntax

result = GETEXITQQ( )

Results:

The result is of type INTEGER(4). The result is exit mode with one of the following constants (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory):

  • QWIN$EXITPROMPT - Displays a message box that reads "Program exited with exit status n. Exit Window?", where n is the exit status from the program.

    If you choose Yes, the application closes the window and terminates. If you choose No, the dialog box disappears and you can manipulate the window as usual. You must then close the window manually.

  • QWIN$EXITNOPERSIST - Terminates the application without displaying a message box.

  • QWIN$EXITPERSIST - Leaves the application open without displaying a message box.

The default for both QuickWin and Console Graphics applications is QWIN$EXITPROMPT.

Compatibility

STANDARD GRAPHICS QUICKWIN.EXE LIB

See Also: SETEXITQQ, Using QuickWin

Example

!  Program to demonstrate GETEXITQQ
     USE DFLIB
     INTEGER i
     i = GETEXITQQ()
     SELECT CASE (i)
       CASE (QWIN$EXITPROMPT)
         WRITE(*, *) "Prompt on exit."
       CASE (QWIN$EXITNOPERSIST)
         WRITE(*,*) "Exit and close."
       CASE (QWIN$EXITPERSIST)
         WRITE(*,*) "Exit and leave open."
     END SELECT
     END


GETFILEINFOQQ

Run-Time Function: Returns information about the specified file. Filenames can contain wildcards (* and ?).

Module: USE DFLIB

Syntax

result = GETFILEINFOQQ (files, buffer, handle)

files
(Input) Character*(*). Search criteria. Can include a full path. Can include wildcards (* and ?).

buffer
(Output) Derived type FILE$INFO. Information about a file that matches the search criteria. The derived type FILE$INFO is defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as follows:
TYPE FILE$INFO
  INTEGER(4) CREATION
  INTEGER(4) LASTWRITE
  INTEGER(4) LASTACCESS
  INTEGER(4) LENGTH
  INTEGER(4) PERMIT
  CHARACTER(255) NAME
END TYPE FILE$INFO
handle
(Input; output) INTEGER(4). Control mechanism. One of the following constants, defined in DFLIB.F90:

  • FILE$FIRST - First matching file found.
  • FILE$LAST - Previous file was the last valid file.
  • FILE$ERROR - No matching file found.

Results:

The result is of type INTEGER(4). The result is the nonblank length of the filename if a match was found, or 0 if no matching files were found.

To get information about one or more files, set handle to FILE$FIRST and call GETFILEINFOQQ. This will return information about the first file which matches the name and return a handle. If the program wants more files, it should call GETFILEINFOQQ with the handle. GETFILEINFOQQ must be called with the handle until GETFILEINFOQQ sets handle to FILE$LAST, or system resources may be lost.

The derived-type element variables FILE$INFO%CREATION, FILE$INFO%LASTWRITE, and FILE$INFO%LASTACCESS contain packed date and time information that indicates when the file was created, last written to, and last accessed, respectively. To break the time and date into component parts, call UNPACKTIMEQQ. FILE$INFO%LENGTH contains the length of the file in bytes. FILE$INFO%PERMIT contains a set of bit flags describing access information about the file as follows:

If this bit flag is set | The file is...
FILE$ARCHIVE | Marked as having been copied to a backup device.
FILE$DIR | A subdirectory of the current directory. Each MS-DOS directory contains two special files, "." and "..". These are directory aliases created by MS-DOS for use in relative directory notation. The first refers to the current directory, and the second refers to the current directory's parent directory.
FILE$HIDDEN | Hidden. It does not appear in the directory list you request from the command line, the Microsoft visual development environment browser, or File Manager.
FILE$READONLY | Write-protected. You can read the file, but you cannot make changes to it.
FILE$SYSTEM | Used by the operating system.
FILE$VOLUME | A logical volume, or partition, on a physical disk drive. This type of file appears only in the root directory of a physical device.

You can use the constant FILE$NORMAL to check that all bit flags are set to 0. If the derived-type element variable FILE$INFO%PERMIT is equal to FILE$NORMAL, the file has no special attributes. The variable FILE$INFO%NAME contains the short name of the file, not the full path of the file.

If an error occurs, call GETLASTERRORQQ to retrieve the error message, such as:

  • ERR$NOENT: The file or path specified was not found.
  • ERR$NOMEM: Not enough memory is available to execute the command; or the available memory has been corrupted; or an invalid block exists, indicating that the process making the call was not allocated properly.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB

See Also: SETFILEACCESSQQ, SETFILETIMEQQ, UNPACKTIMEQQ

Example

 USE DFLIB
 CALL SHOWPERMISSION( )
 END
!  SUBROUTINE to demonstrate GETFILEINFOQQ
 SUBROUTINE SHOWPERMISSION( )
 USE DFLIB
 CHARACTER(80)    files

 INTEGER(4)       handle, length
 CHARACTER(5)     permit
 TYPE (FILE$INFO) info

WRITE (*, 900) ' Enter wildcard of files to view: '
900   FORMAT (A, \)
 length = GETSTRQQ(files)
 handle = FILE$FIRST
 DO WHILE (.TRUE.)
   length = GETFILEINFOQQ(files, info, handle)
   IF ((handle .EQ. FILE$LAST) .OR. &
     (handle .EQ. FILE$ERROR)) THEN
   SELECT CASE (GETLASTERRORQQ( ))
     CASE (ERR$NOMEM)
       WRITE (*,*) 'Out of memory'
     CASE (ERR$NOENT)
       EXIT
     CASE DEFAULT
       WRITE (*,*) 'Invalid file or path name'
   END SELECT
   END IF
   permit = ' '
   IF ((info%permit .AND. FILE$HIDDEN) .NE. 0) &
     permit(1:1) = 'H'
   IF ((info%permit .AND. FILE$SYSTEM) .NE. 0) &
     permit(2:2) = 'S'
   IF ((info%permit .AND. FILE$READONLY) .NE. 0) &
     permit(3:3) = 'R'
   IF ((info%permit .AND. FILE$ARCHIVE) .NE. 0) &
     permit(4:4) = 'A'
   IF ((info%permit .AND. FILE$DIR) .NE. 0) &
     permit(5:5) = 'D'
   WRITE (*, 9000) info%name, info%length, permit
 9000  FORMAT (1X, A5, I9, ' ',A6)
 END DO
 END SUBROUTINE


GETFILLMASK

Graphics Subroutine: Returns the current pattern used to fill shapes.

Module: USE DFLIB

Syntax

CALL GETFILLMASK (mask)

mask
(Output) INTEGER(1). One-dimensional array of length 8.

There are 8 bytes in mask, and each of the 8 bits in each byte represents a pixel, creating an 8x8 pattern. The first element (byte) of mask becomes the top 8 bits of the pattern, and the eighth element (byte) of mask becomes the bottom 8 bits.

During a fill operation, pixels with a bit value of 1 are set to the current graphics color, while pixels with a bit value of 0 are unchanged. The current graphics color is set with SETCOLORRGB or SETCOLOR. The 8-byte mask is replicated over the entire fill area. If no fill mask is set (with SETFILLMASK), or if the mask is all ones, solid current color is used in fill operations.

The fill mask controls the fill pattern for graphics routines (FLOODFILLRGB, PIE, ELLIPSE, POLYGON, and RECTANGLE).

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: ELLIPSE, FLOODFILLRGB, PIE, POLYGON, RECTANGLE, SETFILLMASK

Example

!  Build as QuickWin or Standard Graphics
USE DFLIB
INTEGER(1) style(8). array(8)
INTEGER(2) i
style = 0
style(1) = #F
style(3) = #F
style(5) = #F
style(7) = #F
CALL SETFILLMASK (style)
...
CALL GETFILLMASK (array)
WRITE (*, *) 'Fill mask in bits: '
DO i = 1, 8
  WRITE (*, '(B8)') array(i)
END DO
END


GETFONTINFO

Graphics Function: Gets the current font characteristics.

Module: USE DFLIB

Syntax

result = GETFONTINFO (font)

font
(Output) Derived type FONTINFO. Set of characteristics of the current font. The FONTINFO derived type is defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as follows:
TYPE FONTINFO
  INTEGER(4) type        ! 1 = truetype, 0 = bit map
  INTEGER(4) ascent      ! Pixel distance from top to
                         !   baseline
  INTEGER(4) pixwidth    ! Character width in pixels,
                         !   0=proportional
  INTEGER(4) pixheight   ! Character height in pixels
  INTEGER(4) avgwidth    ! Average character width in
                         !   pixels
  CHARACTER(32)xfacename ! Font name
  LOGICAL(1) italic      ! .TRUE. if current font
                         !   formatted italic
  LOGICAL(1) emphasized  ! .TRUE. if current font
                         !   formatted bold
  LOGICAL(1) underline   ! .TRUE. if current font
                         !   formatted underlined
END TYPE FONTINFO

Results:

The result is of type INTEGER(2). The result is zero if successful; otherwise, -1.

You must initialize fonts with INITIALIZEFONTS before calling any font-related function, including GETFONTINFO.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETGTEXTEXTENT, GETGTEXTROTATION, GRSTATUS, OUTGTEXT, INITIALIZEFONTS, SETFONT, Using Fonts from the Graphics Library

Example

! Build as QuickWin or Standard Graphics
USE DFLIB
TYPE (FONTINFO) info
INTEGER(2)      numfonts, return, line_spacing
numfonts = INITIALIZEFONTS ( )
return = GETFONTINFO(info)
line_spacing = info%pixheight + 2
END


GETGID

Portability Function: Retrieves the group ID of the user of a process.

Module: USE DFPORT

Syntax

result = GETGID( )

Results:

The result is of type INTEGER(4). The result is always 1.

This function is included for compatibility only.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

  ISTAT = GETGID( )


GETGTEXTEXTENT

Graphics Function: Returns the width in pixels that would be required to print a given string of text (including any trailing blanks) with OUTGTEXT using the current font.

Module: USE DFLIB

Syntax

result = GETGTEXTEXTENT (text)

text
(Input) Character*(*). Text to be analyzed.

Results:

The result is of type INTEGER(2). The result is the width of text in pixels if successful; otherwise, -1 (for example, if fonts have not been initialized with INITIALIZEFONTS).

This function is useful for determining the size of text that uses proportionally spaced fonts. You must initialize fonts with INITIALIZEFONTS before calling any font-related function, including GETGTEXTEXTENT.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETFONTINFO, OUTGTEXT, SETFONT, INITIALIZEFONTS, GETGTEXTROTATION

Example

! Build as QuickWin or Standard Graphics
USE DFLIB
INTEGER(2) status, pwidth
CHARACTER(80) text
status= INITIALIZEFONTS( )
status= SETFONT('t''Arial''h22w10')
pwidth= GETGTEXTEXTENT('How many pixels wide is this?')
WRITE(*,*) pwidth
END


GETGTEXTROTATION

Graphics Function: Returns the current orientation of the font text output by OUTGTEXT.

Module: USE DFLIB

Syntax

result = GETGTEXTROTATION( )

Results:

The result is of type INTEGER(4). It is the current orientation of the font text output in tenths of degrees. Horizontal is 0°, and angles increase counterclockwise so that 900 tenths of degrees (90°) is straight up, 1800 tenths of degrees (180°) is upside-down and left, 2700 tenths of degrees (270°) is straight down, and so forth.

The orientation for text output with OUTGTEXT is set with SETGTEXTROTATION.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: OUTGTEXT, SETFONT, SETGTEXTROTATION

Example

! Build as QuickWin or Standard Graphics
USE DFLIB
INTEGER ang
REAL rang
ang = GETGTEXTROTATION( )
rang = FLOAT(ang)/10.0
WRITE(*,*) "Text tilt in degrees is: ", rang
END


GETHWNDQQ

QuickWin Function: Converts a window unit number into a Windows handle.

Module: USE DFLIB

Syntax

result = GETHWNDQQ (unit)

unit
(Input) INTEGER(4). Window unit number. If unit is set to QWIN$FRAMEWINDOW (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory), the handle of the frame window is returned.

Results:

The result is a true Windows handle to the window. The result is of type INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors. It returns -1 if unit is not open.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: GETACTIVEQQ, GETUNITQQ, SETACTIVEQQ Using QuickWin


GETIMAGE, GETIMAGE_W

Graphics Subroutine: Stores the screen image defined by a specified bounding rectangle.

Module: USE DFLIB

Syntax

CALL GETIMAGE (x1, y1, x2, y2, image)
CALL GETIMAGE_W (wx1, wy1, wx2, wy2, image)

x1, y1
(Input) INTEGER(2). Viewport coordinates for upper-left corner of bounding rectangle.

x2, y2
(Input) INTEGER(2). Viewport coordinates for lower-right corner of bounding rectangle.

wx1, wy1
(Input) REAL(8). Window coordinates for upper-left corner of bounding rectangle.

wx2, wy2
(Input) REAL(8). Window coordinates for lower-right corner of bounding rectangle.

image
(Output) INTEGER(1). Array of single-byte integers. Stored image buffer.

GETIMAGE defines the bounding rectangle in viewport-coordinate points (x1, y1) and (x2, y2). GETIMAGE_W defines the bounding rectangle in window-coordinate points (wx1, wy1) and (wx2, wy2).

The buffer used to store the image must be large enough to hold it. You can determine the image size by calling IMAGESIZE at run time, or by using the formula described under IMAGESIZE. After you have determined the image size, you can dimension the buffer accordingly.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: IMAGESIZE, PUTIMAGE

Example

!  Build as QuickWin or Standard Graphics
USE DFLIB
INTEGER(1), ALLOCATABLE:: buffer (:)
INTEGER(2) status, x, y, error
INTEGER(4) imsize
x = 50
y = 30
status = ELLIPSE ($GFILLINTERIOR, INT2(x-15), &
                  INT2(y-15), INT2( x+15), INT2(y+15))
imsize = IMAGESIZE (INT2(x-16), INT2(y-16), &
                  INT2( x+16), INT2(y+16))
ALLOCATE(buffer (imsize), STAT = error)
IF (error .NE. 0) THEN
  STOP 'ERROR: Insufficient memory'
END IF
CALL GETIMAGE (INT2(x-16), INT2(y-16), &
                  INT2( x+16), INT2(y+16), buffer)
END


GETLASTERRORQQ

Run-Time Function: Returns the last error set by a run-time procedure.

Module: USE DFLIB

Syntax

result = GETLASTERRORQQ( )

Results:

The result is of type INTEGER(4). The result is the most recent error code generated by a run-time procedure.

Run-time functions that return a logical or integer value sometimes also provide an error code that identifies the cause of errors. GETLASTERRORQQ retrieves the most recent error message. The error constants are in DFLIB.F90 (in the \DF98\INCLUDE subdirectory). The following table shows the run-time library routines and the errors each routine produces:

This run-time routine | Produces these errors
RUNQQ | ERR$NOMEM, ERR$2BIG, ERR$INVAL, ERR$NOENT, ERR$NOEXEC
SYSTEMQQ | ERR$NOMEM, ERR$2BIG, ERR$NOENT, ERR$NOEXEC
GETDRIVESIZEQQ | ERR$INVAL, ERR$NOENT
GETDRIVESQQ | no error
GETDRIVEDIRQQ | ERR$NOMEM, ERR$RANGE
CHANGEDRIVEQQ | ERR$INVAL, ERR$NOENT
CHANGEDIRQQ | ERR$NOMEM, ERR$NOENT
MAKEDIRQQ | ERR$NOMEM, ERR$ACCES, ERR$EXIST, ERR$NOENT
DELDIRQQ | ERR$NOMEM, ERR$ACCES, ERR$NOENT
FULLPATHQQ | ERR$NOMEM, ERR$INVAL
SPLITPATHQQ | ERR$NOMEM, ERR$INVAL
GETFILEINFOQQ | ERR$NOMEM, ERR$NOENT, ERR$INVAL
SETFILETIMEQQ | ERR$NOMEM, ERR$ACCES, ERR$INVAL, ERR$MFILE, ERR$NOENT
SETFILEACCESSQQ | ERR$NOMEM, ERR$INVAL, ERR$ACCES
DELFILESQQ | ERR$NOMEM, ERR$ACCES, ERR$NOENT, ERR$INVAL
RENAMEFILEQQ | ERR$NOMEM, ERR$ACCES, ERR$NOENT, ERR$XDEV
FINDFILEQQ | ERR$NOMEM, ERR$NOENT
PACKTIMEQQ | no error
UNPACKTIMEQQ | no error
COMMITQQ | ERR$BADF
GETCHARQQ | no error
PEEKCHARQQ | no error
GETSTRQQ | no error
GETLASTERRORQQ | no error
SETERRORMODEQQ | no error
GETENVQQ | ERR$NOMEM, ERR$NOENT
SETENVQQ | ERR$NOMEM, ERR$INVAL
SLEEPQQ | no error
BEEPQQ | no error
SORTQQ | ERR$INVAL
BSEARCHQQ | ERR$INVAL

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB


GETLINESTYLE

Graphics Function: Returns the current graphics line style.

Module: USE DFLIB

Syntax

result = GETLINESTYLE( )

Results:

The result is of type INTEGER(2). The result is the current line style.

GETLINESTYLE retrieves the mask (line style) used for line drawing. The mask is a 16-bit number, where each bit represents a pixel in the line being drawn.

If a bit is 1, the corresponding pixel is colored according to the current graphics color and logical write mode; if a bit is 0, the corresponding pixel is left unchanged. The mask is repeated for the entire length of the line. The default mask is #FFFF (a solid line). A dashed line can be represented by #FF00 (long dashes) or #F0F0 (short dashes).

The line style is set with SETLINESTYLE. The current graphics color is set with SETCOLORRGB or SETCOLOR. SETWRITEMODE affects how the line is displayed.

The line style retrieved by GETLINESTYLE affects the drawing of straight lines as in LINETO, POLYGON and RECTANGLE, but not the drawing of curved lines as in ARC, ELLIPSE or PIE.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: LINETO, POLYGON, RECTANGLE, SETCOLORRGB, SETFILLMASK, SETLINESTYLE, SETWRITEMODE

Example

!  Build as Graphics
     USE DFLIB
     INTEGER(2) lstyle

     lstyle = GETLINESTYLE()
     WRITE (*, 100) lstyle, lstyle
100  FORMAT (1X, 'Line mask in Hex ', Z4, ' and binary ', B16)
     END


GETLOG

Portability Subroutine: Retrieves the user's login name.

Module: USE DFPORT

Syntax

CALL GETLOG (name)

name
(Output) Character*(*). User's login name, or all blanks if the name cannot be determined.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

use dfport
character*20 username
CALL GETLOG (username)
print *, "You logged in as ",username


GETPHYSCOORD

Graphics Subroutine: Translates viewport coordinates to physical coordinates.

Module: USE DFLIB

Syntax

CALL GETPHYSCOORD (x, y, t)

x, y
(Input) INTEGER(2). Viewport coordinates to be translated to physical coordinates.

t
(Output) Derived Type xycoord. Physical coordinates of the input viewport position. The xycoord derived type is defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as follows:
TYPE xycoord
  INTEGER(2) xcoord   ! x-coordinate
  INTEGER(2) ycoord   ! y-coordinate
END TYPE xycoord

Physical coordinates refer to the physical screen. Viewport coordinates refer to an area of the screen defined as the viewport with SETVIEWPORT. Both take integer coordinate values. Window coordinates refer to a window sized with SETWINDOW or SETWSIZEQQ. Window coordinates are floating-point values and allow easy scaling of data to the window area. For a more complete discussion of coordinate systems, see Understanding Coordinate Systems in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETVIEWCOORD, GETWINDOWCOORD, SETCLIPRGN, SETVIEWPORT

Example

!  Program to demonstrate GETPHYSCOORD, GETVIEWCOORD
!  and GETWINDOWCOORD. Build as QuickWin or Standard
!  Graphics
USE DFLIB
TYPE (xycoord)  viewxy, physxy
TYPE (wxycoord) windxy
CALL SETVIEWPORT(INT2(80), INT2(50), &
                 INT2(240), INT2(150))
!  Get viewport equivalent of point (100, 90)
CALL GETVIEWCOORD (INT2(100), INT2(90), viewxy)
!  Get physical equivalent of viewport coordinates
CALL GETPHYSCOORD (viewxy%xcoord, viewxy%ycoord, &
                   physxy)

!  Get physical equivalent of viewport coordinates
CALL GETWINDOWCOORD (viewxy%xcoord, viewxy%ycoord, &
                     windxy)

!  Write viewport coordinates
WRITE (*,*) viewxy%xcoord, viewxy%ycoord
!  Write physical coordinates
WRITE (*,*) physxy%xcoord, physxy%ycoord
!  Write window coordinates
WRITE (*,*) windxy%wx, windxy%wy
END


GETPID

Portability Function: Returns the process ID of the current process.

Module: USE DFPORT

Syntax

result = GETPID( )

Results:

The result is of type INTEGER(4). The result is the process ID number of the current process.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

USE DFPORT
INTEGER(4) istat
istat = GETPID()


GETPIXEL, GETPIXEL_W

Graphics Function: Returns the color index of the pixel at a specified location.

Module: USE DFLIB

Syntax

result = GETPIXEL (x, y)
result = GETPIXEL_W (wx, wy)

x, y
(Input) INTEGER(2). Viewport coordinates for pixel position.

wx, wy
(Input) REAL(8). Window coordinates for pixel position.

Results:

The result is of type INTEGER(2). The result is the pixel color index if successful; otherwise, -1 (if the pixel lies outside the clipping region, for example).

Color routines without the RGB suffix, such as GETPIXEL, use color indexes, not true color values, and limit you to colors in the palette, at most 256. To access all system colors, use SETPIXELRGB to specify an explicit Red-Green-Blue value and retrieve the value with GETPIXELRGB.

Note: The GETPIXEL routine described here is a QuickWin routine. If you are trying to use the Win32 SDK version of the GetPixel routine by including the DFWIN module, you need to specify the routine name as MSFWIN$GetPixel. For more information, see Special Naming Convention for Certain QuickWin and Win32 Graphics Routines in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETPIXELRGB, GRSTATUS, REMAPALLPALETTERGB, REMAPPALETTERGB, SETCOLOR, GETPIXELS, SETPIXEL


GETPIXELRGB, GETPIXELRGB_W

Graphics Function: Returns the Red-Green-Blue (RGB) color value of the pixel at a specified location.

Module: USE DFLIB

Syntax

result = GETPIXELRGB (x, y)
result = GETPIXELRGB_W (wx, wy)

x, y
(Input) INTEGER(2). Viewport coordinates for pixel position.

wx, wy
(Input) REAL(8). Window coordinates for pixel position.

Results:

The result is of type INTEGER(4). The result is the pixel's current RGB color value.

In each RGB color value, each of the three colors, red, green, and blue, is represented by an eight-bit value (2 hex digits). In the value you retrieve with GETPIXELRGB, red is the rightmost byte, followed by green and blue. The RGB value's internal structure is as follows:

Larger numbers correspond to stronger color intensity with binary 1111111 (hex FF) the maximum for each of the three components. For example, #0000FF yields full-intensity red, #00FF00 full-intensity green, #FF0000 full-intensity blue, and #FFFFFF full-intensity for all three, resulting in bright white.

GETPIXELRGB returns the true color value of the pixel, set with SETPIXELRGB, SETCOLORRGB, SETBKCOLORRGB, or SETTEXTCOLORRGB, depending on the pixel's position and the current configuration of the screen.

SETPIXELRGB (and the other RGB color selection functions SETCOLORRGB, SETBKCOLORRGB, and SETTEXTCOLORRGB) sets colors to a color value chosen from the entire available range. The non-RGB color functions (SETPIXELS, SETCOLOR, SETBKCOLOR, and SETTEXTCOLOR) use color indexes rather than true color values. If you use color indexes, you are restricted to the colors available in the palette, at most 256. Some display adapters (SVGA and true color) are capable of creating 262,144 (256K) colors or more. To access any available color, you need to specify an explicit Red-Green-Blue (RGB) value with an RGB color function, rather than a palette index with a non-RGB color function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETPIXELRGB, GETPIXELSRGB, SETPIXELSRGB, GETPIXEL, GETPIXEL_W

Example

!  Build as QuickWin or Standard Graphics
USE DFLIB
INTEGER(4) pixcolor, rseed
INTEGER(2) status
REAL rnd1, rnd2
LOGICAL(4) winstat
TYPE (windowconfig) wc
CALL GETTIM (status, status, status, INT2(rseed))
CALL SEED (rseed)
CALL RANDOM (rnd1)
CALL RANDOM (rnd2)
!  Get the color index of a random pixel, normalized to
!  be in the window. Then set current color to that
!  pixel color.
winstat = GETWINDOWCONFIG(wc)
xnum = wc%numxpixels
ynum = wc%numypixels
pixcolor = GETPIXELRGB( INT2( rnd1*xnum ), INT2( rnd2*ynum ))
status = SETCOLORRGB (pixcolor)
END


GETPIXELS

Graphics Subroutine: Gets the color indexes of multiple pixels.

Module: USE DFLIB

Syntax

CALL GETPIXELS (n, x, y, color)

n
(Input) INTEGER(4). Number of pixels to get. Sets the number of elements in the other arguments.

x, y
(Input) INTEGER(2). Parallel arrays containing viewport coordinates of pixels to get.

color
(Output) INTEGER(2). Array to be filled with the color indexes of the pixels at x and y.

GETPIXELS fills in the array color with color indexes of the pixels specified by the two input arrays x and y. These arrays are parallel: the first element in each of the three arrays refers to a single pixel, the second element refers to the next pixel, and so on.

If the pixel is outside the clipping region, the value placed in the color array is undefined. Calls to GETPIXELS with n less than 1 are ignored. GETPIXELS is a much faster way to acquire multiple pixel color indexes than individual calls to GETPIXEL.

The range of possible pixel color index values is determined by the current video mode and palette, at most 256 colors. To access all system colors you need to specify an explicit Red-Green-Blue (RGB) value with an RGB color function such as SETPIXELSRGB and retrieve the value with GETPIXELSRGB, rather than a palette index with a non-RGB color function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETPIXELSRGB, SETPIXELSRGB, GETPIXEL, SETPIXELS


GETPIXELSRGB

Graphics Subroutine: Returns the Red-Green-Blue (RGB) color values of multiple pixels.

Module: USE DFLIB

Syntax

CALL GETPIXELSRGB (n, x, y, color)

n
(Input) INTEGER(4). Number of pixels to get. Sets the number of elements in the other argument arrays.

x, y
(Input) INTEGER(2). Parallel arrays containing viewport coordinates of pixels.

color
(Output) INTEGER(4). Array to be filled with RGB color values of the pixels at x and y.

GETPIXELS fills in the array color with the RGB color values of the pixels specified by the two input arrays x and y. These arrays are parallel: the first element in each of the three arrays refers to a single pixel, the second element refers to the next pixel, and so on.

In each RGB color value, each of the three colors, red, green, and blue, is represented by an eight-bit value (2 hex digits). In the values you retrieve with GETPIXELSRGB, red is the rightmost byte, followed by green and blue. The RGB value's internal structure is as follows:

Larger numbers correspond to stronger color intensity with binary 11111111 (hex FF) the maximum for each of the three components. For example, #0000FF yields full-intensity red, #00FF00 full-intensity green, #FF0000 full-intensity blue, and #FFFFFF full-intensity for all three, resulting in bright white.

GETPIXELSRGB is a much faster way to acquire multiple pixel RGB colors than individual calls to GETPIXELRGB. GETPIXELSRGB returns an array of true color values of multiple pixels, set with SETPIXELSRGB, SETCOLORRGB, SETBKCOLORRGB, or SETTEXTCOLORRGB, depending on the pixels' positions and the current configuration of the screen.

SETPIXELSRGB (and the other RGB color selection functions SETCOLORRGB, SETBKCOLORRGB, and SETTEXTCOLORRGB) sets colors to a color value chosen from the entire available range. The non-RGB color functions (SETPIXELS, SETCOLOR, SETBKCOLOR, and SETTEXTCOLOR) use color indexes rather than true color values. If you use color indexes, you are restricted to the colors available in the palette, at most 256. Some display adapters (SVGA and true color) are capable of creating 262,144 (256K) colors or more. To access any available color, you need to specify an explicit RGB value with an RGB color function, rather than a palette index with a non-RGB color function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETPIXELSRGB, GETPIXELRGB, GETPIXELRGB_W, GETPIXELS, SETPIXELS

Example

!  Build as QuickWin or Standard Graphics
USE DFLIB
INTEGER(4) color(50), result
INTEGER(2) x(50), y(50), status
TYPE (xycoord) pos

result = SETCOLORRGB(#FF)
CALL MOVETO(INT2(0), INT2(0), pos)
status = LINETO(INT2(100), INT2(200))

!  Get 50 pixels at line 30 in viewport
DO i = 1, 50
  x(i) = i-1
  y(i) = 30
END DO
CALL GETPIXELSRGB(300, x, y, color)
!  Move down 30 pixels and redisplay pixels
DO i = 1, 50
  y(i) = y(i) + 30
END DO
CALL SETPIXELSRGB (50, x, y, color)
END


GETSTATUSFPQQ (ia32 only)

Run-Time Subroutine: Returns the floating-point processor status word. This routine is only available on ia32 processors.

Module: USE DFLIB

Syntax

CALL GETSTATUSFPQQ (status)

status
(Output) INTEGER(2). Floating-point processor status word.

The floating-point status word shows whether various floating-point exception conditions have occurred. Visual Fortran initially clears (sets to 0) all status flags, but after an exception occurs it does not reset the flags before performing additional floating-point operations. A status flag with a value of one thus shows there has been at least one occurence of the corresponding exception. The following table lists the status flags and their values:

Parameter name | Hex value | Description
FPSW$MSW_EM | #003F | Status Mask (set all flags to 1)
FPSW$INVALID | #0001 | An invalid result occurred
FPSW$DENORMAL | #0002 | A denormal (very small number) occurred
FPSW$ZERODIVIDE | #0004 | A divide by zero occurred
FPSW$OVERFLOW | #0008 | An overflow occurred
FPSW$UNDERFLOW | #0010 | An underflow occurred
FPSW$INEXACT | #0020 | Inexact precision occurred

You can use a logical comparison on the status word returned by GETSTATUSFPQQ to determine which of the six floating-point exceptions listed in the table has occurred.

An exception is disabled if its flag is set to 1 and enabled if its flag is cleared to 0. By default, the denormal, underflow and inexact precision exceptions are disabled, and the invalid, overflow and divide-by-zero exceptions are enabled. Exceptions can be enabled and disabled by clearing and setting the flags with SETCONTROLFPQQ. You can use GETCONTROLFPQQ to determine which exceptions are currently enabled and disabled.

If an exception is disabled, it does not cause an interrupt when it occurs. Instead, floating-point processes generate an appropriate special value (NaN or signed infinity), but the program continues. You can find out which exceptions (if any) occurred by calling GETSTATUSFPQQ.

If errors on floating-point exceptions are enabled (by clearing the flags to 0 with SETCONTROLFPQQ), the operating system generates an interrupt when the exception occurs. By default, these interrupts cause run-time errors, but you can capture the interrupts with SIGNALQQ and branch to your own error-handling routines.

For a full discussion of the floating-point status word, exceptions, and error handling, see The Floating-Point Environment in the Programmer's Guide.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB

See Also: SETCONTROLFPQQ, GETCONTROLFPQQ, SIGNALQQ, MATHERRQQ, CLEARSTATUSFPQQ

Example

!  Program to demonstrate GETSTATUSFPQQ
 USE DFLIB
 INTEGER(2) status

 CALL GETSTATUSFPQQ(status)
!  check for divide by zero
 IF (IAND(status, FPSW$ZERODIVIDE) .NE. 0) THEN
   WRITE (*,*) 'Divide by zero occurred. Look    &
   for NaN or signed infinity in resultant data.'
 END IF
END


GETSTRQQ

Run-Time Function: Reads a character string from the keyboard using buffered input.

Module: USE DFLIB

Syntax

result = GETSTRQQ (buffer)

buffer
(Output) Character*(*). Character string returned from keyboard, padded with blanks.

Results:

The result is of type INTEGER(4). The result is the number of characters placed in buffer.

The function does not complete until you press Return or Enter.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: READ, GETCHARQQ, PEEKCHARQQ

Example

!  Program to demonstrate GETSTRQQ
 USE DFLIB
 INTEGER(4) length, result
 CHARACTER(80) prog, args
 WRITE (*, '(A, \)') ' Enter program to run: '
 length = GETSTRQQ (prog)
 WRITE (*, '(A, \)') ' Enter arguments: '
 length = GETSTRQQ (args)
 result = RUNQQ (prog, args)
 IF (result .EQ. -1) THEN
   WRITE (*,*) 'Couldn''t run program'
 ELSE
   WRITE (*, '(A, Z4, A)') 'Return code : ', result, 'h'
 END IF
 END


GETTEXTCOLOR

Graphics Function: Gets the current text color index.

Module: USE DFLIB

Syntax

result = GETTEXTCOLOR( )

Results:

The result is of type INTEGER(2). It is the current text color index.

GETTEXTCOLOR returns the text color index set by SETTEXTCOLOR. SETTEXTCOLOR affects text output with OUTTEXT, WRITE, and PRINT. The background color index is set with SETBKCOLOR and returned with GETBKCOLOR. The color index of graphics over the background color is set with SETCOLOR and returned with GETCOLOR. These non-RGB color functions use color indexes, not true color values, and limit the user to colors in the palette, at most 256. To access all system colors, use SETTEXTCOLORRGB, SETBKCOLORRGB, and SETCOLORRGB.

The default text color index is 15, which is associated with white unless the user remaps the palette.

Note: The GETTEXTCOLOR routine described here is a QuickWin routine. If you are trying to use the Win32 SDK version of the GetTextColor routine by including the DFWIN module, you need to specify the routine name as MSFWIN$GetTextColor. For more information, see Special Naming Convention for Certain QuickWin and Win32 Graphics Routines in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: OUTTEXT, REMAPPALETTERGB, SETCOLOR, SETTEXTCOLOR


GETTEXTCOLORRGB

Graphics Function: Gets the Red-Green-Blue (RGB) value of the current text color (used with OUTTEXT, WRITE and PRINT).

Module: USE DFLIB

Syntax

result = GETTEXTCOLORRGB( )

Results:

The result is of type INTEGER(4). It is the RGB value of the current text color.

In each RGB color calue, each of the three colors, red, green, and blue, is represented by an eight-bit value (2 hex digits). In the value you retrieve with GETTEXTCOLORRGB, red is the rightmost byte, followed by green and blue. The RGB value's internal structure is as follows:

Larger numbers correspond to stronger color intensity with binary (hex FF) the maximum for each of the three components. For example, #0000FF yields full-intensity red, #00FF00 full-intensity green, #FF0000 full-intensity blue, and #FFFFFF full-intensity for all three, resulting in bright white.

GETTEXTCOLORRGB returns the RGB color value of text over the background color (used by text functions such as OUTTEXT, WRITE, and PRINT), set with SETTEXTCOLORRGB. The RGB color value used for graphics is set and returned with SETCOLORRGB and GETCOLORRGB. SETCOLORRGB controls the color used by the graphics function OUTGTEXT, while SETTEXTCOLORRGB controls the color used by all other text output functions. The RGB background color value for both text and graphics is set and returned with SETBKCOLORRGB and GETBKCOLORRGB.

SETTEXTCOLORRGB (and the other RGB color selection functions SETBKCOLORRGB, and SETCOLORRGB) sets the color to a color value chosen from the entire available range. The non-RGB color functions (SETTEXTCOLOR, SETBKCOLOR, and SETCOLOR) use color indexes rather than true color values. If you use color indexes, you are restricted to the colors available in the palette, at most 256. Some display adapters (SVGA and true color) are capable of creating 262,144 (256K) colors or more. To access any available color, you need to specify an explicit RGB value with an RGB color function, rather than a palette index with a non-RGB color function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETTEXTCOLORRGB, GETBKCOLORRGB, GETCOLORRGB, GETTEXTCOLOR

Example

!  Build as QuickWin or Standard Graphics
USE DFLIB
INTEGER(4) oldtextc, oldbackc, temp
TYPE (rccoord) curpos
!  Save color settings
oldtextc = GETTEXTCOLORRGB()
oldbackc = GETBKCOLORRGB()
CALL CLEARSCREEN( $GCLEARSCREEN )
!  Reset colors
temp = SETTEXTCOLORRGB(#00FFFF)  ! full red + full green
                                 ! = full yellow text
temp = SETBKCOLORRGB(#FF0000)    ! blue background
CALL SETTEXTPOSITION( INT2(4), INT2(15), curpos)
CALL OUTTEXT( 'Hello, world')
!  Restore colors
temp = SETTEXTCOLORRGB(oldtextc)
temp = SETBKCOLORRGB(oldbackc)
END


GETTEXTPOSITION

Graphics Subroutine: Returns the current text position.

Module: USE DFLIB

Syntax

CALL GETTEXTPOSITION (t)

t
(Output) Derived type rccord. Current text position.The derived type rccoord is defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as follows:
  TYPE rccoord
    INTEGER(2) row   ! Row coordinate
    INTEGER(2) col   ! Column coordinate
  END TYPE rccoord

The text position given by coordinates (1, 1) is defined as the upper-left corner of the text window. Text output from the OUTTEXT function (and WRITE and PRINT statements) begins at the current text position. Font text is not affected by the current text position. Graphics output, including OUTGTEXT output, begins at the current graphics output position, which is a separate position returned by GETCURRENTPOSITION.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETTEXTPOSITION, GETCURRENTPOSITION, OUTTEXT, WRITE, SETTEXTWINDOW

Example

!  Build as QuickWin or Standard Graphics
     USE DFLIB
     TYPE (rccoord) textpos
     CALL GETTEXTPOSITION (textpos)
     END


GETTEXTWINDOW

Graphics Subroutine: Finds the boundaries of the current text window.

Module: USE DFLIB

Syntax

CALL GETTEXTWINDOW (r1, c1, r2, c2)

r1, c1
(Output) INTEGER(2). Row and column coordinates for upper-left corner of the text window.

r2, c2
(Output) INTEGER(2). Row and column coordinates for lower-right corner of the text window.

Output from OUTTEXT and WRITE is limited to the text window. By default, this is the entire window, unless the text window is redefined by SETTEXTWINDOW.

The window defined by SETTEXTWINDOW has no effect on output from OUTGTEXT.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETTEXTPOSITION, OUTTEXT, WRITE, SCROLLTEXTWINDOW, SETTEXTPOSITION, SETTEXTWINDOW, WRAPON

Example

!  Build as QuickWin or Standard Graphics
USE DFLIB
INTEGER(2) top, left, bottom, right
DO i = 1, 10
  WRITE(*,*) "Hello, world"
END DO
!  Save text window position
 CALL GETTEXTWINDOW (top, left, bottom, right)
!  Scroll text window down seven lines
 CALL SCROLLTEXTWINDOW (INT2(-7))
!  Restore text window
 CALL SETTEXTWINDOW (top, left, bottom, right)
 WRITE(*,*) "At beginning again"
 END


GETTIM

Run-Time Subroutine: Returns the time.

Module: USE DFLIB

Syntax

CALL GETTIM (ihr, imin, isec, i100th)

ihr
(Output) INTEGER(2). Hour (0-23).

imin
(Output) INTEGER(2). Minute (0-59).

isec
(Output) INTEGER(2). Second (0-59).

i100th
(Output) INTEGER(2). Hundredths of a second (0-99).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB

See Also: GETDAT, SETDAT, SETTIM, CLOCK, CTIME, DTIME, ETIME, GMTIME, ITIME, LTIME, RTC, SECNDS, TIME, TIMEF

Example

See the example in GETDAT.


GETUID

Portability Function: Retrieves the user ID of the calling process.

Module: USE DFPORT

Syntax

result = GETUID( )

Results:

The result is of type INTEGER(4). The result is always 1.

This function is included for compatibility only.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

USE DFPORT
integer(4) istat
ISTAT = GETUID( )


GETUNITQQ

QuickWin Function: Returns the unit number corresponding to the specified Windows handle.

Module: USE DFLIB

Syntax

result = GETUNITQQ (whandle)

whandle
(Input) The Windows handle to the window; this is a unique ID. INTEGER(4) on ia32 processors; INTEGER(8) on ia64 processors.

Results:

The result is of type INTEGER(4). The result is the unit number corresponding to the specified Windows handle. It returns -1 if whandle does not exist.

This routine is the inverse of GETHWNDQQ.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: GETHWNDQQ, Using QuickWin


GETVIEWCOORD, GETVIEWCOORD_W

Graphics Subroutine: Translates physical coordinates or window coordinates to viewport coordinates.

Module: USE DFLIB

Syntax

CALL GETVIEWCOORD (x, y, t)
CALL GETVIEWCOORD_W (wx, wy, wt)

x, y
(Input) INTEGER(2). Physical coordinates to be converted to viewport coordinates.

t
(Output) Derived type xycoord. Viewport coordinates. The xycoord derived type is defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as follows:
TYPE xycoord
  INTEGER(2) xcoord   ! x-coordinate
  INTEGER(2) ycoord   ! y-coordinate
END TYPE xycoord
wx, wy
(Input) REAL(8). Window coordinates to be converted to viewport coordinates.

wt
(Output) Derived type xycoord. Viewport coordinates. The xycoord derived type is defined in DFLIB.F90 (see above).

Viewport coordinates refer to an area of the screen defined as the viewport with SETVIEWPORT. Physical coordinates refer to the whole screen. Both take integer coordinate values. Window coordinates refer to a window sized with SETWINDOW or SETWSIZEQQ. Window coordinates are floating-point values and allow easy scaling of data to the window area. For a more complete discussion of coordinate systems, see Understanding Coordinate Systems in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETPHYSCOORD, GETWINDOWCOORD

Example

See the example program in GETPHYSCOORD.


GETWINDOWCONFIG

QuickWin Function: Gets the properties of the current window.

Module: USE DFLIB

Syntax

result = GETWINDOWCONFIG (wc)

wc
(Output) Derived type windowconfig. Contains window properties. The windowconfig derived type is defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as follows:
TYPE windowconfig
  INTEGER(2) numxpixels             ! Number of pixels on x-axis.
  INTEGER(2) numypixels             ! Number of pixels on y-axis.
  INTEGER(2) numtextcols        ! Number of text columns available.
  INTEGER(2) numtextrows        ! Number of text rows available.
  INTEGER(2) numcolors              ! Number of color indexes.
  INTEGER(4) fontsize           ! Size of default font. Set to
                                ! QWIN$EXTENDFONT when specifying
                                ! extended attributes, in which
                                ! case extendfontsize sets the
                                ! font size.
  CHARACTER(80) title               ! The window title.
  INTEGER(2) bitsperpixel       ! The number of bits per pixel.
  INTEGER(2) numvideopages          ! Unused.
  INTEGER(2) mode               ! Controls scrolling mode.
  INTEGER(2) adapter                ! Unused.
  INTEGER(2) monitor                ! Unused.
  INTEGER(2) memory                 ! Unused.
  INTEGER(2) environment            ! Unused.
! The next three parameters provide extended font
! attributes.
  CHARACTER(32) extendfontname      ! The name of the desired font.
  INTEGER(4) extendfontsize     ! Takes the same values as fontsize,
                                ! when fontsize is set to
                                ! QWIN$EXTENDFONT.
  INTEGER(4) extendfontattributes   ! Font attributes such as bold
                                    ! and italic.
END TYPE windowconfig

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

GETWINDOWCONFIG returns information about the active child window. If you have not set the window properties with SETWINDOWCONFIG, GETWINDOWCONFIG returns default window values.

A typical set of values would be 1024 x pixels, 768 y pixels, 128 text columns, 48 text rows, and a font size of 8x16 pixels. The resolution of the display and the assumed font size of 8x16 pixels generates the number of text rows and text columns. The resolution (in this case, 1024 x pixels by 768 y pixels) is the size of the virtual window. To get the size of the physical window visible on the screen, use GETWSIZEQQ. In this case, GETWSIZEQQ returned the following values: (0,0) for the x and y position of the physical window, 25 for the height or number of rows, and 71 for the width or number of columns.

The number of colors returned depends on the video drive. The window title defaults to "Graphic1" for the default window. All of these values can be changed with SETWINDOWCONFIG.

Note that the bitsperpixel field in the windowconfig derived type is an output field only, while the other fields return output values to GETWINDOWCONFIG and accept input values from SETWINDOWCONFIG.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETWSIZEQQ SETWINDOWCONFIG, SETACTIVEQQ, Using QuickWin

Example

!Build as QuickWin or Standard Graphics App.
USE DFLIB
LOGICAL(4) status
TYPE (windowconfig) wc
status = GETWINDOWCONFIG(wc)
IF(wc%numtextrows .LT. 10) THEN
  wc%numtextrows = 10
  status = SETWINDOWCONFIG(wc)
  IF(.NOT. status ) THEN  ! if setwindowconfig error
    status = SETWINDOWCONFIG(wc)   ! reset
             ! setwindowconfig with corrected values
    status = GETWINDOWCONFIG(wc)
    IF(wc%numtextrows .NE. 10) THEN
       WRITE(*,*) 'Error: Cannot increase text rows to 10'
    END IF
  END IF
END IF
END


GETWINDOWCOORD

Graphics Subroutine: Translates viewport coordinates to window coordinates.

Module: USE DFLIB

Syntax

CALL GETWINDOWCOORD (x, y, wt)

x, y
(Input) INTEGER(2). Viewport coordinates to be converted to window coordinates.

wt
(Output) Derived type wxycoord. Window coordinates. The wxycoord derived type is defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as follows:
TYPE wxycoord
  REAL(8) wx   ! x-coordinate
  REAL(8) wy   ! y-coordinate
END TYPE wxycoord

Physical coordinates refer to the physical screen. Viewport coordinates refer to an area of the screen defined as the viewport with SETVIEWPORT. Both take integer coordinate values. Window coordinates refer to a window sized with SETWINDOW or SETWSIZEQQ. Window coordinates are floating-point values and allow easy scaling of data to the window area. For a more complete discussion of coordinate systems, see Understanding Coordinate Systems in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETCURRENTPOSITION, GETPHYSCOORD, GETVIEWCOORD, MOVETO, SETVIEWPORT, SETWINDOW

Example

See the example program in GETPHYSCOORD.


GETWRITEMODE

Graphics Function: Returns the current logical write mode, which is used when drawing lines with the LINETO, POLYGON, and RECTANGLE functions.

Module: USE DFLIB

Syntax

result = GETWRITEMODE( )

Results:

The result is of type INTEGER(2). The result is the current write mode. Possible return values are:

  • $GPSET - Causes lines to be drawn in the current graphics color. (default)

  • $GAND - Causes lines to be drawn in the color that is the logical AND of the current graphics color and the current background color.

  • $GOR - Causes lines to be drawn in the color that is the logical OR of the current graphics color and the current background color.

  • $GPRESET - Causes lines to be drawn in the color that is the logical NOT of the current graphics color.

  • $GXOR - Causes lines to be drawn in the color that is the logical exclusive OR (XOR) of the current graphics color and the current background color.

The default value is $GPSET. These constants are defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory).

The write mode is set with SETWRITEMODE.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETWRITEMODE, SETLINESTYLE, LINETO, POLYGON, PUTIMAGE, RECTANGLE, SETCOLORRGB, SETFILLMASK, GRSTATUS

Example

! Build as QuickWin or Standard Graphics App.
   USE DFLIB
   INTEGER(2) mode
   mode = GETWRITEMODE()
   END


GETWSIZEQQ

QuickWin Function: Gets the size and position of a window.

Module: USE DFLIB

Syntax

result = GETWSIZEQQ (unit, ireq, winfo)

unit
(Input) INTEGER(4). Specifies the window unit. Unit numbers 0, 5 and 6 refer to the default startup window only if you have not explicitly opened them with the OPEN statement. To access information about the frame window (as opposed to a child window), set unit to the symbolic constant QWIN$FRAMEWINDOW, defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory.

ireq
(Input) INTEGER(4). Specifies what information is obtained. The following symbolic constants, defined in DFLIB.F90, are available:

  • QWIN$SIZEMAX - Gets information about the maximum window size.
  • QWIN$SIZECURR - Gets information about the current window size.

winfo
(Output) Derived type qwinfo. Physical coordinates of the window's upper-left corner, and the current or maximum height and width of the window's client area (the area within the frame). The derived type qwinfo is defined in DFLIB.F90 as follows:
TYPE QWINFO
  INTEGER(2) TYPE  ! request type (controls
                   ! SETWSIZEQQ)
  INTEGER(2) X     ! x coordinate for upper left
  INTEGER(2) Y     ! y coordinate for upper left
  INTEGER(2) H     ! window height
  INTEGER(2) W     ! window width
END TYPE QWINFO

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, nonzero.

The position and dimensions of child windows are expressed in units of character height and width. The position and dimensions of the frame window are expressed in screen pixels.

The height and width returned for a frame window reflects the size in pixels of the client area excluding any borders, menus, and status bar at the bottom of the frame window. You should adjust the values used in SETWSIZEQQ to take this into account.

The client area is the area actually available to place child windows.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: GETWINDOWCONFIG, SETWSIZEQQ, Using QuickWin


GMTIME

Portability Subroutine: Returns the Greenwich mean time in an array of time elements.

Module: USE DFPORT

Syntax

CALL GMTIME (stime, tarray)

stime
(Input) Default integer (INTEGER(4) unless changed by the user). Numeric time data to be formatted. Number of seconds since 00:00:00 Greenwich mean time, January 1, 1970.

tarray
(Output) Default integer (INTEGER(4) unless changed by the user). One-dimensional array with 9 elements used to contain numeric time data. The elements of tarray are returned as follows:

Element | Value
tarray(1) | Seconds (0-59)
tarray(2) | Minutes (0-59)
tarray(3) | Hours (0-23)
tarray(4) | Day of month (1-31)
tarray(5) | Month (0-11)
tarray(6) | Number of years since 1900
tarray(7) | Day of week (0-6, where 0 is Sunday)
tarray(8) | Day of year (0-365)
tarray(9) | Daylight saving flag (0 if standard time, 1 if daylight saving time)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE_AND_TIME

Example

use dfport
integer(4) stime, timearray(9)
! initialize stime to number of seconds since
!   00:00:00 GMT January 1, 1970
stime = time()
CALL GMTIME (stime, timearray)
print *, timearray
end


GOTO - Assigned

Statement: Transfers control to the statement whose label was most recently assigned to a variable. This feature has been deleted in Fortran 95; it was obsolescent in Fortran 90. Compaq Fortran fully supports features deleted in Fortran 95.

Syntax

GOTO var [[ , ] ( label-list )]

var
Is a scalar integer variable.

label-list
Is a list of labels (separated by commas) of valid branch target statements in the same scoping unit as the assigned GO TO statement. The same label can appear more than once in this list.

Rules and Behavior

The variable must have a statement label value assigned to it by an ASSIGN statement (not an arithmetic assignment statement) before the GO TO statement is executed.

If a list of labels appears, the statement label assigned to the variable must be one of the labels in the list.

Both the assigned GO TO statement and its associated ASSIGN statement must be in the same scoping unit.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Obsolescent Features in Fortran 90, GOTO - Computed GOTO, GOTO - Unconditional GOTO, Execution Control

Examples

The following example is equivalent to GO TO 200:

  ASSIGN 200 TO IGO
  GO TO IGO

The following example is equivalent to GO TO 450:

  ASSIGN 450 TO IBEG
  GO TO IBEG, (300,450,1000,25)

The following example shows an invalid use of an assigned variable:

  ASSIGN 10 TO I
  J = I
  GO TO J

In this case, variable J is not the variable assigned to, so it cannot be used in the assigned GO TO statement.

The following shows another example:

      ASSIGN 10 TO n
      GOTO n
  10  CONTINUE

The following example uses an assigned GOTO statement to check the value of view:

  C   Show user appropriate view of data depending on
  C   security clearance.
      GOTO view (100, 200, 400)


GOTO - Computed

Statement: Transfers control to one of a set of labeled branch target statements based on the value of an expression. It is an obsolescent feature in Fortran 95.

Syntax

GOTO (label-list) [ , ] expr

label-list
Is a list of labels (separated by commas) of valid branch target statements in the same scoping unit as the computed GO TO statement. (Also called the transfer list.) The same label can appear more than once in this list.

expr
Is a scalar numeric expression in the range 1 to n, where n is the number of statement labels in label-list. If necessary, it is converted to integer data type.

Rules and Behavior

When the computed GO TO statement is executed, the expression is evaluated first. The value of the expression represents the ordinal position of a label in the associated list of labels. Control is transferred to the statement identified by the label. For example, if the list contains (30,20,30,40) and the value of the expression is 2, control is transferred to the statement identified with label 20.

If the value of the expression is less than 1 or greater than the number of labels in the list, control is transferred to the next executable statement or construct following the computed GO TO statement.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GOTO - Unconditional GOTO, Execution Control

Examples

The following example shows valid computed GO TO statements:

GO TO (12,24,36), INDEX
GO TO (320,330,340,350,360), SITU(J,K) + 1

The following shows another example:

   next = 1
C
C  The following statement transfers control to statement 10:
C
   GOTO (10, 20) next
   ...
10 CONTINUE
   ...
20 CONTINUE


GOTO - Unconditional

Statement: Transfers control to the same branch target statement every time it executes.

Syntax

GO TO label

label
Is the label of a valid branch target statement in the same scoping unit as the GO TO statement.

The unconditional GO TO statement transfers control to the branch target statement identified by the specified label.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GOTO - Computed GOTO, Execution Control

Examples

The following are examples of GO TO statements:

  GO TO 7734
  GO TO 99999

The following shows another example:

    integer(2) in
10  print *, 'enter a number from one to ten: '
    read *, in
    select case (in)
    case (1:10)
      exit
    case default
      print *, 'wrong entry, try again'
      goto 10
    end select


GRSTATUS

Graphics Function: Returns the status of the most recently used graphics routine.

Module: USE DFLIB

Syntax

result = GRSTATUS( )

Results:

The result is of type INTEGER(2). The result is the status of the most recently used graphics function.

Use GRSTATUS immediately following a call to a graphics routine to determine if errors or warnings were generated. Return values less than 0 are errors, and values greater than 0 are warnings.

The following symbolic constants are defined in the DFLIB.F90 module file (in the \DF98\INCLUDE subdirectory) for use with GRSTATUS:

Constant | Meaning
$GRFILEWRITEERROR | Error writing bitmap file
$GRFILEOPENERROR | Error opening bitmap file
$GRIMAGEREADERROR | Error reading image
$GRBITMAPDISPLAYERROR | Error displaying bitmap
$GRBITMAPTOOLARGE | Bitmap too large
$GRIMPROPERBITMAPFORMAT | Improper format for bitmap file
$GRFILEREADERROR | Error reading file
$GRNOBITMAPFILE | No bitmap file
$GRINVALIDIMAGEBUFFER | Image buffer data inconsistent
$GRINSUFFICIENTMEMORY | Not enough memory to allocate buffer or to complete a fill operation
$GRINVALIDPARAMETER | One or more parameters invalid
$GRMODENOTSUPPORTED | Requested video mode not supported
$GRERROR | Graphics error
$GROK | Success
$GRNOOUTPUT | No action taken
$GRCLIPPED | Output was clipped to viewport
$GRPARAMETERALTERED | One or more input parameters was altered to be within range, or pairs of parameters were interchanged to be in the proper order

After a graphics call, compare the return value of GRSTATUS to $GROK. to determine if an error has occurred. For example:

  IF ( GRSTATUS .LT. $GROK ) THEN
  ! Code to handle graphics error goes here
  ENDIF

The following routines cannot give errors, and they all set GRSTATUS to $GROK:

DISPLAYCURSOR | GETTEXTCOLORRGB
GETBKCOLOR | GETTEXTPOSITION
GETBKCOLORRGB | GETTEXTWINDOW
GETCOLOR | OUTTEXT
GETCOLORRGB | WRAPON
GETTEXTCOLOR |

The following table lists other routines with the error or warning messages they produce for GRSTATUS:

Function | Possible GRSTATUS error codes | Possible GRSTATUS warning codes
ARC, ARC_W | $GRINVALIDPARAMETER | $GRNOOUTPUT
CLEARSCREEN | $GRINVALIDPARAMETER |
ELLIPSE, ELLIPSE_W | $GRINVALIDPARAMETER, $GRINSUFFICIENTMEMORY | $GRNOOUTPUT
FLOODFILLRGB | $GRINVALIDPARAMETER, $GRINSUFFICIENTMEMORY | $GRNOOUTPUT
GETARCINFO | $GRERROR |
GETFILLMASK | $GRERROR, $GRINVALIDPARAMETER |
GETFONTINFO | $GRERROR |
GETGTEXTEXTENT | $GRERROR |
GETIMAGE | $GRINSUFFICIENTMEMORY | $GRPARAMETERALTERED
GETPIXEL | $GRBITMAPTOOLARGE |
GETPIXELRGB | $GRBITMAPTOOLARGE |
LINETO, LINETO_W |  | $GRNOOUTPUT, $GRCLIPPED
LOADIMAGE | $GRFILEOPENERROR, $GRNOBITMAPFILE, $GRALEREADERROR, $GRIMPROPERBITMAPFORMAT, $GRBITMAPTOOLARGE, $GRIMAGEREADERROR |
OUTGTEXT |  | $GRNOOUTPUT, $GRCLIPPED
PIE, PIE_W | $GRINVALIDPARAMETER, $GRINSUFFICIENTMEMORY | $GRNOOUTPUT
POLYGON, POLYGON_W | $GRINVALIDPARAMETER, $GRINSUFFICIENTMEMORY | $GRNOOUTPUT, $GRCLIPPED
PUTIMAGE, PUTIMAGE_W | $GRERROR, $GRINVALIDPARAMETER, $GRINVALIDIMAGEBUFFER $GRBITMAPDISPLAYERROR | $GRPARAMETERALTERED, $GRNOOUTPUT
RECTANGLE, RECTANGLE_W | $GRINVALIDPARAMETER, $GRINSUFFICIENTMEMORY | $GRNOOUTPUT, $GRCLIPPED
REMAPPALETTERGB | $GRERROR, $GRINVALIDPARAMETER |
REMAPALLPALETTERGB | $GRERROR, $GRINVALIDPARAMETER |
SAVEIMAGE | $GRFILEOPENERROR |
SCROLLTEXTWINDOW |  | $GRNOOUTPUT
SETBKCOLOR | $GRINVALIDPARAMETER | $GRPARAMETERALTERED
SETBKCOLORRGB | $GRINVALIDPARAMETER | $GRPARAMETERALTERED
SETCLIPRGN |  | $GRPARAMETERALTERED
SETCOLOR |  | $GRPARAMETERALTERED
SETCOLORRGB |  | $GRPARAMETERALTERED
SETFONT | $GRERROR, $GRINSUFFICIENTMEMORY | $GRPARAMETERALTERED
SETPIXEL, SETPIXEL_W |  | $GRNOOUTPUT
SETPIXELRGB, SETPIXELRGB_W |  | $GRNOOUTPUT
SETTEXTCOLOR |  | $GRPARAMETERALTERED
SETTEXTCOLORRGB |  | $GRPARAMETERALTERED
SETTEXTPOSITION |  | $GRPARAMETERALTERED
SETTEXTWINDOW |  | $GRPARAMETERALTERED
SETVIEWPORT |  | $GRPARAMETERALTERED
SETWINDOW | $GRINVALIDPARAMETER | $GRPARAMETERALTERED
SETWRITEMODE | $GRINVALIDPARAMETER |

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: ARC, ELLIPSE, FLOODFILLRGB, LINETO, PIE, POLYGON, REMAPALLPALETTERGB, SETBKCOLORRGB, SETCOLORRGB, SETPIXELRGB, SETTEXTCOLORRGB, SETWINDOW, SETWRITEMODE


HOSTNAM

Portability Function: Retrieves the current host computer name.

Module: USE DFPORT

Syntax

result = HOSTNAM (name)

name
(Output) Character*(*). Name of the current host. Should be at least as long as MAX_COMPUTERNAME_LENGTH, which is defined in the DFPORT module.

Results:

The result is of type INTEGER(4). The result is zero if successful. If name is not long enough to contain all of the host name, the function truncates the host name and returns -1.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

use dfport
character*20 hostnam
integer(4) istat
ISTAT = HOSTNAM (hostname)


HUGE

Inquiry Intrinsic Function (Generic): Returns the largest number in the model representing the same type and kind parameters as the argument.

Syntax

result = HUGE (x)

x
(Input) Must be of type integer or real; it can be scalar or array valued.

Results:

The result is a scalar of the same type and kind parameters as x. If x is of type integer, the result has the value rq - 1. If x is of type real, the result has the value (1 - b-p)bemax.

Integer parameters r and q are defined in Model for Integer Data; real parameters b, p, and emax are defined in Model for Real Data.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: TINY, Data Representation Models

Examples

If X is of type REAL(4), HUGE (X) has the value (1 - 2-24) x 2128.


IACHAR

Elemental Intrinsic Function (Generic): Returns the position of a character in the ASCII character set, even if the processor's default character set is different. In Compaq Fortran, IACHAR is equivalent to the ICHAR function.

Syntax

result = IACHAR (c)

c
(Input) Must be of type character of length 1.

Results:

The result is of type default integer. If c is in the ASCII collating sequence, the result is the position of c in that sequence and satisfies the inequality (0 <= IACHAR(c) <= 127).

The results must be consistent with the LGE, LGT, LLE, and LLT lexical comparison functions. For example, if LLE(C, D) is true, IACHAR(C) .LE. IACHAR(D) is also true.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ASCII and Key Code Charts, ACHAR, CHAR, ICHAR, LGE, LGT, LLE, LLT

Examples

IACHAR ( 'Y' ) has the value 89.

IACHAR ( '%' ) has the value 37.


IAND

Elemental Intrinsic Function (Generic): Performs a logical AND on corresponding bits. This function can also be specified as AND.

Syntax

result = IAND (i, j)

i
(Input) Must be of type integer.

j
(Input) Must be of type integer with the same kind parameter as i.

Results:

The result type is the same as i. The result value is derived by combining i and j bit-by-bit according to the following truth table:

   i   j   IAND (i, j)

   1   1        1
   1   0        0
   0   1        0
   0   0        0

The model for the interpretation of an integer value as a sequence of bits is shown in Model for Bit Data.

Specific Name | Argument Type | Result Type
 | INTEGER(1) | INTEGER(1)
IIAND | INTEGER(2) | INTEGER(2)
JIAND | INTEGER(4) | INTEGER(4)
KIAND | INTEGER(8) | INTEGER(8)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: IEOR, IOR, NOT

Examples

IAND (2, 3) has the value 2.

IAND (4, 6) has the value 4.


IARGC

Portability Function: Returns the index of the last command-line argument.

Module: USE DFPORT

Syntax

result = IARGC( )

Results:

The result is of type INTEGER(4). The result is the index of the last command-line argument. For example, IARGC returns 3 for the command-line invocation of PROG1 -g -c -a.

IARGC returns a value that is 1 less than that returned by NARGS. The command is not included in the index count returned by IARGC.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NARGS

Example

use dfport
integer(4) no_of_arguments
no_of_arguments = IARGC ( )
print *, 'total command line arguments are ', no_of_arguments


IARGCOUNT (VMS only)

Inquiry Intrinsic Function (Specific): Returns the count of actual arguments passed to the current routine.

Syntax

result = IARGCOUNT( )

Results:

The result type is default integer. Functions with a type of CHARACTER, COMPLEX(8), or REAL(16) have an extra argument added that is used to return the function value.

Formal (dummy) arguments that can be omitted must be declared VOLATILE.

Formal arguments of type CHARACTER cannot be omitted. Formal arguments that are adjustable arrays cannot be omitted.

The standard way to pass and detect omitted arguments is to use the Fortran 95 features of OPTIONAL arguments and the PRESENT intrinsic function.

Examples

Consider the following:

   CALL SUB (A,B)
   ...
   SUBROUTINE SUB (X,Y,Z)
   VOLATILE Z
   TYPE *, IARGCOUNT()       ! Displays the value 2


IARGPTR

Inquiry Intrinsic Function (Specific): Returns a pointer to the actual argument list for the current routine.

Syntax

result = IARGPTR( )

Results:

The result is of type INTEGER(4) on ia32 processors; INTEGER(8) on Alpha and ia64 processors. The actual argument list is an array of values of the same type.

On Windows, Tru64 UNIX, and Linux systems, the argument count is not present and the first element has the address of the first argument. On OpenVMS systems, the first element in the array contains the argument count; subsequent elements contain the INTEGER(8) address of the actual arguments.

Formal (dummy) arguments that can be omitted must be declared VOLATILE.

See Also: VOLATILE

Example

WRITE (*, '(" Address of argument list is ", Z16.8)') IARGPTR ( )


IBCHNG

Elemental Intrinsic Function (Generic): Reverses the value of a specified bit in an integer.

Syntax

result = IBCHNG (i, pos)

i
(Input) Must be of type integer. This argument contains the bit to be reversed.

pos
(Input) Must be of type integer. This argument is the position of the bit to be changed.
The rightmost (least significant) bit of i is in position 0.

Results:

The result type is the same as i. The result is equal to i with the bit in position pos reversed.

For more information, see Bit Functions.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BTEST, IAND, IBCLR, IBSET, IEOR, IOR, ISHA, ISHC, ISHL, ISHFT, NOT

Example

  INTEGER J, K
  J = IBCHNG(10, 2)     ! returns 14 = 1110
  K = IBCHNG(10, 1)     ! returns 8 = 1000


IBCLR

Elemental Intrinsic Function (Generic): Clears one bit to zero.

Syntax

result = IBCLR (i, pos)

i
(Input) Must be of type integer.

pos
Must be of type integer. It must not be negative and it must be less than BIT_SIZE(i).
The rightmost (least significant) bit of i is in position 0.

Results:

The result type is the same as i. The result has the value of the sequence of bits of i, except that bit pos of i is set to zero.

For more information, see Bit Functions.

The model for the interpretation of an integer value as a sequence of bits is shown in Model for Bit Data.

Specific Name | Argument Type | Result Type
 | INTEGER(1) | INTEGER(1)
IIBCLR | INTEGER(2) | INTEGER(2)
JIBCLR | INTEGER(4) | INTEGER(4)
KIBCLR | INTEGER(8) | INTEGER(8)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BTEST, IAND, IBCHNG, IBSET, IEOR, IOR, ISHA, ISHC, ISHL, ISHFT, NOT

Examples

IBCLR (18, 1) has the value 16.

If V has the value (1, 2, 3, 4), the value of IBCLR (POS = V, I = 15) is (13, 11, 7, 15).

The following shows another example:

INTEGER J, K
J = IBCLR(7, 1) ! returns 5 = 0101
K = IBCLR(5, 1) ! returns 5 = 0101


IBITS

Elemental Intrinsic Function (Generic): Extracts a sequence of bits (a bit field).

Syntax

result = IBITS (i, pos, len)

i
(Input) Must be of type integer.

pos
(Input) Must be of type integer. It must not be negative and pos + len must be less than or equal to BIT_SIZE(i).
The rightmost (least significant) bit of i is in position 0.

len
(Input) Must be of type integer. It must not be negative.

Results:

The result type is the same as i. The result has the value of the sequence of len bits in i, beginning at pos right-adjusted and with all other bits zero.

For more information, see Bit Functions.

The model for the interpretation of an integer value as a sequence of bits is shown in Model for Bit Data.

Specific Name | Argument Type | Result Type
 | INTEGER(1) | INTEGER(1)
IIBITS | INTEGER(2) | INTEGER(2)
JIBITS | INTEGER(4) | INTEGER(4)
KIBITS | INTEGER(8) | INTEGER(8)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BTEST, BIT_SIZE, IBCLR, IBSET, ISHFT, ISHFTC, MVBITS

Examples

IBITS (12, 1, 4) has the value 6.

IBITS (10, 1, 7) has the value 5.


IBSET

Elemental Intrinsic Function (Generic): Sets one bit to 1.

Syntax

result = IBSET (i, pos)

i
(Input) Must be of type integer.

pos
(Input) Must be of type integer. It must not be negative and it must be less than BIT_SIZE(i).
The rightmost (least significant) bit of i is in position 0.

Results:

The result type is the same as i. The result has the value of the sequence of bits of i, except that bit pos of i is set to 1.

For more information, see Bit Functions.

The model for the interpretation of an integer value as a sequence of bits is shown in Model for Bit Data.

Specific Name | Argument Type | Result Type
 | INTEGER(1) | INTEGER(1)
IIBSET | INTEGER(2) | INTEGER(2)
JIBSET | INTEGER(4) | INTEGER(4)
KIBSET | INTEGER(8) | INTEGER(8)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BTEST, IAND, IBCHNG, IBCLR, IEOR, IOR, ISHA, ISHC, ISHL, ISHFT, NOT

Examples

IBSET (8, 1) has the value 10.

If V has the value (1, 2, 3, 4), the value of IBSET (POS = V, I = 2) is (2, 6, 10, 18).

The following shows another example:

INTEGER I
I = IBSET(8, 2) ! returns 12 = 1100


ICHAR

Elemental Intrinsic Function (Generic): Returns the position of a character in the processor's character set.

Syntax

result = ICHAR (c)

c
(Input) Must be of type character of length 1.

Results:

The result is of type default integer. The result value is the position of c in the processor's character set. c is in the range zero to n - 1, where n is the number of characters in the character set.

For any characters C and D (capable of representation in the processor), C .LE. D is true only if ICHAR(C) .LE. ICHAR(D) is true, and C .EQ. D is true only if ICHAR(C) .EQ. ICHAR(D) is true.

Specific Name | Argument Type | Result Type
 | CHARACTER | INTEGER(2)
ICHAR 1 | CHARACTER | INTEGER(4)
 | CHARACTER | INTEGER(8)
1 This specific function cannot be passed as an actual argument.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: IACHAR, CHAR, ASCII and Key Code Charts

Examples

ICHAR ( 'W' ) has the value 87.

ICHAR ( '#' ) has the value 35.


IDATE

IDATE can be used as an intrinsic subroutine or as a portability routine.

Warning: The two-digit year return value may cause problems with the year 2000. Use DATE_AND_TIME instead.

IDATE Intrinsic Subroutine

Intrinsic Subroutine: Returns three integer values representing the current month, day, and year.

Syntax

CALL IDATE (i, j, k)

i
Is the current month.

j
Is the current day.

k
Is the current year.

Example

If the current date is September 16, 1996, the values of the integer variables upon return are: I = 9, J = 16, and K = 96.

IDATE Portability Routine

Portability Subroutine: Returns the month, day, and year of the current system.

Module: USE DFPORT

Syntax

CALL IDATE (i, j, k)

-or-

CALL IDATE (iarray)

i
(Output) INTEGER(4). Current system month.

j
(Output) INTEGER(4). Current system day.

k
(Output) INTEGER(4). Current system year as an offset from 1900.

iarray
(Output) INTEGER(4). Three-element array that holds day as element 1, month as element 2, and year as element 3. The month is between 1 and 12 and the year is greater than or equal to 1969.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE, DATE_AND_TIME, GETDAT

Example

      use dfport
      integer(4) imonth, iday, iyear, datarray(3)
! If the date is July 11, 1996:
    CALL IDATE(IMONTH, IDAY, IYEAR)
! sets IMONTH to 7, IDAY to 11 and IYEAR to 96.
    CALL IDATE (DATARRAY)
! datarray is (/11,7,96/)


IDENT

General Compiler Directive: Specifies a string that identifies an object module. The compiler places the string in the identification field of an object module when it generates the module for each source program unit.

Syntax

c DEC$ IDENT string

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

string
Is a character constant containing up to 31 printable characters.

Only the first IDENT directive is effective; the compiler ignores any additional IDENT directives in a program unit or module.

See Also: General Compiler Directives


IEOR

Elemental Intrinsic Function (Generic): Performs an exclusive OR on corresponding bits. This function can also be specified as XOR.

Syntax

result = IEOR (i, j)

i
(Input) Must be of type integer.

j
(Input) Must be of type integer with the same kind parameter as i.

Results:

The result type is the same as i. The result value is derived by combining i and j bit-by-bit according to the following truth table:

  i   j   IEOR (i, j)
  1   1        0
  1   0        1
  0   1        1
  0   0        0

The model for the interpretation of an integer value as a sequence of bits is shown in Model for Bit Data.

Specific Name | Argument Type | Result Type
 | INTEGER(1) | INTEGER(1)
IIEOR | INTEGER(2) | INTEGER(2)
JIEOR | INTEGER(4) | INTEGER(4)
KIEOR | INTEGER(8) | INTEGER(8)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: IAND, IOR, NOT

Examples

IEOR (1, 4) has the value 5.

IEOR (3, 10) has the value 9.

The following shows another example:

INTEGER I
I = IEOR(240, 90)    ! returns 170


IERRNO

Portability Function: Returns the number of the last detected error from any routines in the DFPORT module that return error codes.

Module: USE DFPORT

Syntax

result = IERRNO( )

Results:

The result is of type INTEGER(4). The result value is the last error code from any portability routines that return error codes. These error codes are analogous to errno on a U*X system. The module DFPORT.F90 (in \DF98\INCLUDE) provides parameter definitions for the following Unix errno names (typically found in errno.h on U*X systems):

Symbolic name | Number | Description
EPERM | 1 | Insufficient permission for operation
ENOENT | 2 | No such file or directory
ESRCH | 3 | No such process
EIO | 5 | I/O error
E2BIG | 7 | Argument list too long
ENOEXEC | 8 | File is not executable
ENOMEM | 12 | Not enough resources
EACCES | 13 | Permission denied
EXDEV | 18 | Cross-device link
ENOTDIR | 20 | Not a directory
EINVAL | 22 | Invalid argument

The value returned by IERRNO is updated only when an error occurs. For example, if an error occurs on a GETLOG call and then two CHMOD calls succeed, a subsequent call to IERRNO returns the error for the GETLOG call.

Examine IERRNO immediately after returning from a Portability routine. Other Fortran routines, as well as any Win32 APIs, can also change the error code to an undefined value. IERRNO is set on a per thread basis.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

USE DFPORT
CHARACTER*20 username
INTEGER(4) ierrval
ierrval=0 !initialize return value
CALL GETLOG(username)
IF (IERRNO( ) == ierrval) then
  print *, 'User name is ',username
  exit
ELSE
  ierrval = ierrno()
  print *, 'Error is ',ierrval
END IF


IF - Arithmetic

Statement: Conditionally transfers control to one of three statements, based on the value of an arithmetic expression. It is an obsolescent feature in Fortran 95 and Fortran 90.

Syntax

IF (expr) label1, label2, label3

expr
Is a scalar numeric expression of type integer or real (enclosed in parentheses).

label1, label2, label3
Are the labels of valid branch target statements that are in the same scoping unit as the arithmetic IF statement.

Rules and Behavior

All three labels are required, but they do not need to refer to three different statements. The same label can appear more than once in the same arithmetic IF statement.

During execution, the expression is evaluated first. Depending on the value of the expression, control is then transferred as follows:

If the Value of expr is: | Control Transfers To:
Less than 0 | Statement label1
Equal to 0 | Statement label2
Greater than 0 | Statement label3

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SELECT CASE...END SELECT, Execution Control, Obsolescent Features in Fortran 90

Examples

The following example transfers control to statement 50 if the real variable THETA is less than or equal to the real variable CHI. Control passes to statement 100 only if THETA is greater than CHI.

  IF (THETA-CHI) 50,50,100

The following example transfers control to statement 40 if the value of the integer variable NUMBER is even. It transfers control to statement 20 if the value is odd.

  IF (NUMBER / 2*2 - NUMBER) 20,40,20

The following statement transfers control to statement 10 for n < 10, to statement 20 for n = 10, and to statement 30 for n > 10:

  IF (n-10) 10, 20, 30

The following statement transfers control to statement 10 if n<= 10, and to statement 30 for n>10:

  IF (n-10) 10, 10, 30


IF - Logical

Statement: Conditionally executes one statement based on the value of a logical expression. (This statement was called a logical IF statement in FORTRAN 77.)

Syntax

IF (expr) stmt

expr
Is a scalar logical expression enclosed in parentheses.

stmt
Is any complete, unlabeled, executable Fortran statement, except for the following:

  • A CASE, DO, IF, FORALL, or WHERE construct
  • Another IF statement
  • The END statement for a program, function, or subroutine

When an IF statement is executed, the logical expression is evaluated first. If the value is true, the statement is executed. If the value is false, the statement is not executed and control transfers to the next statement in the program.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: IF Construct, Execution Control

Examples

The following examples show valid IF statements:

IF (J.GT.4 .OR. J.LT.1) GO TO 250

IF (REF(J,K) .NE. HOLD) REF(J,K) = REF(J,K) * (-1.5D0)

IF (ENDRUN) CALL EXIT

The following shows another example:

   USE DFPORT
   INTEGER(4) istat, errget
   character(inchar)
   real x
   istat = getc(inchar)
   IF (istat) errget = -1
   ...
!
   IF (x .GT. 2.3) call new_subr(x)
   ...


IF Construct

Statement: Conditionally executes one block of constructs or statements depending on the evaluation of a logical expression. (This construct was called a block IF statement in FORTRAN 77.)

Syntax

name:] IF (expr) THEN
block
[ELSE IF (expr) THEN [name]
block] ...
[ELSE [name]
block]
END IF [name]

name
(Optional) Is the name of the IF construct.

expr
Is a scalar logical expression enclosed in parentheses.

block
Is a sequence of zero or more statements or constructs.

Rules and Behavior

If a construct name is specified at the beginning of an IF THEN statement, the same name must appear in the corresponding END IF statement. The same construct name must not be used for different named constructs in the same scoping unit.

Depending on the evaluation of the logical expression, one block or no block is executed. The logical expressions are evaluated in the order in which they appear, until a true value is found or an ELSE or END IF statement is encountered.

Once a true value is found or an ELSE statement is encountered, the block immediately following it is executed and the construct execution terminates.

If none of the logical expressions evaluate to true and no ELSE statement appears in the construct, no block in the construct is executed and the construct execution terminates.

Note: No additional statement can be placed after the IF THEN statement in a block IF construct. For example, the following statement is invalid in the block IF construct:
  IF (e) THEN I = J
This statement is translated as the following logical IF statement:
  IF (e) THENI = J

You cannot use branching statements to transfer control to an ELSE IF statement or ELSE statement. However, you can branch to an END IF statement from within the IF construct.

The following figure shows the flow of control in IF constructs:

Flow of Control in IF Constructs

You can include an IF construct in the statement block of another IF construct, if the nested IF construct is completely contained within a statement block. It cannot overlap statement blocks.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Execution Control, IF - Logical, IF - Arithmetic

Examples

The following example shows the simplest form of an IF construct:

  Form                 Example
  IF (expr) THEN       IF (ABS(ADJU) .GE. 1.0E-6) THEN
    block                TOTERR = TOTERR + ABS(ADJU)
                         QUEST = ADJU/FNDVAL
  END IF               END IF

This construct conditionally executes the block of statements between the IF THEN and the END IF statements.

The following shows another example:

!  Simple block IF:
   IF (i .LT. 10) THEN
      ! the next two statements are only executed if i < 10
      j = i
      slice = TAN (angle)
   END IF

The following example shows a named IF construct:

  BLOCK_A: IF (D > 0.0) THEN        ! Initial statement for named construct

    RADIANS = ACOS(D)               ! These two statements
    DEGREES = ACOSD(D)              !       form a block

  END IF BLOCK_A                    ! Terminal statement for named construct

The following example shows an IF construct containing an ELSE statement:

  Form                 Example
  IF (expr) THEN       IF (NAME .LT. 'N') THEN
    block1               IFRONT = IFRONT + 1
                         FRLET(IFRONT) = NAME(1:2)
  ELSE                 ELSE
    block2               IBACK = IBACK + 1
  END IF               END IF

Block1 consists of all the statements between the IF THEN and ELSE statements. Block2 consists of all the statements between the ELSE and the END IF statements.

If the value of the character variable NAME is less than 'N' , block1 is executed. If the value of NAME is greater than or equal to 'N', block2 is executed.

The following example shows an IF construct containing an ELSE IF THEN statement:

  Form                     Example
  IF (expr) THEN           IF (A .GT. B) THEN
    block1                   D = B
                             F = A - B
  ELSE IF (expr) THEN      ELSE IF (A .GT. B/2.) THEN
    block2                   D = B/2.
                             F = A - B/2.
  END IF                   END IF

If A is greater than B, block1 is executed. If A is not greater than B, but A is greater than B/2, block2 is executed. If A is not greater than B and A is not greater than B/2, neither block1 nor block2 is executed. Control transfers directly to the next executable statement after the END IF statement.

The following shows another example:

!  Block IF with ELSE IF statements:

   IF (j .GT. 1000) THEN
      ! Statements here are executed only if J > 1000
   ELSE IF (j .GT. 100) THEN
      ! Statements here are executed only if J > 100 and j <= 1000
   ELSE IF (j .GT. 10) THEN
      ! Statements here are executed only if J > 10 and j <= 100
   ELSE
      ! Statements here are executed only if j <= 10
   END IF

The following example shows an IF construct containing several ELSE IF THEN statements and an ELSE statement:

  Form                     Example
  IF (expr) THEN           IF (A .GT. B) THEN
    block1                   D = B
                             F = A - B
  ELSE IF (expr) THEN      ELSE IF (A .GT. C) THEN
    block2                   D = C
                             F = A - C
  ELSE IF (expr) THEN      ELSE IF (A .GT. Z) THEN
    block3                   D = Z
                             F = A - Z
  ELSE                     ELSE
    block4                   D = 0.0
                             F = A
  END IF                   END IF

If A is greater than B, block1 is executed. If A is not greater than B but is greater than C, block2 is executed. If A is not greater than B or C but is greater than Z, block3 is executed. If A is not greater than B, C, or Z, block4 is executed.

The following example shows a nested IF construct:

  Form                     Example
  IF (expr) THEN           IF (A .LT. 100) THEN
    block1                   INRAN = INRAN + 1
    IF (expr2) THEN          IF (ABS(A-AVG) .LE. 5.) THEN
      block1a                  INAVG = INAVG + 1
    ELSE                     ELSE
      block1b                  OUTAVG = OUTAVG + 1
    END IF                   END IF
  ELSE                     ELSE
    block2                   OUTRAN = OUTRAN + 1
  END IF                   END IF

If A is less than 100, the code immediately following the IF is executed. This code contains a nested IF construct. If the absolute value of A minus AVG is less than or equal to 5, block1a is executed. If the absolute value of A minus AVG is greater than 5, block1b is executed.

If A is greater than or equal to 100, block2 is executed, and the nested IF construct (in block1) is not executed.

The following shows another example:

!  Nesting of constructs and use of an ELSE statement following
!  a block IF without intervening ELSE IF statements:

   IF (i .LT. 100) THEN
      ! Statements here executed only if i < 100
      IF (j .LT. 10) THEN
      ! Statements here executed only if i < 100 and j < 10
      END IF
      ! Statements here executed only if i < 100
   ELSE
      ! Statements here executed only if i >= 100
      IF (j .LT. 10) THEN
      ! Statements here executed only if i >= 100 and j < 10
      END IF
      ! Statements here executed only if i >= 100
   END IF


IF Directive Construct

General Compiler Directive: A conditional compilation construct that begins with an IF or IF DEFINED directive. IF tests whether a logical expression is .TRUE. or .FALSE.. IF DEFINED tests whether a symbol has been defined.

Syntax

c DEC$ IF (expr) -or-
c DEC$ IF DEFINED (name)
block
[c DEC$ ELSEIF (expr)
block] ...
[c DEC$ ELSE
block]
c DEC$ ENDIF

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

expr
Is a logical expression that evaluates to .TRUE. or .FALSE..

name
Is the name of a symbol to be tested for definition.

block
Are executable statements that are compiled (or not) depending on the value of logical expressions in the IF directive construct.

Rules and Behavior

The IF and IF DEFINED directive constructs end with an ENDIF directive and can contain one or more ELSEIF directives and at most one ELSE directive. If the logical condition within a directive evaluates to .TRUE. at compilation, and all preceding conditions in the IF construct evaluate to .FALSE., then the statements contained in the directive block are compiled.

A name can be defined with a DEFINE directive, and can optionally be assigned an integer value. If the symbol has been defined, with or without being assigned a value, IF DEFINED (name) evaluates to .TRUE.; otherwise, it evaluates to .FALSE..

If the logical condition in the IF or IF DEFINED directive is .TRUE., statements within the IF or IF DEFINED block are compiled. If the condition is .FALSE., control transfers to the next ELSEIF or ELSE directive, if any.

If the logical expression in an ELSEIF directive is .TRUE., statements within the ELSEIF block are compiled. If the expression is .FALSE., control transfers to the next ELSEIF or ELSE directive, if any.

If control reaches an ELSE directive because all previous logical conditions in the IF construct evaluated to .FALSE., the statements in an ELSE block are compiled unconditionally.

You can use any Fortran logical or relational operator or symbol in the logical expression of the directive, including: .LT., <, .GT., >, .EQ., ==, .LE., <=, .GE., >=, .NE., /=, .EQV., .NEQV., .NOT., .AND., .OR., and .XOR.. The logical expression can be as complex as you like, but the whole directive must fit on one line.

Each directive in the construct can begin with !MS$ instead of cDEC$.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DEFINE and UNDEFINE, IF Construct, General Compiler Directives

Example

!  When the following code is compiled and run,
!  the output is:
!  Or this compiled if all preceding conditions .FALSE.
!
!DEC$ DEFINE flag=3
!DEC$ IF (flag .LT. 2)
   WRITE (*,*) "This is compiled if flag less than 2."
!DEC$ ELSEIF (flag >= 8)
   WRITE (*,*) "Or this compiled if flag greater than &
                or equal to 8."
!DEC$ ELSE
   WRITE (*,*) "Or this compiled if all preceding &
                conditions .FALSE."
!DEC$ ENDIF
END


IF DEFINED Directive

See the IF Directive Construct.


IFIX

Elemental Intrinsic Function (Generic): Converts a single-precision real argument to an integer by truncating. For more information, see INT.


ILEN

Elemental Intrinsic Function (Generic): Returns the length (in bits) of the two's complement representation of an integer.

Syntax

result = ILEN (i)

i
Must be of type integer.

Results:

The result type is the same as i. The result value is (LOG2(i + 1 )) if i is not negative; otherwise, the result value is (LOG2( -i )).

Examples

ILEN (4) has the value 3.
ILEN (-4) has the value 2.


IMAGESIZE, IMAGESIZE_W

Graphics Function: Returns the number of bytes needed to store the image inside the specified bounding rectangle. IMAGESIZE is useful for determining how much memory is needed for a call to GETIMAGE.

Module: USE DFLIB

Syntax

result = IMAGESIZE (x1, y1, x2, y2)
result = IMAGESIZE_W (wx1, wy1, wx2, wy2)

x1, y1
(Input) INTEGER(2). Viewport coordinates for upper-left corner of image.

x2, y2
(Input) INTEGER(2). Viewport coordinates for lower-right corner of image.

wx1, wy1
(Input) REAL(8). Window coordinates for upper-left corner of image.

wx2, wy2
(Input) REAL(8). Window coordinates for lower-right corner of image.

Results:

The result is of type INTEGER(4). The result is the storage size of an image in bytes.

IMAGESIZE defines the bounding rectangle in viewport-coordinate points (x1, y1) and (x2, y2). IMAGESIZE_W defines the bounding rectangle in window-coordinate points (wx1, wy1) and (wx2, wy2).

IMAGESIZE_W defines the bounding rectangle in terms of window-coordinate points (wx1, wy1) and (wx2, wy2).

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETIMAGE, GRSTATUS, PUTIMAGE

Example

See the example in GETIMAGE.


IMPLICIT

Statement: Overrides the default implicit typing rules for names. (The default data type is INTEGER for names beginning with the letters I through N, and REAL for names beginning with any other letter.)

The IMPLICIT statement takes one of the following forms:

Syntax

IMPLICIT type (a[, a] ...)[, type (a[, a] ...)] ...
IMPLICIT NONE

type
Is a data type specifier (CHARACTER*(*) is not allowed).

a
Is a single letter, a dollar sign ($), or a range of letters in alphabetical order. The form for a range of letters is a1-a2, where the second letter follows the first alphabetically (for example, A-C).

The dollar sign can be used at the end of a range of letters, since IMPLICIT interprets the dollar sign to alphabetically follow the letter Z. For example, a range of X-$ would apply to identifiers beginning with the letters X, Y, Z, or $.

Rules and Behavior

The IMPLICIT statement assigns the specified data type (and kind parameter) to all names that have no explicit data type and begin with the specified letter or range of letters. It has no effect on the default types of intrinsic procedures.

When the data type is CHARACTER*len, len is the length for character type. The len is an unsigned integer constant or an integer initialization expression enclosed in parentheses. The range for len is 1 to 2**31-1 for Tru64 UNIX and Linux systems, and on ia64 processors; 1 to 65535 for OpenVMS systems and on ia32 processors.

Names beginning with a dollar sign ($) are implicitly INTEGER.

The IMPLICIT NONE statement disables all implicit typing defaults. When IMPLICIT NONE is used, all names in a program unit must be explicitly declared. An IMPLICIT NONE statement must precede any PARAMETER statements, and there must be no other IMPLICIT statements in the scoping unit.

Note: To receive diagnostic messages when variables are used but not declared, you can specify the /warn:declarations complier option instead of using IMPLICIT NONE.

The following IMPLICIT statement represents the default typing for names when they are not explicitly typed:

  IMPLICIT INTEGER (I-N), REAL (A-H, O-Z)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Data Types, Constants, and Variables

Examples

The following are examples of the IMPLICIT statement:

IMPLICIT DOUBLE PRECISION (D)
IMPLICIT COMPLEX (S,Y), LOGICAL(1) (L,A-C)
IMPLICIT CHARACTER*32 (T-V)
IMPLICIT CHARACTER*2 (W)
IMPLICIT TYPE(COLORS) (E-F), INTEGER (G-H)

The following shows another example:

IMPLICIT INTEGER (a-b), CHARACTER*10 (n), TYPE(fried) (c-d)

TYPE fried
  INTEGER e, f
  REAL g, h
END TYPE
age = 10       ! integer
name = 'Paul'  ! character
c%e = 1        ! type fried, integer component


INCHARQQ

QuickWin Function: Reads a single character input from the keyboard and returns the ASCII value of that character without any buffering.

Module: USE DFLIB

Syntax

result = INCHARQQ( )

Results:

The result is of type INTEGER(2). The result is the ASCII key code.

The keystroke is read from the child window that currently has the focus. You must call INCHARQQ before the keystroke is made (INCHARQQ does not read the keyboard buffer). This function does not echo its input. For function keys, INCHARQQ returns 0xE0 as the upper 8 bits, and the ASCII code as the lower 8 bits.

For direction keys, INCHARQQ returns 0xF0 as the upper 8 bits, and the ASCII code as the lower 8 bits. To allow direction keys to be read, you must use the PASSDIRKEYSQQ function. The escape characters (the upper 8 bits) are different from those of GETCHARQQ. Note that console applications do not need, and cannot use PASSDIRKEYSQQ.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: Using QuickWin, GETCHARQQ, READ, MBINCHARQQ, GETC PASSDIRKEYSQQ

Example

use dflib

integer*4 res
integer*2 exchar
character*1 ch, ch1

Print *,"Type X to exit, S to scroll, D to pass Direction keys"

123 continue
exchar = incharqq()
! check for escapes
! 0xE0 0x?? is a function key
! 0xF0 0x?? is a direction key

ch = char(rshift(exchar,8) .and. #00FF)
ch1= char(exchar .and. #00FF)

if (ichar(ch) .eq. 224) then
 print *,"function key  = ",ichar(ch), "  ",ichar(ch1),"  ",ch1
 goto 123
endif

if (ichar(ch) .eq. 240) then
 print *,"direction key = ",ichar(ch), "  ",ichar(ch1),"  ",ch1
 goto 123
endif

print *,"other key  = ",ichar(ch),"  ",ichar(ch1),"  ",ch1

if(ch1 .eq. 'S') then
 res = passdirkeysqq(.false.)
 print *, "Entering Scroll mode"
endif

 if(ch1 .eq. 'D')  then
res = passdirkeysqq(.true.)
print *, "Entering Direction keys mode"
endif

if(ch1 .ne. 'X')  go to 123

end


INCLUDE

Statement: Directs the compiler to stop reading statements from the current file and read statements in an included file or text module.

The INCLUDE statement takes one of the following forms:

Syntax

INCLUDE 'filename [/[NO]LIST]'
INCLUDE '[text-lib] (module-name) [/[NO]LIST]' (VMS only)

filename
Is a character string specifying the name of the file to be included; it must not be a named constant.
The form of the file name must be acceptable to the operating system, as described in your system documentation.

/[NO]LIST
Specifies whether the incorporated code is to appear in the compilation source listing. In the listing, a number precedes each incorporated statement. The number indicates the "include" nesting depth of the code. The default is /NOLIST. /LIST and /NOLIST must be spelled completely.

On Windows, Tru64 UNIX, and Linux systems, you can only use /[NO]LIST if you specify the /vms compiler option (which sets OpenVMS defaults).

text-lib (VMS only)
Is a character string specifying the file name of the text library to be searched.
The form of the file name must be acceptable to the operating system, as described in your system documentation.

module-name (VMS only)
Is a character string specifying the name of the text library module to be included. The name of the text module must be enclosed in parentheses. It can be up to 31 characters long and can contain any alphanumeric character and the special characters dollar sign ($) and underscore ( _ ).

Rules and Behavior

An INCLUDE statement can appear anywhere within a scoping unit. The statement can span more than one source line, but no other statement can appear on the same line. The source line cannot be labeled.

An included file or text module cannot begin with a continuation line, and each Fortran statement must be completely contained within a single file.

An included file or text module can contain any source text, but it cannot begin or end with an incomplete Fortran statement.

The included statements, when combined with the other statements in the compilation, must satisfy the statement-ordering restrictions shown in Statements.

Included files or text modules can contain additional INCLUDE statements, but they must not be recursive. INCLUDE statements can be nested until system resources are exhausted.

When the included file or text module completes execution, compilation resumes with the statement following the INCLUDE statement.

You can use modules instead of include files to achieve encapsulation of related data types and procedures. For example, one module can contain derived type definitions as well as special operators and procedures that apply to those types. For information on how to use modules, see Program Units and Procedures.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MODULE, USE

Examples

In the following example, a file named COMMON.FOR (in the current working directory) is included and read as input.

Including Text from a File

Main Program File                COMMON.FOR File

PROGRAM
  INCLUDE 'COMMON.FOR'           INTEGER, PARAMETER :: M=100
  REAL, DIMENSION(M) :: Z        REAL, DIMENSION(M) :: X, Y
  CALL CUBE                      COMMON X, Y
  DO I = 1, M
    Z(I) = X(I) + SQRT(Y(I))
    ...
  END DO
END

SUBROUTINE CUBE
  INCLUDE 'COMMON.FOR'
  DO I=1,M
    X(I) = Y(I)**3
  END DO
  RETURN
END

The file COMMON.FOR defines a named constant M, and defines arrays X and Y as part of blank common.

The following example program declares its common data in an include file. The contents of the file INCLUDE.INC are inserted in the source code in place of every INCLUDE 'INCLUDE.INC' statement. This guarantees that all references to common storage variables are consistent.

INTEGER i
REAL x
INCLUDE 'INCLUDE.INC'

DO i = 1, 5
  READ (*, '(F10.5)') x
  CALL Push (x)
END DO


INDEX

Elemental Intrinsic Function (Generic): Returns the starting position of a substring within a string.

Syntax

result = INDEX (string, substring [, back] [, kind])

string
(Input) Must be of type character.

substring
(Input) Must be of type character.

back
(Optional; input) Must be of type logical.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

If back does not appear (or appears with the value false), the value returned is the minimum value of I such that string (I : I + LEN (substring) - 1) = substring (or zero if there is no such value). If LEN (string) < LEN (substring), zero is returned. If LEN (substring) = zero, 1 is returned.

If back appears with the value true, the value returned is the maximum value of I such that string (I : I + LEN (substring) - 1) = substring (or zero if there is no such value). If LEN(string) < LEN (substring), zero is returned. If LEN (substring) = zero, LEN (string) + 1 is returned.

Specific Name | Argument Type | Result Type
INDEX | CHARACTER | INTEGER(4)
 | CHARACTER | INTEGER(8)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SCAN

Examples

INDEX ('FORTRAN', 'O', BACK = .TRUE.) has the value 2.

INDEX ('XXXX', " ", BACK = .TRUE.) has the value 5.

The following shows another example:

  I = INDEX('banana','an', BACK = .TRUE.) ! returns 4
  I = INDEX('banana', 'an') ! returns 2


INITIALIZEFONTS

QuickWin Function: Initializes Windows fonts.

Module: USE DFLIB

Syntax

result = INITIALIZEFONTS( )

Results:

The result is of type INTEGER(2). The result is the number of fonts initialized.

All fonts on Windows systems become available after a call to INITIALIZEFONTS. Fonts must be initialized with INITIALIZEFONTS before any other font-related library function (such as GETFONTINFO, GETGTEXTEXTENT, SETFONT, OUTGTEXT) can be used. For more information, see Using Fonts from the Graphics Library in the Programmer's Guide.

The font functions affect the output of OUTGTEXT only. They do not affect other Fortran I/O functions (such as WRITE) or graphics output functions (such as OUTTEXT).

For each window you open, you must call INITIALIZEFONTS before calling SETFONT. INITIALIZEFONTS needs to be executed after each new child window is opened in order for a subsequent SETFONT call to be successful.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: Using QuickWin, SETFONT, OUTGTEXT

Example

! build as a QuickWin or Standard Graphics App.
USE DFLIB
INTEGER(2) numfonts
numfonts = INITIALIZEFONTS()
WRITE (*,*) numfonts
END


INITIALSETTINGS

QuickWin Function: Initializes QuickWin.

Module: USE DFLIB

Syntax

result = INITIALSETTINGS( )

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

You can change the initial appearance of an application's default frame window and menus by defining an INITIALSETTINGS function. Do not use INITIALSETTINGS to open or size child windows.

If no user-defined INITIALSETTINGS function is supplied, QuickWin calls a predefined INITIALSETTINGS routine to control the default frame window and menu appearance. You do not need to call INITIALSETTINGS if you define it, since it will be called automatically during initialization.

For more information, see Controlling the Initial Menu and Frame Window in the Programmer's Guide.

Compatibility

QUICKWIN GRAPHICS WINDOWS LIB

See Also: Using QuickWin, APPENDMENUQQ, INSERTMENUQQ, DELETEMENUQQ, SETWSIZEQQ


INQFOCUSQQ

QuickWin Function: Determines which window has the focus.

Module: USE DFLIB

Syntax

result = INQFOCUSQQ (unit)

unit
(Output) INTEGER(4). Unit number of the window that has the I/O focus.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, nonzero. The function fails if the window with the focus is associated with a closed unit.

Unit numbers 0, 5, and 6 refer to the default window only if the program has not specifically opened them. If these units have been opened and connected to windows, they are automatically reconnected to the console once they are closed.

The window with focus is always in the foreground. Note that the window with the focus is not necessarily the active window (the one that receives graphical output). A window can be made active without getting the focus by calling SETACTIVEQQ.

A window has focus when it is given the focus by FOCUSQQ, when it is selected by a mouse click, or when an I/O operation other than a graphics operation is performed on it, unless the window was opened with IOFOCUS=.FALSE.. The IOFOCUS specifier determines whether a window receives focus when on I/O statement is executed on that unit. For example:

  OPEN (UNIT = 10, FILE = 'USER', IOFOCUS = .TRUE.)

By default IOFOCUS=.TRUE., except for child windows opened with as unit *. If IOFOCUS=.TRUE., the child window receives focus prior to each READ, WRITE, PRINT, or OUTTEXT. Calls to graphics functions (such as OUTGTEXT and ARC) do not cause the focus to shift.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: FOCUSQQ, Programmer's Guide: Using QuickWin


INQUIRE

Statement: Returns information on the status of specified properties of a file or logical unit. It takes one of the following forms:

Syntax

Inquiring by File:

INQUIRE (FILE=name [, ERR=label] [, IOSTAT=i-var] [, DEFAULTFILE=def], slist)

Inquiring by Unit:

INQUIRE ([UNIT=]io-unit [, ERR=label] [, IOSTAT=i-var] slist)

Inquiring by Output List:

INQUIRE (IOLENGTH=len) out-item-list

name
Is a scalar default character expression specifying the name of the file for inquiry.

label
Is the label of the branch target statement that receives control if an error occurs.

i-var
Is a scalar integer variable that is defined as a positive integer if an error occurs and zero if no error occurs.

slist
Is one or more of the following inquiry specifiers (each specifier can appear only once):

ACCESS DELIM NAMED READWRITE
ACTION DIRECT NEXTREC RECL
BINARY EXIST NUMBER RECORDTYPE
BLANK FORM OPENED SEQUENTIAL
BLOCKSIZE FORMATTED ORGANIZATION SHARE
BUFFERED IOFOCUS PAD UNFORMATTED
CARRIAGECONTROL MODE POSITION WRITE
CONVERT NAME READ

def
Is a scalar default character expression specifying a default file pathname string. (For more information, see the DEFAULTFILE specifier.

io-unit
Is an external unit specifier.

The unit does not have to exist, nor does it need to be connected to a file. If the unit is connected to a file, the inquiry encompasses both the connection and the file.

len
(Output) Is a scalar integer variable that is assigned a value corresponding to the length of an unformatted, direct-access record resulting from the use of the out-item-list in a WRITE statement.

The value is suitable to use as a RECL specifier value in an OPEN statement that connects a file for unformatted, direct access.

The unit of the value is 4-byte longwords, by default. However, if you specify the compiler option /assume:byterecl, the unit is bytes.

out-item-list
(Output) Is a list of one or more output items (see I/O Lists).

Rules and Behavior

The control specifiers ([UNIT=]io-unit, ERR=label, and IOSTAT=i-var) and inquiry specifiers can appear anywhere within the parentheses following INQUIRE. However, if the UNIT keyword is omitted, the io-unit must appear first in the list.

An INQUIRE statement can be executed before, during, or after a file is connected to a unit. The specifier values returned are those that are current when the INQUIRE statement executes.

To get file characteristics, specify the INQUIRE statement after opening the file.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: INQUIRE Statement, OPEN

Examples

The following are examples of INQUIRE statements:

INQUIRE (FILE='FILE_B', EXIST=EXT)
INQUIRE (4, FORM=FM, IOSTAT=IOS, ERR=20)
INQUIRE (IOLENGTH=LEN) A, B

In the last statement, you can use the length returned in LEN as the value for the RECL specifier in an OPEN statement that connects a file for unformatted direct access. If you have already specified a value for RECL, you can check LEN to verify that A and B are less than or equal to the record length you specified.

The following shows another example:

!    This program prompts for the name of a data file.
!    The INQUIRE statement then determines whether
!    the file exists. If it does not, the program
!    prompts for another file name.

      CHARACTER*12 fname
      LOGICAL exists

!     Get the name of a file:
100   WRITE (*, '(1X, A\)') 'Enter the file name: '
      READ (*, '(A)') fname

!     INQUIRE about file's existence:
      INQUIRE (FILE = fname, EXIST = exists)

      IF (.NOT. exists) THEN
        WRITE (*,'(2A/)') ' >> Cannot find file ', fname
        GOTO 100
      END IF
      END


INSERTMENUQQ

QuickWin Function: Inserts a menu item into a QuickWin menu and registers its callback routine.

Module: USE DFLIB

Syntax

result = INSERTMENUQQ (menuID, itemID, flag, text, routine)

menuID
(Input) INTEGER(4). Identifies the menu in which the item is inserted, starting with 1 as the leftmost menu.

itemID
(Input) INTEGER(4). Identifies the position in the menu where the item is inserted, starting with 0 as the top menu item.

flag
(Input) INTEGER(4). Constant indicating the menu state. Flags can be combined with an inclusive OR (see Results section below). The following constants are available:

  • $MENUGRAYED - Disables and grays out the menu item.
  • $MENUDISABLED - Disables but does not gray out the menu item.
  • $MENUENABLED - Enables the menu item.
  • $MENUSEPARATOR - Draws a separator bar.
  • $MENUCHECKED - Puts a check by the menu item.
  • $MENUUNCHECKED - Removes the check by the menu item.

text
(Input) Character*(*). Menu item name. Must be a null-terminated C string, for example, words of text'C.

routine
(Input) EXERNAL. Callback subroutine that is called if the menu item is selected. All routines must take a single LOGICAL parameter which indicates whether the menu item is checked or not. You can assign the following predefined routines to menus:

  • WINPRINT: Prints the program.
  • WINSAVE: Saves the program.
  • WINEXIT: Terminates the program.
  • WINSELECTTEXT: Selects text from the current window.
  • WINSELECTGRAPHICS: Selects graphics from the current window.
  • WINSELECTALL: Selects the entire contents of the current window.
  • WINCOPY: Copies the selected text and/or graphics from current window to the Clipboard.
  • WINPASTE: Allows the user to paste Clipboard contents (text only) to the current text window of the active window during a READ.
  • WINCLEARPASTE: Clears the paste buffer.
  • WINSIZETOFIT: Sizes output to fit window.
  • WINFULLSCREEN: Displays output in full screen.
  • WINSTATE: Toggles between pause and resume states of text output.
  • WINCASCADE: Cascades active windows.
  • WINTILE: Tiles active windows.
  • WINARRANGE: Arranges icons.
  • WINSTATUS: Enables a status bar.
  • WININDEX: Displays the index for QuickWin help.
  • WINUSING: Displays information on how to use Help.
  • WINABOUT: Displays information about the current QuickWin application.
  • NUL: No callback routine.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE.

Menus and menu items must be defined in order from left to right and top to bottom. For example, INSERTMENUQQ fails if you try to insert menu item 7 when 5 and 6 are not defined yet. For a top-level menu item, the callback routine is ignored if there are subitems under it.

The constants available for flags can be combined with an inclusive OR where reasonable, for example $MENUCHECKED .OR. $MENUENABLED. Some combinations do not make sense, such as $MENUENABLED and $MENUDISABLED, and lead to undefined behavior.

You can create quick-access keys in the text strings you pass to INSERTMENUQQ as text by placing an ampersand (&) before the letter you want underlined. For example, to add a Print menu item with the r underlined, text should be "P&rint". Quick-access keys allow users of your program to activate that menu item with the key combination ALT+QUICK-ACCESS-KEY (ALT+R in the example) as an alternative to selecting the item with the mouse.

For more information on customizing QuickWin menus, see Using QuickWin in the Programmer's Guide.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: APPENDMENUQQ, DELETEMENUQQ, MODIFYMENUFLAGSQQ, MODIFYMENUROUTINEQQ, MODIFYMENUSTRINGQQ

Example

! build as a QuickWin App.
USE DFLIB
LOGICAL(4) status
! insert new item into Menu 5 (Window)
status= INSERTMENUQQ(5, 5, $MENUCHECKED, 'New Item'C, &
                     WINSTATUS)
! insert new menu in position 2
status= INSERTMENUQQ(2, 0, $MENUENABLED, 'New Menu'C, &
                     WINSAVE)
END


INSTANCE (TU*X only)

Compaq Fortran Parallel Compiler Directive: Specifies the availability of named common blocks.

Syntax

c$PAR INSTANCE { SINGLE | PARALLEL } /cb/[, /cb/] ...

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

cb
Is the name of the common block. The slashes are required.

Rules and Behavior

The keywords are described as follows:

  • SINGLE - Specifies that there will be a single instance of the named common blocks. This implies that all threads share the same copy, and assignments to the constituent items in the common blocks occurring in one thread affect the values of those items in the same named common blocks in other threads.

  • PARALLEL - This is the same as specifying the OpenMP Fortran API THREADPRIVATE directive.

INSTANCE SINGLE is the default for named common blocks.

See Also: Parallel Directives for Tru64 UNIX Systems, Compaq Fortran Parallel Compiler Directives (TU*X only), OpenMP Fortran API Compiler Directives (TU*X only)


INT

Elemental Intrinsic Function (Generic): Converts a value to integer type.

Syntax

result = INT (a [, kind])

a
(Input) Must be of type integer, real, or complex.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is shown in the following table. If the processor cannot represent the result value in the kind of the result, the result is undefined.

Functions that cause conversion of one data type to another type have the same affect as the implied conversion in assignment statements.

The result value depends on the type and absolute value of a, as follows:

  • If a is of type integer, INT (a) = a.

  • If a is of type real and |a| < 1, INT (a) has the value zero.

    If a is of type real and |a| >= 1, INT (a) is the integer whose magnitude is the largest integer that does not exceed the magnitude of a and whose sign is the same as the sign of a.

  • If a is of type complex, INT (a) = a is the value obtained by applying the preceding rules (for a real argument) to the real part of a.
Specific Name1 | Argument Type 2 | Result Type
INTEGER(1), INTEGER(2), INTEGER(4) | INTEGER(4)
INTEGER(1), INTEGER(2), INTEGER(4),
INTEGER(8) 		INTEGER(8)
IIFIX 3 | REAL(4) | INTEGER(2)
IINT | REAL(4) | INTEGER(2)
IFIX 4, 5 | REAL(4) | INTEGER(4)
JFIX INTEGER(1), INTEGER(2), INTEGER(4),
INTEGER(8), REAL(4), REAL(8), REAL(16),
COMPLEX(4), COMPLEX(8), COMPLEX(16) 		INTEGER(4)
INT 6, 7 | REAL(4) | INTEGER(4)
KIFIX | REAL(4) | INTEGER(8)
KINT | REAL(4) | INTEGER(8)
IIDINT | REAL(8) | INTEGER(2)
IDINT 7, 8 | REAL(8) | INTEGER(4)
KIDINT | REAL(8) | INTEGER(8)
IIQINT | REAL(16) | INTEGER(2)
IQINT 7, 9 | REAL(16) | INTEGER(4)
KIQINT | REAL(16) | INTEGER(8)
COMPLEX(4), COMPLEX(8), COMPLEX(16) | INTEGER(2)
COMPLEX(4), COMPLEX(8), COMPLEX(16) | INTEGER(4)
COMPLEX(4), COMPLEX(8), COMPLEX(16) | INTEGER(8)
INT1 INTEGER(1), INTEGER(2), INTEGER(4),
INTEGER(8), REAL(4), REAL(8), REAL(16),
COMPLEX(4), COMPLEX(8), COMPLEX(16) 		INTEGER(1)
INT2 INTEGER(1), INTEGER(2), INTEGER(4),
INTEGER(8), REAL(4), REAL(8), REAL(16),
COMPLEX(4), COMPLEX(8), COMPLEX(16) 		INTEGER(2)
INT4 INTEGER(1), INTEGER(2), INTEGER(4),
INTEGER(8), REAL(4), REAL(8), REAL(16),
COMPLEX(4), COMPLEX(8), COMPLEX(16) 		INTEGER(4)
INT8 INTEGER(1), INTEGER(2), INTEGER(4),
INTEGER(8), REAL(4), REAL(8), REAL(16),
COMPLEX(4), COMPLEX(8), COMPLEX(16) 		INTEGER(8)
1 These specific functions cannot be passed as actual arguments.
2 REAL(16) and COMPLEX(16) are only available on OpenVMS, Tru64 UNIX, and Linux systems.
3 This function can also be specified as HFIX.
4 The setting of compiler option /integer_size or /real_size can affect IFIX.
5 For compatibility with older versions of Fortran, IFIX can also be specified as a generic function.
6 Or JINT.
7 The setting of compiler option /integer_size can affect INT, IDINT, and IQINT.
8 Or JIDINT. For compatibility with older versions of Fortran, IDINT can also be specified as a generic function.
9 Or JIQINT. For compatibility with older versions of Fortran, IQINT can also be specified as a generic function.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NINT, AINT, ANINT, REAL, DBLE, SNGL

Examples

INT (-4.2) has the value -4.

INT (7.8) has the value 7.


INT_PTR_KIND

Inquiry Intrinsic Function (Specific): Returns the INTEGER KIND that will hold an address. This is a specific function that has no generic function associated with it. It must not be passed as an actual argument.

Syntax

result = INT_PTR_KIND( )

Results:

The result is of type default integer. The result is a scalar with the value equal to the value of the kind parameter of the integer data type that can represent an address on the host platform.

On Windows systems, the value is 4. On OpenVMS, Tru64 UNIX, and Linux systems, the value is 8.

Example

   REAL A(100)
   POINTER (P, A)
   INTEGER (KIND=INT_PTR_KIND()) SAVE_P
   P = MALLOC (400)
   SAVE_P = P


INTEGER

Statement: Specifies the INTEGER data type.

Syntax

INTEGER
INTEGER([KIND=]n)
INTEGER*n

n
Is kind 1, 2, 4, or 8.

If a kind parameter is specified, the integer has the kind specified. If a kind parameter is not specified, integer constants are interpreted as follows:

  • If the integer constant is within the default integer kind range, the kind is default integer.
  • If the integer constant is outside the default integer kind range, the kind of the integer constant is the smallest integer kind which holds the constant.

The default kind can also be changed by using the INTEGER directive or the /integer_size compiler option.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: INTEGER Directive, Programmer's Guide: Integer Data Types and Integer Constants

Examples

! Entity-oriented declarations:
INTEGER, DIMENSION(:), POINTER :: days, hours
INTEGER (2) :: k=4
INTEGER (2), PARAMETER :: limit=12

! Attribute-oriented declarations:
INTEGER days, hours
INTEGER (2):: k=4, limit
DIMENSION days(:), hours(:)
POINTER days, hours
PARAMETER (limit=12)


INTEGER Directive

General Compiler Directive: Specifies the default integer kind.

Syntax

c DEC$ INTEGER:{ 2 | 4 | 8 }

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

Rules and Behavior

The INTEGER directive specifies a size of 2 (KIND=2), 4 (KIND=4), or 8 (KIND=8) bytes for default integer numbers.

When the INTEGER directive is in effect, all default integer variables are of the kind specified. Only numbers specified or implied as INTEGER without KIND are affected.

The INTEGER directive can only appear at the top of a program unit. A program unit is a main program, an external subroutine or function, a module or a block data program unit. INTEGER cannot appear between program units, or at the beginning of internal subprograms. It does not affect modules invoked with the USE statement in the program unit that contains it.

The default logical kind is the same as the default integer kind. So, when you change the default integer kind you also change the default logical kind.

The following form is also allowed: !MS$INTEGER:{2|4|8}

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: INTEGER, REAL Directive, General Compiler Directives

Example

INTEGER i            ! a 4-byte integer
WRITE(*,*) KIND(i)
CALL INTEGER2( )
WRITE(*,*) KIND(i)   ! still a 4-byte integer
                     !   not affected by setting in subroutine
END
SUBROUTINE INTEGER2( )
  !DEC$ INTEGER:2
  INTEGER j          ! a 2-byte integer
  WRITE(*,*) KIND(j)
END SUBROUTINE


INTEGERTORGB

QuickWin Subroutine: Converts an RGB color value into its red, green, and blue components.

Module: USE DFLIB

Syntax

CALL INTEGERTORGB (rgb, red, green, blue)

rgb
(Input) INTEGER(4). RGB color value whose red, green, and blue components are to be returned.

red
(Output) INTEGER(4). Intensity of the red component of the RGB color value.

green
(Output) INTEGER(4). Intensity of the green component of the RGB color value.

blue
(Output) INTEGER(4). Intensity of the blue component of the RGB color value.

INTEGERTORGB separates the four-byte RGB color value into the three components as follows:

Compatibility

QUICKWIN GRAPHICS WINDOWS LIB

See Also: Using QuickWin, RGBTOINTEGER, GETCOLORRGB, GETBKCOLORRGB, GETPIXELRRGB, GETPIXELSRGB, GETTEXTCOLORRGB

Example

! build as a QuickWin App.
USE DFLIB
INTEGER(4) r, g, b

CALL INTEGERTORGB(2456, r, g, b)
write(*,*) r, g, b
END


INTENT

Statement and Attribute: Specifies the intended use of one or more dummy arguments.

The INTENT attribute can be specified in a type declaration statement or an INTENT statement, and takes one of the following forms:

Syntax

Type Declaration Statement:

type, [att-ls,] INTENT (intent-spec) [, att-ls] :: d-arg [, d-arg] ...

Statement:

INTENT (intent-spec) [::] d-arg [, d-arg] ...

type
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

intent-spec
Is one of the following specifiers:

  • IN: Specifies that the dummy argument will be used only to provide data to the procedure. The dummy argument must not be redefined (or become undefined) during execution of the procedure.
    Any associated actual argument must be an expression.

  • OUT: Specifies that the dummy argument will be used to pass data from the procedure back to the calling program. The dummy argument is undefined on entry and must be defined before it is referenced in the procedure.
    Any associated actual argument must be definable.

  • INOUT: Specifies that the dummy argument can both provide data to the procedure and return data to the calling program.
    Any associated actual argument must be definable.

d-arg
Is the name of a dummy argument. It cannot be a dummy procedure or dummy pointer.

Rules and Behavior

The INTENT statement can only appear in the specification part of a subprogram or interface body.

If no INTENT attribute is specified for a dummy argument, its use is subject to the limitations of the associated actual argument.

If a function specifies a defined operator, the dummy arguments must have intent IN.

If a subroutine specifies defined assignment, the first argument must have intent OUT or INOUT, and the second argument must have intent IN.

A dummy argument with intent IN (or a subobject of such a dummy argument) must not appear as any of the following:

  • A DO variable or implied-DO variable
  • The variable of an assignment statement
  • The pointer-object of a pointer assignment statement
  • An object or STAT variable in an ALLOCATE or DEALLOCATE statement
  • An input item in a READ statement
  • A variable name in a NAMELIST statement if the namelist group name appears in a NML specifier in a READ statement
  • An internal file unit in a WRITE statement
  • A definable variable in an INQUIRE statement
  • An IOSTAT or SIZE specifier in an I/O statement
  • An actual argument in a reference to a procedure with an explicit interface if the associated dummy argument has intent OUT or INOUT

If an actual argument is an array section with a vector subscript, it cannot be associated with a dummy array that is defined or redefined (has intent OUT or INOUT).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB

See Also: Argument Association, Type Declarations, Compatible attributes

Examples

The following example shows type declaration statements specifying the INTENT attribute:

SUBROUTINE TEST(I, J)
  INTEGER, INTENT(IN) :: I
  INTEGER, INTENT(OUT), DIMENSION(I) :: J

The following are examples of the INTENT statement:

SUBROUTINE TEST(A, B, X)
   INTENT(INOUT) :: A, B
   ...

SUBROUTINE CHANGE(FROM, TO)
   USE EMPLOYEE_MODULE
   TYPE(EMPLOYEE) FROM, TO
   INTENT(IN) FROM
   INTENT(OUT) TO
   ...

The following shows another example:

!Calculate value into a running average and return the average cubed.

TYPE DATA
  INTEGER count
  REAL average
END TYPE
. . .
SUBROUTINE AVERAGE(value,data1,cube_ave)
  TYPE(DATA) data1
  REAL dummy
  ! value cannot be changed, while cube_ave must be defined
  ! before it can be used. Data1 is defined when the procedure is
  ! invoked, and becomes redefined in the subroutine.
  INTENT(IN)::value; INTENT(OUT)::cube_ave
  INTENT(INOUT)::data1

  ! count number of times AVERAGE has been called on the data set
  ! being passed.
  dummy = count*average + value
  data1%count = data1%count + 1
  data1%average = dummy/data1%count
  cube_ave = data1%average**3
END SUBROUTINE


INTERFACE

Statement: Defines explicit interfaces for external or dummy procedures. It can also be used to define a generic name for procedures, a new operator for functions, and a new form of assignment for subroutines.

Syntax

INTERFACE [ generic-spec ]
[ interface-body ] ...
[ MODULE PROCEDURE name-list ] ...
END INTERFACE [ generic-spec ]

generic-spec
(Optional) Is one of the following:

  • A generic name
    For information on generic names, see Program Units and Procedures.

  • OPERATOR (op)

    Defines a generic operator (op). It can be a defined unary, defined binary, or extended intrinsic operator. For information on defined operators, see Program Units and Procedures.

  • ASSIGNMENT (=)

    Defines generic assignment. For information on defined assignment, see Assignment - Defined Assignment.

interface-body
Is one or more function or subroutine subprograms. A function must end with END FUNCTION and a subroutine must end with END SUBROUTINE.

The subprogram must not contain a statement function or a DATA, ENTRY, or FORMAT statement; an entry name can be used as a procedure name.

The subprogram can contain a USE statement.

name-list
Is the name of one or more module procedures that are accessible in the host. The MODULE PROCEDURE statement is only allowed if the interface block specifies a generic-spec and has a host that is a module (or accesses a module by use association).

The characteristics of module procedures are not given in interface blocks, but are assumed from the module subprogram definitions.

Rules and Behavior

Interface blocks can appear in the specification part of the program unit that invokes the external or dummy procedure.

A generic-spec can only appear in the END INTERFACE statement (a Fortran 95 feature) if one appears in the INTERFACE statement; they must be identical.

The characteristics specified for the external or dummy procedure must be consistent with those specified in the procedure's definition.

An interface block must not appear in a block data program unit.

An interface block comprises its own scoping unit, and does not inherit anything from its host through host association.

Internal, module, and intrinsic procedures are all considered to have explicit interfaces. External procedures have implicit interfaces by default; when you specify an interface block for them, their interface becomes explicit. A procedure must not have more than one explicit interface in a given scoping unit. This means that you cannot include internal, module, or intrinsic procedures in an interface block, unless you want to define a generic name for them.

A interface block containing generic-spec specifies a generic interface for the following procedures:

  • The procedures within the interface block

    Any generic name, defined operator, or equals symbol that appears is a generic identifier for all the procedures in the interface block. For the rules on how any two procedures with the same generic identifier must differ, see Unambiguous Generic Procedure References.

  • The module procedures listed in the MODULE PROCEDURE statement

    The module procedures must be accessible by a USE statement.

To make an interface block available to multiple program units (through a USE statement), place the interface block in a module.

The following rules apply to interface blocks containing pure procedures:

  • The interface specification of a pure procedure must declare the INTENT of all dummy arguments except pointer and procedure arguments.

  • A procedure that is declared pure in its definition can also be declared pure in an interface block. However, if it is not declared pure in its definition, it must not be declared pure in an interface block.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: CALL, FUNCTION, MODULE, MODULE PROCEDURE, SUBROUTINE, PURE, Procedure Interfaces, Use and Host Association, Determining When Procedures Require Explicit Interfaces, Defining Generic Names for Procedures, Defining Generic Operators, Defining Generic Assignment

Examples

The following example shows a simple procedure interface block with no generic specification:

SUBROUTINE SUB_B (B, FB)
  REAL B
  ...
  INTERFACE
    FUNCTION FB (GN)
      REAL FB, GN
    END FUNCTION
  END INTERFACE

The following shows another example:

!An interface to an external subroutine SUB1 with header:
!SUBROUTINE SUB1(I1,I2,R1,R2)
!INTEGER I1,I2
!REAL R1,R2

INTERFACE
  SUBROUTINE SUB1(int1,int2,real1,real2)
    INTEGER int1,int2
    REAL real1,real2
  END SUBROUTINE SUB1
END INTERFACE

INTEGER int
. . .


INTRINSIC

Statement and Attribute: Allows the specific name of an intrinsic procedure to be used as an actual argument. (Not all specific names can be used as actual arguments. For more information, see Functions Not Allowed as Actual Arguments.)

The INTRINSIC attribute can be specified in a type declaration statement or an INTRINSIC statement, and takes one of the following forms:

Syntax

Type Declaration Statement:

type, [att-ls,] INTRINSIC [, att-ls] :: in-pro [, in-pro] ...

Statement:

INTRINSIC in-pro [, in-pro] ...

type
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

in-pro
Is the name of an intrinsic procedure.

Rules and Behavior

In a type declaration statement, only functions can be declared INTRINSIC. However, you can use the INTRINSIC statement to declare subroutines, as well as functions, to be intrinsic.

The name declared INTRINSIC is assumed to be the name of an intrinsic procedure. If a generic intrinsic function name is given the INTRINSIC attribute, the name retains its generic properties.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: References to Generic Procedures, Type Declarations, Compatible attributes

Examples

The following example shows a type declaration statement specifying the INTRINSIC attribute:

PROGRAM EXAMPLE
...
REAL(8), INTRINSIC :: DACOS
...
CALL TEST(X, DACOS)     ! Intrinsic function DACOS is an actual argument

The following example shows an INTRINSIC statement:

Main Program | Subprogram
EXTERNAL CTN | SUBROUTINE TRIG(X,F,Y)
INTRINSIC SIN, COS | Y = F(X)
. . . | RETURN
 | END
CALL TRIG(ANGLE,SIN,SINE) |
. . . | FUNCTION CTN(X)
 | CTN = COS(X)/SIN(X)
CALL TRIG(ANGLE,COS,COSINE) | RETURN
. . . | END
CALL TRIG(ANGLE,CTN,COTANGENT) |

Note that when TRIG is called with a second argument of SIN or COS, the function reference F(X) references the Fortran 95/90 library functions SIN and COS; but when TRIG is called with a second argument of CTN, F(X) references the user function CTN.

The following shows another example:

     INTRINSIC SIN, COS
     REAL X, Y, R
 !   SIN and COS are arguments to Calc2:
     R = Calc2 (SIN(x), COS(y))


IOR

Elemental Intrinsic Function (Generic): Performs an inclusive OR on corresponding bits. This function can also be specified as OR.

Syntax

result = IOR (i, j)

i
(Input) Must be of type integer.

j
(Input) Must be of type integer with the same kind parameter as i.

Results:

The result type is the same as i. The result value is derived by combining i and j bit-by-bit according to the following truth table:

  i   j   IOR (i, j)

  1   1       1
  1   0       1
  0   1       1
  0   0       0

The model for the interpretation of an integer value as a sequence of bits is shown in Model for Bit Data.

Specific Name | Argument Type | Result Type
 | INTEGER(1) | INTEGER(1)
IIOR | INTEGER(2) | INTEGER(2)
JIOR | INTEGER(4) | INTEGER(4)
KIOR | INTEGER(8) | INTEGER(8)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: IAND, IEOR, NOT

Examples

IOR (1, 4) has the value 5.

IOR (1, 2) has the value 3.

The following shows another example:

 INTEGER result
 result = IOR(240, 90) ! returns 250


IRAND, IRANDM

Portability Functions: Return random numbers in the range 0 through (2**31)-1, or 0 through (2**15)-1 if called without an argument.

Module: USE DFPORT

Syntax

result = IRAND ([ iflag])
result = IRANDM (iflag)

iflag
(Input) INTEGER(4). Optional for IRAND. Controls the way the returned random number is chosen. If iflag is omitted, it is assumed to be 0, and the return range is 0 through (2**15)-1 (inclusive).

Results:

The result is of type INTEGER(4). If iflag is 1, the generator is restarted and the first random value is returned. If iflag is 0, the next random number in the sequence is returned. If iflag is neither zero nor 1, it is used as a new seed for the random number generator, and the functions return the first new random value.

IRAND and IRANDM are equivalent and return the same random numbers. Both functions are included to ensure portability of existing code that references one or both of them.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RANDOM_NUMBER, RANDOM_SEED, Portability Library

Example

 USE DFPORT
 INTEGER(4) istat, flag_value, r_nums(20)
 flag_value=1
 r_nums(1) = IRAND (flag_value)
 flag_value=0
 do istat=2,20
    r_nums(istat) = irand(flag_value)
 end do


ISHA

Elemental Intrinsic Function (Generic): Arithmetically shifts an integer left or right by a specified number of bits.

Syntax

result = ISHA (i, shift)

i
(Input) Must be of type integer. This argument is the value to be shifted.

shift
(Input) Must be of type integer. This argument is the direction and distance of shift.

Positive shifts are left (toward the most significant bit); negative shifts are right (toward the least significant bit).

Results:

The result type is the same as i. The result is equal to i shifted arithmetically by shift bits.

If shift is positive, the shift is to the left; if shift is negative, the shift is to the right. If shift is zero, no shift is performed.

Bits shifted out from the left or from the right, as appropriate, are lost. Zeros are shifted in from the opposite end.

The kind of integer is important in arithmetic shifting because sign varies among integer representations (see the following example). If you want to shift a one-byte or two-byte argument, you must declare it as INTEGER(1) or INTEGER(2).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ISHC, ISHL, ISHFT, ISHFTC

Example

  INTEGER(1) i, res1
  INTEGER(2) j, res2
  i = -128             ! equal to 10000000
  j = -32768           ! equal to 10000000 00000000
  res1 = ISHA (i, -4)  ! returns 11111000 = -8
  res2 = ISHA (j, -4)  ! returns 11111000 10100000 = -2048


ISHC

Elemental Intrinsic Function (Generic): Rotates an integer left or right by specified number of bits. Bits shifted out one end are shifted in the other end. No bits are lost.

Syntax

result = ISHC (i, shift)

i
(Input) Must be of type integer. This argument is the value to be rotated.

shift
(Input) Must be of type integer. This argument is the direction and distance of rotation.

Positive rotations are left (toward the most significant bit); negative rotations are right (toward the least significant bit).

Results:

The result type is the same as i. The result is equal to i circularly rotated by shift bits.

If shift is positive, i is rotated left shift bits. If shift is negative, i is rotated right shift bits. Bits shifted out one end are shifted in the other. No bits are lost.

The kind of integer is important in circular shifting. With an INTEGER(4) argument, all 32 bits are shifted. If you want to rotate a one-byte or two-byte argument, you must declare it as INTEGER(1) or INTEGER(2).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ISHA, ISHL, ISHFT, ISHFTC

Example

  INTEGER(1) i, res1
  INTEGER(2) j, res2
  i = 10  ! equal to 00001010
  j = 10  ! equal to 00000000 00001010
  res1 = ISHC (i, -3)   ! returns 01000001 = 65
  res2 = ISHC (j, -3)   ! returns 01000000 00000001 =
                        ! 16385


ISHFT

Elemental Intrinsic Function (Generic): Performs a logical shift.

Syntax

result = ISHFT (i, shift)

i
(Input) Must be of type integer.

shift
(Input) Must be of type integer. The absolute value for shift must be less than or equal to BIT_SIZE(i).

Results:

The result type is the same as i. The result has the value obtained by shifting the bits of i by shift positions. If shift is positive, the shift is to the left; if shift is negative, the shift is to the right. If shift is zero, no shift is performed.

Bits shifted out from the left or from the right, as appropriate, are lost. Zeros are shifted in from the opposite end.

ISHFT with a positive shift can also be specified as LSHIFT. ISHFT with a negative shift can also be specified as RSHIFT with |shift|.

For more information, see Bit Functions.

The model for the interpretation of an integer value as a sequence of bits is shown in Model for Bit Data.

Specific Name | Argument Type | Result Type
 | INTEGER(1) | INTEGER(1)
IISHFT | INTEGER(2) | INTEGER(2)
JISHFT | INTEGER(4) | INTEGER(4)
KISHFT | INTEGER(8) | INTEGER(8)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BIT_SIZE, ISHFTC, ISHA, ISHC

Examples

ISHFT (2, 1) has the value 4.

ISHFT (2, -1) has the value 1.

The following shows another example:

  INTEGER(1) i, res1
  INTEGER(2) j, k(3), res2
  i = 10 ! equal to 00001010
  j = 10 ! equal to 00000000 00001010
  res1 = ISHFT (i, 5)  ! returns 01000000 = 64
  res2 = ISHFT (j, 5)  ! returns 00000001 01000000 =
                       ! 320

  k = ISHFT((/3, 5, 1/), (/1, -1, 0/))  ! returns array
                                        ! /6, 2, 1/


ISHFTC

Elemental Intrinsic Function (Generic): Performs a circular shift of the rightmost bits.

Syntax

result = ISHFTC (i, shift [, size])

i
(Input) Must be of type integer.

shift
(Input) Must be of type integer. The absolute value of shift must be less than or equal to size.

size
(Optional; input) Must be of type integer. The value of size must be positive and must not exceed BIT_SIZE(i). If size is omitted, it is assumed to have the value of BIT_SIZE(i).

Results:

The result type is the same as i. The result value is obtained by circular shifting the size rightmost bits of i by shift positions. If shift is positive, the shift is to the left; if shift is negative, the shift is to the right. Ifshift is zero, no shift is performed.

No bits are lost. Bits in i beyond the value specified by size are unaffected.

For more information, see Bit Functions.

The model for the interpretation of an integer value as a sequence of bits is shown in Model for Bit Data.

Specific Name | Argument Type | Result Type
IISHFTC | INTEGER(2) | INTEGER(2)
JISHFTC | INTEGER(4) | INTEGER(4)
KISHFTC | INTEGER(8) | INTEGER(8)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BIT_SIZE, ISHFT, MVBITS

Examples

ISHFTC (4, 2, 4) has the value 1.

ISHFTC (3, 1, 3) has the value 6.

The following shows another example:

  INTEGER(1) i, res1
  INTEGER(2) j, res2
  i = 10  ! equal to 00001010
  j = 10  ! equal to 00000000 00001010
  res1 = ISHFTC (i, 2, 3)   ! rotates the 3 rightmost
                            ! bits by 2 (left) and
                            ! returns 00001001 = 9
  res1 = ISHFTC (i, -2, 3)  ! rotates the 3 rightmost
                            ! bits by -2 (right) and
                            ! returns 00001100 = 12
  res2 = ISHFTC (j, 2, 3)   ! rotates the 3 rightmost
                            ! bits by 2 and returns
                            ! 00000000 00001001 = 9


ISHL

Elemental Intrinsic Function (Generic): Logically shifts an integer left or right by the specified bits. Zeros are shifted in from the opposite end.

Syntax

result = ISHL (i, shift)

i
(Input) Must be of type integer. This argument is the value to be shifted.

shift
(Input) Must be of type integer. This argument is the direction and distance of shift.

If positive, i is shifted left (toward the most significant bit). If negative, i is shifted right (toward the least significant bit).

Results:

The result type is the same as i. The result is equal to i logically shifted by shift bits. Zeros are shifted in from the opposite end.

Unlike circular or arithmetic shifts, which can shift ones into the number being shifted, logical shifts shift in zeros only, regardless of the direction or size of the shift. The integer kind, however, still determines the end that bits are shifted out of, which can make a difference in the result (see the following example).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ISHA, ISHC, ISHFT, ISHFTC

Example

  INTEGER(1) i, res1
  INTEGER(2) j, res2
  i = 10   ! equal to 00001010
  j = 10   ! equal to 00000000 00001010
  res1 = ISHL (i, 5)   ! returns 01000000 = 64
  res2 = ISHL (j, 5)   ! returns 00000001 01000000 = 320


ISNAN

Elemental Intrinsic Function (Generic): Tests whether IEEE® real (S_floating and T_floating) numbers are Not-a-Number (NaN) values.

Syntax

result = ISNAN (x)

x
(Output) Must be of type real.

Results:

The result is of type default logical. The result is .TRUE. if x is an IEEE NaN; otherwise, the result is .FALSE..

Examples

  LOGICAL A
  DOUBLE PRECISION B
  ...
  A = ISNAN(B)

A is assigned the value .TRUE. if B is an IEEE NaN; otherwise, the value assigned is .FALSE..


ITIME

Portability Subroutine: Returns the time in numeric form.

Module: USE DFPORT

Syntax

CALL ITIME (array)

array
(Output) INTEGER(4). A rank one array with three elements used to store numeric time data.

The current time is returned in array in the order hour (array(1)), minute (array(2)), and second (array(3)).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE_AND_TIME, Portability Library

Example

USE DFPORT
 INTEGER(4) time_array(3)
 CALL ITIME (time_array)
 write(*,10) time_array
 10 format (1X,I2,':',I2,':',I2)
 END


IVDEP

General Compiler Directive: Assists the compiler's dependence analysis. It can only be applied to iterative DO loops. This directive can also be specified as INIT_DEP_FWD (INITialize DEPendences ForWarD).

Syntax

c DEC$ IVDEP

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

Rules and Behavior

The IVDEP directive is an assertion to the compiler's optimizer about the order of memory references inside a DO loop.

The IVDEP directive tells the compiler to begin dependence analysis by assuming all dependences occur in the same forward direction as their appearance in the normal scalar execution order. This contrasts with normal compiler behavior, which is for the dependence analysis to make no initial assumptions about the direction of a dependence.

The IVDEP directive must precede the DO statement for each DO loop it affects. No source code lines, other than the following, can be placed between the IVDEP directive statement and the DO statement:

  • An UNROLL directive
  • A PARALLEL DO directive (TU*X only)
  • A PDO directive (TU*X only)
  • Placeholder lines
  • Comment lines
  • Blank lines

The IVDEP directive is applied to a DO loop in which the user knows that dependences are in lexical order. For example, if two memory references in the loop touch the same memory location and one of them modifies the memory location, then the first reference to touch the location has to be the one that appears earlier lexically in the program source code. This assumes that the right-hand side of an assignment statement is "earlier" than the left-hand side.

The IVDEP directive informs the compiler that the program would behave correctly if the statements were executed in certain orders other than the sequential execution order, such as executing the first statement or block to completion for all iterations, then the next statement or block for all iterations, and so forth. The optimizer can use this information, along with whatever else it can prove about the dependences, to choose other execution orders.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: General Compiler Directives

Example

In the following example, the IVDEP directive provides more information about the dependences within the loop, which may enable loop transformations to occur:

  !DEC$ IVDEP
        DO I=1, N
           A(INDARR(I)) = A(INDARR(I)) + B(I)
        END DO

In this case, the scalar execution order follows:

  1. Retrieve INDARR(I).
  2. Use the result from step 1 to retrieve A(INDARR(I)).
  3. Retrieve B(I).
  4. Add the results from steps 2 and 3.
  5. Store the results from step 4 into the location indicated by A(INDARR(I)) from step 1.

IVDEP directs the compiler to initially assume that when steps 1 and 5 access a common memory location, step 1 always accesses the location first because step 1 occurs earlier in the execution sequence. This approach lets the compiler reorder instructions, as long as it chooses an instruction schedule that maintains the relative order of the array references.


JDATE

Portability Function: Returns an 8-character string with the Julian date in the form "yyddd". Three spaces terminate this string.

Module: USE DFPORT

Syntax

result = JDATE( )

Results:

The result is of type character with length 8. The result is the Julian date, in the form YYDDD, followed by three spaces.

A Julian date is a five-digit number whose first two digits are the last two digits of the year, and whose final three represent the day of the year (1 for January 1, 366 for December 31 of a leap year, and so on). For example, the Julian date for February 1, 1994 is 94032.

Warning: The two-digit year return value may cause problems with the year 2000. Use DATE_AND_TIME instead.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE, DATE_AND_TIME, GETDAT, Portability Library

Example

! Sets julian to today's julian date
    USE DFPORT
    CHARACTER*8 julian
    julian = JDATE( )


KILL

Portability Function: Sends a signal to the process given by ID.

Module: USE DFPORT

Syntax

result = KILL (pid, num)

pid
(Input) INTEGER(4). ID of a process to be signaled.

num
(Input) INTEGER(4). Signal value. For the definition of signal values, see the SIGNAL function.

Results:

The result is of type INTEGER(4). The result is zero if the call was successful; otherwise, an error code. Possible error codes are:

  • EINVAL: The signum is not a valid signal number, or PID is not the same as getpid( ) and signum does not equal SIGKILL.
  • ESRCH: The given PID could not be found.
  • EPERM: The current process does not have permission to send a signal to the process given by PID.

Arbitrary signals can be sent only to the calling process (where pid = getpid( )). Other processes can send only the SIGKILL signal (signum = 9), and only if the calling process has permission.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RAISEQQ, SIGNALQQ, Portability Library

Example

USE DFPORT
integer(4) id_number, sig_val, istat
id_number=getpid( )
ISTAT = KILL (id_number, sig_val)


KIND

Inquiry Intrinsic Function (Generic): Returns the kind parameter of the argument.

Syntax

result = KIND (x)

x
(Input) Can be of any intrinsic type.

Results:

The result is a scalar of type default integer. The result has a value equal to the kind type parameter value of x.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SELECTED_INT_KIND, SELECTED_REAL_KIND, CMPLX, INT, REAL, LOGICAL, CHAR, Intrinsic Data Types

Examples

KIND (0.0) has the kind value of default real type.

KIND (12) has the kind value of default integer type.

The following shows another example:

INTEGER i ! a 4-byte integer
WRITE(*,*) KIND(i)
CALL INTEGER2( )
WRITE(*,*) KIND(i)  ! still a 4-byte integer
                    ! not affected by setting in subroutine
END
SUBROUTINE INTEGER2( )
  !DEC$INTEGER:2
  INTEGER j ! a 2-byte integer
  WRITE(*,*) KIND(j)
END SUBROUTINE


LASTPRIVATE (TU*X only)

Parallel Directive Clause: Provides a superset of the functionality provided by the PRIVATE clause; objects are declared PRIVATE and they are given certain values when the parallel region is exited.

Syntax

LASTPRIVATE (list)

list
Is the name of one or more variables or common blocks that are accessible to the scoping unit. Subobjects cannot be specified. Each name must be separated by a comma, and a named common block must appear between slashes (/ /).

Variables that appear in a LASTPRIVATE list are subject to PRIVATE clause semantics. In addition, once the parallel region is exited, each variable has the value provided by the sequentially last section or loop iteration.

When the LASTPRIVATE clause appears in a DO directive, the thread that executes the sequentially last iteration updates the version of the object it had before the construct. When the LASTPRIVATE clause appears in a SECTIONS (or PSECTIONS) directive, the thread that executes the lexically last SECTION updates the version of the object it had before the construct.

Subobjects that are not assigned a value by the last iteration of the DO or the lexically last SECTION of the SECTIONS (or PSECTIONS) directive are undefined after the construct.


LBOUND

Inquiry Intrinsic Function (Generic): Returns the lower bounds for all dimensions of an array, or the lower bound for a specified dimension.

Syntax

result = LBOUND (array [, dim] [, kind])

array
(Input) Must be an array (of any data type). It must not be an allocatable array that is not allocated, or a disassociated pointer.

dim
(Optional; input) Must be a scalar integer with a value in the range 1 to n, where n is the rank array.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

If dim is present, the result is a scalar. Otherwise, the result is a rank-one array with one element for each dimension of array. Each element in the result corresponds to a dimension of array.

If array is an array section or an array expression that is not a whole array or array structure component, each element of the result has the value 1.

If array is a whole array or array structure component, LBOUND (array, dim) has a value equal to the lower bound for subscript dim of array (if array(dim) is nonzero). If array(dim) has size zero, the corresponding element of the result has the value 1.

The setting of compiler options that specify integer size can affect the result of this function.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: UBOUND

Examples

Consider the following:

  REAL ARRAY_A (1:3, 5:8)
  REAL ARRAY_B (2:8, -3:20)

LBOUND(ARRAY_A) is (1, 5). LBOUND(ARRAY_A, DIM=2) is 5.

LBOUND(ARRAY_B) is (2, -3). LBOUND(ARRAY_B (5:8, :)) is (1,1) because the arguments are array sections.

The following shows another example:

  REAL ARRAY (2:6, 8:14)
  INTEGER LB(2), LBD
  LB = LBOUND(ARRAY)            ! returns [2 8]
  LBD = LBOUND(ARRAY, DIM = 2)  ! returns 8


LCWRQQ (ia32 only)

Run-Time Subroutine: Sets the value of the floating-point processor control word. This routine is only available on ia32 processors.

Module: USE DFLIB

Syntax

CALL LCWRQQ (controlword)

controlword
(Input) INTEGER(2). Floating-point processor control word.

LCWRQQ performs the same function as the run-time subroutine SETCONTROLFPQQ and is provided for compatibility.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

USE DFLIB
INTEGER(2) control
CALL SCWRQQ(control) ! get control word
!  Set control word to make processor round up
control = control .AND. (.NOT. FPCW$MCW_RC)  ! Clear
                                             ! control word with inverse
                                             ! of rounding control mask
control = control .OR. FPCW$UP  ! Set control word
                                ! to round up
CALL LCWRQQ(control)
WRITE (*, 9000) 'Control word: ', control
9000 FORMAT (1X, A, Z4)
END


LEADZ

Elemental Intrinsic Function (Generic): Returns the number of leading zero bits in an integer.

Syntax

result = LEADZ (i)

i
Integer.

Results:

The result type is the same as i. The result value is the number of leading zeros in the binary representation of the integer i.

The model for the interpretation of an integer value as a sequence of bits is shown in Model for Bit Data.

Example

Consider the following:

  INTEGER*8 J, TWO
  PARAMETER (TWO=2)
  DO J= -1, 40
    TYPE *, LEADZ(TWO**J)  ! Prints 64 down to 23 (leading zeros)
  ENDDO
  END


LEN

Inquiry Intrinsic Function (Generic): Returns the length of a character expression.

Syntax

result = LEN (string [, kind])

string
(Input) Must be of type character; it can be scalar or array valued. (It can be an array of strings.)

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is a scalar of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

The result has a value equal to the number of characters in string (if it is scalar) or in an element of string (if it is array valued).

The setting of compiler options that specify integer size can affect the result of this function.

Specific Name | Argument Type | Result Type
LEN | CHARACTER | INTEGER(4)
 | CHARACTER | INTEGER(8)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LEN_TRIM

Examples

Consider the following example:

  CHARACTER (15) C (50)
  CHARACTER (25) D

LEN (C) has the value 15, and LEN (D) has the value 25.

The following shows another example:

CHARACTER(11) STR(100)
INTEGER I
I = LEN (STR)  ! returns 11
I = LEN('A phrase with 5 trailing blanks. ')
               ! returns 37


LEN_TRIM

Elemental Intrinsic Function (Generic): Returns the length of the character argument without counting trailing blank characters.

Syntax

result = LEN_TRIM (string [, kind])

string
(Input) Must be of type character.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is a scalar of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

The result has a value equal to the number of characters remaining after any trailing blanks in string are removed. If the argument contains only blank characters, the result is zero.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LEN, LNBLNK

Examples

In these examples, the symbol - represents a blank.

LEN_TRIM ('---C--D---') has the value 7.

LEN_TRIM ('-----') has the value 0.

The following shows another example:

INTEGER LEN1
LEN1 = LEN_TRIM (' GOOD DAY ') ! returns 9
LEN1 = LEN_TRIM (' ')          ! returns 0


LGE

Elemental Intrinsic Function (Generic): Determines if a string is lexically greater than or equal to another string, based on the ASCII collating sequence, even if the processor's default collating sequence is different. In Compaq Fortran, LGE is equivalent to the >= operator.

Syntax

result = LGE (string_a, string_b)

string_a
(Input) Must be of type character.

string_b
(Input) Must be of type character.

Results:

The result is of type default logical. If the strings are of unequal length, the comparison is made as if the shorter string were extended on the right with blanks, to the length of the longer string.

The result is true if the strings are equal, both strings are of zero length, or if string_a follows string_b in the ASCII collating sequence; otherwise, the result is false.

Specific Name | Argument Type | Result Type
LGE 1 | CHARACTER | LOGICAL(4)
1 This specific function cannot be passed as an actual argument.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LGT, LLE, LLT, ASCII and Key Code Charts

Examples

LGE ( 'ONE', 'SIX' ) has the value false.

LGE ( 'TWO', 'THREE' ) has the value true.

The following shows another example:

LOGICAL L
L = LGE('ABC','ABD')       ! returns .FALSE.
L = LGE ('AB', 'AAAAAAAB') ! returns .TRUE.


LGT

Elemental Intrinsic Function (Generic): Determines whether a string is lexically greater than another string, based on the ASCII collating sequence, even if the processor's default collating sequence is different. In Compaq Fortran, LGT is equivalent to the > operator.

Syntax

result = LGT (string_a, string_b)

string_a
(Input) Must be of type character.

string_b
(Input) Must be of type character.

Results:

The result is of type default logical. If the strings are of unequal length, the comparison is made as if the shorter string were extended on the right with blanks, to the length of the longer string.

The result is true if string_a follows string_b in the ASCII collating sequence; otherwise, the result is false. If both strings are of zero length, the result is also false.

Specific Name | Argument Type | Result Type
LGT 1 | CHARACTER | LOGICAL(4)
1 This specific function cannot be passed as an actual argument.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LGE, LLE, LLT, ASCII and Key Code Charts

Examples

LGT ( 'TWO', 'THREE' ) has the value true.

LGT ( 'ONE', 'FOUR' ) has the value true.

The following shows another example:

LOGICAL L
L = LGT('ABC', 'ABC')  ! returns .FALSE.
L = LGT('ABC', 'AABC') ! returns .TRUE.


LINETO, LINETO_W

Graphics Function: Draws a line from the current graphics position up to and including the end point.

Module: USE DFLIB

Syntax

result = LINETO (x, y)
result = LINETO_W (wx, wy)

x, y
(Input) INTEGER(2). Viewport coordinates of end point.

wx, wy
(Input) REAL(8). Window coordinates of end point.

Results:

The result is of type INTEGER(2). The result is a nonzero value if successful; otherwise, 0.

The line is drawn using the current graphics color, logical write mode, and line style. The graphics color is set with SETCOLORRGB, the write mode with SETWRITEMODE, and the line style with SETLINESTYLE.

If no error occurs, LINETO sets the current graphics position to the viewport point (x, y), and LINETO_W sets the current graphics position to the window point (wx, wy).

If you use FLOODFILLRGB to fill in a closed figure drawn with LINETO, the figure must be drawn with a solid line style. Line style is solid by default and can be changed with SETLINESTYLE.

Note: The LINETO routine described here is a QuickWin routine. If you are trying to use the Win32 SDK version of the LineTo routine by including the DFWIN module, you need to specify the routine name as MSFWIN$LineTo. For more information, see Special Naming Convention for Certain QuickWin and Win32 Graphics Routines in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS

See Also: GETCURRENTPOSITION, GETLINESTYLE, GRSTATUS, MOVETO, POLYGON, POLYLINEQQ, SETLINESTYLE, SETWRITEMODE

Example

This program draws the figure shown below.

! Build as QuickWin or Standard Graphics
USE DFLIB
INTEGER(2) status
TYPE (xycoord) xy

CALL MOVETO(INT2(80), INT2(50), xy)
status = LINETO(INT2(240), INT2(150))
status = LINETO(INT2(240), INT2(50))
END

Figure: Output of Program LINETO.FOR


LINETOAR

Graphics Function: Draws a line between each x,y point in the from-array to each corresponding x,y point in the to-array.

Module: USE DFLIB

Syntax

result = LINETOAR (loc(fx), loc(fy), loc(tx) loc(ty), cnt)

fx
(Input) INTEGER(2). From x viewport coordinate array.

fy
(Input) INTEGER(2). From y viewport coordinate array.

tx
(Input) INTEGER(2). To x viewport coordinate array.

ty
(Input) INTEGER(2). To y viewport coordinate array.

cnt
(Input) INTEGER(4). Length of each coordinate array; all should be the same size.

Results:

The result is of type INTEGER(2). The result is a nonzero value if successful; otherwise, zero.

The lines are drawn using the current graphics color, logical write mode, and line style. The graphics color is set with SETCOLORRGB, the write mode with SETWRITEMODE, and the line style with SETLINESTYLE.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS

See Also: LINETO, LINETOAREX, LOC, SETCOLORRGB, SETLINESTYLE, SETWRITEMODE

Example

  ! Build for QuickWin or Standard Graphics
  USE DFLIB
  integer(2) fx(3),fy(3),tx(3),ty(3),result
  integer(4) cnt, i
  ! load the points
  do i = 1,3
    !from here
    fx(i) =20*i
    fy(i) =10
    !to there
    tx(i) =20*i
    ty(i) =60
  end do
  ! draw the lines all at once
  ! 3 white vertical lines in upper left corner
  result = LINETOAR(loc(fx),loc(fy),loc(tx),loc(ty), 3)
  end


LINETOAREX

Graphics Function: Draws a line between each x,y point in the from-array to each corresponding x,y point in the to-array. Each line is drawn with the specified graphics color and line style.

Module: USE DFLIB

Syntax

result = LINETOAREX (loc(fx), loc(fy), loc(tx) loc(ty), loc(C), loc(S), cnt)

fx
(Input) INTEGER(2). From x viewport coordinate array.

fy
(Input) INTEGER(2). From y viewport coordinate array.

tx
(Input) INTEGER(2). To x viewport coordinate array.

ty
(Input) INTEGER(2). To y viewport coordinate array.

C
(Input) INTEGER(4). Color array.

S
(Input) INTEGER(4). Style array.

cnt
(Input) INTEGER(4). Length of each coordinate array; also the length of the color array and style array. All of the arrays should be the same size.

Results:

The result is of type INTEGER(2). The result is a nonzero value if successful; otherwise, zero.

The lines are drawn using the specified graphics colors and line styles, and with the current write mode. The current write mode is set with SETWRITEMODE.

If the color has the #80000000 bit set, the color is an RGB color; otherwise, the color is a palette color.

The styles are as follows from wingdi.h:

  SOLID            0
  DASH             1       /* -------  */
  DOT              2       /* .......  */
  DASHDOT          3       /* _._._._  */
  DASHDOTDOT       4       /* _.._.._  */
  NULL             5

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS

See Also: LINETO, LINETOAR, LOC, POLYLINEQQ, SETWRITEMODE

Example

  ! Build for QuickWin or Standard Graphics
  USE DFLIB
  integer(2) fx(3),fy(3),tx(3),ty(3),result
  integer(4) C(3),S(3),cnt,i,color

  color = #000000FF

  ! load the points
  do i = 1,3
     S(i) = 0  ! all lines solid
     C(i) = IOR(#80000000,color)
     color = color*256 ! pick another of RGB
     if(IAND(color,#00FFFFFF).eq.0) color = #000000FF
     !from here
     fx(i) =20*i
     fy(i) =10
     !to there
     tx(i) =20*i
     ty(i) =60
   end do
   ! draw the lines all at once
   ! 3 vertical lines in upper left corner, Red, Green, and Blue
   result = LINETOAREX(loc(fx),loc(fy),loc(tx),loc(ty),loc(C),loc(S),3)
   end


LLE

Elemental Intrinsic Function (Generic): Determines whether a string is lexically less than or equal to another string, based on the ASCII collating sequence, even if the processor's default collating sequence is different. In Compaq Fortran, LLE is equivalent to the <= operator.

Syntax

result = LLE (string_a, string_b)

string_a
(Input) Must be of type character.

string_b
(Input) Must be of type character.

Results:

The result is of type default logical. If the strings are of unequal length, the comparison is made as if the shorter string were extended on the right with blanks, to the length of the longer string.

The result is true if the strings are equal, both strings are of zero length, or if string_a precedes string_b in the ASCII collating sequence; otherwise, the result is false.

Specific Name | Argument Type | Result Type
LLE 1 | CHARACTER | LOGICAL(4)
1 This specific function cannot be passed as an actual argument.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LGE, LGT, LLT, ASCII and Key Code Charts

Examples

LLE ( 'TWO', 'THREE' ) has the value false.

LLE ( 'ONE', 'FOUR' ) has the value false.

The following shows another example:

LOGICAL L
L = LLE('ABC', 'ABC')   ! returns .TRUE.
L = LLE('ABC', 'AABCD') ! returns .FALSE.


LLT

Elemental Intrinsic Function (Generic): Determines whether a string is lexically less than another string, based on the ASCII collating sequence, even if the processor's default collating sequence is different. In Compaq Fortran, LLT is equivalent to the < operator.

Syntax

result = LLT (string_a, string_b)

string_a
(Input) Must be of type character.

string_b
(Input) Must be of type character.

Results:

The result is of type default logical. If the strings are of unequal length, the comparison is made as if the shorter string were extended on the right with blanks, to the length of the longer string.

The result is true if string_a precedes string_b in the ASCII collating sequence; otherwise, the result is false. If both strings are of zero length, the result is also false.

Specific Name | Argument Type | Result Type
LLT 1 | CHARACTER | LOGICAL(4)
1 This specific function cannot be passed as an actual argument.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LGE, LGT, LLE, ASCII and Key Code Charts

Examples

LLT ( 'ONE', 'SIX' ) has the value true.

LLT ( 'ONE', 'FOUR' ) has the value false.

The following shows another example:

LOGICAL L
L = LLT ('ABC', 'ABC')     ! returns .FALSE.
L = LLT ('AAXYZ', 'ABCDE') ! returns .TRUE.


LNBLNK

Portability Function: Locates the position of the last nonblank character in a string.

Module: USE DFPORT

Syntax

result = LNBLNK (string)

string
(Input) Character*(*). String to be searched. Cannot be an array.

Results:

The result is of type INTEGER(4). The result is the index of the last nonblank character in string.

LNBLNK is very similar to the intrinsic function LEN_TRIM, except that string cannot be an array.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LEN_TRIM, Portability Library

Example

USE DFPORT
integer(4) p
p = LNBLNK(' GOOD DAY ') ! returns 9
p = LNBLNK(' ')          ! returns 0


LOADIMAGE, LOADIMAGE_W

Graphics Function: Reads an image from a Windows bitmap file and displays it at a specified location.

Module: USE DFLIB

Syntax

result = LOADIMAGE (filename, xcoord, ycoord)
result = LOADIMAGE_W (filename, wxcoord, wycoord)

filename
(Input) Character*(*). Path of the bitmap file.

xcoord, ycoord
(Input) INTEGER(4). Viewport coordinates for upper-left corner of image display.

wxcoord, wycoord
(Input) REAL(8). Window coordinates for upper-left corner of image display.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a negative value.

The image is displayed with the colors in the bitmap file. If the color palette in the bitmap file is different from the current system palette, the current palette is discarded and the bitmap's palette is loaded.

LOADIMAGE specifes the screen placement of the image in viewport coordinates. LOADIMAGE_W specifies the screen placement of the image in window coordinates.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SAVEIMAGE, SAVEIMAGE_W


LOC

Inquiry Intrinsic Function (Generic): Returns the internal address of a storage item. This function cannot be passed as an actual argument.

Syntax

result = LOC (x)

x
(Input) Is a variable, an array or record field reference, a procedure, or a constant; it can be of any data type. It must not be the name of an internal procedure or statement function. If it is a pointer, it must be defined and associated with a target.

Results:

The result is of type INTEGER(4) on ia32 processors; INTEGER(8) on Alpha and ia64 processors. The value of the result represents the address of the data object or, in the case of pointers, the address of its associated target. If the argument is not valid, the result is undefined.

LOC performs the same function as the %LOC built-in function.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

! Mixed language example passing Integer Pointer to C

! Fortran main program
      INTERFACE
         SUBROUTINE Ptr_Sub (p)
!DEC$      ATTRIBUTES C, ALIAS:'_Ptr_Sub' :: Ptr_Sub
           INTEGER p
         END SUBROUTINE Ptr_Sub
      END INTERFACE

      REAL A[10], VAR[10]
      POINTER (p, VAR)  ! VAR is the pointer-based
                        ! variable, p is the integer
                        ! pointer
      p = LOC(A)

      CALL Ptr_Sub (p)
      WRITE(*,*) "A(4) = ", A(4)
      END

! C subprogram
void Ptr_Sub (int *p)
{
  float a[10];
  a[3] = 23.5;
  *p = a;
}


%LOC

Built-in Function: Computes the internal address of a storage item.

Syntax

result = %LOC (a)

a
(Input) Is the name of an actual argument. It must be a variable, an expression, or the name of a procedure. (It must not be the name of an internal procedure or statement function.)

The %LOC function produces an integer value that represents the location of the given argument. This value is INTEGER(4) on Windows systems; INTEGER(8) on OpenVMS, Tru64 UNIX, and Linux systems. You can use this integer value as an item in an arithmetic expression.

The LOC intrinsic function serves the same purpose as the %LOC built-in function.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB


LOG

Elemental Intrinsic Function (Generic): Returns the natural logarithm of the argument.

Syntax

result = LOG (x)

x
(Input) Must be of type real or complex. If x is real, its value must be greater than zero. If x is complex, its value must not be zero.

Results:

The result type is the same as x. The result value is approximately equal to logex. If the arguments are complex, the result is the principal value of imaginary part omega in the range -pi < omega <= pi. The imaginary part of the result is pi if the real part of the argument is less than zero and the imaginary part of the argument is zero.

Specific Name | Argument Type | Result Type
ALOG 1 | REAL(4) | REAL(4)
DLOG | REAL(8) | REAL(8)
QLOG 2 | REAL(16) | REAL(16)
CLOG 1 | COMPLEX(4) | COMPLEX(4)
CDLOG 3 | COMPLEX(8) | COMPLEX(8)
CQLOG 2 | COMPLEX(16) | COMPLEX(16)
1 The setting of compiler option /real_size can affect ALOG and CLOG. 2 VMS and U*X 3 This function can also be specified as ZLOG.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: EXP, LOG10

Examples

LOG (8.0) has the value 2.079442.

LOG (25.0) has the value 3.218876.

The following shows another example:

REAL r
r = LOG(10.0)  ! returns 2.302585


LOG10

Elemental Intrinsic Function (Generic): Returns the common logarithm of the argument.

Syntax

result = LOG10 (x)

x
(Input) Must be of type real. The value of x must be greater than zero.

Results:

The result type is the same as x. The result has a value equal to log10x.

Specific Name | Argument Type | Result Type
ALOG10 1 | REAL(4) | REAL(4)
DLOG10 | REAL(8) | REAL(8)
QLOG10 2 | REAL(16) | REAL(16)
1 The setting of compiler option /real_size can affect ALOG10. 2 VMS and U*X

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LOG

Examples

LOG10 (8.0) has the value 0.9030900.

LOG10 (15.0) has the value 1.176091.

The following shows another example:

REAL r
r = LOG10(10.0)  ! returns 1.0


LOGICAL

Statement: Specifies the LOGICAL data type.

Syntax

LOGICAL
LOGICAL([KIND=]n)
LOGICAL*n

n
Is kind 1, 2, 4, or 8.

If a kind parameter is specified, the logical constant has the kind specified. If no kind parameter is specified, the kind of the constant is default logical.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Logical Data Types, Logical Constants, Data Types, Constants, and Variables

Example

LOGICAL, ALLOCATABLE :: flag1, flag2
LOGICAL (2), SAVE :: doit, dont=.FALSE.
LOGICAL switch

! An equivalent declaration is:
LOGICAL flag1, flag2
LOGICAL (2) doit, dont=.FALSE.
ALLOCATABLE flag1, flag2
SAVE doit, dont


LOGICAL Function

Elemental Intrinsic Function (Generic): Converts the logical value of the argument to a logical value with different kind parameters.

Syntax

result = LOGICAL (l [, kind])

l
(Input) Must be of type logical.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is of type logical. If kind is present, the kind parameter is that specified by kind; otherwise, the kind parameter is that of default logical. The result value is that of l.

The setting of compiler option /integer_size can affect this function.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: CMPLX, INT, REAL

Examples

LOGICAL (L .OR. .NOT. L) has the value true and is of type default logical regardless of the kind parameter of logical variable L.

LOGICAL (.FALSE., 2) has the value false, with the kind parameter of INTEGER(KIND=2).


LONG

Portability Function: Returns an INTEGER(2) value as an INTEGER(4) type.

Module: USE DFPORT

Syntax

result = LONG (int2)

int2
(Input) INTEGER(2). Value to be converted.

Results:

The result is of type INTEGER(4). The result is the value of int2 with type INTEGER(4). The upper 16 bits of the result are zeros and the lower 16 are equal to int2.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: INT, KIND, Portability Library


LSHIFT

Elemental Intrinsic Function (Generic): Shifts the bits in an integer left by a specified number of positions. For more information, see ISHFT.


LSTAT

Portability Function: Returns detailed information about a file.

Module: USE DFPORT

Syntax

result = LSTAT (name, statb)

name
(Input) Character*(*). Name of the file to examine.

statb
(Output) INTEGER(4). One-dimensional array with a size of 12. See STAT for the possible values returned in statb.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, an error code (see IERRNO).

LSTAT returns detailed information about the file named in name. In this implementation, LSTAT returns exactly the same information as STAT (because there are no symbolic links). STAT is the preferred function.

INQUIRE also provides information about file properties.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: INQUIRE, GETFILEINFOQQ, STAT, FSTAT, Portability Library

Example

USE DFPORT
INTEGER(4) info_array(12), istatus
character*20 file_name
print *, "Enter name of file to examime: "
read *, file_name
ISTATUS = LSTAT (file_name, info_array)
if (.NOT. ISTATUS) then
   print *, info_array
else
   print *, 'Error ',istatus
end if


LTIME

Portability Subroutine: Returns the components of the local time zone time in a nine-element array.

Module: USE DFPORT

Syntax

CALL LTIME (time, array)

time
(Input) INTEGER(4). An elapsed time in seconds since 00:00:00 Greenwich mean time, January 1, 1970.

array
(Output) INTEGER(4). One-dimensional array with 9 elements to contain local date and time data derived from time.

The elements of array are returned as follows:

Element of array | Data returned
array(1) | Seconds (0 - 59)
array(2) | Minutes (0 - 59)
array(3) | Hours (0 - 23)
array(4) | Day of month (1 - 31)
array(5) | Month (0 - 11)
array(6) | Year number in century (0 - 99)
array(7) | Day of week (0 - 6, where 0 is Sunday)
array(8) | Day of year (1 - 365)
array(9) | 1 if daylight saving time is in effect; otherwise, 0.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE_AND_TIME, Portability Library

Example

USE DFPORT
INTEGER(4) input_time, time_array
!   find number of seconds since 1/1/70
input_time=TIME()
!   convert number of seconds to time array
CALL LTIME (input_time, time_array)
PRINT *, time_array


MAKEDIRQQ

Run-Time Function: Creates a new directory with a specified name.

Module: USE DFLIB

Syntax

result = MAKEDIRQQ (dirname)

dirname
(Input) Character*(*). Name of directory to be created.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

MAKEDIRQQ can create only one directory at a time. You cannot create a new directory and a subdirectory below it in a single command. MAKEDIRQQ does not translate path delimiters. You can use either slash (/) or backslash (\) as valid delimiters.

If an error occurs, call GETLASTERRORQQ to retrieve the error message. Possible errors include:

  • ERR$ACCES - Permission denied. The file's (or directory's) permission setting does not allow the specified access.
  • ERR$EXIST - The directory already exists.
  • ERR$NOENT - The file or path specified was not found.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DELDIRQQ, CHANGEDIRQQ, GETLASTERRORQQ

Example

USE DFLIB
LOGICAL(4) result
result = MAKEDIRQQ('mynewdir')
IF (result) THEN
   WRITE (*,*) 'New subdirectory successfully created'
ELSE
   WRITE (*,*) 'Failed to create subdirectory'
END IF
END


MALLOC

Elemental Intrinsic Function (Specific): Allocates a block of memory. This is a specific function that has no generic function associated with it. It must not be passed as an actual argument.

Syntax

result = MALLOC (i)

i
(Input) Must be of type integer. This value is the size (in bytes) of memory to be allocated.

Results:

The result is of type INTEGER(4) on on ia32 processors; INTEGER(8) on Alpha and ia64 processors. The result is the starting address of the allocated memory. The memory allocated can be freed by using the FREE intrinsic function.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

  INTEGER(4) SIZE
  REAL(4) STORAGE(*)
  POINTER (ADDR, STORAGE)     ! ADDR will point to STORAGE
  SIZE = 1024                 ! Size in bytes
  ADDR = MALLOC(SIZE)         ! Allocate the memory
  CALL FREE(ADDR)             ! Free it
  END


MAP...END MAP

Statement: Specifies mapped field declarations that are part of a UNION declaration within a STRUCTURE statement. For more information, see UNION...END UNION.

Example

UNION
  MAP
     CHARACTER*20 string
  END MAP
  MAP
     INTEGER*2 number(10)
  END MAP
END UNION

UNION
  MAP
     RECORD /Cartesian/ xcoord, ycoord
  END MAP
  MAP
     RECORD /Polar/ length, angle
  END MAP
END UNION


MASTER (TU*X only)

OpenMP Parallel Compiler Directive: Specifies a block of code to be executed by the master thread of the team.

Syntax

c$OMP MASTER
block
c$OMP END MASTER

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

block
Is a structured block (section) of statements or constructs. You cannot branch into or out of the block.

Rules and Behavior

When the MASTER directive is specified, the other threads in the team skip the enclosed block (section) of code and continue execution. There is no implied barrier, either on entry to or exit from the master section.

See Also: Parallel Directives for Tru64 UNIX Systems, OpenMP Fortran API Compiler Directives (TU*X only), Compaq Fortran Parallel Compiler Directives (TU*X only)

Examples

The following example forces the master thread to execute the routines OUTPUT and INPUT:

  c$OMP PARALLEL DEFAULT(SHARED)
        CALL WORK(X)
  c$OMP MASTER
        CALL OUTPUT(X)
        CALL INPUT(Y)
  c$OMP END MASTER
        CALL WORK(Y)
  c$OMP END PARALLEL


MATHERRQQ (ia32 only)

Run-Time Subroutine: Handles run-time math errors. This routine is only available on ia32 processors.

Module: USE DFLIB

Syntax

CALL MATHERRQQ (name, nlen, info, retcode)

name
(Output) Character*(*). Name of the function causing the error. The parameter name is a typeless version of the function called. For example, if an error occurs in a SIN function, the name will be returned as sin for real arguments and csin for complex arguments even though the function may have actually been called with an alternate name such as DSIN or CDSIN, or with SIN and complex arguments.

nlen
(Output) INTEGER(2). Length of name.

info
(Output) Structure. Record containing data about the error. The MTH$E_INFO structure is defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as follows:
 STRUCTURE /MTH$E_INFO/
   INTEGER*4 ERRCODE      ! One of the MTH$ values below
   INTEGER*4 FTYPE        ! One of the TY$ values below
   UNION
   MAP
     REAL*4 R4ARG1        ! INPUT: First argument
     CHARACTER*12 R4FILL1
     REAL*4 R4ARG2        ! INPUT: Second argument (if any)
     CHARACTER*12 R4FILL2
     REAL*4 R4RES         ! OUTPUT : Desired result
     CHARACTER*12 R4FILL3
   END MAP
   MAP
     REAL*8 R8ARG1        ! INPUT : First argument
     CHARACTER*8 R8FILL1
     REAL*8 R8ARG2        ! INPUT : Second argument (if any)
     CHARACTER*8 R8FILL2
     REAL*8 R8RES         ! OUTPUT : Desired result
     CHARACTER*8 R8FILL3
   END MAP
   MAP
     COMPLEX*8 C8ARG1     ! INPUT : First argument
     CHARACTER*8 C8FILL1
     COMPLEX*8 C8ARG2     ! INPUT : Second argument (if any)
     CHARACTER*8 C8FILL2
     COMPLEX*8 C8RES      ! OUTPUT : Desired result
     CHARACTER*8 C8FILL1
   END MAP
   MAP
     COMPLEX*16 C16ARG1    ! INPUT : First argument
     COMPLEX*16 C16ARG2    ! INPUT : Second argument (if any)
     COMPLEX*16 C16RES     ! OUTPUT : Desired result
   END MAP
   END UNION
 END STRUCTURE
retcode
(Output) INTEGER(2). Return code passed back to the run-time library. The value of retcode should be set by the user's MATHERRQQ routine to indicate whether the error was resolved. Set this value to 0 to indicate that the error was not resolved and that the program should fail with a run-time error. Set it to any nonzero value to indicate that the error was resolved and the program should continue.

If you are not compiling with full optimization (using the /Ox compiler option), errors in math functions generate a call to the MATHERRQQ subroutine. You can write a MATHERRQQ function that resolves the error or takes other appropriate action based on arguments passed to the function. If you do not provide your own MATHERRQQ function, a default MATHERRQQ provided with the library terminates the process.

Under the ANSI definition of Fortran, there is no handling of math errors. The programmer is responsible for making sure that arguments to math intrinsics are valid. If they are not valid, the result is undefined. Handling of math errors in math debug mode is a language extension. This mode provides more safety, but the performance of math functions is significantly slower.

The ERRCODE element in the MTH$E_INFO structure specifies the type of math error that occurred, and can have one of the following values:

Value | Meaning
MTH$E_DOMAIN | Argument domain error
MTH$E_OVERFLOW | Overflow range error
MTH$E_PLOSS | Partial loss of significance
MTH$E_SINGULARITY | Argument singularity
MTH$E_TLOSS | Total loss of significance
MTH$E_UNDERFLOW | Underflow range error

The FTYPE element of the info structure identifies the data type of the math function as TY$REAL4, TY$REAL8, TY$CMPLX4, or TY$CMPLX8. Internally, REAL(4) and COMPLEX(4) arguments are converted to REAL(8) and COMPLEX(8). This means that the corresponding mapped sections of the structure are never used.

In general, a MATHERRQQ function should test the FTYPE value and take separate action for TY$REAL8 or TY$CMPLX8 using the appropriate mapped values. If you want to resolve the error, set the R8RES or C8RES field to an appropriate value such as 0.0. You can do calculations within the MATHERRQQ function using the approprate ARG1 and ARG2 fields, but avoid doing any calculations that would cause an error resulting in another call to MATHERRQQ.

Note: You cannot use MATHERRQQ in DLLs or in a program that links with a DLL.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS LIB

Example

See the example MATHERRQQ in Handling Run-Time Math Exceptions in the Programmer's Guide.


MATMUL

Transformational Intrinsic Function (Generic): Performs matrix multiplication of numeric or logical matrices.

Syntax

result = MATMUL (matrix_a, matrix_b)

matrix_a
(Input) Must be an array of rank one or two. It must be of numeric (integer, real, or complex) or logical type.

matrix_b
(Input) Must be an array of rank one or two. It must be of numeric type if matrix_a is of numeric type or logical type if matrix_a is logical type.

At least one argument must be of rank two. The size of the first (or only) dimension of matrix_b must equal the size of the last (or only) dimension of matrix_a.

Results:

The result is an array whose type depends on the data type of the arguments, according to the rules shown in Conversion Rules for Numeric Assignment Statements. The rank and shape of the result depends on the rank and shapes of the arguments, as follows:

  • If matrix_a has shape (n, m) and matrix_b has shape (m, k), the result is a rank-two array with shape (n, k).

  • If matrix_a has shape (m) and matrix_b has shape (m, k), the result is a rank-one array with shape (k).

  • If matrix_a has shape (n, m) and matrix_b has shape (m), the result is a rank-one array with shape (n).

If the arguments are of numeric type, element (i, j) of the result has the value SUM ((row i of matrix_a) * (column j of matrix_b)). If the arguments are of logical type, element (i, j) of the result has the value ANY ((row i of matrix_a) .AND. (column j of matrix_b)).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: TRANSPOSE, PRODUCT

Examples

A is matrix

  [ 2  3  4 ]
  [ 3  4  5 ],
B is matrix
  [ 2  3 ]
  [ 3  4 ]
  [ 4  5 ],
X is vector (1, 2), and Y is vector (1, 2, 3).

The result of MATMUL (A, B) is the matrix-matrix product AB with the value

  [ 29  38 ]
  [ 38  50 ].

The result of MATMUL (X, A) is the vector-matrix product XA with the value (8, 11, 14).

The result of MATMUL (A, Y) is the matrix-vector product AY with the value (20, 26).

The following shows another example:

 INTEGER a(2,3), b(3,2), c(2), d(3), e(2,2), f(3), g(2)
 a = RESHAPE((/1, 2, 3, 4, 5, 6/), (/2, 3/))
 !  a is   1 3 5
 !         2 4 6
 b = RESHAPE((/1, 2, 3, 4, 5, 6/), (/3, 2/))
 !  b is   1 4
 !         2 5
 !         3 6
 c = (/1, 2/)      ! c is [1 2]
 d = (/1, 2, 3/)   ! d is [1 2 3]

 e = MATMUL(a, b)    ! returns 22 49
                     !         28 64

 f = MATMUL(c,a)   ! returns [5 11 17]
 g = MATMUL(a,d)   ! returns [22 28]
 WRITE(*,*) e, f, g
 END


MAX

Elemental Intrinsic Function (Generic): Returns the maximum value of the arguments.

Syntax

result = MAX (a1, a2 [, a3] ...)

a1, a2, a3
(Input) Must all have the same type (integer or real) and kind parameters.

Results:

For MAX0, AMAX1, DMAX1, QMAX1, IMAX0, JMAX0, and KMAX0, the result type is the same as the arguments. For MAX1, IMAX1, JMAX1, and KMAX1, the result type is integer. For AMAX0, AIMAX0, AJMAX0, and AKMAX0, the result type is real. The value of the result is that of the largest argument.

Specific Name 1 | Argument Type | Result Type
 | INTEGER(1) | INTEGER(1)
 | INTEGER(1) | REAL(4)
IMAX0 | INTEGER(2) | INTEGER(2)
AIMAX0 | INTEGER(2) | REAL(4)
MAX0 2 | INTEGER(4) | INTEGER(4)
AMAX0 3, 4 | INTEGER(4) | REAL(4)
KMAX0 | INTEGER(8) | INTEGER(8)
AKMAX0 | INTEGER(8) | REAL(4)
IMAX1 | REAL(4) | INTEGER(2)
MAX1 4, 5, 6 | REAL(4) | INTEGER(4)
KMAX1 | REAL(4) | INTEGER(8)
AMAX1 7 | REAL(4) | REAL(4)
DMAX1 | REAL(8) | REAL(8)
QMAX1 8 | REAL(16) | REAL(16)
1 These specific functions cannot be passed as actual arguments. 2 Or JMAX0. 3 Or AJMAX0. AMAX0 is the same as REAL (MAX). 4 In Fortran 90, AMAX0 and MAX1 are specific functions with no generic name. For compatibility with older versions of Fortran, these functions can also be specified as generic functions. 5 Or JMAX1. MAX1 is the same as INT (MAX). 6 The setting of compiler option /integer_size can affect MAX1. 7 The setting of compiler option /real_size can affect AMAX1. 8 VMS and U*X

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MIN

Examples

MAX (2.0, -8.0, 6.0) has the value 6.0.

MAX (14, 32, -50) has the value 32.

The following shows another example:

 INTEGER m1, m2
 REAL r1, r2
 m1 = MAX(5, 6, 7)           ! returns 7
 m2 = MAX1(5.7, 3.2, -8.3)   ! returns 5
 r1 = AMAX0(5, 6, 7)         ! returns 7.0
 r2 = AMAX1(6.4, -12.2, 4.9) ! returns 6.4


MAXEXPONENT

Inquiry Intrinsic Function (Generic): Returns the maximum exponent in the model representing the same type and kind parameters as the argument.

Syntax

result = MAXEXPONENT (x)

x
(Input) Must be of type real; it can be scalar or array valued.

Results:

The result is a scalar of type default integer. The result has the value emax, as defined in Model for Real Data.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MINEXPONENT

Examples

  REAL(4) x
  INTEGER i
  i = MAXEXPONENT(x)    ! returns 128.


MAXLOC

Transformational Intrinsic Function (Generic): Returns the location of the maximum value of all elements in an array, a set of elements in an array, or elements in a specified dimension of an array.

Syntax

result = MAXLOC (array [, dim] [, mask] [, kind])

array
(Input) Must be an array of type integer or real.

dim
(Optional; input) Must be a scalar integer with a value in the range 1 to n, where n is the rank of array. This argument is a Fortran 95 feature.

mask
(Optional; input) Must be a logical array that is conformable with array.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is an array of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

The following rules apply if dim is omitted:

  • The array result has rank one and a size equal to the rank of array.

  • If MAXLOC(array) is specified, the elements in the array result form the subscript of the location of the element with the maximum value in array.
    The ith subscript returned lies in the range 1 to ei, where ei is the extent of the ith dimension of array.

  • If MAXLOC(array, MASK=mask) is specified, the elements in the array result form the subscript of the location of the element with the maximum value corresponding to the condition specified bymask.

The following rules apply if dim is specified:

  • The array result has a rank that is one less than array, and shape (d1, d2,...ddim-1, ddim+1,...dn), where (d1, d2,...dn) is the shape of array.

  • If array has rank one, MAXLOC(array, dim [,mask]) has a value equal to that of MAXLOC(array [, MASK = mask]). Otherwise, the value of element (s1, s2,...sdim-1, sdim+1,...sn) of MAXLOC(array, dim [,mask]) is equal to MAXLOC(array (s1, s2,...sdim-1, :, sdim+1,...sn) [, MASK = mask (s1, s2,...sdim-1, :, sdim+1,...sn)]).

If more than one element has maximum value, the element whose subscripts are returned is the first such element, taken in array element order. If array has size zero, or every element of mask has the value .FALSE., the value of the result is undefined.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MAXVAL, MINLOC, MINVAL

Examples

The value of MAXLOC((/3, 7, 4, 7/)) is (2), which is the subscript of the location of the first occurrence of the maximum value in the rank-one array.

A is the array

  [  4    0   -3    2 ]
  [  3    1   -2    6 ]
  [ -1   -4    5   -5 ].

MAXLOC (A, MASK=A .LT. 5) has the value (1, 1) because these are the subscripts of the location of the maximum value (4) that is less than 5.

MAXLOC (A, DIM=1) has the value (1, 2, 3, 2). 1 is the subscript of the location of the maximum value (4) in column 1; 2 is the subscript of the location of the maximum value (1) in column 2; and so forth.

MAXLOC (A, DIM=2) has the value (1, 4, 3). 1 is the subscript of the location of the maximum value in row 1; 4 is the subscript of the location of the maximum value in row 2; and so forth.

The following shows another example:

 INTEGER i, max
 INTEGER i, maxl(1)
 INTEGER array(3, 3)
 INTEGER, ALLOCATABLE :: AR1(:)
 ! put values in array
 array = RESHAPE((/7, 9, -1, -2, 5, 0, 3, 6, 9/),     &
                 (/3, 3/))
 ! array is  7 -2 3
 !           9 5 6
 !          -1 0 9
 i = SIZE(SHAPE(array))   ! Get number of dimensions
                          ! in array
 ALLOCATE ( AR1(i))       ! Allocate AR1 to number
                          ! of dimensions in array
 AR1 = MAXLOC (array, MASK = array .LT. 7) ! Get
                          ! the location (subscripts) of
                          ! largest element less than 7
                          ! in array

 !
 ! MASK = array .LT. 7 creates a mask array the same
 ! size and shape as array whose elements are .TRUE. if
 ! the corresponding element in array is less than 7,
 ! and .FALSE. if it is not. This mask causes MAXLOC to
 ! return the index of the element in array with the
 ! greatest value less than 7.
 !
 ! array is  7 -2 3 and MASK=array .LT. 7 is  F T T
 !           9  5 6                           F T T
 !          -1  0 9                           T T F
 ! and AR1 = MAXLOC(array, MASK = array .LT. 7) returns
 ! (2, 3), the location of the element with value 6

 maxl = MAXLOC((/1, 4, 3, 4/))    ! returns 2, the first
                                  ! occurrence of maximum
 END


MAXVAL

Transformational Intrinsic Function (Generic): Returns the maximum value of all elements in an array, a set of elements in an array, or elements in a specified dimension of an array.

Syntax

result = MAXVAL (array [, dim] [, mask])

array
(Input) Must be an array of type integer or real.

dim
(Optional; input) Must be a scalar integer expression with a value in the range 1 to n, where n is the rank of array.

mask
(Optional; input) Must be a logical array that is conformable with array.

Results:

The result is an array or a scalar of the same data type as array.

The result is a scalar if dim is omitted or array has rank one.

The following rules apply if dim is omitted:

  • If MAXVAL (array) is specified, the result has a value equal to the maximum value of all the elements in array.

  • If MAXVAL (array, MASK=mask) is specified, the result has a value equal to the maximum value of the elements in array corresponding to the condition specified by mask.

The following rules apply if dim is specified:

  • An array result has a rank that is one less than array, and shape (d1, d2,...,ddim-1, ddim+1, ..., dn), where (d1, d2, ..., dn) is the shape of array.

  • If array has rank one, MAXVAL (array, dim [,mask]) has a value equal to that of MAXVAL (array [,MASK = mask]). Otherwise, the value of element (s1, s2, ..., sdim-1, sdim+1, ..., sn) of MAXVAL (array, dim, [,mask]) is equal to MAXVAL (array (s1, s2, ..., sdim-1, :, sdim+1, ..., sn) [,MASK = mask (s1, s2, ..., sdim-1, :, sdim+1, ..., sn)]).

If array has size zero or if there are no true elements in mask, the result (if dim is omitted), or each element in the result array (if dim is specified), has the value of the negative number of the largest magnitude supported by the processor for numbers of the type and kind parameters of array.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MAXLOC, MINVAL, MINLOC

Examples

The value of MAXVAL ((/2, 3, 4/)) is 4 because that is the maximum value in the rank-one array.

MAXVAL (B, MASK=B .LT. 0.0) finds the maximum value of the negative elements of B.

C is the array

  [ 2  3  4 ]
  [ 5  6  7 ].

MAXVAL (C, DIM=1) has the value (5, 6, 7). 5 is the maximum value in column 1; 6 is the maximum value in column 2; and so forth.

MAXVAL (C, DIM=2) has the value (4, 7). 4 is the maximum value in row 1 and 7 is the maximum value in row 2.

The following shows another example:

 INTEGER array(2,3), i(2), max
 INTEGER, ALLOCATABLE :: AR1(:), AR2(:)
 array = RESHAPE((/1, 4, 5, 2, 3, 6/),(/2, 3/))
 ! array is   1 5 3
 !            4 2 6
 i = SHAPE(array)      ! i = [2 3]
 ALLOCATE (AR1(i(2)))  ! dimension AR1 to the number of
                       ! elements in dimension 2
                       ! (a column) of array
 ALLOCATE (AR2(i(1)))  ! dimension AR2 to the number of
                       ! elements in dimension 1
                       ! (a row) of array
 max = MAXVAL(array, MASK = array .LT. 4) ! returns 3
 AR1 = MAXVAL(array, DIM = 1)  ! returns [ 4 5 6 ]
 AR2 = MAXVAL(array, DIM = 2)  ! returns [ 5 6 ]
 END


MBCharLen

NLS Function: Returns the length, in bytes, of the first character in a multibyte-character string.

Module: USE DFNLS

Syntax

result = MBCharLen (string)

string
(Input) Character*(*). String containing the character whose length is to be determined. Can contain multibyte characters.

Results:

The result is of type INTEGER(4). The result is the number of bytes in the first character contained in string. Returns 0 if string has no characters (is length 0).

MBCharLen does not test for multibyte character validity.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MBCurMax, MBLead, MBLen, MBLen_Trim


MBConvertMBToUnicode

NLS Function: Converts a multibyte-character string from the current codepage to a Unicode string.

Module: USE DFNLS

Syntax

result = MBConvertMBToUnicode (mbstr, unicodestr [, flags ])

mbstr
(Input) Character*(*). Multibyte codepage string to be converted.

unicodestr
(Output) INTEGER(2). Array of integers that is the translation of the input string into Unicode.

flags
(Optional; input) INTEGER(4). If specified, modifies the string conversion. If flags is omitted, the value NLS$Precomposed is used. Available values (defined in DFNLS.F90) are:

  • NLS$Precomposed - Use precomposed characters always. (default)
  • NLS$Composite - Use composite wide characters always.
  • NLS$UseGlyphChars - Use glyph characters instead of control characters.
  • NLS$ErrorOnInvalidChars - Returns -1 if an invalid input character is encountered.

The flags NLS$Precomposed and NLS$Composite are mutually exclusive. You can combine NLS$UseGlyphChars with either NLS$Precomposed or NLS$Composite using an inclusive OR (IOR or OR).

Results:

The result is of type INTEGER(4). If no error occurs, returns the number of bytes written to unicodestr (bytes are counted, not characters), or the number of bytes required to hold the output string if unicodestr has zero size. If the unicodestr array is bigger than needed to hold the translation, the extra elements are set to space characters. If unicodestr has zero size, the function returns the number of bytes required to hold the translation and nothing is written to unicodestr.

If an error occurs, one of the following negative values is returned:

  • NLS$ErrorInsufficentBuffer - The unicodestr argument is too small, but not zero size so that the needed number of bytes would be returned.
  • NLS$ErrorInvalidFlags - The flags argument has an illegal value.
  • NLS$ErrorInvalidCharacter - A character with no Unicode translation was encountered in mbstr. This error can occur only if the NLS$InvalidCharsError flag was used in flags.

By default, or if flags is set to NLS$Precomposed, the function MBConvertMBToUnicode attempts to translate the multibyte codepage string to a precomposed Unicode string. If a precomposed form does not exist, the function attempts to translate the codepage string to a composite form.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MBConvertUnicodeToMB


MBConvertUnicodeToMB

NLS Function: Converts a Unicode string to a multibyte-character string from the current codepage.

Module: USE DFNLS

Syntax

result = MBConvertUnicodeToMB (unicodestr, mbstr [, flags ])

unicodestr
(Input) INTEGER(2). Array of integers holding the Unicode string to be translated.

mbstr
(Output) Character*(*). Translation of Unicode string into multibyte character string from the current codepage.

flags
(Optional; input) INTEGER(4). If specified, argument to modify the string conversion. If flags is omitted, no extra checking of the conversion takes place. Available values (defined in DFNLS.F90) are:

  • NLS$CompositeCheck - Convert composite characters to precomposed.
  • NLS$SepChars - Generate separate characters.
  • NLS$DiscardDns - Discard nonspacing characters.
  • NLS$DefaultChars - Replace exceptions with default character.

The last three flags (NLS$SepChars, NLS$DiscardDns, and NLS$DefaultChars) are mutually exclusive and can be used only if NLS$CompositeCheck is set, in which case one (and only one) of them is combined with NLS$CompositeCheck using an inclusive OR (IOR or OR). These flags determine what translation to make when there is no precomposed mapping for a base character/nonspace character combination in the Unicode wide character string. The default (IOR(NLS$CompositeCheck, NLS$SepChars)) is to generate separate characters.

Results:

The result is of type INTEGER(4). If no error occurs, returns the number of bytes written to mbstr (bytes are counted, not characters), or the number of bytes required to hold the output string if mbstr has zero length. If mbstr is longer than the translation, it is blank-padded. If mbstr is zero length, the function returns the number of bytes required to hold the translation and nothing is written to mbstr.

If an error occurs, one of the following negative values is returned:

  • NLS$ErrorInsufficentBuffer - The mbstr argument is too small, but not zero length so that the needed number of bytes is returned.
  • NLS$ErrorInvalidFlags - The flags argument has an illegal value.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MBConvertMBToUnicode


MBCurMax

NLS Function: Returns the longest possible multibyte character length, in bytes, for the current codepage.

Module: USE DFNLS

Syntax

result = MBCurMax( )

Results:

The result is of type INTEGER(4). The result is the longest possible multibyte character, in bytes, for the current codepage.

The MBLenMax parameter, defined in the module DFNLS.F90, is the longest length, in bytes, of any character in any codepage installed on the system.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MBCharLen


MBINCHARQQ

NLS Function: Performs the same function as INCHARQQ except that it can read a single multibyte character at once, and it returns the number of bytes read as well as the character.

Module: USE DFNLS

Syntax

result = MBINCHARQQ (string)

string
(Output) CHARACTER(MBLenMax). String containing the read characters, padded with blanks up to the length MBLenMax. The MBLenMax parameter, defined in the module DFNLS.F90 (in \DF98\INCLUDE), is the longest length, in bytes, of any character in any codepage installed on the system.

Results:

The result is of type INTEGER(4). The result is the number of characters read.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: INCHARQQ, MBCurMax, MBCharLen, MBLead


MBINDEX

NLS Function: Performs the same function as INDEX except that the strings manipulated can contain multibyte characters.

Module: USE DFNLS

Syntax

result = MBINDEX (string, substring [, back])

string
(Input) CHARACTER*(*). String to be searched for the presence of substring. Can contain multibyte characters.

substring
(Input) CHARACTER*(*). Substring whose position within string is to be determined. Can contain multibyte characters.

back
(Optional; input) LOGICAL(4). If specified, determines direction of the search. If back is .FALSE. or is omitted, the search starts at the beginning of string and moves toward the end. If back is .TRUE., the search starts end of string and moves toward the beginning.

Results:

The result is of type INTEGER(4). If back is omitted or is .FALSE., returns the leftmost position in string that contains the start of substring. If back is .TRUE., returns the rightmost position in string which contains the start of substring. If string does not contain substring, returns 0. If substring occurs more than once, returns the starting position of the first occurrence ("first" is determined by the presence and value of back).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: INDEX, MBSCAN, MBVERIFY


MBJISToJMS, MBJMSToJIS

NLS Functions: Converts Japan Industry Standard (JIS) characters to Microsoft Kanji (JMS) characters, or converts JMS characters to JIS characters.

Module: USE DFNLS

Syntax

result = MBJISToJMS (char)
result = MBJMSToJIS (char)

char
(Input) CHARACTER(2). JIS or JMS character to be converted.

A JIS character is converted only if the lead and trail bytes are in the hexadecimal range 21 through 7E.

A JMS character is converted only if the lead byte is in the hexadecimal range 81 through 9F or E0 through FC, and the trail byte is in the hexadecimal range 40 through 7E or 80 through FC.

Results:

The result is of type character with length 2. MBJISToJMS returns a Microsoft Kanji (Shift JIS or JMS) character. MBJMSToJIS returns a Japan Industry Standard (JIS) character.

Only computers with Japanese installed as one of the available languages can use the MBJISToJMS and MBJMSToJIS conversion functions.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NLSEnumLocales, NLSEnumCodepages, NLSGetLocale, NLSSetLocale


MBLead

NLS Function: Determines whether a given character is the lead (first) byte of a multibyte character sequence.

Module: USE DFNLS

Syntax

result = MBLead (char)

char
(Input) CHARACTER(1). Character to be tested for lead status.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if char is the first character of a multibyte character sequence; otherwise, .FALSE..

MBLead only works stepping forward through a whole multibyte character string. For example:

       DO i = 1, LEN(str)  ! LEN returns the number of bytes, not the
                           ! number of characters in str
          WRITE(*, 100) MBLead (str(i:i))
       END DO
 100   FORMAT (L2, \)

MBLead is passed only one character at a time and must start on a lead byte and step through a string to establish context for the character. MBLead does not correctly identify a nonlead byte if it is passed only the second byte of a multibyte character because the status of lead byte or trail byte depends on context.

The function MBStrLead is passed a whole string and can identify any byte within the string as a lead or trail byte because it performs a context-sensitive test, scanning all the way back to the beginning of a string if necessary to establish context. So, MBStrLead can be much slower than MBLead (up to n times slower, where n is the length of the string).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MBStrLead, MBCharLen


MBLen

NLS Function: Returns the number of characters in a multibyte-character string, including trailing blanks.

Module: USE DFNLS

Syntax

result = MBLen (string)

string
(Input) CHARACTER*(*). String whose characters are to be counted. Can contain multibyte characters.

Results:

The result is of type INTEGER(4). The result is the number of characters in string.

MBLen recognizes multibyte-character sequences according to the multibyte codepage currently in use. It does not test for multibyte-character validity.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MBLen_Trim, MBStrLead


MBLen_Trim

NLS Function: Returns the number of characters in a multibyte-character string, not including trailing blanks.

Module: USE DFNLS

Syntax

result = MBLen_Trim (string)

string
(Input) Character*(*). String whose characters are to be counted. Can contain multibyte characters.

Results:

The result is of type INTEGER(4). The result is the number of characters in string minus any trailing blanks (blanks are bytes containing character 32 (hex 20) in the ASCII collating sequence).

MBLen_Trim recognizes multibyte-character sequences according to the multibyte codepage currently in use. It does not test for multibyte-character validity.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MBLen, MBStrLead


MBLGE, MBLGT, MBLLE, MBLLT, MBLEQ, MBLNE

NLS Functions: Perform the same functions as LGE, LGT, LLE, LLT and the logical operators .EQ. and .NE. except that the strings being compared can include multibyte characters, and optional flags can modify the comparison.

Module: USE DFNLS

Syntax

result = MBLGE (string_a,
string_b, [ flags ])
result = MBLGT (string_a, string_b, [ flags ])
result = MBLLE (string_a, string_b, [ flags ])
result = MBLLT (string_a, string_b, [ flags ])
result = MBLEQ (string_a, string_b, [ flags ])
result = MBLNE (string_a, string_b, [ flags ])
string_a, string_b
(Input) Character*(*). Strings to be compared. Can contain multibyte characters.

flags
(Optional; input) INTEGER(4). If specified, determines which character traits to use or ignore when comparing strings. You can combine several flags using an inclusive OR (IOR or OR). There are no illegal combinations of flags, and the functions may be used without flags, in which case all flag options are turned off. The available values (defined in DFNLS.F90) are:

  • NLS$MB_IgnoreCase - Ignore case.
  • NLS$MB_IgnoreNonspace - Ignore nonspacing characters (this flag removes Japanese accent characters if they exist).
  • NLS$MB_IgnoreSymbols - Ignore symbols.
  • NLS$MB_IgnoreKanaType - Do not differentiate between Japanese Hiragana and Katakana characters (corresponding Hiragana and Katakana characters will compare as equal).
  • NLS$MB_IgnoreWidth - Do not differentiate between a single-byte character and the same character as a double byte.
  • NLS$MB_StringSort - Sort all symbols at the beginning, including the apostrophe and hyphen (See the last paragraph below).

Results:

The result is of type LOGICAL(4). Comparisons are made using the current locale, not the current codepage. The codepage used is the default for the language/country combination of the current locale.

MBLGE returns .TRUE. if the strings are equal or string_a comes last in the collating sequence. Otherwise, it returns .FALSE..

MBLGT returns .TRUE. if string_a comes last in the collating sequence. Otherwise, it returns .FALSE..

MBLLE returns .TRUE. if the strings are equal or string_a comes first in the collating sequence. Otherwise, it returns .FALSE..

MBLLT returns .TRUE. if string_a comes first in the collating sequence. Otherwise, it returns .FALSE..

MBLEQ returns .TRUE. if the strings are equal in the collating sequence. Otherwise, it returns .FALSE..

MBLNE returns .TRUE. if the strings are not equal in the collating sequence. Otherwise, it returns .FALSE..

If the two strings are of different lengths, they are compared up to the length of the shortest one. If they are equal to that point, then the return value indicates that the longer string is greater.

If flags is invalid, the functions return .FALSE..

If the strings supplied contain Arabic Kashidas, the Kashidas are ignored during the comparison. Therefore, if the two strings are identical except for Kashidas within the strings, the functions return a value indicating they are "equal" in the collation sense, though not necessarily identical.

When not using the NLS$MB_StringSort flag, the hyphen and apostrophe are special symbols and are treated differently than others. This is to ensure that words like coop and co-op stay together within a list. All symbols, except the hyphen and apostrophe, sort before any other alphanumeric character. If you specify the NLS$MB_StringSort flag, hyphen and apostrophe sort at the beginning also.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LGE, LGT, LLE, LLT


MBNext

NLS Function: Returns the position of the first lead byte or single-byte character immediately following the given position in a multibyte-character string.

Module: USE DFNLS

Syntax

result = MBNext (string, position)

string
(Input) Character*(*). String to be seached for the first lead byte or single-byte character after the current position. Can contain multibyte characters.

position
(Input) INTEGER(4). Position in string to search from. Must be the position of a lead byte or a single-byte character. Cannot be the position of a trail (second) byte of a multibyte character.

Results:

The result is of type INTEGER(4). The result is the position of the first lead byte or single-byte character in string immediately following the position given in position, or 0 if no following first byte is found in string.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MBPrev


MBPrev

NLS Function: Returns the position of the first lead byte or single-byte character immediately preceding the given string position in a multibyte-character string.

Module: USE DFNLS

Syntax

result = MBPrev (string, position)

string
(Input) Character*(*). String to be seached for the first lead byte or single-byte character before the current position. Can contain multibyte characters.

position
(Input) INTEGER(4). Position in string to search from. Must be the position of a lead byte or single-byte character. Cannot be the position of the trail (second) byte of a multibyte character.

Results:

The result is of type INTEGER(4). The result is the position of the first lead byte or single-byte character in string immediately preceding the position given in position, or 0 if no preceding first byte is found in string.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MBNext


MBSCAN

NLS Function: Performs the same function as SCAN except that the strings manipulated can contain multibyte characters.

Module: USE DFNLS

Syntax

result = MBSCAN (string, set [, back ])

string
(Input) Character*(*). String to be searched for the presence of any character in set.

set
(Input) Character*(*). Characters to search for.

back
(Optional; input) LOGICAL(4). If specified, determines direction of the search. If back is .FALSE. or is omitted, the search starts at the beginning of string and moves toward the end. If back is .TRUE., the search starts end of string and moves toward the beginning.

Results:

The result is of type INTEGER(4). If back is .FALSE. or is omitted, returns the position of the leftmost character in string that is in set. If back is .TRUE., returns the rightmost character in string that is in set. If no characters in string are in set, returns 0.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SCAN, MBINDEX, MBVERIFY


MBStrLead

NLS Function: Performs a context-senstive test to determine whether a given character byte in a string is a multibyte-character lead byte.

Module: USE DFNLS

Syntax

result = MBStrLead (string, position)

string
(Input) Character*(*). String containing the character byte to be tested for lead status.

position
(Input) INTEGER(4). Position in string of the character byte in the string to be tested.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if the character byte in position of string is a lead byte; otherwise, .FALSE..

MBStrLead is passed a whole string and can identify any byte within the string as a lead or trail byte because it performs a context-sensitive test, scanning all the way back to the beginning of a string if necessary to establish context.

MBLead is passed only one character at a time and must start on a lead byte and step through a string one character at a time to establish context for the character. So, MBStrLead can be much slower than MBLead (up to n times slower, where n is the length of the string).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MBLead


MBVERIFY

NLS Function: Performs the same function as VERIFY except that the strings manipulated can contain multibyte characters.

Module: USE DFNLS

Syntax

result = MBVERIFY (string, set [, back ])

string
(Input) Character*(*). String to be searched for presence of any character not in set.

set
(Input) Character*(*). Set of characters tested to verify that it includes all the characters in string.

back
(Optional; input) LOGICAL(4). If specified, determines direction of the search. If back is .FALSE. or is omitted, the search starts at the beginning of string and moves toward the end. If back is .TRUE., the search starts end of string and moves toward the beginning.

Results:

The result is of type INTEGER(4). If back is .FALSE. or is omitted, returns the position of the leftmost character in string that is not in set. If back is .TRUE., returns the rightmost character in string that is not in set. If all the characters in string are in set, returns 0.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: VERIFY, MBINDEX, MBSCAN


MERGE

Elemental Intrinsic Function (Generic): Selects between two values or between corresponding elements in two arrays, according to the condition specified by a logical mask.

Syntax

result = MERGE (tsource, fsource, mask)

tsource
(Input) Must be a scalar or array (of any data type).

fsource
(Input) Must be a scalar or array of the same type and type parameters as tsource.

mask
(Input) Must be a logical array.

Results:

The result type is the same as tsource. The value of mask determines whether the result value is taken from tsource (if mask is true) or fsource (if mask is false).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MVBITS

Examples

For MERGE (1.0, 0.0, R < 0), R = -3 has the value 1.0, and R = 7 has the value 0.0.

TSOURCE is the array

  [ 1  3  5 ]
  [ 2  4  6 ],
FSOURCE is the array
  [ 8  9  0 ]
  [ 1  2  3 ],
and MASK is the array
  [ F  T  T]
  [ T  T  F].

MERGE (TSOURCE, FSOURCE, MASK) produces the result:

  [ 8  3  5 ]
  [ 2  4  3 ].

The following shows another example:

 INTEGER tsource(2, 3), fsource(2, 3), AR1 (2, 3)
 LOGICAL mask(2, 3)
 tsource = RESHAPE((/1, 4, 2, 5, 3, 6/),(/2, 3/))
 fsource = RESHAPE((/7, 0, 8, -1, 9, -2/), (/2, 3/))
 mask = RESHAPE((/.TRUE., .FALSE., .FALSE., .TRUE.,         &
                  .TRUE., .FALSE./), (/2,3/))
 ! tsource is  1 2 3 , fsource is  7  8  9 , mask is  T F T
 !             4 5 6               0 -1 -2            F T F

 AR1 = MERGE(tsource, fsource, mask) ! returns  1 8  3
                                     !          0 5 -2
 END


MESSAGE

General Compiler Directive: Specifies a character string to be sent to the standard output device during the first compiler pass; this aids debugging.

Syntax

c DEC$ MESSAGE:string

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

string
Is a character constant specifying a message.

The following form is also allowed: !MS$MESSAGE:string

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: General Compiler Directives

Example

!DEC$ MESSAGE:'Compiling Sound Speed Equations'


MESSAGEBOXQQ

QuickWin Function: Displays a message box in a QuickWin window.

Module: USE DFLIB

Syntax

result = MESSAGEBOXQQ (msg, caption, mtype)

msg
(Input) Character*(*). Null-terminated C string. Message the box displays.

caption
(Input) Character*(*). Null-terminated C string. Caption that appears in the title bar.

mtype
(Input) INTEGER(4). Symbolic constant that determines the objects (buttons and icons) and properties of the message box. You can combine several constants (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory) using an inclusive OR (IOR or OR). The symbolic constants and their associated objects or properties are:

  • MB$ABORTRETRYIGNORE - The Abort, Retry, and Ignore buttons.
  • MB$DEFBUTTON1 - The first button is the default.
  • MB$DEFBUTTON2 - The second button is the default.
  • MB$DEFBUTTON3 - The third button is the default.
  • MB$ICONASTERISK - Lowercase i in blue circle icon.
  • MB$ICONEXCLAMATION - The exclamation-mark icon.
  • MB$ICONHAND - The stop-sign icon.
  • MB$ICONINFORMATION - Lowercase i in blue circle icon.
  • MB$ICONQUESTION - The question-mark icon.
  • MB$ICONSTOP - The stop-sign icon.
  • MB$OK - The OK button.
  • MB$OKCANCEL - The OK and Cancel buttons.
  • MB$RETRYCANCEL - The Retry and Cancel buttons.
  • MB$SYSTEMMODAL - Box is system-modal: all applications are suspended until the user responds.
  • MB$YESNO - The Yes and No buttons.
  • MB$YESNOCANCEL - The Yes, No, and Cancel buttons.

Results:

The result is of type INTEGER(4). The result is zero if memory is not sufficient for displaying the message box. Otherwise, the result is one of the following values, indicating the user's response to the message box:

  • MB$IDABORT - The Abort button was pressed.
  • MB$IDCANCEL - The Cancel button was pressed.
  • MB$IDIGNORE - The Ignore button was pressed.
  • MB$IDNO - The No button was pressed.
  • MB$IDOK - The OK button was pressed.
  • MB$IDRETRY - The Retry button was pressed.
  • MB$IDYES - The Yes button was pressed.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: ABOUTBOXQQ, SETMESSAGEQQ, Using QuickWin

Example

 ! Build as QuickWin app
 USE DFLIB
 message = MESSAGEBOXQQ('Do you want to continue?'C,    &
           'Matrix'C,   &
           MB$ICONQUESTION.OR.MB$YESNO.OR.MB$DEFBUTTON1)
 END


MIN

Elemental Intrinsic Function (Generic): Returns the minimum value of the arguments.

Syntax

result = MIN (a1, a2 [, a3...])

a1, a2, a3
(Input) Must all have the same type (integer or real) and kind parameters.

Results:

For MIN0, AMIN1, DMIN1, QMIN1, IMIN0, JMIN0, and KMIN0, the result type is the same as the arguments. For MIN1, IMIN1, JMIN1, and KMIN1, the result type is integer. For AMIN0, AIMIN0, AJMIN0, and AKMIN0, the result type is real. The value of the result is that of the smallest argument.

Specific Name 1 | Argument Type | Result Type
 | INTEGER(1) | INTEGER(1)
 | INTEGER(1) | REAL(4)
IMIN0 | INTEGER(2) | INTEGER(2)
AIMIN0 | INTEGER(2) | REAL(4)
MIN0 2 | INTEGER(4) | INTEGER(4)
AMIN0 3, 4 | INTEGER(4) | REAL(4)
KMIN0 | INTEGER(8) | INTEGER(8)
AKMIN0 | INTEGER(8) | REAL(4)
IMIN1 | REAL(4) | INTEGER(2)
MIN1 4, 5, 6 | REAL(4) | INTEGER(4)
KMIN1 | REAL(4) | INTEGER(8)
AMIN1 7 | REAL(4) | REAL(4)
DMIN1 | REAL(8) | REAL(8)
QMIN1 8 | REAL(16) | REAL(16)
1 These specific functions cannot be passed as actual arguments. 2 Or JMIN0. 3 Or AJMIN0. AMIN0 is the same as REAL (MIN). 4 In Fortran 90, AMIN0 and MIN1 are specific functions with no generic name. For compatibility with older versions of Fortran, these functions can also be specified as generic functions. 5 Or JMIN1. MIN1 is the same as INT (MIN). 6 The setting of compiler option /integer_size can affect MIN1. 7 The setting of compiler option /real_size can affect AMIN1. 8 VMS and U*X

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MAX

Examples

MIN (2.0, -8.0, 6.0) has the value -8.0.

MIN (14, 32, -50) has the value -50.

The following shows another example:

 INTEGER m1, m2
 REAL r1, r2
 m1 = MIN (5, 6, 7)           ! returns 5
 m2 = MIN1 (-5.7, 1.23, -3.8) ! returns -5
 r1 = AMIN0 (-5, -6, -7)      ! returns -7.0
 r2 = AMIN1(-5.7, 1.23, -3.8) ! returns -5.7


MINEXPONENT

Inquiry Intrinsic Function (Generic): Returns the minimum exponent in the model representing the same type and kind parameters as the argument.

Syntax

result = MINEXPONENT (x)

x
(Input) must be of type real; it can be scalar or array valued.

Results:

The result is a scalar of type default integer. The result has the value emin, as defined in Model for Real Data.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MAXEXPONENT

Examples

If X is of type REAL(4), MINEXPONENT (X) has the value -125.

The following shows another example:

 REAL(8) r1  ! DOUBLE PRECISION REAL
 INTEGER i
 i = MINEXPONENT (r1) ! returns - 1021.


MINLOC

Transformational Intrinsic Function (Generic): Returns the location of the minimum value of all elements in an array, a set of elements in an array, or elements in a specified dimension of an array.

Syntax

result = MINLOC (array [, dim] [, mask] [, kind])

array
(Input) Must be an array of type integer or real.

dim
(Optional; input) Must be a scalar integer with a value in the range 1 to n, where n is the rank of array. This argument is a Fortran 95 feature.

mask
(Optional; input) Must be a logical array that is conformable with array.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is an array of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

The following rules apply if dim is omitted:

  • The array result has rank one and a size equal to the rank of array.

  • If MINLOC(array) is specified, the elements in the array result form the subscript of the location of the element with the minimum value in array.
    The ith subscript returned lies in the range 1 to ei, where ei is the extent of the ith dimension of array.

  • If MINLOC(array, MASK=mask) is specified, the elements in the array result form the subscript of the location of the element with the minimum value corresponding to the condition specified by mask.

The following rules apply if dim is specified:

  • The array result has a rank that is one less than array, and shape (d1, d2,...ddim-1, ddim+1,...dn), where (d1, d2,...dn) is the shape of array.

  • If array has rank one, MINLOC(array, dim [,mask]) has a value equal to that of MINLOC(array [,MASK = mask]). Otherwise, the value of element (s1, s2,...sdim-1, sdim+1,...sn) of MINLOC(array, dim [,mask]) is equal to MINLOC(array (s1, s2,...sdim-1, :, sdim+1,...sn) [, MASK = mask (s1, s2,...sdim-1, :, sdim+1,...sn)]).

If more than one element has minimum value, the element whose subscripts are returned is the first such element, taken in array element order. If array has size zero, or every element of mask has the value .FALSE., the value of the result is undefined.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MAXLOC, MINVAL, MAXVAL

Examples

The value of MINLOC ((/3, 1, 4, 1/)) is (2), which is the subscript of the location of the first occurrence of the minimum value in the rank-one array.

A is the array

  [  4    0   -3    2 ]
  [  3    1   -2    6 ]
  [ -1   -4    5   -5 ].

MINLOC (A, MASK=A .GT. -5) has the value (3, 2) because these are the subscripts of the location of the minimum value (-4) that is greater than -5.

MINLOC (A, DIM=1) has the value (3, 3, 1, 3). 3 is the subscript of the location of the minimum value (-1) in column 1; 3 is the subscript of the location of the minimum value (-4) in column 2; and so forth.

MINLOC (A, DIM=2) has the value (3, 3, 4). 3 is the subscript of the location of the minimum value (-3) in row 1; 3 is the subscript of the location of the minimum value (-2) in row 2; and so forth.

The following shows another example:

 INTEGER i, minl(1)
 INTEGER array(2, 3)
 INTEGER, ALLOCATABLE :: AR1(:)
 ! put values in array
 array = RESHAPE((/-7, 1, -2, -9, 5, 0/),(/2, 3/))
 !   array is   -7 -2 5
 !               1 -9 0
 i = SIZE(SHAPE(array))  ! Get the number of dimensions
                         ! in array
 ALLOCATE (AR1 (i) )     ! Allocate AR1 to number
                         ! of dimensions in array
 AR1 = MINLOC (array, MASK = array .GT. -5) ! Get the
                         ! location (subscripts) of
                         ! smallest element greater
                         ! than -5 in array

 !
 ! MASK = array .GT. -5 creates a mask array the same
 ! size and shape as array whose elements are .TRUE. if
 ! the corresponding element in array is greater than
 ! -5, and .FALSE. if it is not. This mask causes MINLOC
 ! to return the index of the element in array with the
 ! smallest value greater than -5.
 !
 !array is  -7 -2 5 and MASK= array .GT. -5 is  F T T
 !           1 -9 0                             T F T
 ! and AR1 = MINLOC(array, MASK = array .GT. -5) returns
 ! (1, 2), the location of the element with value -2

 minl = MINLOC((/-7,2,-7,5/))   ! returns 1, first
                                ! occurrence of minimum
 END


MINVAL

Transformational Intrinsic Function (Generic): Returns the minimum value of all elements in an array, a set of elements in an array, or elements in a specified dimension of an array.

Syntax

result = MINVAL(array [, dim] [, mask])

array
(Input) Must be an array of type integer or real.

dim
(Optional; input) Must be a scalar integer with a value in the range 1 to n, where n is the rank of array.

mask
(Optional; input) Must be a logical array that is conformable with array.

Results:

The result is an array or a scalar of the same data type as array.

The result is a scalar if dim is omitted or array has rank one.

The following rules apply if dim is omitted:

  • If MINVAL(array) is specified, the result has a value equal to the minimum value of all the elements in array.

  • If MINVAL(array, MASK=mask) is specified, the result has a value equal to the minimum value of the elements in array corresponding to the condition specified by mask.

The following rules apply if dim is specified:

  • An array result has a rank that is one less than array, and shape (d1, d2, ..., ddim-1, ddim+1, ..., dn), where (d1, d2, ..., dn) is the shape of array.

  • If array has rank one, MINVAL(array, dim [,mask]) has a value equal to that of MINVAL(array [,MASK = mask]). Otherwise, the value of element (s1, s2, ..., sdim-1, sdim+1, ..., sn) of MINVAL(array, dim, [,mask]) is equal to MINVAL(array(s1, s2, ..., sdim-1, :, sdim+1, ..., sn) [,MASK = mask(s1, s2, ..., sdim-1, :, sdim+1, ..., sn)]).

If array has size zero or if there are no true elements in mask, the result (if dim is omitted), or each element in the result array (if dim is specified), has the value of the positive number of the largest magnitude supported by the processor for numbers of the type and kind parameters of array.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MAXVAL, MINLOC, MAXLOC

Examples

The value of MINVAL ((/2, 3, 4/)) is 2 because that is the minimum value in the rank-one array.

The value of MINVAL (B, MASK=B .GT. 0.0) finds the minimum value of the positive elements of B.

C is the array

  [ 2  3  4 ]
  [ 5  6  7 ].

MINVAL (C, DIM=1) has the value (2, 3, 4). 2 is the minimum value in column 1; 3 is the minimum value in column 2; and so forth.

MINVAL (C, DIM=2) has the value (2, 5). 2 is the minimum value in row 1 and 5 is the minimum value in row 2.

The following shows another example:

 INTEGER array(2, 3), i(2), minv
 INTEGER, ALLOCATABLE :: AR1(:), AR2(:)
 array = RESHAPE((/1, 4, 5, 2, 3, 6/), (/2, 3/))
 !    array is    1 5 3
 !                4 2 6
 i = SHAPE(array)    ! i = [2 3]
 ALLOCATE(AR1(i(2))) ! dimension AR1 to number of
                     ! elements in dimension 2
                     ! (a column) of array.
 ALLOCATE(AR2(i(1))) ! dimension AR2 to number of
                     ! elements in dimension 1
                     ! (a row) of array
 minv = MINVAL(array, MASK = array .GT. 4) ! returns 5
 AR1 = MINVAL(array, DIM = 1)   ! returns [ 1 2 3 ]
 AR2 = MINVAL(array, DIM = 2)   ! returns [ 1 2 ]
 END


MOD

Elemental Intrinsic Function (Generic): Returns the remainder when the first argument is divided by the second argument.

Syntax

result = MOD (a, p)

a
(Input) Must be of type integer or real.

p
(Input)Must have the same type and kind parameters as a.

Results:

The result type is the same as a. If p is not equal to zero, the value of the result is a - INT(a / p) * p. If p is equal to zero, the result is undefined.

Specific Name | Argument Type | Result Type
 | INTEGER(1) | INTEGER(1)
IMOD | INTEGER(2) | INTEGER(2)
MOD 1 | INTEGER(4) | INTEGER(4)
KMOD | INTEGER(8) | INTEGER(8)
AMOD 2 | REAL(4) | REAL(4)
QMOD 3 | REAL(16) | REAL(16)
1 Or JMOD. 2 The setting of compiler option /real_size can affect AMOD. 3 VMS and U*X

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MODULO

Examples

MOD (7, 3) has the value 1.

MOD (9, -6) has the value 3.

MOD (-9, 6) has the value -3.

The following shows more examples:

 INTEGER I
 REAL R
 R = MOD(9.0, 2.0)  ! returns 1.0
 I = MOD(18, 5)     ! returns 3
 I = MOD(-18, 5)    ! returns -3


MODIFYMENUFLAGSQQ

QuickWin Function: Modifies a menu item's state.

Module: USE DFLIB

Syntax

result = MODIFYMENUFLAGSQQ (menuID, itemID, flag)

menuID
(Input) INTEGER(4). Identifies the menu containing the item whose state is to be modified, starting with 1 as the leftmost menu.

itemID
(Input) INTEGER(4). Identifies the menu item whose state is to be modified, starting with 0 as the top item.

flags
(Input) INTEGER(4). Constant indicating the menu state. Flags can be combined with an inclusive OR (see below). The following constants are available:

  • $MENUGRAYED - Disables and grays out the menu item.
  • $MENUDISABLED - Disables but does not gray out the menu item.
  • $MENUENABLED - Enables the menu item.
  • $MENUSEPARATOR - Draws a separator bar.
  • $MENUCHECKED - Puts a check by the menu item.
  • $MENUUNCHECKED - Removes the check by the menu item.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

The constants available for flags can be combined with an inclusive OR where reasonable, for example $MENUCHECKED .OR. $MENUENABLED. Some combinations do not make sense, such as $MENUENABLED and $MENUDISABLED, and lead to undefined behavior.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: APPENDMENUQQ, DELETEMENUQQ, INSERTMENUQQ MODIFYMENUROUTINEQQ, MODIFYMENUSTRINGQQ, Using QuickWin

Example

 USE DFLIB
 LOGICAL(4)    result
 CHARACTER(20) str

 ! Append item to the bottom of the first (FILE) menu
 str = '&Add to File Menu'C
 result = APPENDMENUQQ(1, $MENUENABLED, str, WINSTATUS)
 ! Gray out and disable the first two menu items in the
 ! first (FILE) menu
 result = MODIFYMENUFLAGSQQ (1, 1, $MENUGRAYED)
 result = MODIFYMENUFLAGSQQ (1, 2, $MENUGRAYED)
 END


MODIFYMENUROUTINEQQ

QuickWin Function: Changes a menu item's callback routine.

Module: USE DFLIB

Syntax

result = MODIFYMENUROUTINEQQ (menuIdD, itemID, routine)

menuID
(Input) INTEGER(4). Identifies the menu that contains the item whose callback routine is be changed, starting with 1 as the leftmost menu.

itemID
(Input) INTEGER(4). Identifies the menu item whose callback routine is to be changed, starting with 0 as the top item.

routine
(Input) EXTERNAL. Callback subroutine called if the menu item is selected. All routines must take a single LOGICAL parameter that indicates whether the menu item is checked or not. The following predefined routines are available for assigning to menus:

  • WINPRINT: Prints the program.
  • WINSAVE: Saves the program.
  • WINEXIT: Terminates the program.
  • WINSELECTTEXT: Selects text from the current window.
  • WINSELECTGRAPHICS: Selects graphics from the current window.
  • WINSELECTALL: Selects the entire contents of the current window.
  • WINCOPY: Copies the selected text and/or graphics from the current window to the Clipboard.
  • WINPASTE: Allows the user to paste Clipboard contents (text only) to the current text window of the active window during a READ.
  • WINCLEARPASTE: Clears the paste buffer.
  • WINSIZETOFIT: Sizes output to fit window.
  • WINFULLSCREEN: Displays output in full screen.
  • WINSTATE: Toggles between pause and resume states of text output.
  • WINCASCADE: Cascades active windows.
  • WINTILE: Tiles active windows.
  • WINARRANGE: Arranges icons.
  • WINSTATUS: Enables a status bar.
  • WININDEX: Displays the index for QuickWin Help.
  • WINUSING: Displays information on how to use Help.
  • WINABOUT: Displays information about the current QuickWin application.
  • NUL: No callback routine.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

Compatibility

QUICKWIN GRAPHICS LIB

See Also: APPENDMENUQQ, DELETEMENUQQ, INSERTMENUQQ, MODIFYMENUFLAGSQQ, MODIFYMENUSTRINGQQ, Using QuickWin


MODIFYMENUSTRINGQQ

QuickWin Function: Changes a menu item's text string.

Module: USE DFLIB

Syntax

result = MODIFYMENUSTRINGQQ (menuID, itemID, text)

menuID
(Input) INTEGER(4). Identifies the menu containing the item whose text string is to be changed, starting with 1 as the leftmost item.

itemID
(Input) INTEGER(4). Identifies the menu item whose text string is to be changed, starting with 0 as the top menu item.

text
(Input) Character*(*). Menu item name. Must be a null-terminated C string. For example, words of text'C.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

You can add access keys in your text strings by placing an ampersand (&) before the letter you want underlined. For example, to add a Print menu item with the r underlined, use "P&rint"C as text.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: APPENDMENUQQ, DELETEMENUQQ, INSERTMENUQQ, SETMESSAGEQQ MODIFYMENUFLAGSQQ, MODIFYMENUROUTINEQQ, Using QuickWin

Example

 USE DFLIB
 LOGICAL(4) result
 CHARACTER(25) str

 ! Append item to the bottom of the first (FILE) menu
 str = '&Add to File Menu'C
 result = APPENDMENUQQ(1, $MENUENABLED, str, WINSTATUS)
 ! Change the name of the first item in the first menu
 str ='&Browse'C
 result = MODIFYMENUSTRINGQQ (1, 1, str)
 END


MODULE

Statement: Marks the beginning of a module program unit, which contains specifications and definitions that can be used by one or more program units.

Syntax

MODULE name
[specification-part]
[CONTAINS
module-subprogram
[module-subprogram] ...]
END [MODULE [name]]

name
Is the name of the module.

specification-part
Is one or more specification statements, except for the following:

  • ENTRY
  • FORMAT
  • AUTOMATIC (or its equivalent attribute)
  • INTENT (or its equivalent attribute)
  • OPTIONAL (or its equivalent attribute)
  • Statement functions

An automatic object must not appear in a specification statement.

module-subprogram
Is a function or subroutine subprogram that defines the module procedure. A function must end with END FUNCTION and a subroutine must end with END SUBROUTINE.

A module subprogram can contain internal procedures.

Rules and Behavior

If a name follows the END statement, it must be the same as the name specified in the MODULE statement.

The module name is considered global and must be unique. It cannot be the same as any local name in the main program or the name of any other program unit, external procedure, or common block in the executable program.

A module is host to any module procedures it contains, and entities in the module are accessible to the module procedures through host association.

A module must not reference itself (either directly or indirectly).

You can use the PRIVATE attribute to restrict access to procedures or variables within a module.

Although ENTRY statements, FORMAT statements, and statement functions are not allowed in the specification part of a module, they are allowed in the specification part of a module subprogram.

Any executable statements in a module can only be specified in a module subprogram.

A module can contain one or more procedure interface blocks, which let you specify an explicit interface for an external subprogram or dummy subprogram.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: PUBLIC, PRIVATE, USE, Procedure Interfaces, Program Units and Procedures

Examples

The following example shows a simple module that can be used to provide global data:

MODULE MOD_A
  INTEGER :: B, C
  REAL E(25,5)
END MODULE MOD_A
...
SUBROUTINE SUB_Z
  USE MOD_A               ! Makes scalar variables B and C, and array
  ...                     !   E available to this subroutine
END SUBROUTINE SUB_Z

The following example shows a module procedure:

MODULE RESULTS
...
CONTAINS
  FUNCTION MOD_RESULTS(X,Y)  ! A module procedure
  ...
  END FUNCTION MOD_RESULTS
END MODULE RESULTS

The following example shows a module containing a derived type:

MODULE EMPLOYEE_DATA
  TYPE EMPLOYEE
    INTEGER ID
    CHARACTER(LEN=40) NAME
  END TYPE EMPLOYEE
END MODULE

The following example shows a module containing an interface block:

MODULE ARRAY_CALCULATOR
  INTERFACE
    FUNCTION CALC_AVERAGE(D)
      REAL :: CALC_AVERAGE
      REAL, INTENT(IN) :: D(:)
    END FUNCTION
  END INTERFACE
END MODULE ARRAY_CALCULATOR

The following example shows a derived-type definition that is public with components that are private:

MODULE MATTER
  TYPE ELEMENTS
    PRIVATE
    INTEGER C, D
  END TYPE
...
END MODULE MATTER

In this case, components C and D are private to type ELEMENTS, but type ELEMENTS is not private to MODULE MATTER. Any program unit that uses the module MATTER can declare variables of type ELEMENTS, and pass as arguments values of type ELEMENTS.

This design allows you to change components of a type without affecting other program units that use the module.

If a derived type is needed in more than one program unit, the definition should be placed in a module and accessed by a USE statement whenever it is needed, as follows:

MODULE STUDENTS
  TYPE STUDENT_RECORD
  ...
  END TYPE
CONTAINS
  SUBROUTINE COURSE_GRADE(...)
  TYPE(STUDENT_RECORD) NAME
  ...
  END SUBROUTINE
END MODULE STUDENTS
...

PROGRAM SENIOR_CLASS
  USE STUDENTS
  TYPE(STUDENT_RECORD) ID
  ...
END PROGRAM

Program SENIOR_CLASS has access to type STUDENT_RECORD, because it uses module STUDENTS. Module procedure COURSE_GRADE also has access to type STUDENT_RECORD, because the derived-type definition appears in its host.

The following shows another example:

 MODULE mod1
   REAL(8) a,b,c,d
   INTEGER(4) Int1, Int2, Int3
 CONTAINS
   function fun1(x)
 ....
   end function fun1
 END MODULE


MODULE PROCEDURE

Statement: Identifies module procedures in an interface block that specifies a generic name. For more information, see INTERFACE and MODULE.

Example

!A program that changes non-default integers and reals !into default integers and reals
   PROGRAM CHANGE_KIND
   USE Module1
   INTERFACE DEFAULT
     MODULE PROCEDURE Sub1, Sub2
   END INTERFACE

   integer(2) in
   integer indef
   indef = DEFAULT(in)
   END PROGRAM
! procedures sub1 and sub2 defined as follows:
    MODULE Module1
    CONTAINS
      FUNCTION Sub1(y)
        REAL(8) y
        sub1 = REAL(y)
      END FUNCTION
      FUNCTION Sub2(z)
        INTEGER(2) z
        sub2 = INT(z)
      END FUNCTION
    END MODULE


MODULO

Elemental Intrinsic Function (Generic): Returns the modulo of the arguments.

Syntax

result = MODULO (a, p)

a
(Input) Must be of type integer or real.

p
(Input) Must have the same type and kind parameters as a.

Results:

The result type is the same a. The result value depends on the type of a, as follows:

  • If a is of type integer and P is not equal to zero, the value of the result is a - FLOOR(REAL(a) / REAL(p)) * p.

  • If a is of type real and p is not equal to zero, the value of the result is a - FLOOR(a / p) * p.

If p is equal to zero (regardless of the type of a), the result is undefined.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MOD

Examples

MODULO (7, 3) has the value 1.

MODULO (9, -6) has the value -3.

MODULO (-9, 6) has the value 3.

The following shows more examples:

 INTEGER I
 REAL R
 I= MODULO(8, 5)         ! returns 3          Note: q=1
 I= MODULO(-8, 5)        ! returns 2          Note: q=-2
 I= MODULO(8, -5)        ! returns -2         Note: q=-2
 R= MODULO(7.285, 2.35)  ! returns 0.2350001  Note: q=3
 R= MODULO(7.285, -2.35) ! returns -2.115     Note: q=-4


MOVETO, MOVETO_W

Graphics Subroutine: Moves the current graphics position to a specified point. No drawing occurs.

Module: USE DFLIB

Syntax

CALL MOVETO (x, y, t)
CALL MOVETO_W (wx, wy, wt)

x, y
(Input) INTEGER(2). Viewport coordinates of the new graphics position.

t
(Output) Derived type xycoord. Viewport coordinates of the previous graphics position. The derived type xycoord is defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as follows:
 TYPE xycoord
   INTEGER(2) xcoord  ! x coordinate
   INTEGER(2) ycoord  ! y coordinate
 END TYPE xycoord
wx, wy
(Input) REAL(8). Window coordinates of the new graphics position.

wt
(Output) Derived type wxycoord. Window coordinates of the previous graphics position. The derived type wxycoord is defined in DFLIB.F90 as follows:
 TYPE wxycoord
   REAL(8) wx  ! x window coordinate
   REAL(8) wy  ! y window coordinate
 END TYPE wxycoord

MOVETO sets the current graphics position to the viewport coordinate (x, y). MOVETO_W sets the current graphics position to the window coordinate (wx, wy).

MOVETO and MOVETO_W assign the coordinates of the previous position to t and wt, respectively.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETCURRENTPOSITION, LINETO, OUTGTEXT

Example

 ! Build as QuickWin or Standard Graphics ap.
 USE DFLIB
 INTEGER(2) status, x, y
 INTEGER(4) result
 TYPE (xycoord) xy
 RESULT = SETCOLORRGB(#FF0000) ! blue
 x = 60
 ! Draw a series of lines
 DO y = 50, 92, 3
   CALL MOVETO(x, y, xy)
   status = LINETO(INT2(x + 20), y)
 END DO
 END


MP_SCHEDTYPE (TU*X only)

Compaq Fortran Parallel Compiler Directive: Sets a default run-time scheduling type. The scheduling type does not effect the semantics of the program, but may affect performance.

Syntax

c$PAR MP_SCHEDTYPE = mode

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

mode
Is one of the following:

  • DYNAMIC

    Specifies that when a thread becomes available for more work, it is assigned the next chunksize of the remaining iterations. This is sometimes described as threads competing for iterations. If less than one chunksize of iterations remains, the next available thread is assigned all the remaining iterations.

  • GUIDED (or GSS)

    Similar to DYNAMIC, except that the number of iterations assigned is relatively large at the beginning of the loop, and decreases exponentially as threads become available for more work. The number of iterations assigned is not necessarily divisible by chunksize.

    For this scheduling type, chunksize is the minimum number of iterations that can be assigned when a thread becomes available for work. When the number of iterations remaining to be assigned is less than or equal to chunksize, all the remaining iterations are assigned to the next available thread.

    In some cases, setting a chunksize greater than 1 improves execution efficiency as the loop nears termination, by reducing contention among the threads for the small number of remaining iterations.

  • INTERLEAVED (or INTERLEAVE)

    Specifies that chunks of iterations are to be assigned to threads in a round-robin fashion.

  • RUNTIME

    Specifies that environment variables are to be used to manage scheduling.

    Environment variable names are case-sensitive, but their values are not case-sensitive. Environment variables used are:

    • MP_CHUNK - Specifies a chunksize, where chunksize is an integer constant.

    • MP_SCHEDTYPE - Specifies one of the following modes: DYNAMIC, GSS, GUIDED, INTERLEAVE, INTERLEAVED, SIMPLE, or STATIC.

  • STATIC (or SIMPLE)

    Assigns each slave thread one contiguous group of iterations. Each thread is assigned an approximately equal number of iterations.

    STATIC is the default scheduling type when no other method has been specified.

For details on chunksize, see CHUNK.

Rules and Behavior

The MP_SCHEDTYPE directive can appear anywhere in a Compaq Fortran program. When more than one MP_SCHEDTYPE directive appears in the same program, the most recently encountered directive is used.

The scheduling type used for any parallel DO loop is determined from the following (in the order shown):

  1. A scheduling type specified in the PDO directive for the current DO loop

  2. A user-specified default specified in the most recent MP_SCHEDTYPE directive

  3. If the scheduling type for the current DO loop is RUNTIME, a user-specified default specified in the environment variable MP_SCHEDTYPE

  4. The compiler default of STATIC

The DYNAMIC and GUIDED scheduling types introduce a certain amount of overhead to manage the continuing assignment of iterations to threads during the execution of the loop. However, this overhead is sometimes offset by better load balancing when the average execution time of iterations is not uniform throughout the DO loop.

The STATIC and INTERLEAVED types assign all of the iterations to the threads in advance, with each thread receiving approximately equal numbers of iterations. One of these is usually the most efficient scheduling type when the average execution time of iterations is uniform throughout the DO loop.

The following form is also allowed: c$MP_SCHEDTYPE = mode

See Also: Parallel Directives for Tru64 UNIX Systems, Compaq Fortran Parallel Compiler Directives (TU*X only), OpenMP Fortran API Compiler Directives (TU*X only)


MULT_HIGH (Alpha only)

Elemental Intrinsic Function (Specific): Multiplies two 64-bit unsigned integers. This is a specific function that has no generic function associated with it. It must not be passed as an actual argument.

Syntax

result = MULT_HIGH (i, j)

i
INTEGER(8).

j
INTEGER(8).

Results:

The result is of type INTEGER(8). The result value is the upper (leftmost) 64 bits of the 128-bit unsigned result.

Example

Consider the following:

          INTEGER(8) I,J,K
          I=2_8**53
          J=2_8**51
          K = MULT_HIGH (I,J)
          PRINT *,I,J,K
          WRITE (6,1000)I,J,K
  1000    FORMAT (' ', 3(Z,1X))
          END

This example prints the following:

       9007199254740992      2251799813685248         1099511627776
           20000000000000           8000000000000             10000000000


MVBITS

Elemental Intrinsic Subroutine: Copies a sequence of bits (a bit field) from one location to another.

Syntax

CALL MVBITS (from, frompos, len, to, topos)

from
(Input) Integer. Can be of any integer type. It represents the location from which a bit field is transferred.

frompos
(Input) Can be of any integer type; it must not be negative. It identifies the first bit position in the field transferred from from. frompos + len must be less than or equal to BIT_SIZE(from).

len
(Input) Can be of any integer type; it must not be negative. It identifies the length of the field transferred from from.

to
(Input; output) Can be of any integer type, but must have the same kind parameter as from. It represents the location to which a bit field is transferred. to is set by copying the sequence of bits of length len, starting at position frompos of from to position topos of to. No other bits of to are altered.

On return, the len bits of to (starting at topos) are equal to the value that len bits of from (starting at frompos) had on entry.

topos
(Input) Can be of any integer type; it must not be negative. It identifies the starting position (within to) for the bits being transferred. topos + len must be less than or equal to BIT_SIZE(to).

For more information, see Bit Functions.

The model for the interpretation of an integer value as a sequence of bits is shown in Model for Bit Data.

You can also use the following specific routines:

IMVBITS | All arguments must be INTEGER(2)
JMVBITS | Arguments can be INTEGER(2) or INTEGER(4); at least one must be INTEGER(4)
KMVBITS | Arguments can be INTEGER(2), INTEGER(4), or INTEGER(8); at least one must be INTEGER(8)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BIT_SIZE, IBCLR, IBSET, ISHFT, ISHFTC

Examples

If TO has the initial value of 6, its value after a call to MVBITS with arguments (7, 2, 2, TO, 0) is 5.

The following shows another example:

 INTEGER(1) :: from = 13  ! 00001101
 INTEGER(1) :: to = 6     ! 00000110
 CALL MVBITS(from, 2, 2, to, 0) ! returns to = 00000111
 END


NAMELIST

Statement: Associates a name with a list of variables. This group name can be referenced in some input/output operations.

Syntax

NAMELIST /group/ var-list [[,] /group/ var-list] ...

group
Is the name of the group.

var-list
Is a list of variables (separated by commas) that are to be associated with the preceding group name. The variables can be of any data type.

Rules and Behavior

The namelist group name is used by namelist I/O statements instead of an I/O list. The unique group name identifies a list whose entities can be modified or transferred.

A variable can appear in more than one namelist group.

Each variable in var-list must be accessed by use or host association, or it must have its type, type parameters, and shape explicitly or implicitly specified in the same scoping unit. If the variable is implicitly typed, it can appear in a subsequent type declaration only if that declaration confirms the implicit typing.

The following variables cannot be specified in a namelist group:

  • An array dummy argument with nonconstant bounds
  • A variable with assumed character length
  • An allocatable array
  • An automatic object
  • A pointer
  • A variable of a type that has a pointer as an ultimate component
  • A subobject of any of the above objects

Only the variables specified in the namelist can be read or written in namelist I/O. It is not necessary for the input records in a namelist input statement to define every variable in the associated namelist.

The order of variables in the namelist controls the order in which the values appear on namelist output. Input of namelist values can be in any order.

If the group name has the PUBLIC attribute, no item in the variable list can have the PRIVATE attribute.

The group name can be specified in more than one NAMELIST statement in a scoping unit. The variable list following each successive appearance of the group name is treated as a continuation of the list for that group name.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: READ, WRITE, Namelist Specifier, Namelist Input, Namelist Output

Examples

In the following example, D and E are added to the variables A, B, and C for group name LIST:

NAMELIST /LIST/ A, B, C

NAMELIST /LIST/ D, E

In the following example, two group names are defined:

CHARACTER*30 NAME(25)
NAMELIST /INPUT/ NAME, GRADE, DATE /OUTPUT/ TOTAL, NAME

Group name INPUT contains variables NAME, GRADE, and DATE. Group name OUTPUT contains variables TOTAL and NAME.

The following shows another example:

 NAMELIST /example/ i1, l1, r4, r8, z8, z16, c1, c10, iarray

 ! The corresponding input statements could be:
 &example
 i1  = 11
 l1  = .TRUE.
 r4  = 24.0
 r8  = 28.0d0
 z8  = (38.0, 0.0)
 z16 = (316.0d0, 0.0d0)
 c1  = 'A'
 c10 = 'abcdefghij'
 iarray(8) = 41, 42, 43
 /

A sample program, NAMELIST.F90, is included in the \DF\SAMPLES\TUTORIAL subdirectory.


NARGS

Run-Time Function: Returns the total number of command-line arguments, including the command.

Module: USE DFLIB

Syntax

result = NARGS( )

Results:

The result is of type INTEGER(4). The result is the number of command-line arguments, including the command. For example, NARGS returns 4 for the command-line invocation of PROG1 -g -c -a.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETARG, IARGC

Example

    USE DFLIB
    INTEGER(2) result
    result = RUNQQ('myprog', '-c -r')
    END

 !  MYPROG.F90 responds to command switches -r, -c,
 !  and/or -d
 USE DFLIB
 INTEGER(4) count, num
 INTEGER(2) i, status
 CHARACTER(80) buf
 REAL r1 / 0.0 /
 COMPLEX c1 / (0.0,0.0) /
 REAL(8) d1 / 0.0 /

 num = 5
 count = NARGS( )
 DO i = 1, count-1
    CALL GETARG(i, buf, status)
    IF (buf(2:status) .EQ.'r') THEN
      r1 = REAL(num)
      WRITE (*,*) 'r1 = ',r1
    ELSE IF (buf(2:status) .EQ.'c') THEN
      c1 = CMPLX(num)
      WRITE (*,*) 'c1 = ', c1
    ELSE IF (buf(2:status) .EQ.'d') THEN
      d1 = DBLE(num)
      WRITE (*,*) 'd1 = ', d1
    ELSE
      WRITE(*,*) 'Invalid command switch'
      EXIT
    END IF
 END DO
 END


NEAREST

Elemental Intrinsic Function (Generic): Returns the nearest different number (representable on the processor) in a given direction.

Syntax

result = NEAREST (x, s)

x
(Input) Must be of type real.

s
(Input) Must be of type real and nonzero.

Results:

The result type is the same as x. The result has a value equal to the machine representable number that is different from and nearest to x, in the direction of infinity, with the same sign as s.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: EPSILON

Examples

If 3.0 and 2.0 are REAL(4) values, NEAREST (3.0, 2.0) has the value 3 + 2-22, which equals approximately 3.0000002. (For more information on the model for REAL(4), see Model for Real Data.

The following shows another example:

 REAL(4) r1
 REAL(8) r2, result
 r1 = 3.0
 result = NEAREST (r1, -2.0)
 WRITE(*,*) result           ! writes 2.999999761581421

 ! When finding nearest to REAL(8), can't see
 ! the difference unless output in HEX
 r2 = 111502.07D0
 result = NEAREST(r2, 2.0)
 WRITE(*,'(1x,Z16)') result  ! writes 40FB38E11EB851ED
 result = NEAREST(r2, -2.0)
 WRITE(*,'(1x,Z16)') result  ! writes 40FB38E11EB851EB
 END


NINT

Elemental Intrinsic Function (Generic): Returns the nearest integer to the argument.

Syntax

result = NINT (a [, kind ])

a
(Input) Must be of type real.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is shown in the following table. If the processor cannot represent the result value in the kind of the result, the result is undefined.

If a is greater than zero, NINT(a) has the value INT(a + 0.5); if a is less than or equal to zero, NINT(a) has the value INT(a - 0.5).

Specific Name | Argument Type | Result Type
ININT | REAL(4) | INTEGER(2)
NINT 1, 2 | REAL(4) | INTEGER(4)
KNINT | REAL(4) | INTEGER(8)
IIDNNT | REAL(8) | INTEGER(2)
IDNINT 2, 3 | REAL(8) | INTEGER(4)
KIDNNT | REAL(8) | INTEGER(8)
IIQNNT 4 | REAL(16) | INTEGER(2)
IQNINT 2, 4 | REAL(16) | INTEGER(4)
KIQNNT 4, 5 | REAL(16) | INTEGER(8)
1 Or JNINT. 2 The setting of compiler option /integer_size can affect NINT, IDNINT, and IQNINT. 3 Or JIDNNT. For compatibility with older versions of Fortran, IDNINT can also be specified as a generic function. 4 VMS, U*X 5 This specific function cannot be passed as an actual argument.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ANINT, INT

Examples

NINT (3.879) has the value 4.

NINT (-2.789) has the value -3.

The following shows another example:

 INTEGER(4) i1, i2
 i1 = NINT(2.783) ! returns 3
 i2 = IDNINT(-2.783D0) ! returns -3


NLSEnumCodepages

NLS Function: Returns an array containing the codepages supported by the system, with each array element describing one valid codepage.

Module: USE DFNLS

Syntax

ptr => NLSEnumCodepages( )

Results:

The result is a pointer to an array of codepages, with each element describing one supported codepage.

After use, the pointer returned by NLSEnumCodepages should be deallocated with the DEALLOCATE statement.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NLSEnumLocales


NLSEnumLocales

NLS Function: Returns an array containing the language and country combinations supported by the system, in which each array element describes one valid combination.

Module: USE DFNLS

Syntax

ptr => NLSEnumLocales( )

Results:

The result is a pointer to an array of locales, in which each array element describes one supported language and country combination. Each element has the following structure:

 TYPE NLS$EnumLocale
   CHARACTER*(NLS$MaxLanguageLen)  Language
   CHARACTER*(NLS$MaxCountryLen)   Country
   INTEGER(4)                      DefaultWindowsCodepage
   INTEGER(4)                      DefaultConsoleCodepage
 END TYPE

If the application is a Windows or QuickWin application, NLS$DefaultWindowsCodepage is the codepage used by default for the given language and country combination. If the application is a console application, NLS$DefaultConsoleCodepage is the codepage used by default for the given language and country combination.

Note: After use, the pointer returned by NLSEnumLocales should be deallocated with the DEALLOCATE statement.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NLSEnumCodepages


NLSFormatCurrency

NLS Function: Returns a correctly formatted currency string for the current locale.

Module: USE DFNLS

Syntax

result = NLSFormatCurrency (outstr, instr [, flags ])

outstr
(Output) Character*(*). String containing the correctly formatted currency for the current locale. If outstr is longer than the formatted currency, it is blank-padded.

intstr
(Input) Character*(*). Number string to be formatted. Can contain only the characters '0' through '9', one decimal point (a period) if a floating-point value, and a minus sign in the first position if negative. All other characters are invalid and cause the function to return an error.

flags
(Optional; input) INTEGER(4). If specified, modifies the currency conversion. If you omit flags, the flag NLS$Normal is used. Available values (defined in DFNLS.F90) are:

  • NLS$Normal - No special formatting
  • NLS$NoUserOverride - Do not use user overrides

Results:

The result is of type INTEGER(4). The result is the number of characters written to outstr (bytes are counted, not multibyte characters). If an error occurs, the result is one of the following negative values:

  • NLS$ErrorInsufficentBuffer - outstr buffer is too small
  • NLS$ErrorInvalidFlags - flags has an illegal value
  • NLS$ErrorInvalidInput - instr has an illegal value

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NLSFormatNumber, NLSFormatDate, NLSFormatTime

Example

 USE DFNLS
 CHARACTER(40) str
 INTEGER(4) i
 i = NLSFormatCurrency(str, "1.23")
 print *, str                              ! prints $1.23
 i = NLSFormatCurrency(str, "1000000.99")
 print *, str                              ! prints $1,000,000.99
 i = NLSSetLocale("Spanish", "Spain")
 i = NLSFormatCurrency(str, "1.23")
 print *, str                              ! prints 1 Pts
 i = NLSFormatCurrency(str, "1000000.99")
 print *, str                              ! prints 1.000.001 Pts


NLSFormatDate

NLS Function: Returns a correctly formatted string containing the date for the current locale.

Module: USE DFNLS

Syntax

result = NLSFormatDate (outstr [, intime ] [, flags ])

outstr
(Output) Character*(*). String containing the correctly formatted date for the current locale. If outstr is longer than the formatted date, it is blank-padded.

intime
(Optional; input) INTEGER(4). If specified, date to be formatted for the current locale. Must be an integer date such as the packed time created with PACKTIMEQQ. If you omit intime, the current system date is formatted and returned in outstr.

flags
(Optional; input) INTEGER(4). If specified, modifies the date conversion. If you omit flags, the flag NLS$Normal is used. Available values (defined in DFNLS.F90 in /DF/INCLUDE) are:

  • NLS$Normal - No special formatting
  • NLS$NoUserOverride - Do not use user overrides
  • NLS$UseAltCalendar - Use the locale's alternate calendar
  • NLS$LongDate - Use local long date format
  • NLS$ShortDate - Use local short date format

Results:

The result is of type INTEGER(4). The result is the number of characters written to outstr (bytes are counted, not multibyte characters). If an error occurs, the result is one of the following negative values:

  • NLS$ErrorInsufficentBuffer - outstr buffer is too small
  • NLS$ErrorInvalidFlags - flags has an illegal value
  • NLS$ErrorInvalidInput - intime has an illegal value

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NLSFormatTime, NLSFormatCurrency, NLSFormatNumber

Examples

 USE DFNLS
 INTEGER(4) i
 CHARACTER(40) str
 i = NLSFORMATDATE(str, NLS$NORMAL)           ! 8/1/94
 i = NLSFORMATDATE(str, NLS$USEALTCALENDAR)   ! 8/1/94
 i = NLSFORMATDATE(str, NLS$LONGDATE)         ! Monday, August 1, 1994
 i = NLSFORMATDATE(str, NLS$SHORTDATE)        ! 8/1/94
 END


NLSFormatNumber

NLS Function: Returns a correctly formatted number string for the current locale.

Module: USE DFNLS

Syntax

result = NLSFormatNumber (outstr, instr [, flags ])

outstr
(Output) Character*(*). String containing the correctly formatted number for the current locale. If outstr is longer than the formatted number, it is blank-padded.

instr
(Input) Character*(*). Number string to be formatted. Can only contain the characters '0' through '9', one decimal point (a period) if a floating-point value, and a minus sign in the first position if negative. All other characters are invalid and cause the function to return an error.

flags
(Optional; input) INTEGER(4). If specified, modifies the number conversion. If you omit flags, the flag NLS$Normal is used. Available values (defined in DFNLS.F90 in /DF/INCLUDE) are:

  • NLS$Normal - No special formatting
  • NLS$NoUserOverride - Do not use user overrides

Results:

The result is of type INTEGER(4). The result is the number of characters written to outstr (bytes are counted, not multibyte characters). If an error occurs, the result is one of the following negative values:

  • NLS$ErrorInsufficentBuffer - outstr buffer is too small
  • NLS$ErrorInvalidFlags - flags has an illegal value
  • NLS$ErrorInvalidInput - instr has an illegal value

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NLSFormatTime, NLSFormatCurrency, NLSFormatDate

Example

 USE DFNLS
 CHARACTER(40) str
 INTEGER(4) i
 i = NLSFormatNumber(str, "1.23")
 print *, str                            ! prints 1.23
 i = NLSFormatNumber(str, "1000000.99")
 print *, str                            ! prints 1,000,000.99
 i = NLSSetLocale("Spanish", "Spain")
 i = NLSFormatNumber(str, "1.23")
 print *, str                            ! prints 1,23
 i = NLSFormatNumber(str, "1000000.99")
 print *, str                            ! prints 1.000.000,99


NLSFormatTime

NLS Function: Returns a correctly formatted string containing the time for the current locale.

Module: USE DFNLS

Syntax

result = NLSFormatTime (outstr [, intime ] [, flags ])

outstr
(Output) Character*(*). String containing the correctly formatted time for the current locale. If outstr is longer than the formatted time, it is blank-padded.

intime
(Optional; input) INTEGER(4). If specified, time to be formatted for the current locale. Must be an integer time such as the packed time created with PACKTIMEQQ. If you omit intime, the current system time is formatted and returned in outstr.

flags
(Optional; input) INTEGER(4). If specified, modifies the time conversion. If you omit flags, the flag NLS$Normal is used. Available values (defined in DFNLS.F90 in /DF/INCLUDE) are:

  • NLS$Normal - No special formatting
  • NLS$NoUserOverride - Do not use user overrides
  • NLS$NoMinutesOrSeconds - Do not return minutes or seconds
  • NLS$NoSeconds - Do not return seconds
  • NLS$NoTimeMarker - Do not add a time marker string
  • NLS$Force24HourFormat - Return string in 24 hour format

Results:

The result is of type INTEGER(4). The result is the number of characters written to outstr (bytes are counted, not multibyte characters). If an error occurs, the result is one of the following negative values:

  • NLS$ErrorInsufficentBuffer - outstr buffer is too small
  • NLS$ErrorInvalidFlags - flags has an illegal value
  • NLS$ErrorInvalidInput - intime has an illegal value

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NLSFormatCurrency, NLSFormatDate, NLSFormatNumber

Examples

 USE DFNLS
 INTEGER(4) i
 CHARACTER(20) str
 i = NLSFORMATTIME(str, NLS$NORMAL)              ! 11:38:28 PM
 i = NLSFORMATTIME(str, NLS$NOMINUTESORSECONDS)  ! 11 PM
 i = NLSFORMATTIME(str, NLS$NOTIMEMARKER)        ! 11:38:28 PM
 i = NLSFORMATTIME(str, IOR(NLS$FORCE24HOURFORMAT,               &
 &                      NLS$NOSECONDS))          ! 23:38 PM
 END


NLSGetEnvironmentCodepage

NLS Function: Returns the codepage number for the system (Window) codepage or the console codepage.

Module: USE DFNLS

Syntax

result = NLSGetEnvironmentCodepage (flags)

flags
(Input) INTEGER(4). Tells the function which codepage number to return. Available values (defined in DFNLS.F90 in /DF/INCLUDE) are:

  • NLS$ConsoleEnvironmentCodepage - Gets the codepage for the console
  • NLS$WindowsEnvironmentCodepage - Gets the current Windows codepage

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, it returns one of the following error codes:

  • NLS$ErrorInvalidFlags - flags has an illegal value
  • NLS$ErrorNoConsole - There is no console associated with the given application; so, operations with the console codepage are not possible

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NLSSetEnvironmentCodepage


NLSGetLocale

NLS Subroutine: Retrieves the current language, country, or codepage.

Module: USE DFNLS

Syntax

CALL NLSGetLocale ([language] [, country] [, codepage])

language
(Optional; output) Character*(*). Current language.

country
(Optional; output) Character*(*). Current country.

codepage
(Optional; output) INTEGER(4). Current codepage.

NLSGetLocale returns a valid codepage in codepage. It does not return one of the NLS$... symbolic constants that can be used with NLSSetLocale.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NLSSetLocale

Example

 USE DFNLS
 CHARACTER(50) cntry, lang
 INTEGER(4)    code
 CALL NLSGetLocale (lang, cntry, code)    ! get all three
 CALL NLSGetLocale (CODEPAGE = code)      ! get the codepage
 CALL NLSGetLocale (COUNTRY = cntry, CODEPAGE =code) ! get country
                                                     ! and codepage


NLSGetLocaleInfo

NLS Function: Returns information about the current locale.

Module: USE DFNLS

Syntax

result = NLSGetLocaleInfo (type, outstr)

type
(Input) INTEGER(4). NLS parameter requested. A list of parameter names is given in the NLS Locale Info Parameters Table.

outstr
(Output) Character*(*). Parameter setting for the current locale. All parameter settings placed in outstr are character strings, even numbers. If a parameter setting is numeric, the ASCII representation of the number is used. If the requested parameter is a date or time string, an explanation of how to interpret the format in outstr is given in NLS Date and Time Format.

Results:

The result is of type INTEGER(4). The result is the number of characters written to outstr if successful, or if outstr has 0 length, the number of characters required to hold the requested information. Otherwise, the result is one of the following error codes (defined in DFNLS.F90):

  • NLS$ErrorInvalidLIType - The given type is invalid
  • NLS$ErrorInsufficientBuffer - The outstr buffer was too small, but was not 0 (so that the needed size would be returned)

The NLS$LI parameters are used for the argument type and select the locale information returned by NLSGetLocaleInfo in outstr. You can perform an inclusive OR with NLS$NoUserOverride and any NLS$LI parameter. This causes NLSGetLocaleInfo to bypass any user overrides and always return the system default value. The following table lists the NLS$LI parameters and describes each.

NLS Locale Info Parameters Table
Parameter | Description
NLS$LI_ILANGUAGE | An ID indicating the language.
NLS$LI_SLANGUAGE | The full localized name of the language.
NLS$LI_SENGLANGUAGE | The full English name of the language from the ISO Standard 639. This will always be restricted to characters that map into the ASCII 127 character subset.
NLS$LI_SABBREVLANGNAME | The abbreviated name of the language, created by taking the 2-letter language abbreviation as found in ISO Standard 639 and adding a third letter as appropriate to indicate the sublanguage.
NLS$LI_SNATIVELANGNAME | The native name of the language.
NLS$LI_ICOUNTRY | The country code, based on international phone codes, also referred to as IBM country codes.
NLS$LI_SCOUNTRY | The full localized name of the country.
NLS$LI_SENGCOUNTRY | The full English name of the country. This will always be restricted to characters that map into the ASCII 127 character subset.
NLS$LI_SABBREVCTRYNAME | The abbreviated name of the country as per ISO Standard 3166.
NLS$LI_SNATIVECTRYNAME | The native name of the country.
NLS$LI_IDEFAULTLANGUAGE | Language ID for the principal language spoken in this locale. This is provided so that partially specified locales can be completed with default values.
NLS$LI_IDEFAULTCOUNTRY | Country code for the principal country in this locale. This is provided so that partially specified locales can be completed with default values.
NLS$LI_IDEFAULTANSICODEPAGE | ANSI code page associated with this locale.
NLS$LI_IDEFAULTOEMCODEPAGE | OEM code page associated with the locale.
NLS$LI_SLIST | Character(s) used to separate list items, for example, comma in many locales.
NLS$LI_IMEASURE | This value is 0 if the metric system (S.I.) is used and 1 for the U.S. system of measurements.
NLS$LI_SDECIMAL | The character(s) used as decimal separator. This is restricted such that it cannot be set to digits 0 - 9.
NLS$LI_STHOUSAND | The character(s) used as separator between groups of digits left of the decimal. This is restricted such that it cannot be set to digits 0 - 9.
NLS$LI_SGROUPING | Sizes for each group of digits to the left of the decimal. An explicit size is needed for each group; sizes are separated by semicolons. If the last value is 0 the preceding value is repeated. To group thousands, specify "3;0".
NLS$LI_IDIGITS | The number of decimal digits.
NLS$LI_ILZERO | Determines whether to use leading zeros in decimal fields: 0 - Use no leading zeros 1 - Use leading zeros
NLS$LI_INEGNUMBER | Determines how negative numbers are represented: 0 - Puts negative numbers in parentheses: (1.1) 1 - Puts a minus sign in front: -1.1 2 - Puts a minus sign followed by a space in front: - 1.1 3 - Puts a minus sign after: 1.1- 4 - Puts a space then a minus sign after: 1.1 -
NLS$LI_SNATIVEDIGITS | The ten characters that are the native equivalent to the ASCII 0-9.
NLS$LI_SCURRENCY | The string used as the local monetary symbol. Cannot be set to digits 0-9.
NLS$LI_SINTLSYMBOL | Three characters of the International monetary symbol specified in ISO 4217 "Codes for the Representation of Currencies and Funds", followed by the character separating this string from the amount.
NLS$LI_SMONDECIMALSEP | The character(s) used as monetary decimal separator. This is restricted such that it cannot be set to digits 0-9.
NLS$LI_SMONTHOUSANDSEP | The character(s) used as monetary separator between groups of digits left of the decimal. Cannot be set to digits 0-9.
NLS$LI_SMONGROUPING | Sizes for each group of monetary digits to the left of the decimal. If the last value is 0, the preceding value is repeated. To group thousands, specify "3;0".
NLS$LI_ICURRDIGITS | Number of decimal digits for the local monetary format.
NLS$LI_IINTLCURRDIGITS | Number of decimal digits for the international monetary format.
NLS$LI_ICURRENCY | Determines how positive currency is represented: 0 - Puts currency symbol in front with no separation: $1.1 1 - Puts currency symbol in back with no separation: 1.1$ 2 - Puts currency symbol in front with single space after: $ 1.1 3 - Puts currency symbol in back with single space before: 1.1 $
NLS$LI_INEGCURR | Determines how negative currency is represented: 0 ($1.1) 1 -$1.1 2 $-1.1 3 $1.1- 4 (1.1$) 5 -1.1$ 6 1.1-$ 7 1.1$- 8 -1.1 $ (space before $) 9 -$ 1.1 (space after $) 10 1.1 $- (space before $) 11 $ 1.1- (space after $) 12 $ -1.1 (space after $) 13 1.1- $ (space before $) 14 ($ 1.1) (space after $) 15 (1.1 $) (space before $)
NLS$LI_SPOSITIVESIGN | String value for the positive sign. Cannot be set to digits 0-9.
NLS$LI_SNEGATIVESIGN | String value for the negative sign. Cannot be set to digits 0-9.
NLS$LI_IPOSSIGNPOSN | Determines the formatting index for positive values: 0 - Parenthesis surround the amount and the monetary symbol 1 - The sign string precedes the amount and the monetary symbol 2 - The sign string follows the amount and the monetary symbol 3 - The sign string immediately precedes the monetary symbol 4 - The sign string immediately follows the monetary symbol
NLS$LI_INEGSIGNPOSN | Determines the formatting index for negative values. Same values as for NLS$LI_IPOSSIGNPOSN.
NLS$LI_IPOSSYMPRECEDES | 1 if the monetary symbol precedes, 0 if it follows a positive amount.
NLS$LI_IPOSSEPBYSPACE | 1 if the monetary symbol is separated by a space from a positive amount; otherwise, 0.
NLS$LI_INEGSYMPRECEDES | 1 if the monetary symbol precedes, 0 if it follows a negative amount.
NLS$LI_INEGSEPBYSPACE | 1 if the monetary symbol is separated by a space from a negative amount; otherwise, 0.
NLS$LI_STIMEFORMAT | Time formatting string. See the NLS Date and Time Format section for explanations of the valid strings.
NLS$LI_STIME | Character(s) for the time separator. Cannot be set to digits 0-9.
NLS$LI_ITIME | Time format: 0 - Use 12-hour format 1 - Use 24-hour format
NLS$LI_ITLZERO | Determines whether to use leading zeros in time fields: 0 - Use no leading zeros 1 - Use leading zeros for hours
NLS$LI_S1159 | String for the AM designator.
NLS$LI_S2359 | String for the PM designator.
NLS$LI_SSHORTDATE | Short Date formatting string for this locale. The d, M and y should have the day, month, and year substituted, respectively. See the NLS Date and Time Format section for explanations of the valid strings.
NLS$LI_SDATE | Character(s) for the date separator. Cannot be set to digits 0-9.
NLS$LI_IDATE | Short Date format ordering: 0 - Month-Day-Year 1 - Day-Month-Year 2 - Year-Month-Day
NLS$LI_ICENTURY | Specifies whether to use full 4-digit century for the short date only: 0 - Two-digit year 1 - Full century
NLS$LI_IDAYLZERO | Specifies whether to use leading zeros in day fields for the short date only: 0 - Use no leading zeros 1 - Use leading zeros
NLS$LI_IMONLZERO | Specifies whether to use leading zeros in month fields for the short date only: 0 - Use no leading zeros 1 - Use leading zeros
NLS$LI_SLONGDATE | Long Date formatting string for this locale. The string returned may contain a string within single quotes (' '). Any characters within single quotes should be left as is. The d, M and y should have the day, month, and year substituted, respectively.
NLS$LI_ILDATE | Long Date format ordering: 0 - Month-Day-Year 1 - Day-Month-Year 2 - Year-Month-Day
NLS$LI_ICALENDARTYPE | Specifies which type of calendar is currently being used: 1 - Gregorian (as in United States) 2 - Gregorian (English strings always) 3 - Era: Year of the Emperor (Japan) 4 - Era: Year of the Republic of China 5 - Tangun Era (Korea)
NLS$LI_IOPTIONALCALENDAR | Specifies which additional calendar types are valid and available for this locale. This can be a null separated list of all valid optional calendars: 0 - No additional types valid 1 - Gregorian (localized) 2 - Gregorian (English strings always) 3 - Era: Year of the Emperor (Japan) 4 - Era: Year of the Republic of China 5 - Tangun Era (Korea)
NLS$LI_IFIRSTDAYOFWEEK | Specifies which day is considered first in a week: 0 - SDAYNAME1 1 - SDAYNAME2 2 - SDAYNAME3 3 - SDAYNAME4 4 - SDAYNAME5 5 - SDAYNAME6 6 - SDAYNAME7
NLS$LI_IFIRSTWEEKOFYEAR | Specifies which week of the year is considered first: 0 - Week containing 1/1 1 - First full week following 1/1 2 - First week containing at least 4 days
NLS$LI_SDAYNAME1 - NLS$LI_SDAYNAME7 | Native name for each day of the week. 1 = Monday, 2 = Tuesday, etc.
NLS$LI_SABBREVDAYNAME1 - NLS$LI_SABBREVDAYNAME7 | Native abbreviated name for each day of the week. 1 = Mon, 2 = Tue, etc.
NLS$LI_SMONTHNAME1 - NLS$LI_SMONTHNAME13 | Native name for each month. 1 = January, 2 = February, etc. 13 = the 13th month, if it exists in the locale.
NLS$LI_SABBREVMONTHNAME1 - NLS$LI_SABBREVMONTHNAME13 | Native abbreviated name for each month. 1 = Jan, 2 = Feb, etc. 13 = the 13th month, if it exists in the locale.


NLS Date and Time Format

When NLSGetLocaleInfo (type, outstr) returns information about the date and time formats of the current locale, the value returned in outstr can be interpreted according to the following tables. Any text returned within a date and time string that is enclosed within single quotes should be left in the string in its exact form; that is, do not change the text or the location within the string.

Day

The day can be displayed in one of four formats using the letter "d". The table below shows the four variations:

d | Day of the month as digits without leading zeros for single-digit days
dd | Day of the month as digits with leading zeros for single-digit days
ddd | Day of the week as a three-letter abbreviation (SABBREVDAYNAME)
dddd | Day of the week as its full name (SDAYNAME)

Month

The month can be displayed in one of four formats using the letter "M". The uppercase "M" distinguishes months from minutes. The table below shows the four variations:

M | Month as digits without leading zeros for single-digit months
MM | Month as digits with leading zeros for single-digit months
MMM | Month as a three-letter abbreviation (SABBREVMONTHNAME)
MMMM | Month as its full name (SMONTHNAME)

Year

The year can be displayed in one of three formats using the letter "y". The table below shows the three variations:

y | Year represented by only the last digit
yy | Year represented by only the last two digits
yyyy | Year represented by the full 4 digits

Period/Era

The period/era string is displayed in a single format using the letters "gg".

gg Period/Era string

Time

The time can be displayed in one of many formats using the letter "h" or "H" to denote hours, the letter "m" to denote minutes, the letter "s" to denote seconds and the letter "t" to denote the time marker. The table below shows the numerous variations of the time format. Lowercase "h" denotes the 12 hour clock and uppercase "H" denotes the 24 hour clock. The lowercase "m" distinguishes minutes from months.

h | Hours without leading zeros for single-digit hours (12 hour clock)
hh | Hours with leading zeros for single-digit hours (12 hour clock)
H | Hours without leading zeros for single-digit hours (24 hour clock)
HH | Hours with leading zeros for single-digit hours (24 hour clock)
m | Minutes without leading zeros for single-digit minutes
mm | Minutes with leading zeros for single-digit minutes
s | Seconds without leading zeros for single-digit seconds
ss | Seconds with leading zeros for single-digit seconds
t | One-character time marker string
tt | Multicharacter time marker string

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NLSGetLocale, NLSFormatDate, NLSFormatTime, NLSSetLocale

Example

 USE DFNLS
 INTEGER(4) strlen
 CHARACTER(40) str
 strlen = NLSGetLocaleInfo(NLS$LI_SDAYNAME1, str)
 print *, str    ! prints Monday if language is English
 strlen = NLSGetLocaleInfo(NLS$LI_SDAYNAME2, str)
 print *, str    ! prints Tuesday if language is English


NLSSetEnvironmentCodepage

NLS Function: Sets the codepage for the current console. The specified codepage affects the current console program and any other programs launched from the same console. It does not affect other open consoles or any consoles opened later.

Module: USE DFNLS

Syntax

result = NLSSetEnvironmentCodepage (codepage, flags)

codepage
(Input) INTEGER(4). Number of the codepage to set as the console codepage.

flags
(Input) INTEGER(4). Must be set to NLS$ConsoleEnvironmentCodepage.

Results:

The result is of type INTEGER(4). The result is zero if successful. Otherwise, returns one of the following error codes (defined in DFNLS.F90 in /DF/INCLUDE):

  • NLS$ErrorInvalidCodepage - codepage is invalid or not installed on the system
  • NLS$ErrorInvalidFlags - flags is not valid
  • NLS$ErrorNoConsole - There is no console associated with the given application; so operations, with the console codepage are not possible

The flags argument must be NLS$ConsoleEnvironmentCodepage; it cannot be NLS$WindowsEnvironmentCodepage. NLSSetEnvironmentCodepage does not affect the Windows codepage.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NLSGetEnvironmentCodepage


NLSSetLocale

NLS Function: Sets the current language, country, or codepage.

Module: USE DFNLS

Syntax

result = NLSSetLocale (language [, country] [, codepage])

language
(Input) Character*(*). One of the languages supported by the Win32 NLS APIs.

country
(Optional; input) Character*(*). If specified, characterizes the language further. If omitted, the default country for the language is set.

codepage
(Optional; input) INTEGER(4). If specified, codepage to use for all character-oriented NLS functions. Can be any valid supported codepage or one of the following predefined values (defined in DFNLS.F90 in /DF/INCLUDE/):

  • NLS$CurrentCodepage - The codepage is not changed. Only the language and country settings are altered by the function.
  • NLS$ConsoleEnvironmentCodepage - The codepage is changed to the default environment codepage currently in effect for console programs.
  • NLS$ConsoleLanguageCodepage - The codepage is changed to the default console codepage for the language and country combination specified.
  • NLS$WindowsEnvironmentCodepage - The codepage is changed to the default environment codepage currently in effect for Windows programs.
  • NLS$WindowsLanguageCodepage - The codepage is changed to the default Windows codepage for the language and country combination specified.

If you omit codepage, it defaults to NLS$WindowsLanguageCodepage. At program startup, NLS$WindowsEnvironmentCodepage is used to set the codepage.

Results:

The result is of type INTEGER(4). The result is zero if successful. Otherwise, one of the following error codes (defined in DFNLS.F90) may be returned:

  • NLS$ErrorInvalidLanguage - language is invalid or not supported
  • NLS$ErrorInvalidCountry - country is invalid or is not valid with the language specified
  • NLS$ErrorInvalidCodepage - codepage is invalid or not installed on the system

NLSSetLocale works on installed locales only. Windows NT (including Windows 2000) and Windows 9* support many locales, but these must be installed through the system Windows NT Control Panel/International menu or the Windows 9* Control Panel/Regional Settings menu.

Note that when doing mixed-language programming with Fortran and C, calling NLSSetLocale with a codepage other than the default environment Windows codepage causes the codepage in the C run-time library to change by calling C's setmbcp( ) routine with the new codepage. Conversely, changing the C run-time library codepage does not change the codepage in the Fortran NLS library.

Calling NLSSetLocale has no effect on the locale used by C programs. The locale set with C's setlocale( ) routine is independent of NLSSetLocale.

Calling NLSSetLocale with the default environment console codepage, NLS$ConsoleEnvironmentCodepage, causes an implicit call to the Win32 API SetFileApisToOEM( ). Calling NLSSetLocale with any other codepage causes a call to SetFileApisToANSI( ).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: NLSGetLocale


NOT

Elemental Intrinsic Function (Generic): Returns the logical complement of the argument.

Syntax

result = NOT (i)

i
(Input) Must be of type integer.

Results:

The result type is the same as i. The result value is obtained by complementing i bit-by-bit according to the following truth table:

  I   NOT (I)

  1      0
  0      1

The model for the interpretation of an integer value as a sequence of bits is shown in Model for Bit Data.

Specific Name | Argument Type | Result Type
 | INTEGER(1) | INTEGER(1)
INOT | INTEGER(2) | INTEGER(2)
JNOT | INTEGER(4) | INTEGER(4)
KNOT | INTEGER(8) | INTEGER(8)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BTEST, IAND, IBCHNG, IBCLR, IBSET, IEOR, IOR, ISHA, ISHC, ISHL, ISHFT, ISHFTC

Examples

If I has a value equal to 10101010 (base 2), NOT (I) has the value 01010101 (base 2).

The following shows another example:

 INTEGER(2) i(2), j(2)
 i = (/4, 132/)          ! i(1) = 0000000000000100
                         ! i(2) = 0000000010000100
 j = NOT(i)              ! returns (-5,-133)
                         ! j(1) = 1111111111111011
                         ! j(2) = 1111111101111011


NULL

Transformational Intrinsic Function (Generic): Initializes a pointer as disassociated when it is declared. This is a new intrinsic function in Fortran 95.

Syntax

result = NULL ([ mold ])

mold
(Optional) Must be a pointer; it can be of any type. Its pointer association status can be associated, disassociated, or undefined. If its status is associated, the target does not have to be defined with a value.

Results:

The result type is the same as mold, if present; otherwise, it is determined as follows:

If NULL ( ) Appears... | Type is Determined From...
On the right side of pointer assignment | The pointer on the left side
As initialization for an object in a declaration | The object
As default initialization for a component | The component
In a structure constructor | The corresponding component
As an actual argument | The corresponding dummy argument
In a DATA statement | The corresponding pointer object

The result is a pointer with disassociated association status.

Note: If you use module DFWIN or DFWINTY, you will have a name conflict if you use the NULL intrinsic. To avoid this problem, rename the integer parameter constant NULL to something else; for example:
   USE DFWIN, NULL0 => NULL
This example lets you use both NULL0 and NULL( ) in the same program unit with no conflict.

Examples

Consider the following:

  INTEGER, POINTER :: POINT1 => NULL( )

This statement defines the initial association status of POINT1 to be disassociated.


NULLIFY

Statement: Disassociates a pointer from a target.

Syntax

NULLIFY (pointer-object [, pointer-object] ...)

pointer-object
Is a structure component or the name of a variable; it must be a pointer (have the POINTER attribute).

Rules and Behavior

The initial association status of a pointer is undefined. You can use NULLIFY to initialize an undefined pointer, giving it disassociated status. Then the pointer can be tested using the intrinsic function ASSOCIATED.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ALLOCATE, ASSOCIATED, DEALLOCATE, POINTER, TARGET, NULL, Pointer Assignments.

Examples

The following is an example of the NULLIFY statement:

  REAL, TARGET  :: TAR(0:50)
  REAL, POINTER :: PTR_A(:), PTR_B(:)
  PTR_A => TAR
  PTR_B => TAR
  ...
  NULLIFY(PTR_A)

After these statements are executed, PTR_A will have disassociated status, while PTR_B will continue to be associated with variable TAR.

The following shows another example:

!    POINTER2.F90    Pointing at a Pointer and Target
!DEC$ FIXEDFORMLINESIZE:80

     REAL, POINTER :: arrow1 (:)
     REAL, POINTER :: arrow2 (:)
     REAL, ALLOCATABLE, TARGET :: bullseye (:)

     ALLOCATE (bullseye (7))
     bullseye = 1.
     bullseye (1:7:2) = 10.
     WRITE (*,'(/1x,a,7f8.0)') 'target ',bullseye

     arrow1 => bullseye
     WRITE (*,'(/1x,a,7f8.0)') 'pointer',arrow1

     arrow2 => arrow1
     IF (ASSOCIATED(arrow2)) WRITE (*,'(/a/)') ' ARROW2 is pointed.'
     WRITE (*,'(1x,a,7f8.0)') 'pointer',arrow2

     NULLIFY (arrow2)
     IF (.NOT.ASSOCIATED(arrow2)) WRITE (*,'(/a/)') ' ARROW2 is not pointed.'
     WRITE (*,'( 1x,a,7f8.0)') 'pointer',arrow1
     WRITE (*,'(/1x,a,7f8.0)') 'target ',bullseye

     END


NUMBER_OF_PROCESSORS

Inquiry Intrinsic Function (Specific): Returns the total number of processors (peers) available to the program. This is a specific function that has no generic function associated with it. It must not be passed as an actual argument.

Syntax

result = NUMBER_OF_PROCESSORS ([dim])

dim
(Optional) Has no effect on currently available configurations of Compaq systems. This option is provided for compatibility with the High Performance Fortran (HPF) language specification. If dim is specified, it must have the value of 1.

Results:

The result is of type default integer scalar. The result value is the total number of processors (peers) available to the program.

For single-processor workstations, the result value is 1.


NWORKERS

Inquiry Intrinsic Function (Specific): Returns the number of processes executing a routine.

This is a specific function that has no generic f unction associated with it. It must not be passed as an actual argument. It is provided for compatibility with Compaq Fortran 77 for OpenVMS VAX systems.

Syntax

result = NWORKERS( )

Results:

The result is always 1.


OBJCOMMENT

General Compiler Directive: Specifies a library search path in an object file.

Syntax

c DEC$ OBJCOMMENT LIB:library

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

library
Is a character constant specifying the name and, if necessary, the path of the library that the linker is to search.

Rules and Behavior

The linker searches for the library named in OBJCOMMENT as if you named it on the command line, that is, before default library searches. You can place multiple library search directives in the same source file. Each search directive appears in the object file in the order it is encountered in the source file.

If the OBJCOMMENT directive appears in the scope of a module, any program unit that uses the module also contains the directive, just as if the OBJCOMMENT directive appeared in the source file using the module.

If you want to have the OBJCOMMENT directive in a module, but do not want it in the program units that use the module, place the directive outside the module that is used.

The following form is also allowed: !MS$OBJCOMMENT LIB:library

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: General Compiler Directives

Example

 !  MOD1.F90
 MODULE a
    !DEC$ OBJCOMMENT LIB: "opengl32.lib"
 END MODULE a

 !  MOD2.F90
 !DEC$ OBJCOMMENT LIB: "graftools.lib"
 MODULE b
    !
 END MODULE b

 !  USER.F90
 PROGRAM go
    USE a    ! library search contained in MODULE a
             ! included here
    USE b    ! library search not included
 END


OPEN

Statement: Connects an external file to a unit, creates a new file and connects it to a unit, creates a preconnected file, or changes certain properties of a connection.

Syntax

OPEN ([UNIT=]io-unit [, FILE=name] [, ERR=label] [, IOSTAT=i-var], slist)

io-unit
Is an external unit specifier.

name
Is a character or numeric expression specifying the name of the file to be connected. For more information, see FILE Specifier and STATUS Specifier.

label
Is the label of the branch target statement that receives control if an error occurs.

i-var
Is a scalar integer variable that is defined as a positive integer (the number of the error message) if an error occurs, a negative integer if an end-of-file record is encountered, and zero if no error occurs. For more information, see I/O Status Specifier.

slist
Is one or more of the following OPEN specifiers in the form specifier = value or specifier (each specifier can appear only once):

ACCESS CONVERT MODE RECORDTYPE
ACTION DEFAULTFILE NAME SHARE
ASSOCIATEVARIABLE DELIM ORGANIZATION SHARED
BLANK DISPOSE PAD STATUS
BLOCKSIZE FILE POSITION TITLE
BUFFERCOUNT FORM READONLY TYPE
BUFFERED IOFOCUS RECL USEROPEN
CARRIAGECONTROL MAXREC RECORDSIZE

The OPEN specifiers and their acceptable values are summarized in the OPEN Statement in the Language Reference.

The control specifiers that can be specified in an OPEN statement are discussed in I/O Control List in the Language Reference.

Rules and Behavior

The control specifiers ([UNIT=]io-unit, ERR=label, and IOSTAT=i-var) and OPEN specifiers can appear anywhere within the parentheses following OPEN. However, if the UNIT specifier is omitted, the io-unit must appear first in the list.

Specifier values that are scalar numeric expressions can be any integer or real expression. The value of the expression is converted to integer data type before it is used in the OPEN statement.

Only one unit at a time can be connected to a file, but multiple OPENs can be performed on the same unit. If an OPEN statement is executed for a unit that already exists, the following occurs:

  • If FILE is not specified, or FILE specifies the same file name that appeared in a previous OPEN statement, the current file remains connected.

    If the file names are the same, the values for the BLANK, CARRIAGECONTROL, CONVERT, DELIM, DISPOSE, ERR, IOSTAT, and PAD specifiers can be changed. Other OPEN specifier values cannot be changed, and the file position is unaffected.

  • If FILE specifies a different file name, the previous file is closed and the new file is connected to the unit.

The ERR and IOSTAT specifiers from any previously executed OPEN statement have no effect on any currently executing OPEN statement. If an error occurs, no file is opened or created.

Secondary operating system messages do not display when IOSTAT is specified. To display these messages, remove IOSTAT or use a platform-specific method.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: READ, WRITE, CLOSE, FORMAT, INQUIRE, OPEN Statement

Examples

You can specify character values at run time by substituting a character expression for a specifier value in the OPEN statement. The character value can contain trailing blanks but not leading or embedded blanks; for example:

  CHARACTER*6 FINAL /' '/
  ...
  IF (expr) FINAL = 'DELETE'
  OPEN (UNIT=1, STATUS='NEW', DISP=FINAL)

The following statement creates a new sequential formatted file on unit 1 with the default file name fort.1:

  OPEN (UNIT=1, STATUS='NEW', ERR=100)

The following statement creates a file on magnetic tape:

  OPEN (UNIT=I, FILE='/dev/rmt8',                                  &
       STATUS='NEW', ERR=14, RECL=1024)

The following statement opens the file (created in the previous example) for input:

  OPEN (UNIT=I, FILE='/dev/rmt8', READONLY, STATUS='OLD',          &
       RECL=1024)

The following example opens the existing file /usr/users/someone/test.dat:

   OPEN (unit=10, DEFAULTFILE='/usr/users/someone/', FILE='test.dat',
  1     FORM='FORMATTED', STATUS='OLD')

The following example opens a new file:

 ! Prompt user for a filename and read it:
 CHARACTER*64 filename
 WRITE (*, '(A\)') ' enter file to create: '
 READ (*, '(A)') filename
 ! Open the file for formatted sequential access as unit 7.
 ! Note that the specified access need not have been specified,
 ! since it is the default (as is "formatted").
 OPEN (7, FILE = filename, ACCESS = 'SEQUENTIAL', STATUS = 'NEW')
 The following example opens an existing file called DATA3.TXT:
 ! Open a file created by an editor, "DATA3.TXT", as unit 3:
 OPEN (3, FILE = 'DATA3.TXT')


OPTIONAL

Statement and Attribute: Permits dummy arguments to be omitted in a procedure reference.

The OPTIONAL attribute can be specified in a type declaration statement or an OPTIONAL statement, and takes one of the following forms:

Syntax

Type Declaration Statement:

type, [att-ls,] OPTIONAL [, att-ls] :: d-arg [, d-arg] ...

Statement:

OPTIONAL [::] d-arg [, d-arg] ...

type
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

d-arg
Is the name of a dummy argument.

Rules and Behavior

The OPTIONAL attribute can only appear in the scoping unit of a subprogram or an interface body, and can only be specified for dummy arguments.

A dummy argument is "present" if it associated with an actual argument. A dummy argument that is not optional must be present. You can use the PRESENT intrinsic function to determine whether an optional dummy argument is associated with an actual argument.

To call a procedure that has an optional argument, you must use an explicit interface.

If argument keywords are not used, argument association is positional. The first dummy argument becomes associated with the first actual argument, and so on. If argument keywords are used, arguments are associated by the keyword name, so actual arguments can be in a different order than dummy arguments. A keyword is required for an argument only if a preceding optional argument is omitted or if the argument sequence is changed.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: PRESENT, Argument Keywords in Intrinsic Procedures, Optional Arguments, Argument Association, Type Declarations, Compatible attributes

Examples

The following example shows a type declaration statement specifying the OPTIONAL attribute:

SUBROUTINE TEST(A)
REAL, OPTIONAL, DIMENSION(-10:2) :: A
END SUBROUTINE

The following is an example of the OPTIONAL statement:

SUBROUTINE TEST(A, B, L, X)
  OPTIONAL :: B
  INTEGER A, B, L, X

  IF (PRESENT(B)) THEN        ! Printing of B is conditional
    PRINT *, A, B, L, X       !   on its presence
  ELSE
    PRINT *, A, L, X
  ENDIF
END SUBROUTINE

INTERFACE
  SUBROUTINE TEST(ONE, TWO, THREE, FOUR)
    INTEGER ONE, TWO, THREE, FOUR
    OPTIONAL :: TWO
  END SUBROUTINE
END INTERFACE

INTEGER I, J, K, L

I = 1
J = 2
K = 3
L = 4

CALL TEST(I, J, K, L)            ! Prints:  1  2  3  4
CALL TEST(I, THREE=K, FOUR=L)    ! Prints:  1  3  4
END

Note that in the second call to subroutine TEST, the second positional (optional) argument is omitted. In this case, all following arguments must be keyword arguments.

The following shows another example:

SUBROUTINE ADD (a,b,c,d)
  REAL              a, b, d
  REAL, OPTIONAL :: c

  IF (PRESENT(c)) THEN
    d = a + b + c + d
  ELSE
    d = a + b + d
  END IF
END SUBROUTINE

Consider the following:

SUBROUTINE EX (a, b, c)
REAL, OPTIONAL :: b,c

This subroutine can be called with any of the following statements:

CALL EX (x, y, z)   !All 3 arguments are passed.

CALL EX (x)         !Only the first argument is passed.

CALL EX (x, c=z)    !The first optional argument is omitted.

Note that you cannot use a series of commas to indicate omitted optional arguments, as in the following example:

CALL EX (x,,z)   !Invalid statement.

This results in a compile-time error.


OPTIONS

Statement: Overrides or confirms the compiler options in effect for a program unit.

Syntax

OPTIONS option [option...]

option
Is one of the following:
/ASSUME = [NO]UNDERSCORE (Alpha only)
/CHECK = ALL
[NO]BOUNDS
[NO]OVERFLOW
[NO]UNDERFLOW
NONE
/NOCHECK
/CONVERT = BIG_ENDIAN
CRAY
FDX
FGX
IBM
LITTLE_ENDIAN
NATIVE
VAXD
VAXG
/[NO]EXTEND_SOURCE
/[NO]F77
/FLOAT = D_FLOAT (VMS only)
G_FLOAT (VMS only)
IEEE_FLOAT
/[NO]G_FLOATING (VMS only)
/[NO]I4
/[NO]RECURSIVE

Note that an option must always be preceded by a slash (/).

Some OPTIONS statement options are equivalent to compiler options.

Rules and Behavior

The OPTIONS statement must be the first statement in a program unit, preceding the PROGRAM, SUBROUTINE, FUNCTION, MODULE, and BLOCK DATA statements.

OPTIONS statement options override compiler options, but only until the end of the program unit for which they are defined. If you want to override compiler options in another program unit, you must specify the OPTIONS statement before that program unit.

Example

The following are valid OPTIONS statements:

  OPTIONS /CHECK=ALL/F77
  OPTIONS /I4


OPTIONS Directive

General Compiler Directive: Affects data alignment and warnings about data alignment.

Syntax

c DEC$ OPTIONS option [option]
...
c DEC$ END OPTIONS

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

option
Is one (or both) of the following:

  • /WARN=[NO]ALIGNMENT

    Controls whether warnings are issued by the compiler for data that is not naturally aligned. By default, you receive compiler messages when misaligned data is encountered (/WARN=ALIGNMENT).

  • /[NO]ALIGN[= p]

    Controls alignment of fields in record structures and data items in common blocks. The fields and data items can be naturally aligned (for performance reasons) or they can be packed together on arbitrary byte boundaries.

    p
    Is a specifier with one of the following forms:

    [class = ] rule
    (class = rule,...)
    ALL
    NONE

    class
    Is one of the following keywords:

    • COMMONS: For common blocks
    • RECORDS: For records
    • STRUCTURES: A synonym for RECORDS

    rule
    Is one of the following keywords:

    • PACKED
      Packs fields in records or data items in common blocks on arbitrary byte boundaries.

    • NATURAL
      Naturally aligns fields in records and data items in common blocks on up to 64-bit boundaries (inconsistent with the Fortran 95/90 standard).
      This keyword causes the compiler to naturally align all data in a common block, including INTEGER(KIND=8), REAL(KIND=8), and all COMPLEX data.

    • STANDARD
      Naturally aligns data items in common blocks on up to 32-bit boundaries (consistent with the Fortran 95/90 standard).
      This keyword only applies to common blocks; so, you can specify c DEC$ OPTIONS /ALIGN=COMMONS=STANDARD, but you cannot specify c DEC$ OPTIONS /ALIGN=STANDARD.

    ALL
    Is the same as specifying OPTIONS /ALIGN, OPTIONS /ALIGN=NATURAL, and OPTIONS /ALIGN=(RECORDS=NATURAL,COMMONS=NATURAL).

    NONE
    Is the same as specifying OPTIONS /NOALIGN, OPTIONS /ALIGN=PACKED, and OPTIONS /ALIGN=(RECORDS=PACKED,COMMONS=PACKED).

Rules and Behavior

The OPTIONS (and accompanying END OPTIONS) directives must come after OPTIONS, SUBROUTINE, FUNCTION, and BLOCK DATA statements (if any) in the program unit, and before the executable part of the program unit.

The OPTIONS directive supersedes the /alignment compiler option.

For performance reasons, Compaq Fortran aligns local data items on natural boundaries. However, EQUIVALENCE, COMMON, RECORD, and STRUCTURE data declaration statements can force misaligned data. If c DEC$ OPTIONS/WARN=NOALIGNMENT is specified, warnings will not be issued if misaligned data is encountered.

Note: Misaligned data significantly increases the time it takes to execute a program. As the number of misaligned fields encountered increases, so does the time needed to complete program execution. Specifying c DEC$ OPTIONS/ALIGN (or the /alignment compiler option) minimizes misaligned data.

If you want aligned data in common blocks, do one of the following:

  • Specify OPTIONS /ALIGN=COMMONS=STANDARD for data items up to 32 bits in length.
  • Specify OPTIONS /ALIGN=COMMONS=NATURAL for data items up to 64 bits in length.
  • Place source data declarations within the common block in descending size order, so that each data item is naturally aligned.

If you want packed, unaligned data in a record structure, do one of the following:

  • Specify OPTIONS /ALIGN=RECORDS=PACKED.
  • Place source data declarations in the record structure so that the data is naturally aligned.

See Also: General Compiler Directives

Example

! directives can be nested up to 100 levels
  CDEC$ OPTIONS /ALIGN=PACKED     ! Start of Group A
    declarations
  CDEC$ OPTIONS /ALIGN=RECO=NATU     ! Start of nested Group B
    more declarations
  CDEC$ END OPTIONS                  ! End of Group B
    still more declarations
  CDEC$ END OPTIONS               ! End of Group A

The CDEC$ OPTIONS specification for Group B only applies to RECORDS; common blocks within Group B will be PACKED. This is because COMMONS retains the previous setting (in this case, from the Group A specification).


OR

Elemental Intrinsic Function (Generic): Performs a bitwise inclusive OR on its arguments. For more information, see IOR.

Example

 INTEGER i
 i = OR(3, 10)   ! returns 11


ORDERED (TU*X only)

OpenMP Parallel Compiler Directive: Specifies a block of code to be executed in the order in which iterations would be executed in sequential execution.

Syntax

c$OMP ORDERED
block
c$OMP ORDERED

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

block
Is a structured block (section) of statements or constructs. You cannot branch into or out of the block.

Rules and Behavior

An ORDERED directive can appear only in the dynamic extent of a DO or PARALLEL DO directive. The DO directive to which the ordered section binds must have the ORDERED clause specified.

An iteration of a loop using a DO directive must not execute the same ORDERED directive more than once, and it must not execute more than one ORDERED directive.

One thread is allowed in an ordered section at a time. Threads are allowed to enter in the order of the loop iterations. No thread can enter an ordered section until it can be guaranteed that all previous iterations have completed or will never execute an ordered section. This sequentializes and orders code within ordered sections while allowing code outside the section to run in parallel.

Ordered sections that bind to different DO directives are independent of each other.

See Also: Parallel Directives for Tru64 UNIX Systems, OpenMP Fortran API Compiler Directives (TU*X only), Compaq Fortran Parallel Compiler Directives (TU*X only)

Examples

Ordered sections are useful for sequentially ordering the output from work that is done in parallel. Assuming that a reentrant I/O library exists, the following program prints out the indexes in sequential order:

  c$OMP DO ORDERED SCHEDULE(DYNAMIC)
        DO I=LB,UB,ST
          CALL WORK(I)
        END DO
        ...
        SUBROUTINE WORK(K)
  c$OMP ORDERED
        WRITE(*,*) K
  c$OMP END ORDERED


OUTGTEXT

Graphics Subroutine: In graphics mode, sends a string of text to the screen, including any trailing blanks.

Module: USE DFLIB

Syntax

CALL OUTGTEXT (text)

text
(Input) Character*(*). String to be displayed.

Text output begins at the current graphics position, using the current font set with SETFONT and the current color set with SETCOLORRGB or SETCOLOR. No formatting is provided. After it outputs the text, OUTGTEXT updates the current graphics position.

Before you call OUTGTEXT, you must call INITIALIZEFONTS.

Because OUTGTEXT is a graphics function, the color of text is affected by the SETCOLORRGB function, not by SETTEXTCOLORRGB.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETFONTINFO, GETGTEXTEXTENT, INITIALIZEFONTS, MOVETO, SETCOLORRGB, SETFONT, SETGTEXTROTATION

Example

 ! build as a QuickWin App.
 USE DFLIB
 INTEGER(2) result
 INTEGER(4) i
 TYPE (xycoord) xys

 result = INITIALIZEFONTS()
 result = SETFONT('t''Arial''h18w10pvib')
 do i=1,6
    CALL MOVETO(INT2(0),INT2(30*(i-1)),xys)
    grstat=SETCOLOR(INT2(i))
    CALL OUTGTEXT('This should be ')
    SELECT CASE (i)
      CASE (1)
        CALL OUTGTEXT('Blue')
      CASE (2)
        CALL OUTGTEXT('Green')
      CASE (3)
        CALL OUTGTEXT('Cyan')
      CASE (4)
        CALL OUTGTEXT('Red')
      CASE (5)
        CALL OUTGTEXT('Magenta')
      CASE (6)
        CALL OUTGTEXT('Orange')
    END SELECT
 END DO
 END


OUTTEXT

Graphics Subroutine: In text or graphics mode, sends a string of text to the screen, including any trailing blanks.

Module: USE DFLIB

Syntax

CALL OUTTEXT (text)

text
(Input) Character*(*). String to be displayed.

Text output begins at the current text position in the color set with SETTEXTCOLORRGB or SETTEXTCOLOR. No formatting is provided. After it outputs the text, OUTTEXT updates the current text position.

To output text using special fonts, you must use the OUTGTEXT function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETTEXTPOSITION, SETTEXTCOLORRGB, WRITE

Example

 USE DFLIB
 INTEGER(2) oldcolor
 TYPE (rccoord) rc

 CALL CLEARSCREEN($GCLEARSCREEN)
 CALL SETTEXTPOSITION (INT2(1), INT2(5), rc)
 oldcolor = SETTEXTCOLOR(INT2(4))
 CALL OUTTEXT ('Hello, everyone')
 END


PACK

Transformational Intrinsic Function (Generic): Takes elements from an array and packs them into a rank-one array under the control of a mask.

Syntax

result = PACK (array, mask [, vector])

array
(Input) Must be an array (of any data type).

mask
(Input) Must be of type logical and conformable with array. It determines which elements are taken from array.

vector
(Optional; input) Must be a rank-one array with the same type and type parameters as array. Its size must be at least t, where t is the number of true elements in mask. If mask is a scalar with value true, vector must have at least as many elements as there are in array.

Elements in vector are used to fill out the result array if there are not enough elements selected by mask.

Results:

The result is a rank-one array with the same type and type parameters as array. If vector is present, the size of the result is that of vector. Otherwise, the size of the result is the number of true elements in mask, or the number of elements in array (if mask is a scalar with value true).

Elements in array are processed in array element order to form the result array. Element i of the result is the element of array that corresponds to the ith true element of mask. If vector is present and has more elements than there are true values in mask, any result elements that are empty (because they were not true according to mask) are set to the corresponding values in vector.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: UNPACK

Examples

N is the array

  [ 0  8  0 ]
  [ 0  0  0 ]
  [ 7  0  0 ].

PACK (N, MASK=N .NE. 0, VECTOR=(/1, 3, 5, 9, 11, 13/)) produces the result (7, 8, 5, 9, 11, 13).

PACK (N, MASK=N .NE. 0) produces the result (7, 8).

The following shows another example:

 INTEGER array(2, 3), vec1(2), vec2(5)
 LOGICAL mask (2, 3)
 array = RESHAPE((/7, 0, 0, -5, 0, 0/), (/2, 3/))
 mask = array .NE. 0
 !  array is  7  0 0  and mask is  T F F
 !            0 -5 0               F T F

 VEC1 = PACK(array, mask)      ! returns ( 7, -5 )
 VEC2 = PACK(array, array .GT. 0, VECTOR= (/1,2,3,4,5/))
 !  returns ( 7, 2, 3, 4, 5 )


PACK Directive

General Compiler Directive: Specifies the memory starting addresses of derived-type items (and record structure items).

Syntax

c DEC$ PACK:[{1 | 2 | 4}]

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

Rules and Behavior

Items of derived types, unions, and structures are aligned in memory on the smaller of two sizes: the size of the type of the item, or the current alignment setting. The current alignment setting can be 1, 2, 4, or 8 bytes. The default initial setting is 8 bytes (unless /alignment or /vms specifies otherwise). By reducing the alignment setting, you can pack variables closer together in memory.

The PACK directive lets you control the packing of derived-type or record structure items inside your program by overriding the current memory alignment setting.

For example, if CDEC$ PACK:1 is specified, all variables begin at the next available byte, whether odd or even. Although this slightly increases access time, no memory space is wasted. If CDEC$ PACK:4 is specified, INTEGER(1), LOGICAL(1), and all character variables begin at the next available byte, whether odd or even. INTEGER(2) and LOGICAL(2) begin on the next even byte; all other variables begin on 4-byte boundaries.

If the PACK directive is specified without a number, packing reverts to the compiler option setting (if any), or the default setting of 8.

The directive can appear anywhere in a program before the derived-type definition or record structure definition. It cannot appear inside a derived-type or record structure definition.

The following form is also allowed: !MS$PACK:[{1|2|4}]

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Derived Type, STRUCTURE...END STRUCTURE, UNION...END UNION, General Compiler Directives

Example

 ! Use 4-byte packing for this derived type
 ! Note PACK is used outside of the derived type definition

 !DEC$ PACK:4
 TYPE pair
    INTEGER a, b
 END TYPE
 ! revert to default or compiler option
 !DEC$ PACK:


PACKTIMEQQ

Run-Time Subroutine: Packs time and date values.

Module: USE DFLIB

Syntax

CALL PACKTIMEQQ (timedate, iyr, imon, iday, ihr, imin, isec)

timedate
(Output) INTEGER(4). Packed time and date information.

iyr
(Input) INTEGER(2). Year (xxxx AD).

imon
(Input) INTEGER(2). Month (1 - 12).

iday
(Input) INTEGER(2). Day (1 - 31)

ihr
(Input) INTEGER(2). Hour (0 - 23)

imin
(Input) INTEGER(2). Minute (0 - 59)

isec
(Input) INTEGER(2). Second (0 - 59)

The packed time is the number of seconds since 00:00:00 Greenwich mean time, January 1, 1970. Because packed time values can be numerically compared, you can use PACKTIMEQQ to work with relative date and time values. Use UNPACKTIMEQQ to unpack time information. SETFILETIMEQQ uses packed time.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS DLL LIB

See Also: UNPACKTIMEQQ, SETFILETIMEQQ, GETFILEINFOQQ, TIME

Example

 USE DFLIB
 INTEGER(2) year, month, day, hour, minute, second,   &
 hund
 INTEGER(4) timedate

 CALL GETDAT (year, month, day)
 CALL GETTIM (hour, minute, second, hund)
 CALL PACKTIMEQQ (timedate, year, month, day, hour,   &
                  minute, second)
 END


PARALLEL (TU*X only)

OpenMP Parallel Compiler Directive: Defines a parallel region.

Syntax

c$OMP PARALLEL [clause[[,] clause] ... ]
block
c$OMP END PARALLEL

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

clause
Is one of the following:

  • COPYIN (list)

  • DEFAULT ( PRIVATE | SHARED | NONE )

  • FIRSTPRIVATE (list)

  • IF (scalar_logical_expression)

    Specifies that the enclosed code section is to be executed in parallel only if the scalar_logical_expression evaluates to .TRUE.. Otherwise, the parallel region is serialized. If this clause is not used, the region is executed as if an IF(.TRUE.) clause were specified.

    This clause is evaluated by the master thread before any data scope attributes take effect.

    Only a single IF clause can appear in the directive.

  • PRIVATE (list)

  • REDUCTION( operator | intrinsic : list)

  • SHARED (list)

block
Is a structured block (section) of statements or constructs. You cannot branch into or out of the block (the parallel region).

Rules and Behavior

The PARALLEL and END PARALLEL directive pair must appear in the same routine in the executable section of the code.

The END PARALLEL directive denotes the end of the parallel region. There is an implied barrier at this point. Only the master thread of the team continues execution at the end of a parallel region.

When a thread encounters a parallel region, it creates a team of threads and it becomes the master of the team. The master thread is a member of the team and it has a thread number of zero within the team. The number of threads in the team can be controlled by environment variables and library calls.

Once created, the number of threads in the team remains constant for the duration of that parallel region. However, you can explicitly change the number of threads used in the next parallel region by calling the run-time library routine omp_set_num_threads from a serial portion of the program. This routine overrides any value you may have set using the environment variable OMP_NUM_THREADS. For details on environment variables, see your user manual.

The code contained within the dynamic extent of the parallel region is executed on each thread, and the code path can be different for different threads.

If a thread executing a parallel region encounters another parallel region, it creates a new team and becomes the master of that new team. By default, nested parallel regions are always serialized and executed by a team of one thread.

See Also: Parallel Directives for Tru64 UNIX Systems, OpenMP Fortran API Compiler Directives (TU*X only), Compaq Fortran Parallel Compiler Directives (TU*X only), Parallel Library Routines on Tru64 UNIX Systems

Examples

You can use the PARALLEL directive in coarse-grain parallel programs. In the following example, each thread in the parallel region decides what part of the global array X upon which to work based on the thread number:

  c$OMP PARALLEL DEFAULT(PRIVATE) SHARED(X,NPOINTS)
        IAM = OMP_GET_THREAD_NUM( )
        NP = OMP_GET_NUM_THREADS( )
        IPOINTS = NPOINTS/NP
        CALL SUBDOMAIN(X,IAM,IPOINTS)
  c$OMP END PARALLEL

Assuming you previously used the environment variable OMP_NUM_THREADS to set the number of threads to six, you can change the number of threads between parallel regions as follows:

        CALL OMP_SET_NUM_THREADS(3)
  !$OMP PARALLEL
  ...
  !$OMP END PARALLEL
        CALL OMP_SET_NUM_THREADS(4)
  !$OMP PARALLEL DO
  ...
  !$OMP END PARALLEL DO


PARALLEL DO (TU*X only)

OpenMP Parallel Compiler Directive: Provides an abbreviated way to specify a parallel region containing a single DO directive.

Syntax

c$OMP PARALLEL DO [clause[[,] clause] ... ]
do-loop
[c$OMP END PARALLEL DO]

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

clause
Can be any of the clauses accepted by the DO or PARALLEL directives.

do-loop
Is a DO iteration (a DO loop). It cannot be a DO WHILE or a DO loop without loop control. The DO loop iteration variable must be of type integer.

You cannot branch out of a DO loop associated with a DO directive.

Rules and Behavior

If the END PARALLEL DO directive is not specified, the PARALLEL DO is assumed to end with the DO loop that immediately follows the PARALLEL DO directive. If used, the END PARALLEL DO directive must appear immediately after the end of the DO loop.

The semantics are identical to explicitly specifying a PARALLEL directive immediately followed by a DO directive.

See Also: Parallel Directives for Tru64 UNIX Systems, OpenMP Fortran API Compiler Directives (TU*X only), Compaq Fortran Parallel Compiler Directives (TU*X only)

Examples

In the following example, the loop iteration variable is private by default and it is not necessary to explicitly declare it. The END PARALLEL DO directive is optional:

  c$OMP PARALLEL DO
        DO I=1,N
            B(I) = (A(I) + A(I-1)) / 2.0
        END DO
  c$OMP END PARALLEL DO

The following example shows how to use the REDUCTION clause in a PARALLEL DO directive:

  c$OMP PARALLEL DO DEFAULT(PRIVATE) REDUCTION(+: A,B)
        DO I=1,N
          CALL WORK(ALOCAL,BLOCAL)
          A = A + ALOCAL
          B = B + BLOCAL
        END DO
  c$OMP END PARALLEL DO


PARALLEL SECTIONS (TU*X only)

OpenMP Parallel Compiler Directive: Provides an abbreviated way to specify a parallel region containing a single SECTIONS directive. The semantics are identical to explicitly specifying a PARALLEL directive immediately followed by a SECTIONS directive.

Syntax

c$OMP PARALLEL SECTIONS [clause[[,] clause] ...]
[c$OMP SECTION]
block
[c$OMP SECTION
block] ...
c$OMP END PARALLEL SECTIONS

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

clause
Can be any of the clauses accepted by the PARALLEL or SECTIONS directives.

block
Is a structured block (section) of statements or constructs. You cannot branch into or out of the block.

The last section ends at the END PARALLEL SECTIONS directive.

See Also: Parallel Directives for Tru64 UNIX Systems, OpenMP Fortran API Compiler Directives (TU*X only), Compaq Fortran Parallel Compiler Directives (TU*X only)

Examples

In the following example, subroutines XAXIS, YAXIS, and ZAXIS can be executed concurrently:

  c$OMP PARALLEL SECTIONS
  c$OMP SECTION
        CALL XAXIS
  c$OMP SECTION
        CALL YAXIS
  c$OMP SECTION
        CALL ZAXIS
  c$OMP END PARALLEL SECTIONS


PARAMETER

Statement and Attribute: Defines a named constant.

The PARAMETER attribute can be specified in a type declaration statement or a PARAMETER statement, and takes one of the following forms:

Syntax

Type Declaration Statement:

type, [att-ls,] PARAMETER [, att-ls] :: c = expr [, c = expr] ...

Statement:

PARAMETER [(] c = expr [, c = expr ] ... [)]

type
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

c
Is the name of the constant.

expr
Is an initialization expression. It can be of any data type.

Rules and Behavior

The type, type parameters, and shape of the named constant are determined in one of the following ways:

  • By an explicit type declaration statement in the same scoping unit.

  • By the implicit typing rules in effect for the scoping unit. If the named constant is implicitly typed, it can appear in a subsequent type declaration only if that declaration confirms the implicit typing.

For example, consider the following statement:

  PARAMETER (MU=1.23)

According to implicit typing, MU is of integer type, so MU=1. For MU to equal 1.23, it should previously be declared REAL in a type declaration or be declared in an IMPLICIT statement.

A named constant must not appear in a format specification or as the character count for Hollerith constants. For compilation purposes, writing the name is the same as writing the value.

If the named constant is used as the length specifier in a CHARACTER declaration, it must be enclosed in parentheses.

The name of a constant cannot appear as part of another constant, although it can appear as either the real or imaginary part of a complex constant.

You can only use the named constant within the scoping unit containing the defining PARAMETER statement.

Any named constant that appears in the initialization expression must have been defined previously in the same type declaration statement (or in a previous type declaration statement or PARAMETER statement), or made accessible by use or host association.

The use of parentheses is optional and can be controlled using the /[no]altparam compiler option.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATA, Type Declarations, Using the Compiler and Linker from the Command Line, Compatible attributes, Initialization Expressions, IMPLICIT, Alternative syntax for the PARAMETER statement

Examples

The following example shows a type declaration statement specifying the PARAMETER attribute:

  REAL, PARAMETER :: C = 2.9979251, Y = (4.1 / 3.0)

The following is an example of the PARAMETER statement:

  REAL(4) PI, PIOV2
  REAL(8) DPI, DPIOV2
  LOGICAL FLAG
  CHARACTER*(*) LONGNAME

  PARAMETER (PI=3.1415927, DPI=3.141592653589793238D0)
  PARAMETER (PIOV2=PI/2, DPIOV2=DPI/2)
  PARAMETER (FLAG=.TRUE., LONGNAME='A STRING OF 25 CHARACTERS')

The following shows another example:

 ! implicit integer type
 PARAMETER (nblocks = 10)

 ! implicit real type
 IMPLICIT REAL (L-M)
 PARAMETER (loads = 10.0, mass = 32.2)

 ! typed by PARAMETER statement
 ! Requires compiler option
 PARAMETER mass = 47.3, pi = 3.14159
 PARAMETER bigone = 'This constant is larger than forty characters'

 ! PARAMETER in attribute syntax
 REAL, PARAMETER :: mass=47.3, pi=3.14159, loads=10.0, mass=32.2


PASSDIRKEYSQQ

QuickWin Function: Determines the behavior of direction and page keys in a QuickWin application.

Module: USE DFLIB

Syntax

result = PASSDIRKEYSQQ (val)

val
(Input) INTEGER(4) or LOGICAL(4).

A value of .TRUE. causes direction and page keys to be input as normal characters (the PassDirKeys flag is turned on). A value of .FALSE. causes direction and page keys to be used for scrolling.

The following constants, defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory), can be used as integer arguments:

  • PASS_DIR_FALSE - Turns off any special handling of direction keys. They are not passed to the program by GETCHARQQ.

  • PASS_DIR_TRUE - Turns on special handling of direction keys. That is, they are passed to the program by GETCHARQQ.

  • PASS_DIR_INSDEL - INSERT and DELETE are also passed to the program by GETCHARQQ

  • PASS_DIR_CNTRLC - Only needed for a QuickWin application, but harmless if used with a Standard Graphics application that already passes CTRL+C.
    This value allows CTRL+C to be passed to a QuickWin program by GETCHARQQ if the following is true: the program must have removed the File menu EXIT item by using DELETEMENUQQ.
    This value also passes direction keys and INSERT and DELETE.

Results:

The return value indicates the previous setting of the PassDirKeys flag.

The return data type is the same as the data type of val; that is, either INTEGER(4) or LOGICAL(4).

When the PassDirKeys flag is turned on, the mouse must be used for scrolling since the direction and page keys are treated as normal input characters.

The PASSDIRKEYSQQ function is meant to be used primarily with the GETCHARQQ and INCHARQQ functions. Do not use normal input statements (such as READ) with the PassDirKeys flag turned on, unless your program is prepared to interpret direction and page keys.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETCHARQQ, INCHARQQ

Examples

use dflib

logical*4 res
character*1 ch, ch1

Print *,"Type X to exit, S to scroll, D to pass Direction keys"

123 continue
ch = getcharqq( )
! check for escapes
! 0x00 0x?? is a function key
! 0xE0 0x?? is a direction key
if (ichar(ch) .eq. 0) then
  ch1 = getcharqq()
  print *,"function key follows escape = ",ichar(ch), "  ",ichar(ch1),"  ",ch1
  goto 123
else if (ichar(ch) .eq. 224) then
  ch1 = getcharqq()
  print *,"direction key follows escape = ",ichar(ch),"  ",ichar(ch1),"  ",ch1
  goto 123
else
  print *,ichar(ch),"  ",ch

  if(ch .eq. 'S') then
   res = passdirkeysqq(.false.)
   print *, "Entering Scroll mode ",res
  endif

  if(ch .eq. 'D')  then
   res = passdirkeysqq(.true.)
   print *, "Entering Direction keys mode ",res
  endif

  if(ch .ne. 'X')  go to 123

endif
end

The following example uses an integer constant as an argument to PASSDIRKEYSQQ:

c=======================================================================
c
c dirkeys4.for
c
c The following sample requires a compiler greater that CVF6.1.
c
c=======================================================================
c
c       Compile/Load Input Line for Standard Graphics Full Screen Window
c
c       f90 /libs:qwins dirkeys4.for
c
c       Compile/Load Input Line for QuickWin Graphics
c
c       f90 /libs:qwin dirkeys4.f90
c
c  Program to illustrate how to get almost every character
c  from the keyboard in QuickWin or Standard Graphics mode.
c  Comment out the deletemenu line for Standard Graphics mode.
c
c  If you are doing a standard graphics application,
c  control C will come in as a #03 without further
c  effort.
c
c  In a QuickWin application,  The File menu Exit item must
c  be deleted, and PassDirKeysQQ called with PASS_DIR_CNTRLC
c  to get control C.
c
c=======================================================================
      use dflib

      integer(4) status

      character*1 key1,key2,ch1

      write(*,*) 'Initializing'

c-----don't do this for a Standard Grapics application
c     remove File menu Exit item.
      status = deletemenuqq(1,3) ! stop QuickWin from getting control C

c-------set up to pass all keys to window including control c.
      status  = passdirkeysqq(PASS_DIR_CNTRLC)
c===============================================================
c
c     read and print characters
c
c===============================================================

   10 key1 = getcharqq()

c-------first check for control+c
    if(ichar(key1) .eq. 3) then
      write(*,*) 'Control C Received'
      write(*,*) "Really want to quit?"
      write(*,*) "Type Y <cr> to exit, or any other char <cr> to continue."
      read(*,*) ch1
      if(ch1.eq."y" .or. ch1.eq."Y") goto 30
      goto 10
      endif

      if(ichar(key1).eq.0) then ! function key?
      key2 = getcharqq()
      write(*,15) ichar(key1),ichar(key2),key2
   15 format(1x,2i12,1x,a1,' function key')
      else
      if(ichar(key1).eq.224) then ! direction key?
      key2 = getcharqq()
      write(*,16) ichar(key1),ichar(key2),key2
   16 format(1x,2i12,1x,a1,' direction key')
      else
      write(*,20) key1,ichar(key1)  ! normal key
   20 format(1x,a1,i11)
      endif
      endif
      go to 10
   30 stop
      end


PAUSE

Statement: Temporarily suspends program execution and lets you execute operating system commands during the suspension. The PAUSE statement is a deleted feature in Fortran 95; it was obsolescent in Fortran 90. Compaq Fortran fully supports features deleted in Fortran 95.

Syntax

PAUSE [pause-code]

pause-code
(Optional) Is an optional message. It can be either of the following:

  • A scalar character constant of type default character.
  • A string of up to six digits; leading zeros are ignored. (Fortran 90 and FORTRAN 77 limit digits to five.)

Rules and Behavior

If you specify pause-code, the PAUSE statement displays the specified message and then displays the default prompt.

If you do not specify pause-code, the system displays the following default message:

  FORTRAN PAUSE

The following prompt is then displayed:

  • On Windows systems:
    Fortran Pause - Enter command<CR> or <CR> to continue.
  • On OpenVMS systems, the system prompt

  • On Tru64 UNIX and Linux systems:
    PAUSE prompt>

Effect on Windows Systems

The program waits for input on stdin. If you enter a blank line, execution resumes at the next executable statement.

Anything else is treated as a DOS command and is executed by a system( ) call. The program loops, letting you execute multiple DOS commands, until a blank line is entered. Execution then resumes at the next executable statement.

Effect on OpenVMS Systems

The effect of PAUSE differs depending on whether the program is an interactive or batch process, as follows:

  • If a program is an interactive process, the program is suspended until you enter one of the following commands:

    • CONTINUE resumes execution at the next executable statement.

    • DEBUG resumes execution under control of the OpenVMS Debugger.

    • EXIT terminates execution.

    In general, most other commands also terminate execution.

  • If a program is a batch process, the program is not suspended. If you specify a value for pause-code, this value is written to SYS$OUTPUT.

Effect on Tru64 UNIX and Linux Systems

The effect of PAUSE differs depending on whether the program is a foreground or background process, as follows:

  • If a program is a foreground process, the program is suspended until you enter the CONTINUE command. Execution then resumes at the next executable statement.

    Any other command terminates execution.

  • If a program is a background process, the behavior depends on stdin, as follows:

    • If stdin is redirected from a file, the system displays the following (after the pause code and prompt):
      To continue from background, execute 'kill -15 n'

      In this message, n is the process id of the program.

    • If stdin is not redirected from a file, the program becomes a suspended background job, and you must specify fg to bring the job into the foreground. You can then enter a command to resume or terminate processing.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: STOP, SYSTEM, Obsolescent and Deleted Language Features

Examples

The following examples show valid PAUSE statements:

  PAUSE 701
  PAUSE 'ERRONEOUS RESULT DETECTED'

The following shows another example:

  CHARACTER*24 filename
  PAUSE 'Enter DIR to see available files or press RETURN'   &
 &' if you already know filename.'
  READ(*,'(A\)') filename
  OPEN(1, FILE=filename)
  . . .


PDO (TU*X only)

Compaq Fortran Parallel Compiler Directive: Specifies that the iterations of the immediately following DO loop must be executed in parallel.

Syntax

c$PAR PDO [option[[,] option] ...]
do_loop
[c$PAR END PDO [NOWAIT]]

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

option
Is one of the following:

  • CHUNK (chunksize)

    Adjusts the number of consecutive iterations assigned to a thread. At the end of the PDO construct, chunksize reverts to the default. The effect of CHUNK varies, depending on the scheduling type.

    A chunksize specified in a PDO directive supersedes any chunksize set with a CHUNK directive earlier in the program, and applies only for the duration of the PDO construct.

    For details on default chunksize and on the effect of specifying chunksizes for the same program in more than one context, see CHUNK (TU*X).

    BLOCKED is allowed as an alternative spelling for CHUNK.

  • FIRSTPRIVATE (list)

  • LASTLOCAL (var[[,] var] ...)

    The LASTLOCAL keyword is the same as the LASTPRIVATE clause.

    LAST LOCAL is allowed as an alternative spelling for LASTLOCAL, even in free form source code.

  • [MP_SCHEDTYPE=] mode

    Controls the scheduling type and allocation of work for the PDO construct.

    There are several ways to specify a scheduling type. The scheduling type defaults to STATIC when no other information is available. For a description of mode and scheduling types, see MP_SCHEDTYPE (TU*X only).

    At the end of the PDO construct, the scheduling type reverts to the default. The scheduling type does not affect the correctness of the program, but may affect performance.

  • (ORDERED)

    Specifies that iterations are assigned to threads in the same order in which iterations would be generated by a normal Compaq Fortran DO statement.

  • PRIVATE (list)

    LOCAL is allowed as an alternative spelling for PRIVATE.

  • REDUCTION (var[[,] var] ...)

    The REDUCTION keyword used here is different from the REDUCTION clause described previously, where both a variable and an operator type need to be specified.

    In this version of the keyword, the operator is not given in the PDO directive. The compiler must be able to determine the reduction operation from the source code.

    The REDUCTION keyword can be applied to a variable in a DO loop only if the variable meets the following criteria:

    • It must be scalar.

    • It must be assigned to exactly once in the DO loop.

    • It must be read from exactly once in the DO loop and only in the right side of the assignment.

    • The assignment must be one of the following forms:
        x = x operator expr

  x = expr operator x (except for subtraction)

  x  = operator(x, expr)

  x = operator(expr, x)

      where operator is one of the following supported reduction operations: +, -, *, .AND., .OR., .EQV., .NEQV., MAX, MIN, IAND, or IOR.

    The compiler rewrites the reduction operation by computing partial results into local variables and then combining the results into the reduction variable. The reduction variable must be SHARED in the enclosing context.

do_loop
Is a Compaq Fortran DO construct with loop control. It cannot be a DO WHILE or a DO loop without loop control. The DO loop iteration variable must be of type integer.

The iterations of the DO loop are distributed across the already existing threads.

Rules and Behavior

Specifying NOWAIT is the same as specifying NOWAIT in an OpenMP Fortran API DO directive.

PDO directives are permitted only within the lexical extent of the PARALLEL and END PARALLEL directives.

For more information about rules and restrictions, see your user manual.

See Also: Parallel Directives for Tru64 UNIX Systems, Compaq Fortran Parallel Compiler Directives (TU*X only), OpenMP Fortran API Compiler Directives (TU*X only)


PDONE (TU*X only)

Compaq Fortran Parallel Compiler Directive: Is an executable statement that terminates the current parallel DO loop.

Syntax

c$PAR PDONE

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

Rules and Behavior

The PDONE directive terminates the current parallel DO loop early, without completing any iterations that have not yet been assigned to a thread. Any iterations that have already been assigned to a thread are completed.

PDONE directives are permitted only within the lexical extent of a PDO or PARALLEL DO construct.

When the scheduling type is STATIC or INTERLEAVED, a PDONE directive has no effect because all iterations are assigned before execution of the parallel DO loop begins.

See Also: Parallel Directives for Tru64 UNIX Systems, Compaq Fortran Parallel Compiler Directives (TU*X only), OpenMP Fortran API Compiler Directives (TU*X only)


PEEKCHARQQ

Run-Time Function: Checks the keystroke buffer for a recent console keystroke and returns .TRUE. if there is a character in the buffer or .FALSE. if there is not.

Module: USE DFLIB

Syntax

result = PEEKCHARQQ( )

Results:

The result is of type LOGICAL(4). The result is .TRUE. if there is a character waiting in the keyboard buffer; otherwise, .FALSE..

To find out the value of the key in the buffer, call GETCHARQQ. If there is no character waiting in the buffer when you call GETCHARQQ, GETCHARQQ waits until there is a character in the buffer. If you call PEEKCHARQQ first, you prevent GETCHARQQ from halting your process while it waits for a keystroke. If there is a keystroke, GETCHARQQ returns it and resets PEEKCHARQQ to .FALSE..

Compatibility

CONSOLE DLL LIB

See Also: GETCHARQQ, GETSTRQQ, FGETC, GETC

Example

 USE DFLIB
 LOGICAL(4) pressed / .FALSE. /

 DO WHILE (.NOT. pressed)
   WRITE(*,*) ' Press any key'
   pressed = PEEKCHARQQ ( )
 END DO
 END


PERROR

Portability Subroutine: Sends a message to the standard error stream, preceded by a specified string, for the last detected error.

Module: USE DFPORT

Syntax

CALL PERROR (string)

string
(Input) Character*(*). Message to precede the standard error message.

The string sent is the same as that given by GERROR.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also:R GERROR, IERRNO

Example

 USE DFPORT
 character*24 errtext
 errtext = 'In my opinion, '
 . . .
 ! any error message generated by errtext is
 ! preceded by 'In my opinion, '
 Call PERROR (errtext)


PIE, PIE_W

Graphics Function: Draws a pie-shaped wedge in the current graphics color.

Module: USE DFLIB

Syntax

result = PIE (i, x1, y1, x2, y2, x3, y3, x4, y4)
result = PIE_W (i, wx1, wy1, wx2, wy2, wx3, wy3, wx4, wy4)

i
(Input) INTEGER(2). Fill flag. One of the following symbolic constants (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory):

  • $GFILLINTERIOR - Fills the figure using the current color and fill mask.
  • $GBORDER - Does not fill the figure.

x1, y1
(Input) INTEGER(2). Viewport coordinates for upper-left corner of bounding rectangle.

x2, y2
(Input) INTEGER(2). Viewport coordinates for lower-right corner of bounding rectangle.

x3, y3
(Input) INTEGER(2). Viewport coordinates of start vector.

x4, y4
(Input) INTEGER(2). Viewport coordinates of end vector.

wx1, wy1
(Input) REAL(8). Window coordinates for upper-left corner of bounding rectangle.

wx2, wy2
(Input) REAL(8). Window coordinates for lower-right corner of bounding rectangle.

wx3, wy3
(Input) REAL(8). Window coordinates of start vector.

wx4, wy4
(Input) REAL(8). Window coordinates of end vector.

Results:

The result is of type INTEGER(2). The result is nonzero if successful; otherwise, 0. If the pie is clipped or partially out of bounds, the pie is considered successfully drawn and the return is 1. If the pie is drawn completely out of bounds, the return is 0.

The border of the pie wedge is drawn in the current color set by SETCOLORRGB.

The PIE function uses the viewport-coordinate system. The center of the arc is the center of the bounding rectangle, which is specified by the viewport-coordinate points (x1, y1) and (x2, y2). The arc starts where it intersects an imaginary line extending from the center of the arc through (x3, y3). It is drawn counterclockwise about the center of the arc, ending where it intersects an imaginary line extending from the center of the arc through (x4, y4).

The PIE_W function uses the window-coordinate system. The center of the arc is the center of the bounding rectangle specified by the window-coordinate points (wx1, wy1) and (wx2, wy2). The arc starts where it intersects an imaginary line extending from the center of the arc through (wx3, wy3). It is drawn counterclockwise about the center of the arc, ending where it intersects an imaginary line extending from the center of the arc through (wx4, wy4).

The fill flag option $GFILLINTERIOR is equivalent to a subsequent call to FLOODFILLRGB using the center of the pie as the starting point and the current graphics color (set by SETCOLORRGB) as the fill color. If you want a fill color different from the boundary color, you cannot use the $GFILLINTERIOR option. Instead, after you have drawn the pie wedge, change the current color with SETCOLORRGB and then call FLOODFILLRGB. You must supply FLOODFILLRGB with an interior point in the figure you want to fill. You can get this point for the last drawn pie or arc by calling GETARCINFO.

If you fill the pie with FLOODFILLRGB, the pie must be bordered by a solid line style. Line style is solid by default and can be changed with SETLINESTYLE.

Note: The PIE routine described here is a QuickWin routine. If you are trying to use the Win32 SDK version of the Pie routine by including the DFWIN module, you need to specify the routine name as MSFWIN$Pie. For more information, see Special Naming Convention for Certain QuickWin and Win32 Graphics Routines in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETCOLORRGB, SETFILLMASK, SETLINESTYLE, FLOODFILLRGB, GETARCINFO, ARC, ELLIPSE, GRSTATUS, LINETO, POLYGON, RECTANGLE

Example

 ! build as Graphics App.
 USE DFLIB
 INTEGER(2) status, dummy
 INTEGER(2) x1, y1, x2, y2, x3, y3, x4, y4
 x1 = 80; y1 = 50
 x2 = 180; y2 = 150
 x3 = 110; y3 = 80
 x4 = 90; y4 = 180

 status = SETCOLOR(INT2(4))
 dummy = PIE( $GFILLINTERIOR, x1, y1, x2, y2, &
                              x3, y3, x4, y4)
 END

Figure: Coordinates Used to Define PIE and PIE_W


POINTER - Fortran 90

POINTER - Fortran 95/90

Statement and Attribute: Specifies that an object is a pointer (a dynamic variable). A pointer does not contain data, but points to a scalar or array variable where data is stored. A pointer has no initial storage set aside for it; memory storage is created for the pointer as a program runs.

The POINTER attribute can be specified in a type declaration statement or a POINTER statement, and takes one of the following forms:

Syntax

Type Declaration Statement:

type, [att-ls,] POINTER [, att-ls] :: ptr [(d-spec)] [, ptr [(d-spec)]] ...

Statement:

POINTER [::] ptr [(d-spec)] [, ptr [(d-spec)]] ...

type-spec
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

ptr
Is the name of the pointer. The pointer cannot be declared with the INTENT or PARAMETER attributes.

d-spec
(Optional) Is a deferred-shape specification (: [, :] ...). Each colon represents a dimension of the array.

Rules and Behavior

No storage space is created for a pointer until it is allocated with an ALLOCATE statement or until it is assigned to a allocated target. A pointer must not be referenced or defined until memory is associated with it.

Each pointer has an association status, which tells whether the pointer is currently associated with a target object. When a pointer is initially declared, its status is undefined. You can use the ASSOCIATED intrinsic function to find the association status of a pointer.

If the pointer is an array, and it is given the DIMENSION attribute elsewhere in the program, it must be declared as a deferred-shape array.

A pointer cannot be specified in a DATA, EQUIVALENCE, or NAMELIST statement.

Fortran 90 pointers are not the same as integer pointers. For more information, see the POINTER - Compaq Fortran statement.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ALLOCATE, ASSOCIATED, DEALLOCATE, NULLIFY, TARGET, Deferred-Shape Arrays, Pointer Assignments, Pointer Association, Pointer Arguments, NULL, Compaq Fortran POINTER statement, Type Declarations, Compatible attributes

Examples

The following example shows type declaration statements specifying the POINTER attribute:

  TYPE(SYSTEM), POINTER :: CURRENT, LAST
  REAL, DIMENSION(:,:), POINTER :: I, J, REVERSE

The following is an example of the POINTER statement:

  TYPE(SYSTEM) :: TODAYS
  POINTER :: TODAYS, A(:,:)

See also the examples POINTER.F90 and POINTER2.F90 in /DF98/SAMPLES/TUTORIAL.

The following shows another example:

 REAL, POINTER :: arrow (:)
 REAL, ALLOCATABLE, TARGET :: bullseye (:,:)

 ! The following statement associates the pointer with an unused
 ! block of memory.

 ALLOCATE (arrow (1:8), STAT = ierr)
 IF (ierr.eq.0) WRITE (*,'(/1x,a)') 'ARROW allocated'
 arrow = 5.
 WRITE (*,'(1x,8f8.0/)') arrow
 ALLOCATE (bullseye (1:8,3), STAT = ierr)
 IF (ierr.eq.0) WRITE (*,*) 'BULLSEYE allocated'
 bullseye = 1.
 bullseye (1:8:2,2) = 10.
 WRITE (*,'(1x,8f8.0)') bullseye

 ! The following association breaks the association with the first
 ! target, which being unnamed and unassociated with other pointers,
 ! becomes lost. ARROW acquires a new shape.

 arrow => bullseye (2:7,2)
 WRITE (*,'(/1x,a)') 'ARROW is repointed & resized, all the 5s are lost'
 WRITE (*,'(1x,8f8.0)') arrow

 NULLIFY (arrow)
 IF (.NOT.ASSOCIATED(arrow)) WRITE (*,'(/a/)') ' ARROW is not pointed'

 DEALLOCATE (bullseye, STAT = ierr)
 IF (ierr.eq.0) WRITE (*,*) 'Deallocation successful.'
 END


POINTER - Compaq Fortran

Statement: Establishes pairs of variables and pointers, in which each pointer contains the address of its paired variable. This statement is different from the Fortran 95/90 POINTER statement.

Syntax

POINTER (pointer, pointee) [, (pointer, pointee)] . . .

pointer
Is a variable whose value is used as the address of the pointee.

pointee
Is a variable; it can be an array name or array specification.

Rules and Behavior

The following are pointer rules and behavior:

  • Two pointers can have the same value, so pointer aliasing is allowed.

  • When used directly, a pointer is treated like an integer variable. On ia32 systems, a pointer occupies one numeric storage unit, so it is a 32-bit quantity (INTEGER(4)). On Alpha and ia64 systems, a pointer occupies two numeric storage units, so it is a 64-bit quantity (INTEGER(8)).

  • A pointer cannot be a pointee.

  • A pointer cannot appear in an ASSIGN statement and cannot have the following attributes:

    ALLOCATABLE | INTRINSIC | POINTER
    EXTERNAL | PARAMETER | TARGET

    A pointer can appear in a DATA statement with integer literals only.

  • Integers can be converted to pointers, so you can point to absolute memory locations.

  • A pointer variable cannot be declared to have any other data type.

  • A pointer cannot be a function return value.

  • You can give values to pointers by doing the following:

    • Retrieve addresses by using the LOC intrinsic function (or the %LOC built-in function)

    • Allocate storage for an object by using the MALLOC intrinsic function (or by using malloc(3f) on Tru64 UNIX or Linux systems, or LIB$GET_VM on OpenVMS systems)

    For example:

    Using %LOC:                  Using MALLOC:

INTEGER I(10)                INTEGER I(10)
INTEGER I1(10) /10*10/       POINTER (P,I)
POINTER (P,I)                P = MALLOC(40)
P = %LOC(I1)                 I(2) = I(2) + 1
I(2) = I(2) + 1
  • The value in a pointer is used as the pointee's base address.

The following are pointee rules and behavior:

  • A pointee is not allocated any storage. References to a pointee look to the current contents of its associated pointer to find the pointee's base address.

  • A pointee cannot be data-initialized or have a record structure that contains data-initialized fields.

  • A pointee can appear in only one (Compaq Fortran) POINTER statement.

  • A pointee array can have fixed, adjustable, or assumed dimensions.

  • A pointee cannot appear in a COMMON, DATA, EQUIVALENCE, or NAMELIST statement, and it cannot have the following attributes:

    ALLOCATABLE | OPTIONAL | SAVE
    AUTOMATIC | PARAMETER | STATIC
    INTENT | POINTER | TARGET

  • A pointee cannot be:

    • A dummy argument
    • A function return value
    • A record field or an array element
    • Zero-sized
    • An automatic object
    • The name of a generic interface block

  • If a pointee is of derived type, it must be of sequence type.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LOC, MALLOC, FREE

Example

 POINTER (p, k)
 INTEGER j(2)

 ! This has the same effect as j(1) = 0, j(2) = 5
 p = LOC(j)
 k = 0
 p = p + SIZEOF(k) ! 4 for 4-byte integer
 k = 5


POLYBEZIER, POLYBEZIER_W

Graphics Function: Draws one or more Bezier curves.

Module: USE DFLIB

Syntax

result = POLYBEZIER (ppoints, cpoints)
result = POLYBEZIER_W (wppoints, cpoints)

ppoints
(Input) Derived type xycoord. Array of derived types defining the endpoints and the control points for each Bezier curve. The derived type xycoord is defined in DFLIB.F90 as follows:
 TYPE xycoord
   INTEGER(2) xcoord
   INTEGER(2) ycoord
 END TYPE xycoord
cpoints
(Input) INTEGER(2). Number of points in ppoints or wppoints.

wppoints
(Input) Derived type wxycoord. Array of derived types defining the endpoints and the control points for each Bezier curve. The derived type wxycoord is defined in DFLIB.F90 as follows:
 TYPE wxycoord
   REAL(8) wx
   REAL(8) wy
 END TYPE wxycoord

Results:

The result is of type INTEGER(2). The result is nonzero if anything is drawn; otherwise, 0.

A Bezier curve is based on fitting a cubic curve to four points. The first point is the starting point, the next two points are control points, and last point is the ending point. The starting point must be given for the first curve; subsequent curves use the ending point of the previous curve as their starting point. So, cpoints should contain 4 for one curve, 7 for 2 curves, 10 for 3 curves, and so forth.

POLYBEZIER does not use or change the current graphics position.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: POLYBEZIERTO, POLYBEZIERTO_W

Example

Program Bezier
use dflib

!Shows how to use POLYBEZIER, POLYBEZIER_W,
!POLYBEZIERTO, and POLYBEZIERTO_W,

TYPE(xycoord)  lppoints(31)
TYPE(wxycoord) wlppoints(31)
TYPE(xycoord)  xy
TYPE(wxycoord) wxy

integer(4) i
integer(2) istat, orgx, orgy
real(8) worgx, worgy

i = setcolorrgb(#00FFFFFF) ! graphic to black
i = settextcolorrgb(#00FFFFFF) ! text to black
i = setbkcolorrgb(#00000000) ! background to white
call clearscreen($GCLEARSCREEN)

orgx = 20
orgy = 20

lppoints(1).xcoord = 1+orgx
lppoints(1).ycoord = 1+orgy

lppoints(2).xcoord = 30+orgx
lppoints(2).ycoord = 120+orgy

lppoints(3).xcoord = 150+orgx
lppoints(3).ycoord = 60+orgy

lppoints(4).xcoord = 180+orgx
lppoints(4).ycoord = 180+orgy

istat = PolyBezier(lppoints, 4)

!Show tangent lines
!A bezier curve is tangent to the line
!from the begin point to the first control
!point.   It is also tangent to the line from
!the second control point to the end point.
do i = 1,4,2
call moveto(lppoints(i).xcoord,lppoints(i).ycoord,xy)
istat = lineto(lppoints(i+1).xcoord,lppoints(i+1).ycoord)
end do

read(*,*)

worgx = 50.0
worgy = 50.0

wlppoints(1).wx = 1.0+worgx
wlppoints(1).wy = 1.0+worgy

wlppoints(2).wx = 30.0+worgx
wlppoints(2).wy = 120.0+worgy

wlppoints(3).wx = 150.0+worgx
wlppoints(3).wy = 60.0+worgy

wlppoints(4).wx = 180.0+worgx
wlppoints(4).wy = 180.0+worgy

i = setcolorrgb(#000000FF) ! graphic to red
istat = PolyBezier_W(wlppoints, 4)

!Show tangent lines
!A bezier curve is tangent to the line
!from the begin point to the first control
!point.   It is also tangent to the line from
!the second control point to the end point.
do i = 1,4,2
call moveto_w(wlppoints(i).wx,wlppoints(i).wy,wxy)
istat = lineto_w(wlppoints(i+1).wx,wlppoints(i+1).wy)
end do

read(*,*)

orgx = 80
orgy = 80

! POLYBEZIERTO uses the current graphics position
! as its initial starting point so we start the
! array with the first first control point.

!lppoints(1).xcoord = 1+orgx ! need to move to this
!lppoints(1).ycoord = 1+orgy

lppoints(1).xcoord = 30+orgx
lppoints(1).ycoord = 120+orgy

lppoints(2).xcoord = 150+orgx
lppoints(2).ycoord = 60+orgy

lppoints(3).xcoord = 180+orgx
lppoints(3).ycoord = 180+orgy

i = setcolorrgb(#0000FF00) ! graphic to green
call moveto(1+orgx,1+orgy,xy)
istat = PolyBezierTo(lppoints, 3)

!Show tangent lines
!A bezier curve is tangent to the line
!from the begin point to the first control
!point.   It is also tangent to the line from
!the second control point to the end point.
call moveto(1+orgx,1+orgy,xy)
istat = lineto(lppoints(1).xcoord,lppoints(1).ycoord)
call moveto(lppoints(2).xcoord,lppoints(2).ycoord,xy)
istat = lineto(lppoints(3).xcoord,lppoints(3).ycoord)

read(*,*)

worgx = 110.0
worgy = 110.0

!wlppoints(1).wx = 1.0+worgx
!wlppoints(1).wy = 1.0+worgy

wlppoints(1).wx = 30.0+worgx
wlppoints(1).wy = 120.0+worgy

wlppoints(2).wx = 150.0+worgx
wlppoints(2).wy = 60.0+worgy

wlppoints(3).wx = 180.0+worgx
wlppoints(3).wy = 180.0+worgy

call moveto_w(1.0+worgx,1.0+worgy,wxy)
i = setcolorrgb(#00FF0000) ! graphic to blue
istat = PolyBezierTo_W(wlppoints, 3)

!Show tangent lines
!A bezier curve is tangent to the line
!from the begin point to the first control
!point.   It is also tangent to the line from
!the second control point to the end point.
call moveto_w(1.0+worgx,1.0+worgy,wxy)
istat = lineto_w(wlppoints(1).wx,wlppoints(1).wy)
call moveto_w(wlppoints(2).wx,wlppoints(2).wy,wxy)
istat = lineto_w(wlppoints(3).wx,wlppoints(3).wy)

read(*,*)

END PROGRAM Bezier


POLYBEZIERTO, POLYBEZIERTO_W

Graphics Function: Draws one or more Bezier curves.

Module: USE DFLIB

Syntax

result = POLYBEZIERTO (ppoints, cpoints)
result = POLYBEZIERTO_W (wppoints, cpoints)

ppoints
(Input) Derived type xycoord. Array of derived types defining the endpoints and the control points for each Bezier curve. The derived type xycoord is defined in DFLIB.F90 as follows:
 TYPE xycoord
   INTEGER(2) xcoord
   INTEGER(2) ycoord
 END TYPE xycoord
cpoints
(Input) INTEGER(2). Number of points in ppoints or wppoints.

wppoints
(Input) Derived type wxycoord. Array of derived types defining the endpoints and the control points for each Bezier curve. The derived type wxycoord is defined in DFLIB.F90 as follows:
 TYPE wxycoord
   REAL(8) wx
   REAL(8) wy
 END TYPE wxycoord

Results:

The result is of type INTEGER(2). The result is nonzero if anything is drawn; otherwise, 0.

A Bezier curve is based on fitting a cubic curve to four points. The first point is the starting point, the next two points are control points, and last point is the ending point. The starting point is the current graphics position as set by MOVETO for the first curve; subsequent curves use the ending point of the previous curve as their starting point. So, cpoints should contain 3 for one curve, 6 for 2 curves, 9 for 3 curves, and so forth.

POLYBEZIERTO moves the current graphics position to the ending point of the last curve drawn.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: POLYBEZIER, POLYBEZIER_W, MOVETO, MOVETO_W

Example

Program Bezier
use dflib

!Shows how to use POLYBEZIER, POLYBEZIER_W,
!POLYBEZIERTO, and POLYBEZIERTO_W,

TYPE(xycoord)  lppoints(31)
TYPE(wxycoord) wlppoints(31)
TYPE(xycoord)  xy
TYPE(wxycoord) wxy

integer(4) i
integer(2) istat, orgx, orgy
real(8) worgx, worgy

i = setcolorrgb(#00FFFFFF) ! graphic to black
i = settextcolorrgb(#00FFFFFF) ! text to black
i = setbkcolorrgb(#00000000) ! background to white
call clearscreen($GCLEARSCREEN)

orgx = 20
orgy = 20

lppoints(1).xcoord = 1+orgx
lppoints(1).ycoord = 1+orgy

lppoints(2).xcoord = 30+orgx
lppoints(2).ycoord = 120+orgy

lppoints(3).xcoord = 150+orgx
lppoints(3).ycoord = 60+orgy

lppoints(4).xcoord = 180+orgx
lppoints(4).ycoord = 180+orgy

istat = PolyBezier(lppoints, 4)

!Show tangent lines
!A bezier curve is tangent to the line
!from the begin point to the first control
!point.   It is also tangent to the line from
!the second control point to the end point.
do i = 1,4,2
call moveto(lppoints(i).xcoord,lppoints(i).ycoord,xy)
istat = lineto(lppoints(i+1).xcoord,lppoints(i+1).ycoord)
end do

read(*,*)

worgx = 50.0
worgy = 50.0

wlppoints(1).wx = 1.0+worgx
wlppoints(1).wy = 1.0+worgy

wlppoints(2).wx = 30.0+worgx
wlppoints(2).wy = 120.0+worgy

wlppoints(3).wx = 150.0+worgx
wlppoints(3).wy = 60.0+worgy

wlppoints(4).wx = 180.0+worgx
wlppoints(4).wy = 180.0+worgy

i = setcolorrgb(#000000FF) ! graphic to red
istat = PolyBezier_W(wlppoints, 4)

!Show tangent lines
!A bezier curve is tangent to the line
!from the begin point to the first control
!point.   It is also tangent to the line from
!the second control point to the end point.
do i = 1,4,2
call moveto_w(wlppoints(i).wx,wlppoints(i).wy,wxy)
istat = lineto_w(wlppoints(i+1).wx,wlppoints(i+1).wy)
end do

read(*,*)

orgx = 80
orgy = 80

! POLYBEZIERTO uses the current graphics position
! as its initial starting point so we start the
! array with the first first control point.

!lppoints(1).xcoord = 1+orgx ! need to move to this
!lppoints(1).ycoord = 1+orgy

lppoints(1).xcoord = 30+orgx
lppoints(1).ycoord = 120+orgy

lppoints(2).xcoord = 150+orgx
lppoints(2).ycoord = 60+orgy

lppoints(3).xcoord = 180+orgx
lppoints(3).ycoord = 180+orgy

i = setcolorrgb(#0000FF00) ! graphic to green
call moveto(1+orgx,1+orgy,xy)
istat = PolyBezierTo(lppoints, 3)

!Show tangent lines
!A bezier curve is tangent to the line
!from the begin point to the first control
!point.   It is also tangent to the line from
!the second control point to the end point.
call moveto(1+orgx,1+orgy,xy)
istat = lineto(lppoints(1).xcoord,lppoints(1).ycoord)
call moveto(lppoints(2).xcoord,lppoints(2).ycoord,xy)
istat = lineto(lppoints(3).xcoord,lppoints(3).ycoord)

read(*,*)

worgx = 110.0
worgy = 110.0

!wlppoints(1).wx = 1.0+worgx
!wlppoints(1).wy = 1.0+worgy

wlppoints(1).wx = 30.0+worgx
wlppoints(1).wy = 120.0+worgy

wlppoints(2).wx = 150.0+worgx
wlppoints(2).wy = 60.0+worgy

wlppoints(3).wx = 180.0+worgx
wlppoints(3).wy = 180.0+worgy

call moveto_w(1.0+worgx,1.0+worgy,wxy)
i = setcolorrgb(#00FF0000) ! graphic to blue
istat = PolyBezierTo_W(wlppoints, 3)

!Show tangent lines
!A bezier curve is tangent to the line
!from the begin point to the first control
!point.   It is also tangent to the line from
!the second control point to the end point.
call moveto_w(1.0+worgx,1.0+worgy,wxy)
istat = lineto_w(wlppoints(1).wx,wlppoints(1).wy)
call moveto_w(wlppoints(2).wx,wlppoints(2).wy,wxy)
istat = lineto_w(wlppoints(3).wx,wlppoints(3).wy)

read(*,*)

END PROGRAM Bezier


POLYGON, POLYGON_W

Graphics Function: Draws a polygon using the current graphics color, logical write mode, and line style.

Module: USE DFLIB

Syntax

result = POLYGON (control, ppoints, cpoints)
result = POLYGON_W (control, wppoints, cpoints)

control
(Input) INTEGER(2). Fill flag. One of the following symbolic constants (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory):

  • $GFILLINTERIOR - Draws a solid polygon using the current color and fill mask.
  • $GBORDER - Draws the border of a polygon using the current color and line style.

ppoints
(Input) Derived type xycoord. Array of derived types defining the polygon vertices in viewport coordinates. The derived type xycoord is defined in DFLIB.F90 as follows:
 TYPE xycoord
   INTEGER(2) xcoord
   INTEGER(2) ycoord
 END TYPE xycoord
cpoints
(Input) INTEGER(2). Number of polygon vertices.

wppoints
(Input) Derived type wxycoord. Array of derived types defining the polygon vertices in window coordinates. The derived type wxycoord is defined in DFLIB.F90 as follows:
 TYPE wxycoord
   REAL(8) wx
   REAL(8) wy
 END TYPE wxycoord

Results:

The result is of type INTEGER(2). The result is nonzero if anything is drawn; otherwise, 0.

The border of the polygon is drawn in the current graphics color, logical write mode, and line style, set with SETCOLORRGB, SETWRITEMODE, and SETLINESTYLE, respectively. The POLYGON routine uses the viewport-coordinate system (expressed in xycoord derived types), and the POLYGON_W routine uses real-valued window coordinates (expressed in wxycoord types).

The arguments ppoints and wppoints are arrays whose elements are xycoord or wxycoord derived types. Each element specifies one of the polygon's vertices. The argument cpoints is the number of elements (the number of vertices) in the ppoints or wppoints array.

Note that POLYGON draws between the vertices in their order in the array. Therefore, when drawing outlines, skeletal figures, or any other figure that is not filled, you need to be careful about the order of the vertices. If you don't want lines between some vertices, you may need to repeat vertices to make the drawing backtrack and go to another vertex to avoid drawing across your figure. Also, POLYGON draws a line from the last specified vertex back to the first vertex.

If you fill the polygon using FLOODFILLRGB, the polygon must be bordered by a solid line style. Line style is solid by default and can be changed with SETLINESTYLE.

Note: The POLYGON routine described here is a QuickWin routine. If you are trying to use the Win32 SDK version of the Polygon routine by including the DFWIN module, you need to specify the routine name as MSFWIN$Polygon. For more information, see Special Naming Convention for Certain QuickWin and Win32 Graphics Routines in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETCOLORRGB, SETFILLMASK, SETLINESTYLE, FLOODFILLRGB, GRSTATUS, LINETO, RECTANGLE, SETWRITEMODE

Example

! Build as a Graphics App.
 !
 ! Draw a skeletal box
     USE DFLIB

     INTEGER(2) status
     TYPE (xycoord) poly(12)

 ! Set up box vertices in order they will be drawn, &
 ! repeating some to avoid unwanted lines across box

     poly(1)%xcoord = 50
     poly(1)%ycoord = 80
     poly(2)%xcoord = 85
     poly(2)%ycoord = 35
     poly(3)%xcoord = 185
     poly(3)%ycoord = 35
     poly(4)%xcoord = 150
     poly(4)%ycoord = 80
     poly(5)%xcoord = 50
     poly(5)%ycoord = 80
     poly(6)%xcoord = 50
     poly(6)%ycoord = 180
     poly(7)%xcoord = 150
     poly(7)%ycoord = 180
     poly(8)%xcoord = 185
     poly(8)%ycoord = 135
     poly(9)%xcoord = 185
     poly(9)%ycoord = 35
     poly(10)%xcoord = 150
     poly(10)%ycoord = 80
     poly(11)%xcoord = 150
     poly(11)%ycoord = 180
     poly(12)%xcoord = 150
     poly(12)%ycoord = 80

     status = SETCOLORRGB(#0000FF)
     status = POLYGON($GBORDER, poly, INT2(12))
     END


POLYLINEQQ

Graphics Function: Draws a line between each sucessive x, y point in a given array.

Module: USE DFLIB

Syntax

result = POLYLINEQQ (points, cnt)

points
(Input) An array of DF_POINT objects. The derived type DF_POINT is defined in DFLIB.F90 as:
type DF_POINT
  sequence
  integer(4) x
  integer(4) y
end type DF_POINT
cnt
(Input) INTEGER(4). Number of elements in the points array. On Windows 9* systems, cnt must be less than or equal to 16383. This is a limitation of the operating system.

Results:

The result is of type INTEGER(4). The result is a nonzero value if successful; otherwise, zero.

POLYLINEQQ uses the viewport-coordinate system.

The lines are drawn using the current graphics color, logical write mode, and line style. The graphics color is set with SETCOLORRGB, the write mode with SETWRITEMODE, and the line style with SETLINESTYLE.

The current graphics position is not used or changed as it is in the LINETO function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS

See Also: LINETO, LINETOAREX, SETCOLORRGB, SETLINESTYLE, SETWRITEMODE

Example

  ! Build for QuickWin or Standard Graphics
  USE DFLIB
  TYPE(DF_POINT) points(12)
  integer(4) result
  integer(4) cnt, i
  ! load the points
  do i = 1,12,2
    points(i).x =20*i
    points(i).y =10
    points(i+1).x =20*i
    points(i+1).y =60
  end do
  ! A sawtooth pattern will appear in the upper left corner
  result = POLYLINEQQ(points, 12)
  end


POPCNT

Elemental Intrinsic Function (Generic): Returns the number of 1 bits in an integer.

Syntax

result = POPCNT (i)

i
Integer.

Results:

The result type is the same as i. The result value is the number of 1 bits in the binary representation of the integer i.

The model for the interpretation of an integer value as a sequence of bits is shown in Model for Bit Data.

Example

If the value of I is B'0...00011010110', the value of POPCNT(I) is 5.


POPPAR

Elemental Intrinsic Function (Generic): Returns the parity of an integer.

Syntax

result = POPPAR (i)

i
Integer.

Results:

The result type is the same as i. If there are an odd number of 1 bits in the binary representation of the integer I, the result value is 1. If there are an even number, the result value is zero.

The model for the interpretation of an integer value as a sequence of bits is shown in Model for Bit Data.

Example

If the value of I is B'0...00011010110', the value of POPPAR(I) is 1.


PRECISION

Inquiry Intrinsic Function (Generic): Returns the decimal precision in the model representing real numbers with the same kind parameter as the argument.

Syntax

result = PRECISION (x)

x
(Input) Must be of type real or complex. It can be scalar or array valued.

Results:

The result is a scalar of type default integer. The result has the value INT((DIGITS(x) - 1) * LOG10(RADIX(x))). If RADIX(x) is an integral power of 10, 1 is added to the result.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

If X is a REAL(4) value, PRECISION(X) has the value 6. The value 6 is derived from INT ((24-1) * LOG10 (2.)) = INT (6.92...). For more information on the model for REAL(4), see Model for Real Data.


PRESENT

Inquiry Intrinsic Function (Generic): Returns whether or not an optional dummy argument is present (has an associated actual argument).

Syntax

result = PRESENT (a)

a
(Input) Must be an optional argument of the current procedure.

Results:

The result is a scalar of type default logical. The result is .TRUE. if a is present; otherwise, the result is .FALSE..

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: OPTIONAL

Examples

Consider the following:

SUBROUTINE CHECK (X, Y)
  REAL X, Z
  REAL, OPTIONAL :: Y
  ...
  IF (PRESENT (Y)) THEN
    Z = Y
  ELSE
     Z = X * 2
  END IF
END
...
CALL CHECK (15.0, 12.0)      ! Causes B to be set to 12.0
CALL CHECK (15.0)            ! Causes B to be set to 30.0

The following shows another example:

 CALL who( 1, 2 ) ! prints "A present" "B present"
 CALL who( 1 ) ! prints "A present"
 CALL who( b = 2 ) ! prints "B present"
 CALL who( ) ! prints nothing
 CONTAINS
   SUBROUTINE who( a, b )
     INTEGER(4), OPTIONAL :: a, b
     IF (PRESENT(a)) PRINT *,'A present'
     IF (PRESENT(b)) PRINT *,'B present'
   END SUBROUTINE who
 END


PRINT

Statement: Displays output on the screen. TYPE is a synonym for PRINT. All forms and rules for the PRINT statement also apply to the TYPE statement.

The PRINT statement is the same as a formatted, sequential WRITE statement, except that the PRINT statement must never transfer data to user-specified I/O units.

A PRINT statement takes one of the following forms:

Syntax

Formatted:

PRINT form [, io-list]

Formatted - List-Directed:

PRINT * [, io-list]

Formatted - Namelist:

PRINT nml

form
Is the nonkeyword form of a format specifier (no FMT=).

io-list
Is an I/O list.

*
Is the format specifier indicating list-directed formatting.

nml
Is the nonkeyword form of a namelist specifier (no NML=) indicating namelist formatting.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: PUTC, READ, WRITE, FORMAT, Data Transfer I/O Statements, File Operation I/O Statements

Examples

In the following example, one record (containing four fields of data) is printed to the implicit output device:

      CHARACTER*16 NAME, JOB
      PRINT 400, NAME, JOB
400   FORMAT ('NAME=', A, 'JOB=', A)

The following shows another example:

!   The following statements are equivalent:
    PRINT     '(A11)', 'Abbottsford'
    WRITE (*, '(A11)') 'Abbottsford'
    TYPE      '(A11)', 'Abbottsford'


PRIVATE

Statement and Attribute: Specifies that entities in a module can be accessed only within the module itself.

The PRIVATE attribute can be specified in a type declaration statement or a PRIVATE statement, and takes one of the following forms:

Syntax

Type Declaration Statement:

type, [att-ls,] PRIVATE [, att-ls] :: entity [, entity] ...

Statement:

PRIVATE [[::] entity [, entity] ...]

type
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

entity
Is one of the following:

  • A variable name
  • A procedure name
  • A derived type name
  • A named constant
  • A namelist group name

In statement form, an entity can also be a generic identifier (a generic name, defined operator, or defined assignment).

Rules and Behavior

The PRIVATE attribute can only appear in the scoping unit of a module.

Only one PRIVATE statement without an entity list is permitted in the scoping unit of a module; it sets the default accessibility of all entities in the module.

If no PRIVATE statements are specified in a module, the default is PUBLIC accessibility. Entities with PUBLIC accessibility can be accessed from outside the module by means of a USE statement.

If a derived type is declared PRIVATE in a module, its components are also PRIVATE. The derived type and its components are accessible to any subprograms within the defining module through host association, but they are not accessible from outside the module.

If the derived type is declared PUBLIC in a module, but its components are declared PRIVATE, any scoping unit accessing the module though use association (or host association) can access the derived-type definition, but not its components.

If a module procedure has a dummy argument or a function result of a type that has PRIVATE accessibility, the module procedure must have PRIVATE accessibility. If the module has a generic identifier, it must also be declared PRIVATE.

If a procedure has a generic identifier, the accessibility of the procedure's specific name is independent of the accessibility of its generic identifier. One can be declared PRIVATE and the other PUBLIC.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: MODULE, PUBLIC, TYPE, Defining Generic Names for Procedures, USE, Use and Host Association, Type Declarations, Compatible attributes

Examples

The following examples show type declaration statements specifying the PUBLIC and PRIVATE attributes:

REAL,  PRIVATE  :: A, B, C
INTEGER, PUBLIC :: LOCAL_SUMS

The following is an example of the PUBLIC and PRIVATE statements:

MODULE SOME_DATA
  REAL ALL_B
  PUBLIC ALL_B
  TYPE RESTRICTED_DATA
    REAL LOCAL_C
    DIMENSION LOCAL_C(50)
  END TYPE RESTRICTED_DATA
  PRIVATE RESTRICTED_DATA
END MODULE

The following derived-type declaration statement indicates that the type is restricted to the module:

TYPE, PRIVATE  :: DATA
  ...
END TYPE DATA

The following example shows a PUBLIC type with PRIVATE components:

MODULE MATTER
  TYPE ELEMENTS
    PRIVATE
    INTEGER C, D
  END TYPE
...
END MODULE MATTER

In this case, components C and D are private to type ELEMENTS, but type ELEMENTS is not private to MODULE MATTER. Any program unit that uses the module MATTER, can declare variables of type ELEMENTS, and pass as arguments values of type ELEMENTS.

The following shows another example:

 !LENGTH in module VECTRLEN calculates the length of a 2-D vector.
 !The module contains both private and public procedures
    MODULE VECTRLEN
      PRIVATE SQUARE
      PUBLIC LENGTH
     CONTAINS
     SUBROUTINE LENGTH(x,y,z)
        REAL,INTENT(IN) x,y
        REAL,INTENT(OUT) z
        CALL SQUARE(x,y)
        z = SQRT(x + y)
        RETURN
     END SUBROUTINE
     SUBROUTINE SQUARE(x1,y1)
        REAL x1,y1
        x1 = x1**2
        y1 = y1**2
        RETURN
     END SUBROUTINE
    END MODULE


PRIVATE Clause (TU*X only)

Parallel Directive Clause: Declares specified variables to be private to each thread in a team.

Syntax

PRIVATE (list)

list
Is the name of one or more variables or common blocks that are accessible to the scoping unit. Subobjects cannot be specified. Each name must be separated by a comma, and a named common block must appear between slashes (/ /).

The following occurs when variables are declared in a PRIVATE clause:

  • A new object of the same type is declared once for each thread in the team. The new object is no longer storage associated with the original object.

  • All references to the original object in the lexical extent of the directive construct are replaced with references to the private object.

  • Variables defined as PRIVATE are undefined for each thread on entering the construct and the corresponding shared variable is undefined on exit from a parallel construct.

  • Contents, allocation state, and association status of variables defined as PRIVATE are undefined when they are referenced outside the lexical extent (but inside the dynamic extent) of the construct, unless they are passed as actual arguments to called routines.

For Compaq Fortran parallel directives, LOCAL is an alternative spelling for PRIVATE.


PROCESSORS_SHAPE

Inquiry Intrinsic Function (Specific): Returns the shape of an implementation-dependent hardware processor array.

This is a specific function that has no generic function associated with it. It must not be passed as an actual argument. It is provided for compatibility with High Performance Fortran.

Syntax

result = PROCESSORS_SHAPE( )

Results:

The result is a rank-one array of size zero.


PRODUCT

Transformational Intrinsic Function (Generic): Returns the product of all the elements in an entire array or in a specified dimension of an array.

Syntax

result = PRODUCT (array [, dim] [, mask])

array
(Input) Must be an array of type integer or real.

dim
(Optional; input) Must be a scalar integer with a value in the range 1 to n, where n is the rank of array.

mask
(Optional; input) Must be of type logical and conformable with array.

Results:

The result is an array or a scalar of the same data type as array.

The result is a scalar if dim is omitted or array has rank one.

The following rules apply if dim is omitted:

  • If PRODUCT(array) is specified, the result is the product of all elements of array. If array has size zero, the result is 1.

  • If PRODUCT(array, MASK=mask) is specified, the result is the product of all elements of array corresponding to true elements of mask. If array has size zero, or every element of mask has the value .FALSE., the result is 1.

The following rules apply if dim is specified:

  • If array has rank one, the value is the same as PRODUCT(array [,MASK=mask]).

  • An array result has a rank that is one less than array, and shape (d1, d2, ..., ddim-1, ddim+1, ..., dn), where (d1, d2, ..., dn) is the shape of array.

  • The value of element (s1, s2, ..., sdim-1, sdim+1, ..., sn) of PRODUCT(array, dim [,mask]) is equal to PRODUCT(array (s1, s2, ..., sdim-1, :, sdim+1, ..., sn) [,MASK=mask (s1, s2, ..., sdim-1, :, sdim+1, ..., sn)]).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SUM

Examples

PRODUCT ((/2, 3, 4/)) returns the value 24 (the product of 2 * 3 * 4). PRODUCT ((/2, 3, 4/), DIM=1) returns the same result.

PRODUCT (C, MASK=C .LT. 0.0) returns the product of the negative elements of C.

A is the array

  [ 1  4  7 ]
  [ 2  3  5 ].

PRODUCT (A, DIM=1) returns the value (2, 12, 35), which is the product of all elements in each column. 2 is the product of 1 * 2 in column 1. 12 is the product of 4 * 3 in column 2, and so forth.

PRODUCT (A, DIM=2) returns the value (28, 30), which is the product of all elements in each row. 28 is the product of 1 * 4 * 7 in row 1. 30 is the product of 2 * 3 * 5 in row 2.

If array has shape (2, 2, 2), mask is omitted, and dim is 1, the result is an array result with shape (2, 2) whose elements have the following values.

Resultant array element | Value
result(1, 1) | array(1, 1, 1) * array(2, 1, 1)
result(2, 1) | array(1, 2, 1) * array(2, 2, 1)
result(1, 2) | array(1, 1, 2) * array(2, 1, 2)
result(2, 2) | array(1, 2, 2) * array(2, 2, 2)

The following shows another example:

 INTEGER array (2, 3)
 INTEGER AR1(3), AR2(2)
 array = RESHAPE((/1, 4, 2, 5, 3, 6/),(/2,3/))
 ! array is  1 2 3
 !           4 5 6

 AR1 = PRODUCT(array, DIM = 1) ! returns [ 4 10 18 ]
 AR2 = PRODUCT(array, MASK = array .LT. 6, DIM = 2)
                                  ! returns [ 6 20 ]
 END


PROGRAM

Statement: Identifies the program unit as a main program and gives it a name.

Syntax

[PROGRAM name]
[specification-part]
[execution-part]
[CONTAINS
internal-subprogram-part]
END [PROGRAM [name]]

name
Is the name of the program.

specification-part
Is one or more specification statements, except for the following:

  • INTENT (or its equivalent attribute)
  • OPTIONAL (or its equivalent attribute)
  • PUBLIC and PRIVATE (or their equivalent attributes)

An automatic object must not appear in a specification statement. If a SAVE statement is specified, it has no effect.

execution-part
Is one or more executable constructs or statements, except for ENTRY or RETURN statements.

internal-subprogram-part
Is one or more internal subprograms (defining internal procedures). The internal-subprogram-part is preceded by a CONTAINS statement.

Rules and Behavior

The PROGRAM statement is optional. Within a program unit, a PROGRAM statement can be preceded only by comment lines or an OPTIONS statement.

The END statement is the only required part of a program. If a name follows the END statement, it must be the same as the name specified in the PROGRAM statement.

The program name is considered global and must be unique. It cannot be the same as any local name in the main program or the name of any other program unit, external procedure, or common block in the executable program.

A main program must not reference itself (either directly or indirectly).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Building Programs and Libraries

Examples

The following is an example of a main program:

PROGRAM TEST
  INTEGER C, D, E(20,20)     ! Specification part
  CALL SUB_1                 ! Executable part
...
CONTAINS
  SUBROUTINE SUB_1           ! Internal subprogram
  ...
  END SUBROUTINE SUB_1
END PROGRAM TEST

The following shows another example:

 PROGRAM MyProg
 PRINT *, 'hello world'
 END


PSECT

General Compiler Directive: Modifies several characteristics of a common block.

Syntax

c DEC$ PSECT /common-name/ a [, a] ...

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

common-name
Is the name of the common block. The slashes ( / ) are required.

a
Is one of the following:

  • ALIGN=val or ALIGN=keyword

    Specifies alignment for the common block.

    The val must be a constant ranging from 0 through 16 on OpenVMS systems, 0 through 6 on Windows systems, and 0 through 4 on Tru64 UNIX and Linux systems. The specified number is interpreted as a power of 2. The value of the expression is the alignment in bytes.

    The keyword is one of the following:

    Keyword | Equivalent to val
    BYTE | 0
    WORD | 1
    LONG | 2
    QUAD | 3
    OCTA | 4
    PAGE 1 Alpha: 16
    ia32: 12
    ia64: 13
    1 Range for Alpha is 0 to 16; for ia32 and ia64, 0 to 13.

  • GBL (VMS only)

    Specifies global scope.

  • LCL (VMS only)

    Specifies local scope. This keyword is opposite to GBL and cannot appear with it.

  • [NO]MULTILANGUAGE (VMS only)

    Controls whether the compiler pads the size of common blocks to ensure compatibility when the common block program section (psect) is shared by code created by other Compaq compilers.

    When a program section generated by a Fortran common block is overlaid with a program section consisting of a C structure, linker error messages can occur. This is because the sizes of the program sections are inconsistent; the C structure is padded, but the Fortran common block is not.

    Specifying MULTILANGUAGE ensures that Compaq Fortran follows a consistent program section size allocation scheme that works with Compaq C program sections shared across multiple images. Program sections shared in a single image do not have a problem.

    You can use a compiler option to specify MULTILANGUAGE for all common blocks in a module.

  • [NO]SHR (VMS only)

    Determines whether the contents of a common block can be shared by more than one process.

  • [NO]WRT

    Determines whether the contents of a common block can be modified during program execution.

Rules and Behavior

Global or local scope is significant for an image that has more than one cluster. Program sections with the same name that are from different modules in different clusters are placed in separate clusters if local scope is in effect. They are placed in the same cluster if global scope is in effect.

If one program unit changes one or more characteristics of a common block, all other units that reference that common block must also change those characteristics in the same way.

Default characteristics apply if you do not modify them with a PSECT directive. The following table shows the default characteristics of common blocks and how they can be modified by PSECT:

Default Characteristics | PSECT Modification
Relocatable | None
Overlaid | None
Global Scope | Global or local scope
Not executable | None
Not multilanguage | Multilanguage or not multilanguage
Writable | Writable or not writable
Readable | None
No protection | None
Octaword alignment 1 (4) | VMS: 0 through 16 2 WNT and W9*: 0 through 6 3 U*X: 0 through 4 3
On Alpha processors:
Not shareable | Shareable or not shareable
Position dependent | None
On ia32 processors:
Shareable | Shareable or not shareable
Position independent | None
1 An address that is an integral multiple of 16. 2 Or keywords BYTE through PAGE. 3 Or keywords BYTE through OCTA.

See Also: General Compiler Directives


PSECTIONS (TU*X only)

Compaq Fortran Parallel Compiler Directive: Specifies a block of code to be divided among threads in a team (a worksharing area). This is the same as the OpenMP Fortran API SECTIONS directive with the following exceptions:

  • No REDUCTION clause or LASTPRIVATE clause is permitted.

  • LOCAL is permitted as an alternative spelling for the PRIVATE clause.

See Also: Parallel Directives for Tru64 UNIX Systems, Compaq Fortran Parallel Compiler Directives (TU*X only), OpenMP Fortran API Compiler Directives (TU*X only)


PUBLIC

Statement and Attribute: Specifies that entities in a module can be accessed from outside the module (by specifying a USE statement).

The PUBLIC attribute can be specified in a type declaration statement or a PUBLIC statement, and takes one of the following forms:

Syntax

Type Declaration Statement:

type, [att-ls,] PUBLIC [, att-ls] :: entity [, entity] ...

Statement:

PUBLIC [[::] entity [, entity] ...]

type
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

entity
Is one of the following:

  • A variable name
  • A procedure name
  • A derived type name
  • A named constant
  • A namelist group name

In statement form, an entity can also be a generic identifier (a generic name, defined operator, or defined assignment).

Rules and Behavior

The PUBLIC attribute can only appear in the scoping unit of a module.

Only one PUBLIC statement without an entity list is permitted in the scoping unit of a module; it sets the default accessibility of all entities in the module.

If no PRIVATE statements are specified in a module, the default is PUBLIC accessibility.

If a derived type is declared PUBLIC in a module, but its components are declared PRIVATE, any scoping unit accessing the module though use association (or host association) can access the derived-type definition, but not its components.

If a module procedure has a dummy argument or a function result of a type that has PRIVATE accessibility, the module procedure must have PRIVATE accessibility. If the module has a generic identifier, it must also be declared PRIVATE.

If a procedure has a generic identifier, the accessibility of the procedure's specific name is independent of the accessibility of its generic identifier. One can be declared PRIVATE and the other PUBLIC.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: PRIVATE, MODULE, TYPE, Defining Generic Names for Procedures, USE, Use and Host Association, Type Declarations, Compatible attributes

Examples

The following examples show type declaration statements specifying the PUBLIC and PRIVATE attributes:

REAL,  PRIVATE  :: A, B, C
INTEGER, PUBLIC :: LOCAL_SUMS

The following is an example of the PUBLIC and PRIVATE statements:

MODULE SOME_DATA
  REAL ALL_B
  PUBLIC ALL_B
  TYPE RESTRICTED_DATA
    REAL LOCAL_C
    DIMENSION LOCAL_C(50)
  END TYPE RESTRICTED_DATA
  PRIVATE RESTRICTED_DATA
END MODULE

The following example shows a PUBLIC type with PRIVATE components:

MODULE MATTER
  TYPE ELEMENTS
    PRIVATE
    INTEGER C, D
  END TYPE
...
END MODULE MATTER

In this case, components C and D are private to type ELEMENTS, but type ELEMENTS is not private to MODULE MATTER. Any program unit that uses the module MATTER, can declare variables of type ELEMENTS, and pass as arguments values of type ELEMENTS.

The following shows another example:

 !LENGTH in module VECTRLEN calculates the length of a 2-D vector.
 !The module contains both private and public procedures
    MODULE VECTRLEN
      PRIVATE SQUARE
      PUBLIC LENGTH
     CONTAINS
     SUBROUTINE LENGTH(x,y,z)
        REAL,INTENT(IN) x,y
        REAL,INTENT(OUT) z
        CALL SQUARE(x,y)
        z = SQRT(x + y)
        RETURN
     END SUBROUTINE
     SUBROUTINE SQUARE(x1,y1)
        REAL x1,y1
        x1 = x1**2
        y1 = y1**2
        RETURN
     END SUBROUTINE
    END MODULE


PURE

Keyword: Asserts that a user-defined procedure has no side effects. This kind of procedure is specified by using the prefix PURE (or ELEMENTAL) in a FUNCTION or SUBROUTINE statement. Pure procedures are a Fortran 95 feature.

A pure procedure has no side effects. It has no effect on the state of the program, except for the following:

  • For functions: It returns a value.
  • For subroutines: It modifies INTENT(OUT) and INTENT(INOUT) parameters.

The following intrinsic and library procedures are implicitly pure:

  • All intrinsic functions
  • The elemental intrinsic subroutine MVBITS

A statement function is pure only if all functions that it references are pure.

Rules and Behavior

Except for procedure arguments and pointer arguments, the following intent must be specified for all dummy arguments in the specification part of the procedure:

  • For functions: INTENT(IN)
  • For subroutines: any INTENT (IN, OUT, or INOUT)

A local variable declared in a pure procedure (including variables declared in any internal procedure) must not:

  • Specify the SAVE attribute
  • Be initialized in a type declaration statement or a DATA statement

The following variables have restricted use in pure procedures (and any internal procedures):

  • Global variables
  • Dummy arguments with INTENT(IN) (or no declared intent)
  • Objects that are storage associated with any part of a global variable

They must not be used in any context that does either of the following:

  • Causes their value to change. For example, they must not be used as:

    • The left side of an assignment statement or pointer assignment statement
    • An actual argument associated with a dummy argument with INTENT(OUT), INTENT(INOUT), or the POINTER attribute
    • An index variable in a DO or FORALL statement, or an implied-do clause
    • The variable in an ASSIGN statement
    • An input item in a READ statement
    • An internal file unit in a WRITE statement
    • An object in an ALLOCATE, DEALLOCATE, or NULLIFY statement
    • An IOSTAT or SIZE specifier in an I/O statement, or the STAT specifier in a ALLOCATE or DEALLOCATE statement

  • Creates a pointer to that variable. For example, they must not be used as:

    • The target in a pointer assignment statement
    • The right side of an assignment to a derived-type variable (including a pointer to a derived type) if the derived type has a pointer component at any level

A pure procedure must not contain the following:

  • Any external I/O statement (including a READ or WRITE statement whose I/O unit is an external file unit number or *)
  • A PAUSE statement
  • A STOP statement

A pure procedure can be used in contexts where other procedures are restricted; for example:

  • It can be called directly in a FORALL statement or be used in the mask expression of a FORALL statement.
  • It can be called from a pure procedure. Pure procedures can only call other pure procedures.
  • It can be passed as an actual argument to a pure procedure.

If a procedure is used in any of these contexts, its interface must be explicit and it must be declared pure in that interface.

See Also: FUNCTION, SUBROUTINE, FORALL, ELEMENTAL prefix

Examples

Consider the following:

PURE FUNCTION DOUBLE(X)
  REAL, INTENT(IN) :: X
  DOUBLE = 2 * X
END FUNCTION DOUBLE

The following shows another example:

PURE INTEGER FUNCTION MANDELBROT(X)
  COMPLEX, INTENT(IN) :: X
  COMPLEX__:: XTMP
  INTEGER__:: K
  ! Assume SHARED_DEFS includes the declaration
  ! INTEGER ITOL
  USE SHARED_DEFS

  K = 0
  XTMP = -X
  DO WHILE (ABS(XTMP) < 2.0 .AND. K < ITOL)
    XTMP = XTMP**2 - X
    K = K + 1
  END DO
  ITER = K
END FUNCTION

The following shows the preceding function used in an interface block:

INTERFACE
  PURE INTEGER FUNCTION MANDELBROT(X)
    COMPLEX, INTENT(IN) :: X
  END FUNCTION MANDELBROT
END INTERFACE

The following shows a FORALL construct calling the MANDELBROT function to update all the elements of an array:

FORALL (I = 1:N, J = 1:M)
  A(I,J) = MANDELBROT(COMPLX((I-1)*1.0/(N-1), (J-1)*1.0/(M-1))
END FORALL


PUTC

Portability Function: Writes a character to Fortran external unit number 6.

Module: USE DFPORT

Syntax

result = PUTC (char)

char
(Input) Character. Character to be written to external unit 6.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, an error code.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETC, WRITE, PRINT, FPUTC, Portability Library

Example

 use dfport
 integer(4) i4
 character*1 char1
 do i = 1,26
   char1 = char(123-i)
   i4 = putc(char1)
   if (i4.ne.0) iflag = 1
 enddo


PUTIMAGE, PUTIMAGE_W

Graphics Subroutine: Transfers the image stored in memory to the screen.

Module USE DFLIB

Syntax

CALL PUTIMAGE (x, y, image, action)
CALL PUTIMAGE_W (wx, wy, image, action)

x, y
(Input) INTEGER(2). Viewport coordinates for upper-left corner of the image when placed on the screen.

wx, wy
(Input) REAL(8). Window coordinates for upper-left corner of the image when placed on the screen.

image
(Input) INTEGER(1). Array of single-byte integers. Stored image buffer.

action
(Input) INTEGER(2). Interaction of the stored image with the existing screen image. One of the following symbolic constants (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory):

  • $GAND - Forms a new screen display as the logical AND of the stored image and the existing screen display. Points that have the same color in both the existing screen image and the stored image remain the same color, while points that have different colors are joined by a logical AND.

  • $GOR - Superimposes the stored image onto the existing screen display. The resulting image is the logical OR of the image.

  • $GPRESET - Transfers the data point-by-point onto the screen. Each point has the inverse of the color attribute it had when it was taken from the screen by GETIMAGE, producing a negative image.

  • $GPSET - Transfers the data point-by-point onto the screen. Each point has the exact color attribute it had when it was taken from the screen by GETIMAGE.

  • $GXOR - Causes points in the existing screen image to be inverted wherever a point exists in the stored image. This behavior is like that of a cursor. If you perform an exclusive OR of an image with the background twice, the background is restored unchanged. This allows you to move an object around without erasing the background. The $GXOR constant is a special mode often used for animation.

  • In addition, the following ternary raster operation constants can be used (described in the online documentation for the Win32 API BitBlt):

    • $GSRCCOPY (same as $GPSET)
    • $GSRCPAINT (same as $GOR)
    • $GSRCAND (same as $GAND)
    • $GSRCINVERT (same as $GXOR)
    • $GSRCERASE
    • $GNOTSRCCOPY (same as $GPRESET)
    • $GNOTSRCERASE
    • $GMERGECOPY
    • $GMERGEPAINT
    • $GPATCOPY
    • $GPATPAINT
    • $GPATINVERT
    • $GDSTINVERT
    • $GBLACKNESS
    • $GWHITENESS

PUTIMAGE places the upper-left corner of the image at the viewport coordinates (x,y). PUTIMAGE_W places the upper-left corner of the image at the window coordinates (wx, wy).

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETIMAGE, GRSTATUS, IMAGESIZE

Example

 ! Build as a Graphics App.
 USE DFLIB
 INTEGER(1), ALLOCATABLE :: buffer(:)
 INTEGER(2) status, x
 INTEGER(4) imsize

 status = SETCOLOR(INT2(4))
 ! draw a circle
 status = ELLIPSE($GFILLINTERIOR,INT2(40),INT2(55),    &
                   INT2(70),INT2(85))
 imsize = IMAGESIZE (INT2(39),INT2(54),INT2(71), &
                   INT2(86))
 ALLOCATE (buffer(imsize))
 CALL GETIMAGE(INT2(39),INT2(54),INT2(71),INT2(86),    &
               buffer)
 ! copy a row of circles beneath it
 DO x = 5 , 395, 35
    CALL PUTIMAGE(x, INT2(90), buffer, $GPSET)
 END DO
 DEALLOCATE(buffer)
 END


QCMPLX (VMS, U*X)

Elemental Intrinsic Function (Generic): Converts the argument to COMPLEX(16) type. This function must not be passed as an actual argument.

Syntax

result = QCMPLX (x [, y])

x
(Input) Must be of type integer, real, or complex.

y
(Optional; input) Must be of type integer or real. It must not be present if x is of type complex.

Results:

The result type is COMPLEX(16) (or COMPLEX*32).

If only one noncomplex argument appears, it is converted into the real part of the result value and zero is assigned to the imaginary part. If y is not specified and x is complex, the result value is CMPLX (REAL(x), AIMAG(x)).

If two noncomplex arguments appear, the complex value is produced by converting the first argument into the real part of the value, and converting the second argument into the imaginary part.

QCMPLX(x, y) has the complex value whose real part is REAL(x, kind=16) and whose imaginary part is REAL(y, kind=16).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: CMPLX, DCMPLX, FLOAT, INT, IFIX, REAL, SNGL

Examples

QCMPLX (-3) has the value (-3.0Q0, 0.0Q0).

QCMPLX (4.1, 2.3) has the value (4.1Q0, 2.3Q0).


QEXT (VMS, U*X)

Elemental Intrinsic Function (Generic): Converts a number to quad precision (REAL(16)) type.

Syntax

result = QEXT (a)

a
(Input) Must be of type integer, real, or complex.

Results:

The result is of type REAL(16) (REAL*16). Functions that cause conversion of one data type to another type have the same effect as the implied conversion in assignment statements.

If a is of type REAL(16), the result is the value of the a with no conversion (QEXT(a) = a).

If a is of type integer or real, the result has as much precision of the significant part of a as a REAL(16) value can contain.

If a is of type complex, the result has as much precision of the significant part of the real part of a as a REAL(16) value can contain.

Specific Name 1 | Argument Type | Result Type
 | INTEGER(1) | REAL(16)
 | INTEGER(2) | REAL(16)
 | INTEGER(4) | REAL(16)
 | INTEGER(8) | REAL(16)
QEXT | REAL(4) | REAL(16)
QEXTD | REAL(8) | REAL(16)
 | REAL(16) | REAL(16)
 | COMPLEX(4) | REAL(16)
 | COMPLEX(8) | REAL(16)
 | COMPLEX(16) | REAL(16)
1 These specific functions cannot be passed as actual arguments.

Examples

QEXT (4) has the value 4.0 (rounded; there are 32 places to the right of the decimal point).

QEXT ((3.4, 2.0)) has the value 3.4 (rounded; there are 32 places to the right of the decimal point).


QFLOAT (VMS, U*X)

Elemental Intrinsic Function (Generic): Converts an integer to quad precision (REAL(16)) type.

Syntax

result = QFLOAT (a)

a
(Input) Must be of type integer.

Results:

The result is of type REAL(16) (REAL*16).

Functions that cause conversion of one data type to another type have the same affect as the implied conversion in assignment statements.

Examples

QFLOAT (-4) has the value -4.0 (rounded; there are 32 places to the right of the decimal point).


QREAL (VMS, U*X)

Elemental Intrinsic Function (Specific): Converts the real part of a COMPLEX(16) argument to REAL(16) type. This is a specific function that has no generic function associated with it. It must not be passed as an actual argument.

Syntax

result = QREAL (a)

a
(Input) Must be of type COMPLEX(16) (or COMPLEX*32).

Results:

The result type is double precision real (REAL(16) or REAL*16).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: REAL, DREAL

Examples

QREAL ((2.0q0, 3.0q0)) has the value 2.0q0.


QSORT

Portability Subroutine: Performs a quick sort on an array of rank one.

Module: USE DFPORT

Syntax

CALL QSORT (array, len, isize, compar)

array
(Input) Any type. One-dimensional array to be sorted.
If the data type does not conform to one of the predefined interfaces for QSORT, you may have to create a new interface (see below).

len
(Input) INTEGER(4). Number of elements in array.

isize
(Input) INTEGER(4). Size, in bytes, of a single element of array:

  • 4 if array is of type REAL(4)
  • 8 if array is REAL(8) or complex
  • 16 if array is COMPLEX(8)

compar
(Input) INTEGER(2). Name of a user-defined ordering function that determines sort order. The type declaration of compar takes the form:

INTEGER(2) FUNCTION compar(arg1, arg2)

where arg1 and arg2 have the same type as array. Once you have created an ordering scheme, implement your sorting function so that it returns the following:

  • Negative if arg1 should precede arg2
  • Zero if arg1 is equivalent to arg2
  • Positive if arg1 should follow arg2

Dummy argument compar must be declared as external.

If you use QSORT with different data types, your program must have a USE DFPORT statement in order for all the calls to work correctly. In addition, if you wish to use QSORT with a derived type or a type that is not in the predefined interfaces, you must include an overload for the generic subroutine QSORT. Examples of how to do this are in the portability module's source file, DFPORT.F90, located in your \DF98\INCLUDE subdirectory.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

 PROGRAM SORTQ
    USE DFPORT
    integer(2), external :: cmp_function
    integer(2) insort(26), i
    integer (4) array_len, array_size
    array_len = 26
    array_size = 2
    do i=90,65,-1
      insort(i-64)=91 - i
    end do
    print *, "Before: "
    print *,insort
    CALL qsort(insort,array_len,array_size,cmp_function)
    print *, 'After: '
    print *, insort
 END
 !
    integer(2) function cmp_function(a1, a2)
    integer(2) a1, a2
    cmp_function=a1-a2
    end function


RADIX

Inquiry Intrinsic Function (Generic): Returns the base of the model representing numbers of the same type and kind as the argument.

Syntax

result = RADIX (x)

x
(Input) Must be of type integer or real; it can be scalar or array valued.

Results:

The result is a scalar of type default integer. For an integer argument, the result has the value r (as defined in Model for Integer Data). For a real argument, the result has the value b (as defined in Model for Real Data).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DIGITS, EXPONENT, FRACTION, Data Representation Models

Example

If X is a REAL(4) value, RADIX (X) has the value 2.


RAISEQQ

Run-Time Function: Sends a signal to the executing program.

Module: USE DFLIB

Syntax

result = RAISEQQ (sig)

sig
(Input) INTEGER(4). Signal to raise. One of the following constants (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory):

  • SIG$ABORT - Abnormal termination
  • SIG$FPE - Floating-point error
  • SIG$ILL - Illegal instruction
  • SIG$INT - CTRL+C signal
  • SIG$SEGV - Illegal storage access
  • SIG$TERM - Termination request

If you do not install a signal handler (with SIGNALQQ, for example), when a signal occurs the system by default terminates the program with exit code 3.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, nonzero.

If a signal-handling routine for sig has been installed by a prior call to SIGNALQQ, RAISEQQ causes that routine to be executed. If no handler routine has been installed, the system terminates the program (the default action).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SIGNALQQ, SIGNAL, KILL


RAN

RAN can be used as an intrinsic function or as a run-time routine.

RAN Intrinsic Function

Nonelemental Intrinsic Function (Specific): Returns the next number from a sequence of pseudorandom numbers of uniform distribution over the range 0 to 1.

This is a specific function that has no generic function associated with it. It must not be passed as an actual argument. It is not a pure function, so it cannot be referenced inside a FORALL construct.

Syntax

result = RAN (i)

i
(Input) Must be an INTEGER(4) variable or array element.
It should initially be set to a large, odd integer value. The RAN function stores a value in the argument that is later used to calculate the next random number.

There are no restrictions on the seed, although it should be initialized with different values on separate runs to obtain different random numbers.

Results:

The result type is REAL(4). The result is a floating-point number that is uniformly distributed in the range between 0.0 inclusive and 1.0 exclusive. It is set equal to the value associated with the argument i.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RANDOM, RANDOM_NUMBER

Example

In RAN (I), if variable I has the value 3, RAN has the value 4.8220158E-05.

RAN Run-Time Routine

Run-Time Function: Returns a pseudorandom number greater than or equal to zero and less than one from the uniform distribution.

Syntax

result = RAN (iseed)

iseed
(Input) INTEGER(4). Seed for the random number generator.

Results:

The result is of type REAL(4). The result is a pseudorandom number, x, where 0 <= x < 1.

To ensure different random values for each run of a program, use different initial values of iseed (for example, use a reading from the system clock). The argument iseed should initially be set to a large, odd integer value. RAN stores a value in the argument iseed that it later uses to calculate the next random number.

The procedures RANDOM, RAN, and RANDOM_NUMBER, and the portability functions DRAND, DRANDM, RAND, IRANDM, RAND, and RANDOM use the same algorithms and thus return the same answers. They are all compatible and can be used interchangeably. (The algortihm used is a "Prime Modulus M Multiplicative Linear Congruential Generator," a modified version of the random number generator by Park and Miller in "Random Number Generators: Good Ones Are Hard to Find," CACM, October 1988, Vol. 31, No. 10.)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RANDOM, RANDOM_NUMBER

Example

 INTEGER(4) iseed
 REAL(4) rnd
 iseed = 425001
 rnd = RAN(iseed)


RAND, RANDOM

Portability Functions: Return real random numbers in the range 0.0 through 1.0.

Module: USE DFPORT

Syntax

result = RAND ([ iflag ])
result = RANDOM (iflag)

iflag
(Input) INTEGER(4). Optional for RAND. Controls the way the random number is selected.

Results:

The result is of type REAL(4). RAND and RANDOM return random numbers in the range 0.0 through 1.0.

Value of iflag | Selection process
1 | The generator is restarted and the first random value is selected.
0 | The next random number in the sequence is selected.
Otherwise | The generator is reseeded using iflag, restarted, and the first random value is selected.

When RAND is called without an argument, iflag is assumed to be 0.

There is no difference between RAND and RANDOM. Both functions are included to ensure portability of existing code that references one or both of them. The intrinsic functions RANDOM_NUMBER and RANDOM_SEED provide the same functionality.

Note: Because Visual Fortran offers an intrinsic subroutine also called RANDOM in the default library, the only way to access this portability function is with the USE DFPORT statement. Without it, you can only access the default subroutine.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RANDOM_NUMBER, RANDOM_SEED, RANDOM


RANDOM

Run-Time Subroutine: Returns a pseudorandom number greater than or equal to zero and less than one from the uniform distribution.

Module: USE DFLIB

Syntax

CALL RANDOM (ranval)

ranval
(Output) REAL(4). Pseudorandom number, 0 <= ranval < 1, from the uniform distribution.

A given seed always produces the same sequence of values from RANDOM.

If SEED is not called before the first call to RANDOM, RANDOM begins with a seed value of one. If a program must have a different pseudorandom sequence each time it runs, pass the constant RND$TIMESEED (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory) to SEED before the first call to RANDOM.

All the random procedures (RANDOM, RAN, and RANDOM_NUMBER, and the portability functions DRAND, DRANDM, RAND, IRANDM, RAND, and RANDOM) use the same algorithms and thus return the same answers. They are all compatible and can be used interchangeably. (The algorithm used is a "Prime Modulus M Multiplicative Linear Congruential Generator," a modified version of the random number generator by Park and Miller in "Random Number Generators: Good Ones Are Hard to Find," CACM, October 1988, Vol. 31, No. 10.)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RANDOM_NUMBER, SEED, DRAND and DRANDM, IRAND and IRANDM, RAN, RAND

Example

 USE DFLIB
 REAL(4) ran

 CALL SEED(1995)
 CALL RANDOM(ran)


RANDOM_NUMBER

Intrinsic Subroutine: Returns one pseudorandom number or an array of such numbers.

Syntax

CALL RANDOM_NUMBER (harvest)

harvest
(Output) Must be of type real. It can be a scalar or an array variable. It is set to contain pseudorandom numbers from the uniform distribution within the range 0 <= x < 1.

The seed for the pseudorandom number generator used by RANDOM_NUMBER can be set or queried with RANDOM_SEED. If RANDOM_SEED is not used, the processor sets the seed for RANDOM_NUMBER to a processor-dependent value.

The RANDOM_NUMBER generator uses two separate congruential generators together to produce a period of approximately 10**18, and produces real pseudorandom results with a uniform distribution in (0,1). It accepts two integer seeds, the first of which is reduced to the range [1, 2147483562]. The second seed is reduced to the range [1, 2147483398]. This means that the generator effectively uses two 31-bit seeds.

For more information on the algorithm, see the following:

  • Communications of the ACM vol 31 num 6 June 1988, titled: Efficient and Portable Combined Random Number Generators by Pierre L'ecuyer.
  • Springer-Verlag New York, N. Y. 2nd ed. 1987, titled: A Guide to Simulation by Bratley, P., Fox, B. L., and Schrage, L. E.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RANDOM_SEED, RANDOM, SEED, DRAND and DRANDM, IRAND and IRANDM, RAN, RAND and RANDOM

Examples

Consider the following:

REAL Y, Z (5, 5)
! Initialize Y with a pseudorandom number
CALL RANDOM_NUMBER (HARVEST = Y)
CALL RANDOM_NUMBER (Z)

Y and Z contain uniformly distributed random numbers.

The following shows another example:

 REAL x, array1 (5, 5)
 CALL RANDOM_SEED()
 CALL RANDOM_NUMBER(x)
 CALL RANDOM_NUMBER(array1)

Consider also the following:

  program testrand
    intrinsic random_seed, random_number
    integer size, seed(2), gseed(2), hiseed(2), zseed(2)
    real harvest(10)
    data seed /123456789, 987654321/
    data hiseed /-1, -1/
    data zseed /0, 0/
    call random_seed(SIZE=size)
    print *,"size ",size
    call random_seed(PUT=hiseed(1:size))
    call random_seed(GET=gseed(1:size))
    print *,"hiseed gseed", hiseed, gseed
    call random_seed(PUT=zseed(1:size))
    call random_seed(GET=gseed(1:size))
    print *,"zseed gseed ", zseed, gseed
    call random_seed(PUT=seed(1:size))
    call random_seed(GET=gseed(1:size))
    call random_number(HARVEST=harvest)
    print *, "seed gseed ", seed, gseed
    print *, "harvest"
    print *, harvest
    call random_seed(GET=gseed(1:size))
    print *,"gseed after harvest ", gseed
  end program testrand


RANDOM_SEED

Intrinsic Subroutine: Changes or queries the seed (starting point) for the pseudorandom number generator used by RANDOM_NUMBER.

Syntax

CALL RANDOM_SEED ([size] [, put] [, get])

size
(Optional; output) Must be scalar and of type default integer. Number of integers the processor uses to hold the value of the seed.

put
(Optional; input) Must be a default integer array of rank one. It is used by the processor to reset the value of the seed.

get
(Optional; output) Must be a default integer array of rank one. It is set to the current value of the seed.

No more than one argument can be specified. Both put and get must be greater than or equal to the size of the array the processor uses to store the seed. You can determine this size by calling RANDOM_SEED with the size argument (see second example).

If no argument is specified, a random number based on the date and time is assigned to the seed.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RANDOM_NUMBER, SEED, SRAND

Examples

Consider the following:

CALL RANDOM_SEED                        ! Processor initializes the
                                        !   seed randomly from the date
                                        !   and time
CALL RANDOM_SEED (SIZE = M)             ! Sets M to N
CALL RANDOM_SEED (PUT = SEED (1 : M))   ! Sets user seed
CALL RANDOM_SEED (GET = OLD  (1 : M))   ! Reads current seed

The following shows another example:

 INTEGER I
 INTEGER, ALLOCATABLE :: new (:), old(:)
 CALL RANDOM_SEED ( )  ! Processor reinitializes the seed
                       ! randomly from the date and time
 CALL RANDOM_SEED (SIZE = I)  ! I is set to the size of
                              ! the seed array
 ALLOCATE (new(I))
 ALLOCATE (old(I))
 CALL RANDOM_SEED (GET=old(1:I)) ! Gets the current seed
 WRITE(*,*) old
 new = 5
 CALL RANDOM_SEED (PUT=new(1:I)) ! Sets seed from array
                                 ! new
 END


RANDU

Intrinsic Subroutine: Computes a pseudorandom number as a single-precision value.

Syntax

CALL RANDU (i1, i2, x)

i1, i2
INTEGER(2) variables or array elements that contain the seed for computing the random number. These values are updated during the computation so that they contain the updated seed.

x
A REAL(4) variable or array element where the computed random number is returned.

Results:

The result is returned in x, which must be of type REAL(4). The result value is a pseudorandom number in the range 0.0 to 1.0. The algorithm for computing the random number value is based on the values for i1 and i2.

If i1=0 and i2=0, the generator base is set as follows:

    x(n + 1 = 2**16 + 3)

Otherwise, it is set as follows:

    x(n + 1 = (2**16 + 3) * x(n) mod 2**32)

The generator base x(n + 1) is stored in i1, i2. The result is x(n + 1) scaled to a real value y(n + 1), for 0.0 <= y(n + 1) < 1.

Example

REAL X
INTEGER(2) I, J
...
CALL RANDU (I, J, X)

If I and J are values 4 and 6, X stores the value 5.4932479E-04.


RANGE

Inquiry Intrinsic Function (Generic): Returns the decimal exponent range in the model representing numbers with the same kind parameter as the argument.

Syntax

result = RANGE (x)

x
(Input) Must be of type integer, real, or complex. It can be scalar or array valued.

Results:

The result is a scalar of type default integer.

For an integer argument, the result has the value INT(LOG10( HUGE(x) )). For information on the integer model, see Model for Integer Data.

For a real or complex argument, the result has the value INT(MIN (LOG10( HUGE(x) ), -LOG10( TINY(x) ))). For information on the real model, see Model for Real Data.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: HUGE, TINY

Examples

If X is a REAL(4) value, RANGE (X) has the value 37. (HUGE(X) = (1 - 2-24) x 2128 and TINY(X) = 2-126)


READ

Statement: Transfers input data from external sequential, direct-access, or internal records.

Syntax

Sequential

Formatted:

READ (eunit, format [, advance] [, size] [, iostat] [, err] [, end] [, eor]) [io-list]
READ form [, io-list]

Formatted - List-Directed:

READ (eunit, * [, iostat] [, err] [, end]) [io-list]
READ * [, io-list]

Formatted - Namelist:

READ (eunit, nml-group [, iostat] [, err] [, end])
READ nml

Unformatted:

READ (eunit [, iostat] [, err] [, end]) [io-list]

Direct-Access

Formatted:

READ (eunit, format, rec [, iostat] [, err]) [io-list]

Unformatted:

READ (eunit, rec [, iostat] [, err]) [io-list]

Indexed (VMS only)

Formatted:

READ (eunit, format, key [, keyid] [, iostat] [, err]) [io-list]

Unformatted:

READ (eunit, key [, keyid] [, iostat] [, err]) [io-list]

Internal

READ (iunit, format [, iostat] [, err] [, end]) [io-list]

eunit
Is an external unit specifier, optionally prefaced by UNIT=. UNIT= is required if eunit is not the first specifier in the list.

format
Is a format specifier. It is optionally prefaced by FMT= if format is the second specifier in the list and the first specifier indicates a logical or internal unit specifier without the optional keyword UNIT=.

For internal READs, an asterisk (*) indicates list-directed formatting. For direct-access READs, an asterisk is not permitted.

advance
Is an advance specifier (ADVANCE=c-expr). If the value of c-expr is 'YES', the statement uses advancing input; if the value is 'NO', the statement uses nonadvancing input. The default value is 'YES'.

size
Is a character count specifier (SIZE=i-var). It can only be specified for nonadvancing READ statements.

iostat
Is the name of a variable to contain the completion status of the I/O operation. Optionally prefaced by IOSTAT=.

err, end, eor
Are branch specifiers if an error (ERR=label), end-of-file (END=label), or end-of-record (EOR=label) condition occurs.

EOR can only be specified for nonadvancing READ statements.

io-list
Is an I/O list: the names of the variables, arrays, array elements, or character substrings from which or to which data will be transferred. Optionally an implied-DO list.

form
Is the nonkeyword form of a format specifier (no FMT=).

*
Is the format specifier indicating list-directed formatting. (It can also be specified as FMT=*.)

nml-group
Is the namelist group specification for namelist I/O. Optionally prefaced by NML=. NML= is required if nml-group is not the second I/O specifier.

nml
Is the nonkeyword form of a namelist specifier (no NML=) indicating namelist I/O.

rec
Is the cell number of a record to be accessed directly. Optionally prefaced by REC=.

key (VMS only)
Is a key specifier (KEY[con]=value).

keyid (VMS only)
Is a key-of-reference specifier (KEYID=kn).

iunit
Is an internal unit specifier, optionally prefaced by UNIT=. UNIT= is required if iunit is not the first specifier in the list.

It must be a character variable. It must not be an array section with a vector subscript.

If a parameter of the READ statement is an expression that calls a function, that function must not execute an I/O statement or the EOF intrinsic function, because the results are unpredictable.

If I/O is to or from a formatted device, io-list cannot contain derived type variables, but it can contain components of derived types. If I/O is to a binary or unformatted device, io-list can contain either derived type components or a derived type variable.

The READ statement can disrupt the results of certain graphics text functions (such as SETTEXTWINDOW) that alter the location of the cursor. You can avoid the problem by getting keyboard input with the GETCHARQQ function and echoing the keystrokes to the screen using OUTTEXT. Alternatively, you can use SETTEXTPOSITION to control cursor location.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: I/O Lists, I/O Control List, Forms for Sequential READ Statements, Forms for Direct-Access READ Statements, Forms for Indexed READ Statements (VMS only), Forms and Rules for Internal READ Statements, PRINT, WRITE, I/O Formatting

Example

 DIMENSION ia(10,20)
 ! Read in the bounds for the array.
 ! Then read in the array in nested implied-DO lists
 ! with input format of 8 columns of width 5 each.
 READ (6, 990) il, jl, ((ia(i,j), j = 1, jl), i =1, il)
 990 FORMAT (2I5, /, (8I5))

 ! Internal read gives a variable string-represented numbers
 CHARACTER*12 str
 str = '123456'
 READ (str,'(i6)') i

 ! List-directed read uses no specified format
 REAL x, y
 INTEGER i, j
 READ (*,*) x, y, i, j


REAL

Statement: Specifies the REAL data type.

Syntax

REAL
REAL([KIND=]n)
REAL*n
DOUBLE PRECISION

n
Is kind 4 or 8.

If a kind parameter is specified, the real constant has the kind specified. If a kind parameter is not specified, the kind is default real.

DOUBLE PRECISION is REAL(8). No kind parameter is permitted for data declared with type DOUBLE PRECISION.

To change the default kind value, use the /real_size compiler option or the cDEC$ REAL:8 directive.

REAL(4) and REAL*4 (single precision) are the same data type. REAL(8), REAL*8, and DOUBLE PRECISION are the same data type.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DOUBLE PRECISION, REAL directive, Real Data Types, General Rules for Real Constants, REAL(4) Constants, REAL(8) or DOUBLE PRECISION Constants

Examples

Entity-oriented examples are:

 MODULE DATDECLARE
    REAL (8), OPTIONAL :: testval=50.d0
    REAL, SAVE :: a(10), b(20,30)
    REAL, PARAMETER :: x = 100.

 Attribute-oriented examples are:
 MODULE DATDECLARE
    REAL (8) testval=50.d0
    REAL x, a(10), b(20,30)
    OPTIONAL testval
    SAVE a, b
    PARAMETER (x = 100.)


REAL Directive

General Compiler Directive: Specifies the default real kind.

Syntax

c DEC$ REAL:{ 4 | 8 }

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

Rules and Behavior

The REAL directive selects a size of 4 or 8 bytes (KIND=4 or KIND=8) for default real numbers. When the directive is in effect, all default real variables are of the kind specified in the directive. Only numbers specified or implied as REAL without KIND are affected.

The REAL directive can appear only at the top of a program unit. A program unit is a main program, an external subroutine or function, a module, or a block data program unit. REAL cannot appear between program units, or at the beginning of internal subprograms. It does not affect modules invoked with the USE statement in the program unit that contains it.

The following form is also allowed: !MS$REAL:{4 | 8}

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: REAL, INTEGER Directive, General Compiler Directives

Example

 REAL r              ! a 4-byte REAL
 WRITE(*,*) KIND(r)
 CALL REAL8( )
 WRITE(*,*) KIND(r)  ! still a 4-byte REAL
                     !   not affected by setting in subroutine
 END
 SUBROUTINE REAL8( )
   !DEC$ REAL:8
   REAL s ! an 8-byte REAL
   WRITE(*,*) KIND(s)
 END SUBROUTINE


REAL Function

Elemental Intrinsic Function (Generic): Converts a value to real type.

Syntax

result = REAL (a [, kind])

a
(Input) Must be of type integer, real, or complex.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is of type real. If kind is present, the kind parameter is that specified by kind. If kind is not present, see the following table for the kind parameter.

Functions that cause conversion of one data type to another type have the same affect as the implied conversion in assignment statements.

If a is integer or real, the result is equal to an approximation of a. If a is complex, the result is equal to an approximation of the real part of a.

Specific Name 1 | Argument Type | Result Type
 | INTEGER(1) | REAL(4)
FLOATI | INTEGER(2) | REAL(4)
FLOAT 2, 3 | INTEGER(4) | REAL(4)
REAL 2 | INTEGER(4) | REAL(4)
FLOATK | INTEGER(8) | REAL(4)
 | REAL(4) | REAL(4)
SNGL 2, 4 | REAL(8) | REAL(4)
SNGLQ 5 | REAL(16) | REAL(4)
 | COMPLEX(4) | REAL(4)
 | COMPLEX(8) | REAL(8)
1 These specific functions cannot be passed as actual arguments. 2 The setting of compiler option /real_size can affect FLOAT, REAL, and SNGL. 3 Or FLOATJ. For compatibility with older versions of Fortran, FLOAT can also be specified as a generic function. 4 For compatibility with older versions of Fortran, SNGL can also be specified as a generic function. The generic SNGL includes specific function REAL, which takes a REAL(4) argument and produces a REAL(4) result. 5 VMS, U*X

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DFLOAT, DREAL, DBLE

Examples

REAL (-4) has the value -4.0.

REAL (Y) has the same kind parameter and value as the real part of complex variable Y.


RECORD

Statement: Declares a record structure as an entity with a name.

Syntax

RECORD /structure-name/record-namelist
[, /structure-name/record-namelist]
. . .
[, /structure-name/record-namelist]

structure-name
Is the name of a previously declared structure.

record-namelist
Is a list of one or more variable names, array names, or array specifications, separated by commas. All of the records named in this list have the same structure and are allocated separately in memory.

Rules and Behavior

You can use record names in COMMON and DIMENSION statements, but not in DATA, EQUIVALENCE, or NAMELIST statements.

Records initially have undefined values unless you have defined their values in structure declarations.

STRUCTURE and RECORD constructs have been replaced by derived types, which should be used in writing new code. See Derived Type and TYPE.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Derived Type, MAP...END MAP, STRUCTURE...END STRUCTURE, TYPE, UNION...END UNION, Record Structures

Example

 STRUCTURE /address/
   LOGICAL*2    house_or_apt
   INTEGER*2    apt
   INTEGER*2    housenumber
   CHARACTER*30 street
   CHARACTER*20 city
   CHARACTER*2  state
   INTEGER*4    zip
 END STRUCTURE

 RECORD /address/ mailing_addr(20), shipping_addr(20)


RECTANGLE, RECTANGLE_W

Graphics Function: Draws a rectangle using the current graphics color, logical write mode, and line style.

Module: USE DFLIB

Syntax

result = RECTANGLE (control, x1, y1, x2, y2)
result = RECTANGLE_W (control, wx1, wy1, wx2, wy2)

control
(Input) INTEGER(2). Fill flag. One of the following symbolic constants (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory):

  • $GFILLINTERIOR - Draws a solid figure using the current color and fill mask.
  • $GBORDER - Draws the border of a rectangle using the current color and line style.

x1, y1
(Input) INTEGER(2). Viewport coordinates for upper-left corner of rectangle.

x2, y2
(Input) INTEGER(2). Viewport coordinates for lower-right corner of rectangle.

wx1, wy1
(Input) REAL(8). Window coordinates for upper-left corner of rectangle.

wx2, wy2
(Input) REAL(8). Window coordinates for lower-right corner of rectangle.

Results:

The result is of type INTEGER(2). The result is nonzero if successful; otherwise, 0.

The RECTANGLE function uses the viewport-coordinate system. The viewport coordinates (x1, y1) and (x2, y2) are the diagonally opposed corners of the rectangle.

The RECTANGLE_W function uses the window-coordinate system. The window coordinates (wx1, wy1) and (wx2, wy2) are the diagonally opposed corners of the rectangle.

SETCOLORRGB sets the current graphics color. SETFILLMASK sets the current fill mask. By default, filled graphic shapes are filled solid with the current color.

If you fill the rectangle using FLOODFILLRGB, the rectangle must be bordered by a solid line style. Line style is solid by default and can be changed with SETLINESTYLE.

Note: The RECTANGLE routine described here is a QuickWin routine. If you are trying to use the Win32 SDK version of the Rectangle routine by including the DFWIN module, you need to specify the routine name as MSFWIN$Rectangle. For more information, see Special Naming Convention for Certain QuickWin and Win32 Graphics Routines in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETFILLMASK, GRSTATUS, LINETO, POLYGON, FLOODFILLRGB, SETLINESTYLE, SETCOLOR, SETWRITEMODE

Example

This program draws the rectangle shown below.

 ! Build as a QuickWin or Standard Graphics App.
 USE DFLIB
 INTEGER(2) dummy, x1, y1, x2, y2
 x1 = 80; y1 = 50
 x2 = 240; y2 = 150
 dummy = RECTANGLE( $GBORDER, x1, y1, x2, y2 )
 END

Figure: Output of Program RECTNGL.FOR


RECURSIVE

Keyword: Specifies that a subroutine or function can call itself directly or indirectly. Recursion is permitted if the keyword is specified in a FUNCTION or SUBROUTINE statement, or if RECURSIVE is specified as a compiler option or in an OPTIONS statement.

If a function is directly recursive and array valued, the keywords RECURSIVE and RESULT must both be specified in the FUNCTION statement.

The procedure interface is explicit within the subprogram in the following cases:

  • When RECURSIVE is specified for a subroutine

  • When RECURSIVE and RESULT are specified for a function

The keyword RECURSIVE must be specified if any of the following applies (directly or indirectly):

  • The subprogram invokes itself.

  • The subprogram invokes a subprogram defined by an ENTRY statement in the same subprogram.

  • An ENTRY procedure in the same subprogram invokes one of the following:

    • Itself
    • Another ENTRY procedure in the same subprogram
    • The subprogram defined by the FUNCTION or SUBROUTINE statement

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ENTRY, FUNCTION, SUBROUTINE, /recursive, OPTIONS, Program Units and Procedures

Example

 ! RECURS.F90
 !
   i = 0
   CALL Inc (i)
   END

   RECURSIVE SUBROUTINE Inc (i)
   i = i + 1
   CALL Out (i)
   IF (i.LT.20) CALL Inc (i)    ! This also works in OUT
   END SUBROUTINE Inc

   SUBROUTINE Out (i)
   WRITE (*,*) i
   END SUBROUTINE Out


REDUCTION (TU*X only)

Parallel Directive Clause: Performs a commutative reduction operation on the specified variables.

Syntax

REDUCTION (operator | intrinsic : list)

operator
Is one of the following: +, *, -, .AND., .OR., .EQV., or .NEQV.

intrinsic
Is one of the following: MAX, MIN, IAND, IOR, or IEOR.

list
Is the name of one or more scalar variables or intrinsic type or common blocks that are accessible to the scoping unit. Subobjects cannot be specified. Each name must be separated by a comma, and a named common block must appear between slashes (/ /).

Variables that appear in a REDUCTION clause must be SHARED in the enclosing context. A private copy of each variable in list is created for each thread as if the PRIVATE clause had been used. The private copy is initialized according to the operator (see the table below).

At the end of the REDUCTION, the shared variable is updated to reflect the result of combining the original value of the shared reduction variable with the final value of each of the private copies using the operator specified. The reduction operators are all associative (except for subtraction), and the compiler can freely reassociate the computation of the final value; the partial results of a subtraction reduction are added to form the final value.

The value of the shared variable becomes undefined when the first thread reaches the clause containing the reduction, and it remains undefined until the reduction computation is complete. Normally, the computation is complete at the end of the REDUCTION construct.

However, if the REDUCTION clause is used in a construct to which NOWAIT is also applied, the shared variable remains undefined until a barrier synchronization has been performed. This ensures that all the threads complete the REDUCTION clause.

The REDUCTION clause must be used in a region or worksharing construct where the reduction variable is used only in a reduction statement having one of the following forms:

  x = x operator expr

  x = expr operator x (except for subtraction)

  x = intrinsic (x, expr)

  x = intrinsic (expr, x)

Some reductions can be expressed in other forms. For instance, a MAX reduction can be expressed as follows:

  IF (x .LT. expr) x = expr

Alternatively, the reduction might be hidden inside a subroutine call. Be careful that the operator you specify in the REDUCTION clause matches the reduction operation.

The following table lists the operators and intrinsics and their initialization values. The actual initialization value will be consistent with the data type of the reduction variable.

Initialization Values for REDUCTION Operators and Intrinsics (TU*X only)

Operator | Initialization Value
+ | 0
* | 1
- | 0
.AND. | .TRUE.
.OR. | .FALSE.
.EQV. | .TRUE.
.NEQV. | .FALSE.
Intrinsic | Initialization Value
MAX | Smallest representable number
MIN | Largest representable number
IAND | All bits on
IOR | 0
IEOR | 0

If a directive allows reduction clauses, the number you can specify is not limited. However, each variable name can appear in only one of the clauses.


%REF

Built-in Function: Changes the form of an actual argument. Passes the argument by reference. In Visual Fortran, passing by reference is the default.

Syntax

result = %REF (a)

a
(Input) An expression, record name, procedure name, array, character array section, or array element.

You must specify %REF in the actual argument list of a CALL statement or function reference. You cannot use it in any other context.

The following table lists the Compaq Fortran defaults for argument passing, and the allowed uses of %REF:

Actual Argument Data Type | Default | %REF
Expressions:
Logical | REF | Yes
Integer | REF | Yes
REAL(4) | REF | Yes
REAL(8) | REF | Yes
REAL(16) 1 | REF | Yes
COMPLEX(4) | REF | Yes
COMPLEX(8) | REF | Yes
COMPLEX(16) 1 | REF | Yes
Character | See table note 2 | Yes
Hollerith | REF | No
Aggregate 3 | REF | Yes
Derived | REF | Yes
Array Name:
Numeric | REF | Yes
Character | See table note 2 | Yes
Aggregate 3 | REF | Yes
Derived | REF | Yes
Procedure Name:
Numeric | REF | Yes
Character | See table note 2 | Yes
1 VMS, U*X 2 On Tru64 UNIX, Linux, and Windows systems, a character argument is passed by address and hidden length. 3 In Compaq Fortran record structures

The %REF, %VAL, and %DESCR functions override related cDEC$ ATTRIBUTE settings.

See Also: CALL, %VAL, %DESCR

Example

  CHARACTER(LEN=10) A, B
  CALL SUB(A, %REF(B))

Variable A is passed by address and hidden length. Variable B is passed by reference.

Note that on Windows systems, the option /iface determines how the character argument for variable B is passed.


REGISTERMOUSEEVENT

QuickWin Function: Registers the application-supplied callback routine to be called when a specified mouse event occurs in a specified window.

Module: USE DFLIB

Syntax

result = REGISTERMOUSEEVENT (unit, mouseevents, callbackroutine)

unit
(Input) INTEGER(4). Unit number of the window whose callback routine on mouse events is to be registered.

mouseevents
(Input) INTEGER(4). One or more mouse events to be handled by the callback routine to be registered. Symbolic constants (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory) for the possible mouse events are:

  • MOUSE$LBUTTONDOWN - Left mouse button down
  • MOUSE$LBUTTONUP - Left mouse button up
  • MOUSE$LBUTTONDBLCLK - Left mouse button double-click
  • MOUSE$RBUTTONDOWN - Right mouse button down
  • MOUSE$RBUTTONUP - Right mouse button up
  • MOUSE$RBUTTONDBLCLK - Right mouse button double-click
  • MOUSE$MOVE - Mouse moved

callbackroutine
(Input) Routine to be called on the specified mouse event in the specified window. It must be declared EXTERNAL. For a prototype mouse callback routine, see Using QuickWin in the Programmer's Guide.

Results:

The result is of type INTEGER(4). The result is zero or a positive integer if successful; otherwise, a negative integer that can be one of the following:

  • MOUSE$BADUNIT - The unit specified is not open, or is not associated with a QuickWin window.
  • MOUSE$BADEVENT - The event specified is not supported.

For every BUTTONDOWN or BUTTONDBLCLK event there is an associated BUTTONUP event. When the user double clicks, four events happen: BUTTONDOWN and BUTTONUP for the first click, and BUTTONDBLCLK and BUTTONUP for the second click. The difference between getting BUTTONDBLCLK and BUTTONDOWN for the second click depends on whether the second click occurs in the double click interval, set in the system's CONTROL PANEL/MOUSE.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: Using QuickWin, UNREGISTERMOUSEEVENT, WAITONMOUSEEVENT


REMAPALLPALETTERGB, REMAPPALETTERGB

Graphics Function: REMAPALLPALETTERGB remaps a set of Red-Green-Blue (RGB) color values to indexes recognized by the video hardware. REMAPPALETTERGB remaps one color index to an RGB color value.

Module: USE DFLIB

Syntax

result = REMAPALLPALETTERGB (colors)
result = REMAPPALETTERGB (index, color)

colors
(Input) INTEGER(4). Ordered array of RGB color values to be mapped in order to indexes. Must hold 0-255 elements.

color
(Input) INTEGER(4). RGB color value to assign to a color index.

index
(Input) INTEGER(4). Color index to be reassigned an RGB color.

Results:

The result is of type INTEGER(4). REMAPALLPALETTERGB returns 0 if successful; otherwise, -1. REMAPPALETTERGB returns the previous color assigned to the index.

The REMAPALLPALETTERGB function remaps all of the available color indexes simultaneously (up to 236; 20 indexes are reserved by the operating system). The colors argument points to an array of RGB color values. The default mapping between the first 16 indexes and color values is shown in the following table. The 16 default colors are provided with symbolic constants in DFLIB.F90 (in the \DF98\INCLUDE subdirectory).

Index | Color | Index | Color
0 | $BLACK | 8 | $GRAY
1 | $BLUE | 9 | $LIGHTBLUE
2 | $GREEN | 10 | $LIGHTGREEN
3 | $CYAN | 11 | $LIGHTCYAN
4 | $RED | 12 | $LIGHTRED
5 | $MAGENTA | 13 | $LIGHTMAGENTA
6 | $BROWN | 14 | $YELLOW
7 | $WHITE | 15 | $BRIGHTWHITE

The number of colors mapped can be fewer than 236 if the number of colors supported by the current video mode is fewer, but at most 236 colors can be mapped by REMAPALLPALETTERGB. Most Windows graphics drivers support a palette of 256K colors or more, of which only a few can be mapped into the 236 palette indexes at a time. To access and use all colors on the system, bypass the palette and use direct RGB color functions such as such as SETCOLORRGB and SETPIXELSRGB.

Any RGB colors can be mapped into the 236 palette indexes. Thus, you could specify a palette with 236 shades of red. For further details on using different color procedures see Adding Color in the Programmer's Guide.

In each RGB color value, each of the three colors, red, green and blue, is represented by an eight-bit value (2 hex digits). In the values you specify with REMAPALLPALETTERGB or REMAPPALETTERGB, red is the rightmost byte, followed by green and blue. The RGB value's internal structure is as follows:

Larger numbers correspond to stronger color intensity with binary 11111111 (hex FF) the maximum for each of the three components. For example, #008080 yields full-intensity red, #00FF00 full-intensity green, #FF0000 full-intensity blue, and #FFFFFF full-intensity for all three, resulting in bright white.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETBKCOLORRGB, SETCOLORRGB, SETBKCOLOR, SETCOLOR

Example

 ! Build as QuickWin or Standard Graphics App.

 USE DFLIB
 INTEGER(4) colors(3)
 INTEGER(2) status

 colors(1) = #00FFFF ! yellow
 colors(2) = #FFFFFF ! bright white
 colors(3) = 0       ! black
 status = REMAPALLPALETTERGB(colors)

 status = REMAPPALETTERGB(INT2(47), #45A315)
 END


RENAME

Portability Function: Renames a file.

Module: USE DFPORT

Syntax

result = RENAME (from, to)

from
(Input) Character*(*). Path of an existing file.

to
(Input) Character*(*). The new path (see Warning below).

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, an error code, such as:

  • EACCES: File or directory specified by to could not be created (invalid path). This error is also returned if the drive specified is not currently connected to a device.
  • ENOENT: File or path specified by from could not be found.
  • EXDEV: Attempt to move a file to a different device.
Warning: This routine can cause data to be lost. If the file specified in to already exists, RENAME deletes the pre-existing file.

It is possible to rename a file to itself without error.

The paths can use forward (/) or backward (\) slashes as path separators and can include drive letters.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RENAMEFILEQQ

Example

 use dfport
 integer(4) istatus
 character*12 old_name, new_name
 print *, "Enter file to rename: "
 read *, old_name
 print *, "Enter new name: "
 read *, new_name
 ISTATUS = RENAME (old_name, new_name)


RENAMEFILEQQ

Run-Time Function: Renames a file.

Module: USE DFLIB

Syntax

result = RENAMEFILEQQ (oldname, newname)

oldname
(Input) Character*(*). Current name of the file to be renamed.

newname
(Input) Character*(*). New name of the file to be renamed.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

You can use RENAMEFILEQQ to move a file from one directory to another on the same drive by giving a different path in the newname parameter.

If the function fails, call GETLASTERRORQQ to determine the reason. One of the following errors can be returned:

  • ERR$ACCES - Permission denied. The file's permission setting does not allow the specified access.
  • ERR$EXIST - The file already exists.
  • ERR$NOENT - File or path specified by oldname not found.
  • ERR$XDEV - Attempt to move a file to a different device.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: FINDFILEQQ, RENAME, GETLASTERRORQQ

Example

 USE DFLIB
 INTEGER(4) len
 CHARACTER(80) oldname, newname
 LOGICAL(4) result

 WRITE(*,'(A, \)') ' Enter old name: '
 len = GETSTRQQ(oldname)
 WRITE(*,'(A, \)') ' Enter new name: '
 len = GETSTRQQ(newname)
 result = RENAMEFILEQQ(oldname, newname)
 END


REPEAT

Transformational Intrinsic Function (Generic): Concatenates several copies of a string.

Syntax

result = REPEAT (string, ncopies)

string
(Input) Must be scalar and of type character.

ncopies
(Input) Must be scalar and of type integer. It must not be negative.

Results:

The result is a scalar of type character and length ncopies x LEN(string). The kind parameter is the same as string. The value of the result is the concatenation of ncopies copies of string.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPREAD

Example

REPEAT ('S', 3) has the value SSS.

REPEAT ('ABC', 0) has the value of a zero-length string.

The following shows another example:

 CHARACTER(6) str
 str = REPEAT('HO', 3)  ! returns HOHOHO


RESHAPE

Transformational Intrinsic Function (Generic): Constructs an array with a different shape from the argument array.

Syntax

result = RESHAPE (source, shape [, pad] [, order])

source
(Input) Must be an array (of any data type). It supplies the elements for the result array. Its size must be greater than or equal to PRODUCT(shape) if pad is omitted or has size zero.

shape
(Input) Must be an integer array of up to 7 elements, with rank one and constant size. It defines the shape of the result array. Its size must be positive; its elements must not have negative values.

pad
(Optional; input) Must be an array with the same type and kind parameters as source. It is used to fill in extra values if the result array is larger than source.

order
(Optional; input) Must be an integer array with the same shape as shape. Its elements must be a permutation of (1,2,...,n), where n is the size of shape. If order is omitted, it is assumed to be (1,2,...,n).

Results:

The result is an array of shape shape with the same type and kind parameters as source. The size of the result is the product of the values of the elements of shape.

In the result array, the array elements of source are placed in the order of dimensions specified by order. If order is omitted, the array elements are placed in normal array element order.

The array elements of source are followed (if necessary) by the array elements of pad in array element order. If necessary, additional copies of pad follow until all the elements of the result array have values.

In standard Fortran array element order, the first dimension varies fastest. For example, element order in a two-dimensional array would be (1,1), (2,1), (3,1) and so on. In a three-dimensional array, each dimension having two elements, the array element order would be (1,1,1), (2, 1, 1), (1, 2, 1), (2, 2, 1), (1, 1, 2), (2, 1, 2), (1, 2, 2), (2, 2, 2).

RESHAPE can be used to reorder a Fortran array to match C array ordering before the array is passed from a Fortran to a C procedure.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: PACK, SHAPE, TRANSPOSE

Examples

RESHAPE ((/3, 4, 5, 6, 7, 8/), (/2, 3/)) has the value

  [ 3  5  7 ]
  [ 4  6  8 ].
RESHAPE ((/3, 4, 5, 6, 7, 8/), (/2, 4/), (/1, 1/), (/2, 1/)) has the value
  [ 3  4  5  6 ]
  [ 7  8  1  1 ].

The following shows another example:

 INTEGER AR1( 2, 5)
 REAL F(5,3,8)
 REAL C(8,3,5)
 AR1 = RESHAPE((/1,2,3,4,5,6/),(/2,5/),(/0,0/),(/2,1/))
 ! returns      1 2 3 4 5
 !              6 0 0 0 0
 !
 ! Change Fortran array order to C array order
 C = RESHAPE(F, (/8,3,5/), ORDER = (/3, 2, 1/))
 END


RESULT

Keyword: Specifies a name for a function result.

Normally, a function result is returned in the function's name, and all references to the function name are references to the function result.

However, if you use the RESULT keyword in a FUNCTION statement, you can specify a local variable name for the function result. In this case, all references to the function name are recursive calls, and the function name must not appear in specification statements.

The RESULT name must be different from the name of the function.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: FUNCTION, ENTRY, RECURSIVE, Program Units and Procedures

Examples

The following shows an example of a recursive function specifying a RESULT variable:

  RECURSIVE FUNCTION FACTORIAL(P) RESULT(L)
    INTEGER, INTENT(IN) :: P
    INTEGER L
    IF (P == 1) THEN
      L = 1
    ELSE
      L = P * FACTORIAL(P - 1)
    END IF
  END FUNCTION

The following shows another example:

  recursive function FindSame(Aindex,Last,Used) &
 &  result(FindSameResult)
  type(card) Last
  integer Aindex, i
  logical matched, used(5)
  if( Aindex > 5 ) then
    FindSameResult = .true.
    return
  endif
  . . .


RETURN

Statement: Transfers control from a subprogram to the calling program unit.

Syntax

RETURN [expr]

expr
Is a scalar expression that is converted to an integer value if necessary.

The expr is only allowed in subroutines; it indicates an alternate return. (An alternate return is an obsolescent feature in Fortran 95 and Fortran 90.)

Rules and Behavior

When a RETURN statement is executed in a function subprogram, control is transferred to the referencing statement in the calling program unit.

When a RETURN statement is executed in a subroutine subprogram, control is transferred to the first executable statement following the CALL statement that invoked the subroutine, or to the alternate return (if one is specified).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: CALL, CASE

Examples

The following shows how alternate returns can be used in a subroutine:

   CALL CHECK(A, B, *10, *20, C)
   ...
10 ...
20 ...
   SUBROUTINE CHECK(X, Y, *, *, C)
   ...
50   IF (X) 60, 70, 80
60   RETURN
70   RETURN 1
80   RETURN 2
   END

The value of X determines the return, as follows:

  • If X < 0, a normal return occurs and control is transferred to the first executable statement following CALL CHECK in the calling program.

  • If X = = 0, the first alternate return (RETURN 1) occurs and control is transferred to the statement identified with label 10.

  • If X > 0, the second alternate return (RETURN 2) occurs and control is transferred to the statement identified with label 20.

Note that an asterisk (*) specifies the alternate return. An ampersand (&) can also specify an alternate return in a CALL statement, but not in a subroutine's dummy argument list.

The following shows another example:

     SUBROUTINE Loop
     CHARACTER in
 10  READ (*, '(A)') in
     IF (in .EQ. 'Y') RETURN
     GOTO 10
 !   RETURN implied by the following statement:
     END

 !The following example demonstrates alternate returns:
     CALL AltRet (i, *10, *20, *30)
     WRITE (*, *) 'normal return'
     GOTO 40
 10  WRITE (*, *) 'I = 10'
     GOTO 40
 20  WRITE (*, *) 'I = 20'
     GOTO 40
 30  WRITE (*, *) 'I = 30'
 40  CONTINUE
     END
     SUBROUTINE AltRet (i, *, *, *)
     IF (i .EQ. 10) RETURN 1
     IF (i .EQ. 20) RETURN 2
     IF (i .EQ. 30) RETURN 3
     END

In this example, RETURN 1 specifies the list's first alternate-return label, which is a symbol for the actual argument *10 in the CALL statement. RETURN 2 specifies the second alternate-return label, and RETURN 3 specifies the third alternate-return label.


REWIND

Statement: Positions a sequential or direct access file at the beginning of the file (the initial point). It takes one of the following forms:

Syntax

REWIND ([UNIT=]io-unit [, ERR=label] [, IOSTAT=i-var])
REWIND io-unit

io-unit
(Input) Is an external unit specifier.

label
Is the label of the branch target statement that receives control if an error occurs.

i-var
(Output)Is a scalar integer variable that is defined as a positive integer if an error occurs and zero if no error occurs.

Rules and Behavior

The unit number must refer to a file on disk or magnetic tape, and the file must be open for sequential, direct, or append access.

If a REWIND is done on a direct access file, the NEXTREC specifier is assigned a value of 1.

If a file is already positioned at the initial point, a REWIND statement has no effect.

If a REWIND statement is specified for a unit that is not open, it has no effect.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: OPEN, READ, WRITE, Data Transfer I/O Statements, Branch Specifiers

Examples

The following statement repositions the file connected to I/O unit 3 to the beginning of the file:

REWIND 3

Consider the following statement:

REWIND (UNIT=9, IOSTAT=IOS, ERR=10)

This statement positions the file connected to unit 9 at the beginning of the file. If an error occurs, control is transferred to the statement labeled 10, and a positive integer is stored in variable IOS.

The following shows another example:

 WRITE (7, '(I10)') int
 REWIND (7)
 READ (7, '(I10)') int


REWRITE

Statement: Rewrites the current record.

Formatted:

REWRITE (eunit, format [, iostat] [, err]) [io-list]

Unformatted:

REWRITE (eunit [, iostat] [, err]) [io-list]

eunit
Is an external unit specifier ([UNIT=]io-unit).

format
Is a format specifier ([FMT=]format).

iostat
Is a status specifier (IOSTAT=i-var).

err
Is a branch specifier (ERR=label) if an error condition occurs.

io-list
Is an I/O list.

In the REWRITE statement, data (translated if formatted; untranslated if unformatted) is written to the current (existing) record in one of the following types of external files:

  • On Windows, Tru64 UNIX, and Linux systems: In a file with direct access.
  • On OpenVMS systems: In all types of files. In sequential files, the current record and new record must be the same length.

The current record is the last record accessed by a preceding, successful sequential, or direct-access READ statement.

Between a READ and REWRITE statement, you should not specify any other I/O statement (except INQUIRE) on that logical unit. Execution of any other I/O statement on the logical unit destroys the current-record context and causes the current record to become undefined.

Only one record can be rewritten in a single REWRITE statement operation.

The output list (and format specification, if any) must not specify more characters for a record than the record size. (Record size is specified by RECL in an OPEN statement.)

If the number of characters specified by the I/O list (and format, if any) do not fill a record, blank characters are added to fill the record.

Example

In the following example, the current record (contained in the relative organization file connected to logical unit 3) is updated with the values represented by NAME, AGE, and BIRTH:

      REWRITE (3, 10, ERR=99) NAME, ,AGE, BIRTH
10    FORMAT (A16, I2, A8)


RGBTOINTEGER

QuickWin Function: Converts three integers specifying red, green, and blue color intensities into a four-byte RGB integer for use with RGB functions and subroutines.

Module: USE DFLIB

Syntax

result = RGBTOINTEGER (red, green, blue)

red
(Input) INTEGER(4). Intensity of the red component of the RGB color value. Only the lower 8 bits of red are used.

green
(Input) INTEGER(4). Intensity of the green component of the RGB color value. Only the lower 8 bits of green are used.

blue
(Input) INTEGER(4). Intensity of the blue component of the RGB color value. Only the lower 8 bits of blue are used.

Results:

The result is of type INTEGER(4). The result is the combined RGB color value.

In each RGB color value, each of the three colors, red, green, and blue, is represented by an eight-bit value (2 hex digits). In the value returned with RGBTOINTEGER, red is the rightmost byte, followed by green and blue. The RGB value's internal structure is as follows:

Larger numbers correspond to stronger color intensity with binary 1111111 (hex FF) the maximum for each of the three components. For example, #0000FF yields full-intensity red, #00FF00 full-intensity green, #FF0000 full-intensity blue, and #FFFFFF full-intensity for all three, resulting in bright white.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: Using QuickWin, INTEGERTORGB, SETCOLORRGB, SETBKCOLORRGB, SETPIXELRGB, SETPIXELSRGB, SETTEXTCOLORRGB

Example

 ! Build as a QuickWin App.
 USE DFLIB
 INTEGER r, g, b, rgb, result
 INTEGER(2) status
 r = #F0
 g = #F0
 b = 0
 rgb = RGBTOINTEGER(r, g, b)
 result = SETCOLORRGB(rgb)
 status = ELLIPSE($GFILLINTERIOR,INT2(40), INT2(55), &
                   INT2(90), INT2(85))
 END


RINDEX

Portability Function: Locates the index of the last occurrence of a substring within a string.

Module: USE DFPORT

Syntax

result = RINDEX (string, substr)

string
(Input) Character*(*). Original string to search.

substr
(Input) Character*(*). String to search for.

Results:

The result is of type INTEGER(4). The result is the starting position of the final occurence of substrg in string. Returns 0 if substring does not occur in string.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: INDEX

Example

 USE DFPORT
 character*80 mainstring
 character*4 shortstr
 integer(4) where
 mainstring="Hello Hello Hello Hello There There There"
 shortstr="Hello"
 where=rindex(mainstring,shortstr)
 ! where is 19


RRSPACING

Elemental Intrinsic Function (Generic): Returns the reciprocal of the relative spacing of model numbers near the argument value.

Syntax

result = RRSPACING (x)

x
(Input) Must be of type real.

Results:

The result type is the same as x. The result has the value |x * b-e| x bp. Parameters b, e, p are defined in Model for Real Data.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPACING, Data Representation Models

Examples

If -3.0 is a REAL(4) value, RRSPACING (-3.0) has the value 0.75 x 224.

The following shows another example:

 REAL(4) res4
 REAL(8) res8, r2
 res4 = RRSPACING(3.0)  ! returns 1.258291E+07
 res4 = RRSPACING(-3.0) ! returns 1.258291E+07
 r2 = 487923.3
 res8 = RRSPACING(r2)   ! returns 8.382458680573952E+015
 END


RSHIFT

Elemental Intrinsic Function (Generic): Shifts the bits in an integer right by a specified number of positions. For more information, see ISHFT.


RTC

Portability Function: Returns the number of seconds elapsed since a specific Greenwich mean time.

Module: USE DFPORT

Syntax

result = RTC( )

Results:

The result is of type REAL(8). The result is the number of seconds elapsed since 00:00:00 Greenwich mean time, January 1, 1970.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE_AND_TIME, TIME

Example

 USE DFPORT
 real(8) s, s1, time_spent
 INTEGER(4) i, j
 s = RTC( )
 call sleep(4)
 s1 = RTC( )
 time_spent = s1 - s
 PRINT *, 'It took ',time_spent, 'seconds to run.'


RUNQQ

Run-Time Function: Executes another program and waits for it to complete.

Module: USE DFLIB

Syntax

result = RUNQQ (filename, commandline)

filename
(Input) Character*(*). Filename of a program to be executed.

commandline
(Input) Character*(*). Command-line arguments passed to the program to be executed.

Results:

The result is of type INTEGER(2). If the program executed with RUNQQ terminates normally, the exit code of that program is returned to the program that launched it. If the program fails, -1 is returned.

The RUNQQ function executes a new process for the operating system using the same path, environment, and resources as the process that launched it. The launching process is suspended until execution of the launched process is complete.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SYSTEM, NARGS

Example

See example in NARGS.

 USE DFLIB
 INTEGER(2) result
 result = RUNQQ('myprog', '-c -r')
 END


SAVE

Statement and Attribute: Causes the values and definition of objects to be retained after execution of a RETURN or END statement in a subprogram.

The SAVE attribute can be specified in a type declaration statement or a SAVE statement, and takes one of the following forms:

Syntax

Type Declaration Statement:

type, [att-ls,] SAVE [, att-ls] :: [object [, object] ...]

Statement:

SAVE [object [, object] ...]

type
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

object
Is the name of an object, or the name of a common block enclosed in slashes (/common-block-name/).

Rules and Behavior

In Compaq Fortran, certain variables are given the SAVE attribute, or not, by default:

  • The following variables are saved by default:

    • COMMON variables
    • Local variables of recursive subprograms
    • Data initialized by DATA statements

  • The following variables are not saved by default:

    • Variables that are declared AUTOMATIC
    • Local variables that are allocatable arrays
    • Derived-type variables that are data initialized by default initialization of any of their components
    • RECORD variables that are data initialized by default initialization specified in its STRUCTURE declaration

  • Local variables that are not described in the preceding two lists are saved by default.

To enhance portability and avoid possible compiler warning messages, Compaq recommends that you use the SAVE statement to name variables whose values you want to preserve between subprogram invocations.

When a SAVE statement does not explicitly contain a list, all allowable items in the scoping unit are saved.

A SAVE statement cannot specify the following (their values cannot be saved):

  • A blank common
  • An object in a common block
  • A procedure
  • A dummy argument
  • A function result
  • An automatic object
  • A PARAMETER (named) constant

Even though a common block can be included in a SAVE statement, individual variables within the common block can become undefined (or redefined) in another scoping unit.

If a common block is saved in any scoping unit of a program (other than the main program), it must be saved in every scoping unit in which the common block appears.

A SAVE statement has no effect in a main program.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: COMMON, DATA, RECURSIVE, MODULE, MODULE PROCEDURE, Type Declarations, Compatible attributes

Examples

The following example shows a type declaration statement specifying the SAVE attribute:

SUBROUTINE TEST()
  REAL, SAVE :: X, Y

The following is an example of the SAVE statement:

SAVE A, /BLOCK_B/, C, /BLOCK_D/, E

The following shows another example:

  SUBROUTINE MySub
    COMMON /z/ da, in, a, idum(10)
    real(8) x,y
    ...

    SAVE x, y, /z/
! alternate declaration
    REAL(8), SAVE :: x, y
    SAVE /z/


SAVEIMAGE, SAVEIMAGE_W

Graphics Function: Saves an image from a specified portion of the screen into a Windows bitmap file.

Module: USE DFLIB

Syntax

result = SAVEIMAGE (filename, ulxcoord, ulycoord, lrxcoord, lrycoord)
result = SAVEIMAGE_W (filename, ulwxcoord, ulwycoord, lrwxcoord, lrwycoord)

filename
(Input) Character*(*). Path of the bitmap file.

ulxcoord, ulycoord
(Input) INTEGER(4). Viewport coordinates for upper-left corner of the screen image to be captured.

lrxcoord, lrycoord
(Input) INTEGER(4). Viewport coordinates for lower-right corner of the screen image to be captured.

ulwxcoord, ulwycoord
(Input) REAL(8). Window coordinates for upper-left corner of the screen image to be captured.

lrwxcoord, lrwycoord
(Input) REAL(8). Window coordinates for lower-right corner of the screen image to be captured.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a negative value.

The SAVEIMAGE function captures the screen image within a rectangle defined by the upper-left and lower-right screen coordinates and stores the image as a Windows bitmap file specified by filename. The image is stored with a palette containing the colors displayed on the screen.

SAVEIMAGE defines the bounding rectangle in viewport coordinates. SAVEIMAGE_W defines the bounding rectangle in window coordinates.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETIMAGE, GETIMAGE_W, IMAGESIZE, IMAGESIZE_W, LOADIMAGE, LOADIMAGE_W, PUTIMAGE, PUTIMAGE_W


SCALE

Elemental Intrinsic Function (Generic): Returns the value of the exponent part (of the model for the argument) changed by a specified value.

Syntax

result = SCALE (x, i)

x
(Input) Must be of type real.

i
(Input) Must be of type integer.

Results:

The result type is the same as x. The result has the value x x bi. Parameter b is defined in Model for Real Data.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LSHIFT, Data Representation Models

Examples

If 3.0 is a REAL(4) value, SCALE (3.0, 2) has the value 12.0 and SCALE (3.0, 3) has the value 24.0.

The following shows another example:

REAL r
r = SCALE(5.2, 2)     !returns 20.8


SCAN

Elemental Intrinsic Function (Generic): Scans a string for any character in a set of characters.

Syntax

result = SCAN (string, set [, back] [, kind])

string
(Input) Must be of type character.

set
(Input) Must be of type character with the same kind parameter as string.

back
(Input) Must be of type logical.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

If back is omitted (or is present with the value false) and string has at least one character that is in set, the value of the result is the position of the leftmost character of string that is in set.

If back is present with the value true and string has at least one character that is in set, the value of the result is the position of the rightmost character of string that is in set.

If no character of string is in set or the length of string or set is zero, the value of the result is zero.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: VERIFY

Examples

SCAN ('ASTRING', 'ST') has the value 2.

SCAN ('ASTRING', 'ST', BACK=.TRUE.) has the value 3.

SCAN ('ASTRING', 'CD') has the value zero.

The following shows another example:

 INTEGER i
 INTEGER array(2)
 i = SCAN ('FORTRAN', 'TR')                 ! returns 3
 i = SCAN ('FORTRAN', 'TR', BACK = .TRUE.)  ! returns 5
 i = SCAN ('FORTRAN', 'GHA')                ! returns 6
 i = SCAN ('FORTRAN', 'ora')                ! returns 0
 array = SCAN ((/'FORTRAN','VISUALC'/),(/'A', 'A'/))
                                        ! returns (6, 5)
 ! Note that when using SCAN with arrays, the string
 ! elements must be the same length. When using string
 ! constants, blank pad to make strings the same length.
 ! For example:

 array = SCAN ((/'FORTRAN','MASM '/),(/'A', 'A'/))
                                        ! returns (6, 2)
 END


SCROLLTEXTWINDOW

Graphics Subroutine: Scrolls the contents of a text window.

Module: USE DFLIB

Syntax

CALL SCROLLTEXTWINDOW (rows)

rows
(Input) INTEGER(2). Number of rows to scroll.

The SCROLLTEXTWINDOW subroutine scrolls the text in a text window (previously defined by SETTEXTWINDOW). The default text window is the entire window.

The rows argument specifies the number of lines to scroll. A positive value for rows scrolls the window up (the usual direction); a negative value scrolls the window down. Specifying a number larger than the height of the current text window is equivalent to calling CLEARSCREEN ($GWINDOW). A value of 0 for rows has no effect.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: CLEARSCREEN, GETTEXTPOSITION, GETTEXTWINDOW, GRSTATUS, OUTTEXT, SETTEXTPOSITION, SETTEXTWINDOW, WRAPON

Example

 !  Build as QuickWin or Standard Graphics app.
 USE DFLIB
 INTEGER(2) row
 CHARACTER(18) string
 TYPE (rccoord) oldpos

 CALL SETTEXTWINDOW (INT2(1), INT2(0), &
                     INT2(25), INT2(80))
 CALL CLEARSCREEN ( $GCLEARSCREEN )

 DO row = 1, 6
    string = 'Hello, World # '
    CALL SETTEXTPOSITION( row, INT2(1), oldpos )
    WRITE(string(15:16), '(I2)') row
    CALL OUTTEXT( string )
 END DO
 WRITE(*,*) "Hit ENTER"
 READ (*,*) ! wait for ENTER
 !  Scroll window down 4 lines
 CALL SCROLLTEXTWINDOW(INT2( -4) )
 WRITE(*,*) "Hit ENTER"
 READ( *,* ) ! wait for ENTER
 !  Scroll window up 5 lines
 CALL SCROLLTEXTWINDOW( INT2(5 ))
 END


SCWRQQ (ia32 only)

Run-Time Subroutine: Returns the floating-point processor control word. This routine is only available on ia32 processors.

Module: USE DFLIB

Syntax

CALL SCWRQQ (control)

control
(Output) INTEGER(2). Floating-point processor control word.

SCRWQQ performs the same function as the run-time subroutine GETCONTROLFPQQ, and is provided for compatibility.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LCWRQQ

Example

See the example in LCWRQQ.


SECNDS

SECNDS can be used as an intrinsic function or as a portability routine.

SECNDS Intrinsic Function

Elemental Intrinsic Function (Specific): Provides the system time of day, or elapsed time, as a floating-point value in seconds.

This is a specific function that has no generic function associated with it. It must not be passed as an actual argument. It is not a pure function, so it cannot be referenced inside a FORALL construct.

Syntax

result = SECNDS (x)

x
(Input) Must be of type REAL(4).

Results:

The result type is the same as x. The result value is the time in seconds since midnight - x. (The function also produces correct results for time intervals that span midnight.)

The value of SECNDS is accurate to 0.01 second, which is the resolution of the system clock.

The 24 bits of precision provide accuracy to the resolution of the system clock for about one day. However, loss of significance can occur if you attempt to compute very small elapsed times late in the day.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE_AND_TIME, RTC, SYSTEM_CLOCK, TIME

Example

The following shows how to use SECNDS to perform elapsed-time computations:

C    START OF TIMED SEQUENCE
     T1 = SECNDS(0.0)

C    CODE TO BE TIMED
     ...
     DELTA = SECNDS(T1)      ! DELTA gives the elapsed time

SECNDS Portability Routine

Portability Function: Returns the number of seconds that have elapsed since midnight, less the value of its argument.

Module: USE DFPORT

Syntax

result = SECNDS (r)

r
(Input) REAL(4). Number of seconds, precise to a hundredth of a second (0.01), to be subtracted.

Results:

The result is of type REAL(4). The result is the number of seconds that have elapsed since midnight, minus r, with a precision of a hundredth of a second (0.01).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE_AND_TIME, RTC, SYSTEM_CLOCK, TIME

Example

 USE DFPORT
 REAL(4) s
 INTEGER(4) i, j
 s = SECNDS(0.0)
 DO I = 1, 100000
    J = J + 1
 END DO
 s = SECNDS(s)
 PRINT *, 'It took ',s, 'seconds to run.'


SECTIONS (TU*X only)

OpenMP Parallel Compiler Directive: Specifies one or more blocks of code that must be divided among threads in the team. Each section is executed once by a thread in the team.

Syntax

c$OMP SECTIONS [clause[[,] clause] ... ]
[c$OMP SECTION]
block
[c$OMP SECTION
block] ...
c$OMP END SECTIONS [NOWAIT]

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

clause
Is one of the following:

  • FIRSTPRIVATE (list)
  • LASTPRIVATE (list)
  • PRIVATE (list)
  • REDUCTION( operator | intrinsic : list)

block
Is a structured block (section) of statements or constructs. Any constituent section must also be a structured block.

You cannot branch into or out of the block.

Rules and Behavior

Each section of code is preceded by a SECTION directive, although the directive is optional for the first section. The SECTION directives must appear within the lexical extent of the SECTIONS and END SECTIONS directive pair.

The last section ends at the END SECTIONS directive. Threads that complete execution of their SECTIONs encounter an implied barrier at the END SECTIONS directive unless NOWAIT is specified.

SECTIONS directives must be encountered by all threads in a team or by none at all. It must also be encountered in the same order by all threads in a team.

See Also: Parallel Directives for Tru64 UNIX Systems, OpenMP Fortran API Compiler Directives (TU*X only), Compaq Fortran Parallel Compiler Directives (TU*X only)

Examples

In the following example, subroutines XAXIS, YAXIS, and ZAXIS can be executed concurrently:

  c$OMP PARALLEL
  c$OMP SECTIONS
  c$OMP SECTION
        CALL XAXIS
  c$OMP SECTION
        CALL YAXIS
  c$OMP SECTION
        CALL ZAXIS
  c$OMP END SECTIONS
  c$OMP END PARALLEL


SEED

Run-Time Subroutine: Changes the starting point of the pseudorandom number generator.

Module: USE DFLIB

Syntax

CALL SEED (iseed)

iseed
(Input) INTEGER(4). Starting point for RANDOM.

SEED uses iseed to establish the starting point of the pseudorandom number generator. A given seed always produces the same sequence of values from RANDOM.

If SEED is not called before the first call to RANDOM, RANDOM always begins with a seed value of one. If a program must have a different pseudorandom sequence each time it runs, pass the constant RND$TIMESEED (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory) to the SEED routine before the first call to RANDOM.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RANDOM, RANDOM_SEED, RANDOM_NUMBER

Example

 USE DFLIB
 REAL rand
 CALL SEED(7531)
 CALL RANDOM(rand)


SELECT CASE...END SELECT

Statement: Transfers program control to a selected block of statements according to the value of a controlling expression. For more information, see CASE.

Example

 CHARACTER*1 cmdchar
 . . .
 Files: SELECT CASE (cmdchar)
   CASE ('0')
     WRITE (*, *) "Must retrieve one to nine files"
   CASE ('1':'9')
     CALL RetrieveNumFiles (cmdchar)
   CASE ('A', 'a')
     CALL AddEntry
   CASE ('D', 'd')
     CALL DeleteEntry
   CASE ('H', 'h')
     CALL Help
   CASE DEFAULT
     WRITE (*, *) "Command not recognized; please re-enter"
 END SELECT Files


SELECTED_INT_KIND

Transformational Intrinsic Function (Generic): Returns the value of the kind parameter of an integer data type.

Syntax

result = SELECTED_INT_KIND (r)

r
(Input) Must be scalar and of type integer.

Results:

The result is a scalar of type default integer. The result has a value equal to the value of the kind parameter of the integer data type that represents all values n in the range of values n with -10r < n < 10r.

If no such kind type parameter is available on the processor, the result is -1. If more than one kind type parameter meets the criteria, the value returned is the one with the smallest decimal exponent range. For more information, see Model for Integer Data.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SELECTED_REAL_KIND

Example

SELECTED_INT_KIND (6) = 4

The following shows another example:

 i = SELECTED_INT_KIND(8)  ! returns 4
 i = SELECTED_INT_KIND(3)  ! returns 2
 i = SELECTED_INT_KIND(10) ! returns -1, precision
                           ! not available for this type


SELECTED_REAL_KIND

Transformational Intrinsic Function (Generic): Returns the value of the kind parameter of a real data type.

Syntax

result = SELECTED_REAL_KIND ([p] [, r])

p
(Optional; input) Must be scalar and of type integer.

r
(Optional; input) Must be scalar and of type integer.

At least one argument must be specified.

Results:

The result is a scalar of type default integer. The result has a value equal to a value of the kind parameter of a real data type with decimal precision, as returned by the function PRECISION, of at least p digits and a decimal exponent range, as returned by the function RANGE, of at least r.

If no such kind type parameter is available on the processor, the result is as follows:

   -1 if the precision is not available
   -2 if the exponent range is not available
   -3 if neither is available

If more than one kind type parameter value meets the criteria, the value returned is the one with the smallest decimal precision. For more information, see Model for Real Data.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SELECTED_INT_KIND

Example

SELECTED_REAL_KIND (6, 70) = 8

The following shows another example:

 i = SELECTED_REAL_KIND(r=200)  ! returns 8
 i = SELECTED_REAL_KIND(13)     ! returns 8


SEQUENCE

Statement: Preserves the storage order of a derived-type definition.

Syntax

SEQUENCE

Rules and Behavior

The SEQUENCE statement allows derived types to be used in common blocks and to be equivalenced.

The SEQUENCE statement appears only as part of derived-type definitions. It causes the components of the derived type to be stored in the same sequence they are listed in the type definition. If you do not specify SEQUENCE, the physical storage order is not necessarily the same as the order of components in the type definition.

If a derived type is a sequence derived type, then any other derived type that includes it must also be a sequence type.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Derived Type, Data Types, Constants, and Variables

Example

 !DEC$ PACK:1
 TYPE NUM1_SEQ
   SEQUENCE
   INTEGER(2)::int_val
   REAL(4)::real_val
   LOGICAL(2)::log_val
 END TYPE NUM1_SEQ
 TYPE num2_seq
    SEQUENCE
    logical(2)::log_val
    integer(2)::int_val
    real(4)::real_val
 end type num2_seq
 type (num1_seq) num1
 type (num2_seq) num2
 character*8 t, t1
 equivalence (num1,t)
 equivalence (num2,t1)
 num1%int_val=2
 num1%real_val=3.5
 num1%log_val=.TRUE.
 t1(1:2)=t(7:8)
 t1(3:4)=t(1:2)
 t1(5:8)=t(3:6)
 print *, num2%int_val, num2%real_val, num2%log_val
 end


SETACTIVEQQ

QuickWin Function: Makes a child window active, but does not give it focus.

Module: USE DFLIB

Syntax

result = SETACTIVEQQ (unit)

unit
(Input) INTEGER(4). Unit number of the child window to be made active.

Results:

The result is of type INTEGER(4). The result is 1 if successful; otherwise, 0.

When a window is made active, it receives graphics output (from ARC, LINETO and OUTGTEXT, for example) but is not brought to the foreground and does not have the focus. If a window needs to be brought to the foreground, it must be given the focus. A window is given focus with FOCUSQQ, by clicking it with the mouse, or by performing I/O other than graphics on it, unless the window was opened with IOFOCUS='.FALSE.'. By default, IOFOCUS='.TRUE.', except for child windows opened as unit '*'.

The window that has the focus is always on top, and all other windows have their title bars grayed out. A window can have the focus and yet not be active and not have graphics output directed to it. Graphical output is independent of focus.

If IOFOCUS='.TRUE.', the child window receives focus prior to each READ, WRITE, PRINT, or OUTTEXT. Calls to graphics functions (such as OUTGTEXT and ARC) do not cause the focus to shift.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: GETACTIVEQQ, FOCUSQQ, INQFOCUSQQ, Using QuickWin


SETBKCOLOR

Graphics Function: Sets the current background color index for both text and graphics.

Module: USE DFLIB

Syntax

result = SETBKCOLOR (color)

color
(Input) INTEGER(4). Color index to set the background color to.

Results:

The result is of type INTEGER(4). The result is the previous background color index.

SETBKCOLOR changes the background color index for both text and graphics. The color index of text over the background color is set with SETTEXTCOLOR. The color index of graphics over the background color (used by drawing functions such as FLOODFILL and ELLIPSE) is set with SETCOLOR. These non-RGB color functions use color indexes, not true color values, and limit the user to colors in the palette, at most 256. For access to all system colors, use SETBKCOLORRGB, SETCOLORRGB, and SETTEXTCOLORRGB.

Changing the background color index does not change the screen immediately. The change becomes effective when CLEARSCREEN is executed or when doing text input or output, such as with READ, WRITE, or OUTTEXT. The graphics output function OUTGTEXT does not affect the color of the background.

Generally, INTEGER(4) color arguments refer to color values and INTEGER(2) color arguments refer to color indexes. The two exceptions are GETBKCOLOR and SETBKCOLOR. The default background color index is 0, which is associated with black unless the user remaps the palette with REMAPPALETTERGB.

Note: The SETBKCOLOR routine described here is a QuickWin routine. If you are trying to use the Win32 SDK version of the SetBkColor routine by including the DFWIN module, you need to specify the routine name as MSFWIN$SetBkColor. For more information, see Special Naming Convention for Certain QuickWin and Win32 Graphics Routines in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETBKCOLORRGB, GETBKCOLOR, REMAPALLPALETTERGB, REMAPPALETTERGB, SETCOLOR, SETTEXTCOLOR

Example

 USE DFLIB
 INTEGER(4) i
 i = SETBKCOLOR(14)


SETBKCOLORRGB

Graphics Function: Sets the current background color to the given Red-Green-Blue (RGB) value.

Module: USE DFLIB

Syntax

result = SETBKCOLORRGB (color)

color
(Input) INTEGER(4). RGB color value to set the background color to. Range and result depend on the system's display adapter.

Results:

The result is of type INTEGER(4). The result is the previous background RGB color value.

In each RGB color value, each of the three colors, red, green, and blue, is represented by an eight-bit value (2 hex digits). In the value you specify with SETBKCOLORRGB, red is the rightmost byte, followed by green and blue. The RGB value's internal structure is as follows:

Larger numbers correspond to stronger color intensity with binary 1111111 (hex FF) the maximum for each of the three components. For example, #0000FF yields full-intensity red, #00FF00 full-intensity green, #FF0000 full-intensity blue, and #FFFFFF full-intensity for all three, resulting in bright white.

The default background color is value 0, which is black. Changing the background color value does not change the screen immediately, but becomes effective when CLEARSCREEN is executed or when doing text input or output such as READ, WRITE, or OUTTEXT. The graphics output function OUTGTEXT does not affect the color of the background.

SETBKCOLORRGB sets the RGB color value of the current background for both text and graphics. The RGB color value of text over the background color (used by text functions such as OUTTEXT, WRITE, and PRINT) is set with SETTEXTCOLORRGB. The RGB color value of graphics over the background color (used by graphics functions such as ARC, OUTGTEXT, and FLOODFILLRGB) is set with SETCOLORRGB.

SETBKCOLORRGB (and the other RGB color selection functions SETCOLORRGB, and SETTEXTCOLORRGB) sets the color to a value chosen from the entire available range. The non-RGB color functions (SETCOLOR, SETBKCOLOR, and SETTEXTCOLOR) use color indexes rather than true color values. If you use color indexes, you are restricted to the colors available in the palette, at most 256. Some display adapters (SVGA and true color) are capable of creating 262,144 (256K) colors or more. To access any available color, you need to specify an explicit RGB value with an RGB color function, rather than a palette index with a non-RGB color function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETBKCOLORRGB, SETCOLORRGB, SETTEXTCOLORRGB, SETPIXELRGB, SETPIXELSRGB, SETBKCOLOR

Example

 ! Build as a QuickWin or Standard Graphics App.
 USE DFLIB
 INTEGER(4) oldcolor
 INTEGER(2) status, x1, y1, x2, y2
 x1 = 80; y1 = 50
 x2 = 240; y2 = 150
 oldcolor = SETBKCOLORRGB(#FF0000) !blue
 oldcolor = SETCOLORRGB(#FF) ! red
 CALL CLEARSCREEN ($GCLEARSCREEN)
 status = ELLIPSE($GBORDER, x1, y1, x2, y2)
 END


SETCLIPRGN

Graphics Subroutine: Limits graphics output to part of the screen.

Module: USE DFLIB

Syntax

CALL SETCLIPRGN (x1, y1, x2, x2)

x1, y1
(Input) INTEGER(2). Physical coordinates for upper-left corner of clipping region.

x2, y2
(Input) INTEGER(2). Physical coordinates for lower-right corner of clipping region.

The SETCLIPRGN function limits the display of subsequent graphics output and font text output to that which fits within a designated area of the screen (the "clipping region"). The physical coordinates (x1, y1) and (x2, y2) are the upper-left and lower-right corners of the rectangle that defines the clipping region. The SETCLIPRGN function does not change the viewport-coordinate system; it merely masks graphics output to the screen.

SETCLIPRGN affects graphics and font text output only, such as OUTGTEXT. To mask the screen for text output using OUTTEXT, use SETTEXTWINDOW.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETPHYSCOORD, GRSTATUS, SETTEXTWINDOW, SETVIEWORG, SETVIEWPORT, SETWINDOW

Example

This program draws an ellipse lying partly within a clipping region, as shown below.

 ! Build as QuickWin or Standard Graphics ap.
 USE DFLIB
 INTEGER(2) status, x1, y1, x2, y2
 INTEGER(4) oldcolor
 x1 = 10;  y1 = 50
 x2 = 170; y2 = 150
 ! Draw full ellipse in white
 status = ELLIPSE($GBORDER, x1, y1, x2, y2)
 oldcolor = SETCOLORRGB(#FF0000) !blue
 WRITE(*,*) "Hit enter"
 READ(*,*)
 CALL CLEARSCREEN($GCLEARSCREEN) ! clear screen
 CALL SETCLIPRGN( INT2(0), INT2(0), &
                  INT2(150), INT2(125))
 ! only part of ellipse inside clip region drawn now
 status = ELLIPSE($GBORDER, x1, y1, x2, y2)
 END

Figure: Output of Program SETCLIP.FOR


SETCOLOR

Graphics Function: Sets the current graphics color index.

Module: USE DFLIB

Syntax

result = SETCOLOR (color)

color
(Input) INTEGER(2). Color index to set the current graphics color to.

Results:

The result is of type INTEGER(2). The result is the previous color index if successful; otherwise, -1.

The SETCOLOR function sets the current graphics color index, which is used by graphics functions such as ELLIPSE. The background color index is set with SETBKCOLOR. The color index of text over the background color is set with SETTEXTCOLOR. These non-RGB color functions use color indexes, not true color values, and limit the user to colors in the palette, at most 256. For access to all system colors, use SETCOLORRGB, SETBKCOLORRGB, and SETTEXTCOLORRGB.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETCOLORRGB, GETCOLOR, REMAPPALETTERGB, SETBKCOLOR, SETTEXTCOLOR, SETPIXEL, SETPIXELS

Example

 USE DFLIB
 INTEGER(2) color, oldcolor
 LOGICAL status
 TYPE (windowconfig) wc

 status = GETWINDOWCONFIG(wc)
 color = wc%numcolors - 1
 oldcolor = SETCOLOR(color)
 END


SETCOLORRGB

Graphics Function: Sets the current graphics color to the specified Red-Green-Blue (RGB) value.

Module: USE DFLIB

Syntax

result = SETCOLORRGB (color)

color
(Input) INTEGER(4). RGB color value to set the current graphics color to. Range and result depend on the system's display adapter.

Results:

The result is of type INTEGER(4). The result is the previous RGB color value.

In each RGB color value, each of the three colors, red, green, and blue, is represented by an eight-bit value (2 hex digits). In the value you specify with SETCOLORRGB, red is the rightmost byte, followed by green and blue. The RGB value's internal structure is as follows:

Larger numbers correspond to stronger color intensity with binary 1111111 (hex FF) the maximum for each of the three components. For example, #0000FF yields full-intensity red, #00FF00 full-intensity green, #FF0000 full-intensity blue, and #FFFFFF full-intensity for all three, resulting in bright white.

SETCOLORRGB sets the RGB color value of graphics over the background color, used by the following graphics functions: ARC, ELLIPSE, FLOODFILL, LINETO, OUTGTEXT, PIE, POLYGON, RECTANGLE, and SETPIXEL. SETBKCOLORRGB sets the RGB color value of the current background for both text and graphics. SETTEXTCOLORRGB sets the RGB color value of text over the background color (used by text functions such as OUTTEXT, WRITE, and PRINT).

SETCOLORRGB (and the other RGB color selection functions SETBKCOLORRGB, and SETTEXTCOLORRGB) sets the color to a value chosen from the entire available range. The non-RGB color functions (SETCOLOR, SETBKCOLOR, and SETTEXTCOLOR) use color indexes rather than true color values. If you use color indexes, you are restricted to the colors available in the palette, at most 256. Some display adapters (SVGA and true color) are capable of creating 262,144 (256K) colors or more. To access any available color, you need to specify an explicit RGB value with an RGB color function, rather than a palette index with a non-RGB color function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETBKCOLORRGB, SETTEXTCOLORRGB, GETCOLORRGB, ARC, ELLIPSE, FLOODFILLRGB, SETCOLOR, LINETO, OUTGTEXT, PIE, POLYGON, RECTANGLE, REMAPPALETTERGB, SETPIXELRGB, SETPIXELSRGB

Example

 ! Build as a QuickWin or Standard Graphics App.
 USE DFLIB
 INTEGER(2) numfonts
 INTEGER(4) oldcolor
 TYPE (xycoord) xy
 numfonts = INITIALIZEFONTS( )
 oldcolor = SETCOLORRGB(#0000FF)   ! red
 oldcolor = SETBKCOLORRGB(#00FF00) ! green
 CALL MOVETO(INT2(200), INT2(100), xy)
 CALL OUTGTEXT("hello, world")
 END


SETCONTROLFPQQ (ia32 only)

Run-Time Subroutine: Sets the value of the floating-point processor control word. This routine is only available on ia32 processors.

Module: USE DFLIB

Syntax

CALL SETCONTROLFPQQ (controlword)

controlword
(Input) INTEGER(2). Floating-point processor control word.

The floating-point control word specifies how various exception conditions are handled by the floating-point math coprocessor, sets the floating-point precision, and specifies the floating-point rounding mechanism used.

The DFLIB.F90 module file (in the \DF98\INCLUDE subdirectory) contains constants defined for the control word as follows:

Parameter name | Hex value | Description
FPCW$MCW_IC | #1000 | Infinity control mask
FPCW$AFFINE | #1000 | Affine infinity
FPCW$PROJECTIVE | #0000 | Projective infinity
FPCW$MCW_PC | #0300 | Precision control mask
FPCW$64 | #0300 | 64-bit precision
FPCW$53 | #0200 | 53-bit precision
FPCW$24 | #0000 | 24-bit precision
FPCW$MCW_RC | #0C00 | Rounding control mask
FPCW$CHOP | #0C00 | Truncate
FPCW$UP | #0800 | Round up
FPCW$DOWN | #0400 | Round down
FPCW$NEAR | #0000 | Round to nearest
FPCW$MCW_EM | #003F | Exception mask
FPCW$INVALID | #0001 | Allow invalid numbers
FPCW$DENORMAL | #0002 | Allow denormals (very small numbers)
FPCW$ZERODIVIDE | #0004 | Allow divide by zero
FPCW$OVERFLOW | #0008 | Allow overflow
FPCW$UNDERFLOW | #0010 | Allow underflow
FPCW$INEXACT | #0020 | Allow inexact precision

The defaults for the floating-point control word are 53-bit precision, round to nearest, and the denormal, underflow and inexact precision exceptions disabled. An exception is disabled if its flag is set to 1 and enabled if its flag is cleared to 0.

Setting the floating-point precision and rounding mechanism can be useful if you are reusing old code that is sensitive to the floating-point precision standard used and you want to get the same results as on the old machine.

You can use GETCONTROLFPQQ to retrieve the current control word and SETCONTROLFPQQ to change the control word. Most users do not need to change the default settings. If you need to change the control word, always use SETCONTROLFPQQ to make sure that special routines handling floating-point stack exceptions and abnormal propagation work correctly.

For a full discussion of the floating-point control word, exceptions, and error handling, see The Floating-Point Environment in the Programmer's Guide.

The Visual Fortran exception handler allows for software masking of invalid operations, but does not allow the math chip to mask them. If you choose to use the software masking, be aware that this can affect program performance if you compile code written for Visual Fortran with another compiler.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETCONTROLFPQQ, GETSTATUSFPQQ, LCWRQQ, SCWRQQ, CLEARSTATUSFPQQ

Example

 USE DFLIB
 INTEGER(2) status, control, controlo

 CALL GETCONTROLFPQQ(control)
 WRITE (*, 9000) 'Control word: ', control
 !     Save old control word
 controlo = control
 !     Clear all flags
 control = control .AND. #0000
 !     Set new control to round up
 control = control .OR. FPCW$UP
 CALL SETCONTROLFPQQ(control)
 CALL GETCONTROLFPQQ(control)
 WRITE (*, 9000) 'Control word: ', control
 9000 FORMAT (1X, A, Z4)
 END


SETDAT

Run-Time Function: Sets the system date.

Module: USE DFLIB

Syntax

result = SETDAT (iyr, imon, iday)

iyr
(Input) INTEGER(2). Year (xxxx AD).

imon
(Input) INTEGER(2). Month (1-12).

iday
(Input) INTEGER(2). Day of the month (1-31).

Results:

The result is of type LOGICAL(4). The result is .TRUE. if the system date is changed; .FALSE. if no change is made.

Actual arguments of the function SETDAT can be any valid INTEGER(2) expression.

Refer to your operating system documentation for the range of permitted dates.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETDAT, GETTIM, SETTIM

Example

 USE DFLIB
 LOGICAL(4) success
 success = SETDAT(INT2(1997+1), INT2(2*3), INT2(30))
 END


SETENVQQ

Run-Time Function: Sets the value of an existing environment variable, or adds and sets a new environment variable.

Module: USE DFLIB

Syntax

result = SETENVQQ (varname=value)

varname = value
(Input) Character*(*). String containing both the name and the value of the variable to be added or modified. Must be in the form: varname = value, where varname is the name of an environment variable and value is the value being assigned to it.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

Environment variables define the environment in which a program executes. For example, the LIB environment variable defines the default search path for libraries to be linked with a program.

SETENVQQ deletes any terminating blanks in the string. Although the equal sign (=) is an illegal character within an environment value, you can use it to terminate value so that trailing blanks are preserved. For example, the string PATH=  = sets value to ''.

You can use SETENVQQ to remove an existing variable by giving a variable name followed by an equal sign with no value. For example, LIB= removes the variable LIB from the list of environment variables. If you specify a value for a variable that already exists, its value is changed. If the variable does not exist, it is created.

SETENVQQ affects only the environment that is local to the current process. You cannot use it to modify the command-level environment. When the current process terminates, the environment reverts to the level of the parent process. In most cases, this is the operating system level. However, you can pass the environment modified by SETENVQQ to any child process created by RUNQQ. These child processes get new variables and/or values added by SETENVQQ.

SETENVQQ uses the C runtime routine _putenv and GETENVQQ uses the C runtime routine getenv. From the C documentation:

getenv and _putenv use the copy of the environment pointed to by the global variable _environ to access the environment. getenv operates only on the data structures accessible to the run-time library and not on the environment segment created for the process by the operating system.

SETENVQQ and GETENVQQ will not work properly with the Win32 APIs SetEnvironmentVariable and GetEnvironmentVariable.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETENVQQ

Example

 USE DFLIB
 LOGICAL(4) success
 success = SETENVQQ("PATH=c:\mydir\tmp")
 success = &
 SETENVQQ("LIB=c:\mylib\bessel.lib;c:\math\difq.lib")
 END


SETERRORMODEQQ

Run-Time Subroutine: Sets the prompt mode for critical errors that by default generate system prompts.

Module: USE DFLIB

Syntax

CALL SETERRORMODEQQ (pmode)

pmode
(Input) LOGICAL(4). Flag that determines whether a prompt is displayed when a critical error occurs.

Certain I/O errors cause the system to display an error prompt. For example, attempting to write to a disk drive with the drive door open generates an "Abort, Retry, Ignore" message. When the system starts up, system error prompting is enabled by default (pmode = .TRUE.). You can also enable system error prompts by calling SETERRORMODEQQ with pmode set to ERR$HARDPROMPT (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory).

If prompt mode is turned off, a critical error that by default causes a system prompt will not cause a system prompt. Erroneous I/O statements such as OPEN, READ, and WRITE fail immediately instead of being interrupted with prompts. This allows you to intercept failures in the I/O statement (by setting ERR=errlabel, for example, where errlabel designates an executable statement) and to take a different action than that requested by the system prompt, such as opening a temporary file, giving a more informative error message, or exiting. You can turn off prompt mode by setting pmode to .FALSE. or to the constant ERR$HARDFAIL (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory).

Note that SETERRORMODEQQ affects only errors that generate a system prompt. It does not affect other I/O errors, such as writing to a nonexistent file or attempting to open a nonexistent file with STATUS='OLD'.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

 !PROGRAM 1
 !  DRIVE B door open
 OPEN (10, FILE = 'B:\NOFILE.DAT', ERR = 100)
 !  Generates a system prompt error here and waits for the user
 !  to respond to the prompt before continuing
 100   WRITE(*,*) ' Continuing'
 END

 ! PROGRAM 2
 !  DRIVE B door open
  USE DFLIB
  CALL SETERRORMODEQQ(.FALSE.)
  OPEN (10, FILE = 'B:\NOFILE.DAT', ERR = 100)
 !  Causes the statement at label 100 to execute
 !  without system prompt
 100   WRITE(*,*) ' Drive B: not available, opening      &
                    &alternative drive.'
  OPEN (10, FILE = 'C:\NOFILE.DAT')
  END


SETEXITQQ

QuickWin Function: Sets a QuickWin application's exit behavior.

Module: USE DFLIB

Syntax

result = SETEXITQQ (exitmode)

exitmode
(Input) INTEGER(4). Determines the program exit behavior. The following exit parameters are defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory):

  • QWIN$EXITPROMPT - Displays the following message box:

    "Program exited with exit status X. Exit Window?"

    where X is the exit status from the program.

    If Yes is entered, the application closes the window and terminates. If No is entered, the dialog box disappears and you can manipulate the windows as usual. You must then close the window manually.

  • QWIN$EXITNOPERSIST - Terminates the application without displaying a message box.

  • QWIN$EXITPERSIST - Leaves the application open without displaying a message box.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a negative value.

The default for both QuickWin and Standard Graphics applications is QWIN$EXITPROMPT.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETEXITQQ, Using QuickWin

Example

 ! Build as QuickWin Ap
 USE DFLIB
 INTEGER(4) exmode, result

 WRITE(*,'(1X,A,/)') 'Please enter the exit mode 1, 2   &
                      or 3 '
 READ(*,*) exmode
 SELECT CASE (exmode)
   CASE (1)
     result = SETEXITQQ(QWIN$EXITPROMPT)
   CASE (2)
     result = SETEXITQQ(QWIN$EXITNOPERSIST)
   CASE (3)
     result = SETEXITQQ(QWIN$EXITPERSIST)
   CASE DEFAULT
     WRITE(*,*) 'Invalid option - checking for bad     &
                 return'
     IF(SETEXITQQ( exmode ) .NE. -1) THEN
       WRITE(*,*) 'Error not returned'
     ELSE
       WRITE(*,*) 'Error code returned'
     ENDIF
 END SELECT
 END


SET_EXPONENT

Elemental Intrinsic Function (Generic): Returns the value of the exponent part (of the model for the argument) set to a specified value.

Syntax

result = SET_EXPONENT (x, i)

x
(Input) Must be of type real.

i
(Input) Must be of type integer.

Results:

The result type is the same as x. The result has the value x x bi-e. Parameters b and e are defined in Model for Real Data. If x has the value zero, the result is zero.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: EXPONENT, Data Representation Models

Example

If 3.0 is a REAL(4) value, SET_EXPONENT (3.0, 1) has the value 1.5.


SETFILEACCESSQQ

Run-Time Function: Sets the file access mode for a specified file.

Module: USE DFLIB

Syntax

result = SETFILEACCESSQQ (filename, access)

filename
(Input) Character*(*). Name of a file to set access for.

access
(Input) INTEGER(4). Constant that sets the access. Can be any combination of the following flags, combined by an inclusive OR (such as IOR or OR):

  • FILE$ARCHIVE - Marked as having been copied to a backup device.
  • FILE$HIDDEN - Hidden. The file does not appear in the directory list that you can request from the command console.
  • FILE$NORMAL - No special attributes (default).
  • FILE$READONLY - Write-protected. You can read the file, but you cannot make changes to it.
  • FILE$SYSTEM - Used by the operating system.

The flags are defined in module DFLIB.F90 in the \DF98\INCLUDE subdirectory.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

To set the access value for a file, add the constants representing the appropriate access.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETFILEINFOQQ

Example

 USE DFLIB
 INTEGER(4) permit
 LOGICAL(4) result

 permit = 0   ! clear permit
 permit = IOR(FILE$READONLY, FILE$HIDDEN)
 result = SETFILEACCESSQQ ('formula.f90', permit)
 END


SETFILETIMEQQ

Run-Time Function: Sets the modification time for a specified file.

Module: USE DFLIB

Syntax

result = SETFILETIMEQQ (filename, timedate)

filename
(Input) Character*(*). Name of a file.

timedate
(Input) INTEGER(4). Time and date information, as packed by PACKTIMEQQ.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

The modification time is the time the file was last modified and is useful for keeping track of different versions of the file. The process that calls SETFILETIMEQQ must have write access to the file; otherwise, the time cannot be changed. If you set timedate to FILE$CURTIME (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory), SETFILETIMEQQ sets the modification time to the current system time.

If the function fails, call GETLASTERRORQQ to determine the reason. It can be one of the following:

  • ERR$ACCES - Permission denied. The file's (or directory's) permission setting does not allow the specified access.
  • ERR$INVAL - Invalid argument; the timedate argument is invalid.
  • ERR$MFILE - Too many open files (the file must be opened to change its modification time).
  • ERR$NOENT - File or path not found.
  • ERR$NOMEM - Not enough memory is available to execute the command; or the available memory has been corrupted; or an invalid block exists, indicating that the process making the call was not allocated properly.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: PACKTIMEQQ, UNPACKTIMEQQ, GETLASTERRORQQ

Example

 USE DFLIB
 INTEGER(2) day, month, year
 INTEGER(2) hour, minute, second, hund
 INTEGER(4) timedate
 LOGICAL(4) result

 CALL GETDAT(year, month, day)
 CALL GETTIM(hour, minute, second, hund)
 CALL PACKTIMEQQ (timedate, year, month, day,    &
                  hour, minute, second)
 result = SETFILETIMEQQ('myfile.dat', timedate)
 END


SETFILLMASK

Graphics Subroutine: Sets the current fill mask to a new pattern.

Module: USE DFLIB

Syntax

CALL SETFILLMASK (mask)

mask
(Input) INTEGER(1). One-dimensional array of length 8.

There are 8 bytes in mask, and each of the 8 bits in each byte represents a pixel, creating an 8x8 pattern. The first element (byte) of mask becomes the top 8 bits of the pattern, and the eighth element (byte) of mask becomes the bottom 8 bits.

During a fill operation, pixels with a bit value of 1 are set to the current graphics color, while pixels with a bit value of zero are set to the current background color. The current graphics color is set with SETCOLORRGB or SETCOLOR. The 8-byte mask is replicated over the entire fill area. If no fill mask is set (with SETFILLMASK), or if the mask is all ones, solid current color is used in fill operations.

The fill mask controls the fill pattern for graphics routines (FLOODFILLRGB, PIE, ELLIPSE, POLYGON, and RECTANGLE).

To change the current fill mask, determine the array of bytes that corresponds to the desired bit pattern and set the pattern with SETFILLMASK, as in the following example.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: ELLIPSE, FLOODFILLRGB, GETFILLMASK, PIE, POLYGON, RECTANGLE

Example

This program draws six rectangles, each with a different fill mask, as shown below.

 ! Build as QuickWin or Standard Graphics Ap.
 USE DFLIB

 INTEGER(1), TARGET :: style1(8) &
             /#18,#18,#18,#18,#18,#18,#18,#18/
 INTEGER(1), TARGET :: style2(8) &
             /#08,#08,#08,#08,#08,#08,#08,#08/
 INTEGER(1), TARGET :: style3(8) &
             /#18,#00,#18,#18,#18,#00,#18,#18/
 INTEGER(1), TARGET :: style4(8) &
             /#00,#08,#00,#08,#08,#08,#08,#08/
 INTEGER(1), TARGET :: style5(8) &
             /#18,#18,#00,#18,#18,#00,#18,#18/
 INTEGER(1), TARGET :: style6(8) &
             /#08,#00,#08,#00,#08,#00,#08,#00/
 INTEGER(1) oldstyle(8) ! Placeholder for old style
 INTEGER loop
 INTEGER(1), POINTER :: ptr(:)

 CALL GETFILLMASK( oldstyle )
 ! Make 6 rectangles, each with a different fill
 DO loop = 1, 6
   SELECT CASE (loop)
     CASE (1)
       ptr => style1
     CASE (2)
       ptr => style2
     CASE (3)
       ptr => style3
     CASE (4)
       ptr => style4
     CASE (5)
       ptr => style5
     CASE (6)
       ptr => style6
   END SELECT
   CALL SETFILLMASK( ptr)
   status = RECTANGLE($GFILLINTERIOR,INT2(loop*40+5), &
                INT2(90),INT2((loop+1)*40), INT2(110))
 END DO

 CALL SETFILLMASK( oldstyle )  ! Restore old style
 READ (*,*)                    ! Wait for ENTER to be
                               ! pressed
 END

Figure: Output of Program SETFILL.FOR


SETFONT

Graphics Function: Finds a single font that matches a specified set of characteristics and makes it the current font used by the OUTGTEXT function.

Module: USE DFLIB

Syntax

result = SETFONT (options)

options
(Input) Character*(*). String describing font characteristics (see below for details).

Results:

The result is of type INTEGER(2). The result is the index number (x as used in the n x option) of the font if successful; otherwise, -1.

The SETFONT function searches the list of available fonts for a font matching the characteristics specified in options. If a font matching the characteristics is found, it becomes the current font. The current font is used in all subsequent calls to the OUTGTEXT function. There can be only one current font.

The options argument consists of letter codes, as follows, that describe the desired font. The options parameter is not case sensitive or position sensitive.

t'fontname' | Name of the desired typeface. It can be any installed font.
h y | Character height, where y is the number of pixels.
w x | Select character width, where x is the number of pixels.
f | Select only a fixed-space font (do not use with the p characteristic).
p | Select only a proportional-space font (do not use with the f characteristic).
v | Select only a vector-mapped font (do not use with the r characteristic). On WNT systems, Roman, Modern, and Script are examples of vector-mapped fonts, also called plotter fonts. True Type fonts (for example, Arial, Symbol, and Times New Roman) are not vector-mapped.
r | Select only a raster-mapped (bitmapped) font (do not use with the v characteristic). On WNT systems, Courier, Helvetica, and Palatino are examples of raster-mapped fonts, also called screen fonts. True Type fonts are not raster-mapped.
e | Select the bold text format. This parameter is ignored if the font does not allow the bold format.
u | Select the underline text format. This parameter is ignored if the font does not allow underlining.
i | Select the italic text format. This parameter is ignored if the font does not allow italics.
b | Select the font that best fits the other parameters specified.
n x | Select font number x, where x is less than or equal to the value returned by the INTIALIZEFONTS function.

You can specify as many options as you want, except with n x, which should be used alone. If you specify options that are mutually exclusive (such as the pairs f/p or r/v), the SETFONT function ignores them. There is no error detection for incompatible parameters used with n x.

If the b option is specified and at least one font is initialized, SETFONT sets a font and returns 0 to indicate success.

In selecting a font, the SETFONT routine uses the following criteria, rated from highest precedence to lowest:

  1. Pixel height
  2. Typeface
  3. Pixel width
  4. Fixed or proportional font

You can also specify a pixel width and height for fonts. If you choose a nonexistent value for either and specify the b option, SETFONT chooses the closest match.

A smaller font size has precedence over a larger size. If you request Arial 12 with best fit, and only Arial 10 and Arial 14 are available, SETFONT selects Arial 10.

If you choose a nonexistent value for pixel height and width, the SETFONT function applies a magnification factor to a vector-mapped font to obtain a suitable font size. This automatic magnification does not apply if you specify the r option (raster-mapped font), or if you request a specific typeface and do not specify the b option (best-fit).

If you specify the n x parameter, SETFONT ignores any other specified options and supplies only the font number corresponding to x.

If a height is given, but not a width, SETFONT computes the a width to preserve the correct font proportions.

If a width is given, but not a height, SETFONT uses a default height, which may vary from font type to font type. This may lead to characters that appear distorted, particularly when a very wide width is specified. This behavior is the same as that of the Win32 API CreateFontIndirect. A sample program is provided below showing you how to calculate the correct height for a given width.

The font functions affect only OUTGTEXT and the current graphics position; no other Fortran Graphics Library output functions are affected by font usage.

For each window you open, you must call INITIALIZEFONTS before calling SETFONT. INITIALIZEFONTS needs to be executed after each new child window is opened in order for a subsequent SETFONT call to be successful.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETFONTINFO, GETGTEXTEXTENT, GRSTATUS, OUTGTEXT, INITIALIZEFONTS, SETGTEXTROTATION

Example

 !  Build as a Graphics ap.
 USE DFLIB
 INTEGER(2) fontnum, numfonts
 TYPE (xycoord) pos
 numfonts = INITIALIZEFONTS ( )
 !  Set typeface to Arial, character height to 18,
 !  character width to 10, and italic
 fontnum = SETFONT ('t''Arial''h18w10i')
 CALL MOVETO (INT2(10), INT2(30), pos)
 CALL OUTGTEXT('Demo text')
 END

Another example follows:

 ! The following program shows you how to compute
 !  an appropriate font height for a given font width
 !
 !  Build as a Graphics ap.
  USE DFLIB
  INTEGER(2) fontnum, numfonts
  TYPE (xycoord) pos
  TYPE (rccoord) rcc
  TYPE (FONTINFO) info
  CHARACTER*11 str, str1
  CHARACTER*22 str2
  real rh
  integer h, inw
  str = "t'Arial'bih"
  str1= " "
  numfonts = INITIALIZEFONTS ( )
  ! Default both height and width.  This seems to work
  ! properly.  From this setting get the ratio between
  ! height and width.
  fontnum = SETFONT ("t'Arial'")
  ireturn = GETFONTINFO(info)
  rh =  real(info%pixheight)/real(info%avgwidth)

  ! Now calculate the height for a width of 40
  write(*,*) 'Input desired width:'
  read(*,*) inw
  h =int(inw*rh)
  write(str1,'(I3.3)') h
  str2 = str//str1
  print *,str2
  fontnum = SETFONT (str2)
  CALL MOVETO (INT2(10), INT2(50), pos)
  CALL OUTGTEXT('ABCDEFGabcdefg12345!@#$%')
  CALL MOVETO (INT2(10), INT2(50+10+h), pos)
  CALL OUTGTEXT('123456789012345678901234')
  ireturn = GETFONTINFO(info)
  call settextposition(4,1, rcc)
  print *,  info%avgwidth, info%pixheight
 END


SETGTEXTROTATION

Graphics Subroutine: Sets the orientation angle of the font text output in degrees. The current orientation is used in calls to OUTGTEXT.

Module: USE DFLIB

Syntax

CALL SETGTEXTROTATION (degree-tenths)

degree-tenths
(Input) INTEGER(4). Angle of orientation, in tenths of degrees, of the font text output.

The orientation of the font text output is set in tenths of degrees. Horizontal is 0°, and angles increase counterclockwise so that 900 (90°) is straight up, 1800 (180°) is upside down and left, 2700 (270°) is straight down, and so forth. If the user specifies a value greater than 3600 (360°), the subroutine takes a value equal to:

MODULO (user-specified tenths of degrees, 3600)

Although SETGTEXTROTATION accepts arguments in tenths of degrees, only increments of one full degree differ visually from each other on the screen.

Bitmap fonts cannot be rotated; TruType fonts should be used instead.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETGTEXTROTATION

Example

 ! Build as a Graphics ap.
 USE DFLIB
 INTEGER(2) fontnum, numfonts
 INTEGER(4) oldcolor, deg
 TYPE (xycoord) pos
 numfonts = INITIALIZEFONTS ( )
 fontnum = SETFONT ('t''Arial''h18w10i')
 CALL MOVETO (INT2(10), INT2(30), pos)
 CALL OUTGTEXT('Straight text')
 deg = -1370
 CALL SETGTEXTROTATION(deg)
 oldcolor = SETCOLORRGB(#008080)
 CALL OUTGTEXT('Slanted text')
 END


SETLINESTYLE

Graphics Subroutine: Sets the current line style to a new line style.

Module: USE DFLIB

Syntax

CALL SETLINESTYLE (mask)

mask
(Input) INTEGER(2). Desired Quickwin line-style mask. (See the table below.)

The mask is mapped to the style that most closly equivalences the the percentage of the bits in the mask that are set. The style produces lines that cover a certain percentage of the pixels in that line.

SETLINESTYLE sets the style used in drawing a line. You can choose from the following styles:

QuickWin Mask Internal Windows Style Selection Criteria Appearance
0xFFFF PS_SOLID 16 bits on ____________
0xEEEE PS_DASH 11 to 15 bits on ----------------
0xECEC PS_DASHDOT 10 bits on -.-.-.-.-.-.-.-.-.-.
0xECCC PS_DASHDOTDOT 9 bits on -..-..-..-..-..-..-..
0xAAAA PS_DOT 1 to 8 bits on ........................
0x0000 PS_NULL 0 bits on

SETLINESTYLE affects the drawing of straight lines as in LINETO, POLYGON, and RECTANGLE, but not the drawing of curved lines as in ARC, ELLIPSE, or PIE.

The current graphics color is set with SETCOLORRGB or SETCOLOR. SETWRITEMODE affects how the line is displayed.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETLINESTYLE, GRSTATUS, LINETO, POLYGON, RECTANGLE, SETCOLOR, SETWRITEMODE

Example

! Build as a Graphics ap.
 USE DFLIB
 INTEGER(2)     status, style
 TYPE (xycoord) xy

 style = #FFFF
 CALL SETLINESTYLE(style)
 CALL MOVETO(INT2(50), INT2(50), xy )
 status = LINETO(INT2(300), INT2(300))
 END


SETMESSAGEQQ

QuickWin Subroutine: Changes QuickWin status messages, state messages, and dialog box messages.

Module: USE DFLIB

Syntax

CALL SETMESSAGEQQ (msg, id)

msg
(Input) Character*(*). Message to be displayed. Must be a regular Fortran string, not a C string. Can include multibyte characters.

id
(Input) INTEGER(4). Identifier of the message to be changed. The following table shows the messages that can be changed and their identifiers:

Id | Message
QWIN$MSG_TERM | "Program terminated with exit code"
QWIN$MSG_EXITQ | "\nExit Window?"
QWIN$MSG_FINISHED | "Finished"
QWIN$MSG_PAUSED | "Paused"
QWIN$MSG_RUNNING | "Running"
QWIN$MSG_FILEOPENDLG | "Text Files(*.txt), *.txt; Data Files(*.dat), *.dat; All Files(*.*), *.*;"
QWIN$MSG_BMPSAVEDLG | "Bitmap Files(*.bmp), *.bmp; All Files(*.*), *.*;"
QWIN$MSG_INPUTPEND | "Input pending in"
QWIN$MSG_PASTEINPUTPEND | "Paste input pending"
QWIN$MSG_MOUSEINPUTPEND | "Mouse input pending in"
QWIN$MSG_SELECTTEXT | "Select Text in"
QWIN$MSG_SELECTGRAPHICS | "Select Graphics in"
QWIN$MSG_PRINTABORT | "Error! Printing Aborted."
QWIN$MSG_PRINTLOAD | "Error loading printer driver"
QWIN$MSG_PRINTNODEFAULT | "No Default Printer."
QWIN$MSG_PRINTDRIVER | "No Printer Driver."
QWIN$MSG_PRINTINGERROR | "Print: Printing Error."
QWIN$MSG_PRINTING | "Printing"
QWIN$MSG_PRINTCANCEL | "Cancel"
QWIN$MSG_PRINTINPROGRESS | "Printing in progress..."
QWIN$MSG_HELPNOTAVAIL | "Help Not Available for Menu Item"
QWIN$MSG_TITLETEXT | "Graphic"

Note that QWIN$MSG_FILEOPENDLG and QWIN$MSG_BMPSAVEDLG control the text in file choosing dialog boxes and have the following syntax:

"file description, file designation"

You can change any string produced by QuickWin by calling SETMESSAGEQQ with the appropriate id. This includes status messages displayed at the bottom of a QuickWin application, state messages (such as "Paused"), and dialog box messages. These messages can include multibyte characters. (For more information on multibyte characters, see Using National Language Support Routines in the Programmer's Guide.) To change menu messages, use MODIFYMENUSTRINGQQ.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: MODIFYMENUSTRINGQQ

Example

 USE DFLIB
 print*, "Hello"
 CALL SETMESSAGEQQ('Changed exit text', QWIN$MSG_EXITQ)


SETMOUSECURSOR

Graphics Function: Sets the shape of the mouse cursor for the window in focus.

Module: USE DFLIB
USE DFWIN

Syntax

oldcursor = SETMOUSECURSOR (newcursor)

newcursor
(Input) INTEGER(4). A Windows HCURSOR value. For many predefined shapes, LoadCursor(0, shape) is a convenient way to get a legitimate value. See the list of predefined shapes below.

A value of zero causes the cursor not to be displayed.

Results:

The result is of type INTEGER(4). This is also an HCURSOR Value. The result is the previous cursor value.

The window in focus at the time SETMOUSECURSOR is called has its cursor changed to the specified value. Once changed, the cursor retains its shape until another call to SETMOUSECURSOR.

In Standard Graphics applications, units 5 and 6 (the default screen input and output units) are always considered to be in focus.

The following predefined values for cursor shapes are available:

Predefined Value | Cursor Shape
IDC_APPSTARTING | Standard arrow and small hourglass
IDC_ARROW | Standard arrow
IDC_CROSS | Crosshair
IDC_IBEAM | Text I-beam
IDC_ICON | Obsolete value
IDC_NO | Slashed circle
IDC_SIZE | Obsolete value; use IDC_SIZEALL
IDC_SIZEALL | Four-pointed arrow
IDC_SIZENESW | Double-pointed arrow pointing northeast and southwest
IDC_SIZENS | Double-pointed arrow pointing north and south
IDC_SIZENWSE | Double-pointed arrow pointing northwest and southeast
IDC_SIZEWE | Double-pointed arrow pointing west and east
IDC_UPARROW | Vertical arrow
IDC_WAIT | Hour glass

A LoadCursor must be done on these values before they can be used by SETMOUSECURSOR.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

Examples

! Build as QuickWin
    use dflib
    use dfwin
    integer*4  cursor, oldcursor
    open(8,file='user')

    write(8,*) 'The cursor will now be changed to an hour glass shape'
    write(8,*) 'Hit <return> to see the next change'
    cursor = LoadCursor(0, IDC_WAIT)
    oldcursor = SetMouseCursor(cursor)
    read(8,*)

    write(8,*) 'The cursor will now be changed to a cross-hair shape'
    write(8,*) 'Hit <return> to see the next change'
    cursor = LoadCursor(0, IDC_CROSS)
    oldcursor = SetMouseCursor(cursor)
    read(8,*)

    write(8,*) 'The cursor will now be turned off'
    write(8,*) 'Hit <return> to see the next change'
    oldcursor = SetMouseCursor(0)
    read(8,*)

    write(8,*) 'The cursor will now be turned on'
    write(8,*) 'Hit <return> to see the next change'
    oldcursor = SetMouseCursor(oldcursor)
    read(8,*)
  stop
  end

! Build as Standard Graphics or QuickWin
    use dflib
    use dfwin

    integer*4  cursor, oldcursor
    write(6,*) 'The cursor will now be changed to an hour glass shape'
    write(6,*) 'Hit <return> to see the next change'
    cursor = LoadCursor(0, IDC_WAIT)
    oldcursor = SetMouseCursor(cursor)
    read(5,*)

    write(6,*) 'The cursor will now be changed to a cross-hair shape'
    write(6,*) 'Hit <return> to see the next change'
    cursor = LoadCursor(0, IDC_CROSS)
    oldcursor = SetMouseCursor(cursor)
    read(5,*)

    write(6,*) 'The cursor will now be turned off'
    write(6,*) 'Hit <return> to see the next change'
    oldcursor = SetMouseCursor(0)
    read(5,*)

    write(6,*) 'The cursor will now be turned on'
    write(6,*) 'Hit <return> to see the next change'
    oldcursor = SetMouseCursor(oldcursor)
    read(5,*)

  stop
  end


SETPIXEL, SETPIXEL_W

Graphics Function: Sets a pixel at a specified location to the current graphics color index.

Module: USE DFLIB

Syntax

result = SETPIXEL (x, y)
result = SETPIXEL_W (wx, wy)

x, y
(Input) INTEGER(2). Viewport coordinates for target pixel.

wx, wy
(Input) REAL(8). Window coordinates for target pixel.

Results:

The result is of type INTEGER(2). The result is the previous color index of the target pixel if successful; otherwise, -1 (for example, if the pixel lies outside the clipping region).

SETPIXEL sets the specified pixel to the current graphics color index. The current graphics color index is set with SETCOLOR and retrieved with GETCOLOR. The non-RGB color functions (such as SETCOLOR and SETPIXELS) use color indexes rather than true color values.

If you use color indexes, you are restricted to the colors available in the palette, at most 256. Some display adapters (SVGA and true color) are capable of creating 262,144 (256K) colors or more. To access any available color, you need to specify an explicit Red-Green-Blue(RGB) value with an RGB color function, rather than a palette index with a non-RGB color function. SETPIXELRGB and SETPIXELRGB_W give access to the full color capacity of the system by using direct color values rather than indexes to a palette.

Note: The SETPIXEL routine described here is a QuickWin routine. If you are trying to use the Win32 SDK version of the SetPixel routine by including the DFWIN module, you need to specify the routine name as MSFWIN$SetPixel. For more information, see Special Naming Convention for Certain QuickWin and Win32 Graphics Routines in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETPIXELRGB, GETPIXEL, SETPIXELS, GETPIXELS, GETCOLOR, SETCOLOR

Example

 ! Build as a Graphics ap.
 USE DFLIB
 INTEGER(2) status, x, y
 status = SETCOLOR(INT2(2))
 x = 10
 ! Draw pixels.
 DO y = 50, 389, 3
    status = SETPIXEL( x, y )
    x = x + 2
 END DO
 READ (*,*) ! Wait for ENTER to be pressed
 END


SETPIXELRGB, SETPIXELRGB_W

Graphics Function: Sets a pixel at a specified location to the specified Red-Green-Blue (RGB) color value.

Module: USE DFLIB

Syntax

result = SETPIXELRGB (x, y, color)
result = SETPIXELRGB_W (wx, wy, color)

x, y
(Input) INTEGER(2). Viewport coordinates for target pixel.

wx, wy
(Input) REAL(8). Window coordinates for target pixel.

color
(Input) INTEGER(4). RGB color value to set the pixel to. Range and result depend on the system's display adapter.

Results:

The result is of type INTEGER(4). The result is the previous RGB color value of the pixel.

In each RGB color value, each of the three colors, red, green, and blue, is represented by an eight-bit value (2 hex digits). In the value you specify with SETPIXELRGB or SETPIXELRGB_W, red is the rightmost byte, followed by green and blue. The RGB value's internal structure is as follows:

Larger numbers correspond to stronger color intensity with binary 1111111 (hex FF) the maximum for each of the three components. For example, #0000FF yields full-intensity red, #00FF00 full-intensity green, #FF0000 full-intensity blue, and #FFFFFF full-intensity for all three, resulting in bright white.

If any of the pixels are outside the clipping region, those pixels are ignored.

SETPIXELRGB (and the other RGB color selection functions such as SETPIXELSRGB, SETCOLORRGB) sets the color to a value chosen from the entire available range. The non-RGB color functions (such as SETPIXELS and SETCOLOR) use color indexes rather than true color values.

If you use color indexes, you are restricted to the colors available in the palette, at most 256. Some display adapters (SVGA and true color) are capable of creating 262,144 (256K) colors or more. To access any available color, you need to specify an explicit RGB value with an RGB color function, rather than a palette index with a non-RGB color function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETPIXELRGB, GETPIXELSRGB, SETCOLORRGB, SETPIXELSRGB

Example

 ! Build as a Graphics ap.
 USE DFLIB
 INTEGER(2) x, y
 INTEGER(4) color
 DO i = 10, 30, 10
   SELECT CASE (i)
     CASE(10)
       color = #0000FF
     CASE(20)
       color = #00FF00
     CASE (30)
       color = #FF0000
   END SELECT
 ! Draw pixels.
   DO y = 50, 180, 2
     status = SETPIXELRGB( x, y, color )
     x      = x + 2
   END DO
 END DO
 READ (*,*) ! Wait for ENTER to be pressed
 END


SETPIXELS

Graphics Subroutine: Sets the color indexes of multiple pixels.

Module: USE DFLIB

Syntax

CALL SETPIXELS (n, x, y, color)

n
(Input) INTEGER(4). Number of pixels to set. Sets the number of elements in the other arguments.

x, y
(Input) INTEGER(2). Parallel arrays containing viewport coordinates of pixels to set.

color
(Input) INTEGER(2). Array containing color indexes to set the pixels to.

SETPIXELS sets the pixels specified in the arrays x and y to the color indexes in color. These arrays are parallel: the first element in each of the three arrays refers to a single pixel, the second element refers to the next pixel, and so on.

If any of the pixels are outside the clipping region, those pixels are ignored. Calls to SETPIXELS with n less than 1 are also ignored. SETPIXELS is a much faster way to set multiple pixel color indexes than individual calls to SETPIXEL.

Unlike SETPIXELS, SETPIXELSRGB gives access to the full color capacity of the system by using direct color values rather than indexes to a palette. The non-RGB color functions (such as SETPIXELS and SETCOLOR) use color indexes rather than true color values.

If you use color indexes, you are restricted to the colors available in the palette, at most 256. Some display adapters (SVGA and true color) are capable of creating 262,144 (256K) colors or more. To access any available color, you need to specify an explicit RGB value with an RGB color function, rather than a palette index with a non-RGB color function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETPIXELS, SETPIXEL, SETPIXELSRGB

Example

 ! Build as a Graphics ap.
     USE DFLIB
     INTEGER(2) color(9)
     INTEGER(2) x(9), y(9), i
     DO i = 1, 9
       x(i) = 20 * i
       y(i) = 10 * i
       color(i) = INT2(i)
     END DO
     CALL SETPIXELS(9, x, y, color)
     END


SETPIXELSRGB

Graphics Subroutine: Sets multiple pixels to the given Red-Green-Blue (RGB) color.

Module: USE DFLIB

Syntax

CALL SETPIXELSRGB (n, x, y, color)

n
(Input) INTEGER(4). Number of pixels to be changed. Determines the number of elements in arrays x and y.

x, y
(Input) INTEGER(2). Parallel arrays containing viewport coordinates of the pixels to set.

color
(Input) INTEGER(4). Array containing the RGB color values to set the pixels to. Range and result depend on the system's display adapter.

SETPIXELSRGB sets the pixels specified in the arrays x and y to the RGB color values in color. These arrays are parallel: the first element in each of the three arrays refers to a single pixel, the second element refers to the next pixel, and so on.

In each RGB color value, each of the three color values, red, green, and blue, is represented by an eight-bit value (2 hex digits). In the value you set with SETPIXELSRGB, red is the rightmost byte, followed by green and blue. The RGB value's internal structure is as follows:

Larger numbers correspond to stronger color intensity with binary 1111111 (hex FF) the maximum for each of the three components. For example, #0000FF yields full-intensity red, #00FF00 full-intensity green, #FF0000 full-intensity blue, and #FFFFFF full-intensity for all three, resulting in bright white.

A good use for SETPIXELSRGB is as a buffering form of SETPIXELRGB, which can improve performance substantially. The example code shows how to do this.

If any of the pixels are outside the clipping region, those pixels are ignored. Calls to SETPIXELSRGB with n less than 1 are also ignored.

SETPIXELSRGB (and the other RGB color selection functions such as SETPIXELRGB and SETCOLORRGB) sets colors to values chosen from the entire available range. The non-RGB color functions (such as SETPIXELS and SETCOLOR) use color indexes rather than true color values.

If you use color indexes, you are restricted to the colors available in the palette, at most 256. Some display adapters (SVGA and true color) are capable of creating 262,144 (256K) colors or more. To access any available color, you need to specify an explicit RGB value with an RGB color function, rather than a palette index with a non-RGB color function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETPIXELSRGB, SETPIXELRGB, GETPIXELRGB, SETPIXELS

Example

 ! Buffering replacement for SetPixelRGB and
 ! SetPixelRGB_W. This can improve performance by
 ! doing batches of pixels together.

 USE DFLIB
 PARAMETER (I$SIZE = 200)
 INTEGER(4) bn, bc(I$SIZE), status
 INTEGER(2) bx(I$SIZE),by(I$SIZE)

 bn = 0
 DO i = 1, I$SIZE
   bn = bn + 1
   bx(bn) = i
   by(bn) = i
   bc(bn) = GETCOLORRGB()
   status = SETCOLORRGB(bc(bn)+1)
 END DO
 CALL SETPIXELSRGB(bn,bx,by,bc)
 END


SETTEXTCOLOR

Graphics Function: Sets the current text color index.

Module: USE DFLIB

Syntax

result = SETTEXTCOLOR (index)

index
(Input) INTEGER(2). Color index to set the text color to.

Results:

The result is of type INTEGER(2). The result is the previous text color index.

SETTEXTCOLOR sets the current text color index. The default value is 15, which is associated with white unless the user remaps the palette. GETTEXTCOLOR returns the text color index set by SETTEXTCOLOR. SETTEXTCOLOR affects text output with OUTTEXT, WRITE, and PRINT.

The background color index is set with SETBKCOLOR and returned with GETBKCOLOR. The color index of graphics over the background color is set with SETCOLOR and returned with GETCOLOR. These non-RGB color functions use color indexes, not true color values, and limit the user to colors in the palette, at most 256. To access all system colors, use SETTEXTCOLORRGB, SETBKCOLORRGB, and SETCOLORRGB.

Note: The SETTEXTCOLOR routine described here is a QuickWin routine. If you are trying to use the Win32 SDK version of the SetTextColor routine by including the DFWIN module, you need to specify the routine name as MSFWIN$SetTextColor. For more information, see Special Naming Convention for Certain QuickWin and Win32 Graphics Routines in the Programmer's Guide.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETTEXTCOLOR, REMAPPALETTERGB, SETCOLOR, SETTEXTCOLORRGB

Example

 ! Build as a Graphics ap.
 USE DFLIB
 INTEGER(2) oldtc
 oldtc = SETTEXTCOLOR(INT2(2)) ! green
 WRITE(*,*) "hello, world"
 END


SETTEXTCOLORRGB

Graphics Function: Sets the current text color to the specified Red-Green-Blue (RGB) value.

Module: USE DFLIB

Syntax

result = SETTEXTCOLORRGB (color)

color
(Input) INTEGER(4). RGB color value to set the text color to. Range and result depend on the system's display adapter.

Results:

The result is of type INTEGER(4). The result is the previous text RGB color value.

In each RGB color value, each of the three colors, red, green, and blue, is represented by an eight-bit value (2 hex digits). In the value you specify with SETTEXTCOLORRGB, red is the rightmost byte, followed by green and blue. The RGB value's internal structure is as follows:

Larger numbers correspond to stronger color intensity with binary 1111111 (hex FF) the maximum for each of the three components. For example, #0000FF yields full-intensity red, #00FF00 full-intensity green, #FF0000 full-intensity blue, and #FFFFFF full-intensity for all three, resulting in bright white.

SETTEXTCOLORRGB sets the current text RGB color. The default value is #00FFFFFF, which is full-intensity white. SETTEXTCOLORRGB sets the color used by OUTTEXT, WRITE, and PRINT. It does not affect the color of text output with the OUTGTEXT font routine. Use SETCOLORRGB to change the color of font output.

SETBKCOLORRGB sets the RGB color value of the current background for both text and graphics. SETCOLORRGB sets the RGB color value of graphics over the background color, used by the graphics functions such as ARC, FLOODFILLRGB, and OUTGTEXT.

SETTEXTCOLORRGB (and the other RGB color selection functions SETBKCOLORRGB and SETCOLORRGB) sets the color to a value chosen from the entire available range. The non-RGB color functions (SETTEXTCOLOR, SETBKCOLOR, and SETCOLOR) use color indexes rather than true color values.

If you use color indexes, you are restricted to the colors available in the palette, at most 256. Some display adapters (SVGA and true color) are capable of creating 262,144 (256K) colors or more. To access any available color, you need to specify an explicit RGB value with an RGB color function, rather than a palette index with a non-RGB color function.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: SETBKCOLORRGB, SETCOLORRGB, GETTEXTCOLORRGB, GETWINDOWCONFIG, OUTTEXT

Example

 ! Build as a Graphics ap.
 USE DFLIB
 INTEGER(4) oldtc

 oldtc = SETTEXTCOLORRGB(#000000FF)
 WRITE(*,*) 'I am red'
 oldtc = SETTEXTCOLORRGB(#0000FF00)
 CALL OUTTEXT ('I am green'//CHAR(13)//CHAR(10))
 oldtc = SETTEXTCOLORRGB(#00FF0000)
 PRINT *, 'I am blue'
 END


SETTEXTCURSOR

Graphics Function: Sets the height and width of the text cursor (the caret) for the window in focus.

Module: USE DFLIB

Syntax

result = SETTEXTCURSOR (newcursor)

newcursor
(Input) INTEGER(2). The leftmost 8 bits specify the width of the cursor, and the rightmost 8 bits specify the height of the cursor. These dimensions can range from 1 to 8, and represent a fraction of the current character cell size. For example:

  • #0808 - Specifies the full character cell; this is the default size.
  • #0108 - Specifies 1/8th of the character cell width, and 8/8th (or all) of the character cell height.

If either of these dimensions is outside the range 1 to 8, it is forced to 8.

Results:

The result is of type INTEGER(2); it is the previous text cursor value in the same format as newcursor.

Note: After calling SETTEXTCURSOR, you must call DISPLAYCURSOR($GCURSORON) to actually see the cursor.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: DISPLAYCURSOR

Example

use dflib
integer(2) oldcur
integer(2) istat
type(rccoord) rc
open(10,file='user')
istat  = displaycursor($GCURSORON)
write(10,*) 'Text cursor is now character cell size, the default.'
read(10,*)
write(10,*) 'Setting text cursor to wide and low.'
oldcur = settextcursor(#0801)
istat  = displaycursor($GCURSORON)
read(10,*)
write(10,*) 'Setting text cursor to high and narrow.'
oldcur = settextcursor(#0108)
istat  = displaycursor($GCURSORON)
read(10,*)
write(10,*) 'Setting text cursor to a dot.'
oldcur = settextcursor(#0101)
istat  = displaycursor($GCURSORON)
read(10,*)
end


SETTEXTPOSITION

Graphics Subroutine: Sets the current text position to a specified position relative to the current text window.

Module: USE DFLIB

Syntax

CALL SETTEXTPOSITION (row, column, t)

row
(Input) INTEGER(2). New text row position.

column
(Input) INTEGER(2). New text column position.

t
(Output) Derived type rccoord. Previous text position. The derived type rccoord is defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as follows:
 TYPE rccoord
   INTEGER(2) row ! Row coordinate
   INTEGER(2) col ! Column coordinate
 END TYPE rccoord

Subsequent text output with the OUTTEXT function (as well as standard console I/O statements, such as PRINT and WRITE) begins at the point (row, column).

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: CLEARSCREEN, GETTEXTPOSITION, OUTTEXT, SCROLLTEXTWINDOW, SETTEXTWINDOW, WRAPON

Example

 USE DFLIB
 TYPE (rccoord) curpos

 WRITE(*,*) "Original text position"
 CALL SETTEXTPOSITION (INT2(6), INT2(5), curpos)
 WRITE (*,*) 'New text position'
 END


SETTEXTWINDOW

Graphics Subroutine: Sets the current text window.

Module: USE DFLIB

Syntax

CALL SETTEXTWINDOW (r1, c1, r2, c2)

r1, c1
(Input) INTEGER(2). Row and column coordinates for upper-left corner of the text window.

r2, c2
(Input) INTEGER(2). Row and column coordinates for lower-right corner of the text window.

SETTEXTWINDOW specifies a window in row and column coordinates where text output to the screen using OUTTEXT, WRITE, or PRINT will be displayed. You set the text location within this window with SETTEXTPOSITION.

Text is output from the top of the window down. When the window is full, successive lines overwrite the last line.

SETTEXTWINDOW does not affect the output of the graphics text routine OUTGTEXT. Use the SETVIEWPORT function to control the display area for graphics output.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETTEXTPOSITION, GETTEXTWINDOW, GRSTATUS, OUTTEXT, SCROLLTEXTWINDOW, SETTEXTPOSITION, SETVIEWPORT, WRAPON

Example

 USE DFLIB
 TYPE (rccoord) curpos

 CALL SETTEXTWINDOW(INT2(5), INT2(1), INT2(7), &
                    INT2(40))
 CALL SETTEXTPOSITION (INT2(5), INT2(5), curpos)
 WRITE(*,*) "Only two lines in this text window"
 WRITE(*,*) "so this line will be overwritten"
 WRITE(*,*) "by this line"
 END


SETTIM

Run-Time Function: Sets the system time in your programs.

Module: USE DFLIB

Syntax

result = SETTIM (ihr, imin, isec, i100th)

ihr
(Input) INTEGER(2). Hour (0 - 23).

imin
(Input) INTEGER(2). Minute (0 - 59).

isec
(Input) INTEGER(2). Second (0 - 59).

i100th
(Input) INTEGER(2). Hundredth of a second (0 - 99).

Results:

The result is of type LOGICAL(4). The result is .TRUE. if the system time is changed; .FALSE. if no change is made.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETDAT, GETTIM, SETDAT

Example

 USE DFLIB
 LOGICAL(4) success
 success = SETTIM(INT2(21),INT2(53+3),&
                  INT2(14*2),INT2(88))
 END


SETVIEWORG

Graphics Subroutine: Moves the viewport-coordinate origin (0, 0) to the specified physical point.

Module: USE DFLIB

Syntax

CALL SETVIEWORG (x, y, t)

x, y
(Input) INTEGER(2). Physical coordinates of new viewport origin.

t
(Output) Derived type xycoord. Physical coordinates of the previous viewport origin. The derived type xycoord is defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as follows:
 TYPE xycoord
   INTEGER(2) xcoord ! x-coordinate
   INTEGER(2) ycoord ! y-coordinate
 END TYPE xycoord

The xycoord type variable t, defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory), returns the physical coordinates of the previous viewport origin.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETCURRENTPOSITION, GETPHYSCOORD, GETVIEWCOORD, GETWINDOWCOORD, GRSTATUS, SETCLIPRGN, SETVIEWPORT

Example

 USE DFLIB
 TYPE ( xycoord ) xy

 CALL SETVIEWORG(INT2(30), INT2(30), xy)


SETVIEWPORT

Graphics Subroutine: Redefines the graphics viewport by defining a clipping region in the same manner as SETCLIPRGN and then setting the viewport-coordinate origin to the upper-left corner of the region.

Module: USE DFLIB

Syntax

CALL SETVIEWPORT (x1, y1, x2, y2)

x1, y1
(Input) INTEGER(2). Physical coordinates for upper-left corner of viewport.

x2, y2
(Input) INTEGER(2). Physical coordinates for lower-right corner of viewport.

The physical coordinates (x1, y1) and (x2, y2) are the upper-left and lower-right corners of the rectangular clipping region. Any window transformation done with the SETWINDOW function is relative to the viewport, not the entire screen.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETVIEWCOORD, GETPHYSCOORD, GRSTATUS, SETCLIPRGN, SETVIEWORG, SETWINDOW

Example

 USE DFLIB
 INTEGER(2) upx, upy
 INTEGER(2) downx, downy

 upx = 0
 upy = 30
 downx= 250
 downy = 100
 CALL SETVIEWPORT(upx, upy, downx, downy)


SETWINDOW

Graphics Function: Defines a window bound by the specified coordinates.

Module: USE DFLIB

Syntax

result = SETWINDOW (finvert, wx1, wy1, wx2, wy2)

finvert
(Input) LOGICAL(2). Direction of increase of the y-axis. If finvert is .TRUE., the y-axis increases from the window bottom to the window top (as Cartesian coordinates). If finvert is .FALSE., the y-axis increases from the window top to the window bottom (as pixel coordinates).

wx1, wy1
(Input) REAL(8). Window coordinates for upper-left corner of window.

wx2, wy2
(Input) REAL(8). Window coordinates for lower-right corner of window.

Results:

The result is of type INTEGER(2). The result is nonzero if successful; otherwise, 0 (for example, if the program that calls SETWINDOW is not in a graphics mode).

The SETWINDOW function determines the coordinate system used by all window-relative graphics routines. Any graphics routines that end in _W (such as ARC_W, RECTANGLE_W, and LINETO_W) use the coordinate sytem set by SETWINDOW.

Any window transformation done with the SETWINDOW function is relative to the viewport, not the entire screen.

An arc drawn using inverted window coordinates is not an upside-down version of an arc drawn with the same parameters in a noninverted window. The arc is still drawn counterclockwise, but the points that define where the arc begins and ends are inverted.

If wx1 equals wx2 or wy1 equals wy2, SETWINDOW fails.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETWINDOWCOORD, SETCLIPRGN, SETVIEWORG, SETVIEWPORT, GRSTATUS, ARC_W, LINETO_W, MOVETO_W, PIE_W, POLYGON_W, RECTANGLE_W

Example

 USE DFLIB
 INTEGER(2) status
 LOGICAL(2) invert /.TRUE./
 REAL(8) upx /0.0/, upy /0.0/
 REAL(8) downx /1000.0/, downy /1000.0/
 status = SETWINDOW(invert, upx, upy, downx, downy)


SETWINDOWCONFIG

QuickWin Function: Sets the properties of a child window.

Module: USE DFLIB

Syntax

result = SETWINDOWCONFIG (wc)

wc
(Input) Derived type windowconfig. Contains window properties. The windowconfig derived type is defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as follows:

TYPE windowconfig
  INTEGER(2) numxpixels             ! Number of pixels on x-axis.
  INTEGER(2) numypixels             ! Number of pixels on y-axis.
  INTEGER(2) numtextcols        ! Number of text columns available.
  INTEGER(2) numtextrows        ! Number of text rows available.
  INTEGER(2) numcolors              ! Number of color indexes.
  INTEGER(4) fontsize           ! Size of default font. Set to
                                ! QWIN$EXTENDFONT when specifying
                                ! extended attributes, in which
                                ! case extendfontsize sets the
                                ! font size.
  CHARACTER(80) title               ! The window title.
  INTEGER(2) bitsperpixel       ! The number of bits per pixel.
  INTEGER(2) numvideopages          ! Unused.
  INTEGER(2) mode               ! Controls scrolling mode.
  INTEGER(2) adapter                ! Unused.
  INTEGER(2) monitor                ! Unused.
  INTEGER(2) memory                 ! Unused.
  INTEGER(2) environment            ! Unused.
! The next three parameters provide extended font
! attributes.
  CHARACTER(32) extendfontname      ! The name of the desired font.
  INTEGER(4) extendfontsize     ! Takes the same values as fontsize,
                                ! when fontsize is set to
                                ! QWIN$EXTENDFONT.
  INTEGER(4) extendfontattributes   ! Font attributes such as bold
                                    ! and italic.
END TYPE windowconfig

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

The following value can be used to configure a QuickWin window so that it will show the last line written and the text cursor (if it is on):

  wc%mode = QWIN$SCROLLDOWN

Note that if you scroll the window to another position, you will have to scroll back to the last line to see your input.

The following values can be used with SETWINDOWCONFIG extended fonts:

Style:
QWIN$EXTENDFONT_NORMAL | Gives no underline, no italic, and a font weight of 400 out of 1000.
QWIN$EXTENDFONT_UNDERLINE | Gives underlined characters.
QWIN$EXTENDFONT_BOLD | Gives a font weight of 700 out of 1000.
QWIN$EXTENDFONT_ITALIC | Gives italic characters.
Pitch:
QWIN$EXTENDFONT_FIXED_PITCH | QuickWin default. Equal character widths.
QWIN$EXTENDFONT_VARIABLE_PITCH | Variable character widths.
Font Families:
QWIN$EXTENDFONT_FF_ROMAN | Variable stroke width, serifed. Times Roman, Century Schoolbook, etc.
QWIN$EXTENDFONT_FF_SWISS | Variable stroke width, sans-serifed. Helvetica, Swiss, etc.
QWIN$EXTENDFONT_FF_MODERN | QuickWin default. Constant stroke width, serifed or sans-serifed. Pica, Elite, Courier, etc.
QWIN$EXTENDFONT_FF_SCRIPT | Cursive, etc.
QWIN$EXTENDFONT_FF_DECORATIVE | Old English, etc.
Character Sets:
QWIN$EXTENDFONT_ANSI_CHARSET | QuickWin default.
QWIN$EXTENDFONT_OEM_CHARSET | Use this to get Microsoft LineDraw.

Using QWIN$EXTENDFONT_OEM_CHARSET with the font name 'MS LineDraw'C will get the old DOS-style character set with symbols that can be used to draw lines and boxes. The pitch and font family items can be specified to help guide the font matching algorithms used by CreateFontIndirect, the Win32 API used by SETWINDOWCONFIG.

If you use SETWINDOWCONFIG to set the variables in windowconfig to -1, the function sets the highest resolution possible for your system, given the other fields you specify, if any. You can set the actual size of the window by specifying parameters that influence the window size: the number of x and y pixels, the number of rows and columns, and the font size. If you do not call SETWINDOWCONFIG, the window defaults to the best possible resolution and a font size of 8x16. The number of colors available depends on the video driver used.

If you use SETWINDOWCONFIG, you should specify a value for each field (-1 or your own value for the numeric fields and a C string for the title, for example, "words of text"C). Using SETWINDOWCONFIG with only some fields specified can result in useless values for the unspecified fields.

If you request a configuration that cannot be set, SETWINDOWCONFIG returns .FALSE. and calculates parameter values that will work and are as close as possible to the requested configuration. A second call to SETWINDOWCONFIG establishes the adjusted values; for example:

status = SETWINDOWCONFIG(wc)
if (.NOT.status) status = SETWINDOWCONFIG(wc)

If you specify values for all four of the size parameters, numxpixels, numypixel, numtextcols, and numtextrows, the font size is calculated by dividing these values.The default font is Courier New and the default font size is 8x16. There is no restriction on font size, except that the window must be large enough to hold it.

Under Standard Graphics, the application attempts to start in Full Screen mode with no window decoration (window decoration includes scroll bars, menu bar, title bar, and message bar) so that the maximum resolution can be fully used. Otherwise, the application starts in a window. You can use ALT+ENTER at any time to toggle between the two modes.

Note that if you are in Full Screen mode and the resolution of the window does not match the resolution of the video driver, graphics output will be slow compared to drawing in a window.

You must call DISPLAYCURSOR($GCURSORON) to make the cursor visible after calling SETWINDOWCONFIG.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: Using QuickWin, GETWINDOWCONFIG

Example

 USE DFLIB
 TYPE (windowconfig) wc
 LOGICAL status /.FALSE./
 ! Set the x & y pixels to 800X600 and font size to 8x12
 wc%numxpixels  = 800
 wc%numypixels  = 600
 wc%numtextcols = -1
 wc%numtextrows = -1
 wc%numcolors   = -1
 wc%title= "This is a test"C
 wc%fontsize = #0008000C
 status = SETWINDOWCONFIG(wc)  ! attempt to set configuration with above values
    ! if attempt fails, set with system estimated values
 if (.NOT.status) status = SETWINDOWCONFIG(wc)


SETWINDOWMENUQQ

QuickWin Function: Sets a top-level menu as the menu to which a list of current child window names is appended.

Module: USE DFLIB

Syntax

result = SETWINDOWMENUQQ (menuID)

menuID
(Input) INTEGER(4). Identifies the menu to hold the child window names, starting with 1 as the leftmost menu.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

The list of current child window names can appear in only one menu at a time. If the list of windows is currently in a menu, it is removed from that menu. By default, the list of child windows appears at the end of the Window menu.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: APPENDMENUQQ, Using QuickWin, Customizing QuickWin Applications

Example

 USE DFLIB
 TYPE (windowconfig) wc
 LOGICAL(4) result, status /.FALSE./
 ! Set title for child window
 wc%numxpixels  = -1
 wc%numypixels  = -1
 wc%numtextcols = -1
 wc%numtextrows = -1
 wc%numcolors   = -1
 wc%fontsize    = -1
 wc%title= "I am child window name"C
 if (.NOT.status) status = SETWINDOWCONFIG(wc)

 ! put child window list under menu 3 (View)
 result = SETWINDOWMENUQQ(3)
 END


SETWRITEMODE

Graphics Function: Sets the current logical write mode, which is used when drawing lines with the LINETO, POLYGON, and RECTANGLE functions.

Module: USE DFLIB

Syntax

result = SETWRITEMODE (wmode)

wmode
(Input) INTEGER(2). Write mode to be set. One of the following symbolic constants (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory):

  • $GPSET - Causes lines to be drawn in the current graphics color. (Default)

  • $GAND - Causes lines to be drawn in the color that is the logical AND of the current graphics color and the current background color.

  • $GOR - Causes lines to be drawn in the color that is the logical OR of the current graphics color and the current background color.

  • $GPRESET - Causes lines to be drawn in the color that is the logical NOT of the current graphics color.

  • $GXOR - Causes lines to be drawn in the color that is the logical exclusive OR (XOR) of the current graphics color and the current background color.

In addition, one of the following binary raster operation constants can be used (described in the online documentation for the Win32 API SetROP2):

  • $GR2_BLACK
  • $GR2_NOTMERGEPEN
  • $GR2_MASKNOTPEN
  • $GR2_NOTCOPYPEN (same as $GPRESET)
  • $GR2_MASKPENNOT
  • $GR2_NOT
  • $GR2_XORPEN (same as $GXOR)
  • $GR2_NOTMASKPEN
  • $GR2_MASKPEN (same as $GAND)
  • $GR2_NOTXORPEN
  • $GR2_NOP
  • $GR2_MERGENOTPEN
  • $GR2_COPYPEN (same as $GPSET)
  • $GR2_MERGEPENNOT
  • $GR2_MERGEPEN (same as $GOR)
  • $GR2_WHITE

Results:

The result is of type INTEGER(2). The result is the previous write mode if successful; otherwise, -1.

The current graphics color is set with SETCOLORRGB (or SETCOLOR) and the current background color is set with SETBKCOLORRGB (or SETBKCOLOR). As an example, suppose you set the background color to yellow (#00FFFF) and the graphics color to purple (#FF00FF) with the following commands:

  oldcolor = SETBKCOLORRGB(#00FFFF)
  CALL CLEARSCREEN($GCLEARSCREEN)
  oldcolor = SETCOLORRGB(#FF00FF)

If you then set the write mode with the $GAND option, lines are drawn in red (#0000FF); with the $GOR option, lines are drawn in white (#FFFFFF); with the $GXOR option, lines are drawn in turquoise (#FFFF00); and with the $GPRESET option, lines are drawn in green (#00FF00). Setting the write mode to $GPSET causes lines to be drawn in the graphics color.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: GETWRITEMODE, GRSTATUS, LINETO, POLYGON, PUTIMAGE, RECTANGLE, SETCOLOR, SETLINESTYLE

Example

 ! Build as a Graphics ap.
 USE DFLIB
 INTEGER(2) result, oldmode
 INTEGER(4) oldcolor
 TYPE (xycoord) xy

 oldcolor = SETBKCOLORRGB(#00FFFF)
 CALL CLEARSCREEN ($GCLEARSCREEN)
 oldcolor = SETCOLORRGB(#FF00FF)
 CALL MOVETO(INT2(0), INT2(0), xy)
 result = LINETO(INT2(200), INT2(200)) ! purple

 oldmode = SETWRITEMODE( $GAND)
 CALL MOVETO(INT2(50), INT2(0), xy)
 result = LINETO(INT2(250), INT2(200)) ! red
 END


SETWSIZEQQ

QuickWin Function: Sets the size and position of a window.

Module: USE DFLIB

Syntax

result = SETWSIZEQQ (unit, winfo)

unit
(Input) INTEGER(4). Specifies the window unit. Unit numbers 0, 5, and 6 refer to the default startup window only if the program does not explicitly open them with the OPEN statement. To set the size of the frame window (as opposed to a child window), set unit to the symbolic constant QWIN$FRAMEWINDOW (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory).

When called from INITIALSETTINGS, SETWSIZEQQ behaves slightly differently than when called from a user routine after initialization. See below under Results.

winfo
(Input) Derived type qwinfo. Physical coordinates of the window's upper-left corner, and the current or maximum height and width of the window's client area (the area within the frame). The derived type qwinfo is defined in DFLIB.F90 as follows:
 TYPE QWINFO
    INTEGER(2) TYPE  ! request type
    INTEGER(2) X     ! x coordinate for upper left
    INTEGER(2) Y     ! y coordinate for upper left
    INTEGER(2) H     ! window height
    INTEGER(2) W     ! window width
 END TYPE QWINFO

This function's behavior depends on the value of QWINFO%TYPE, which can be any of the following:

  • QWIN$MIN - Minimizes the window.
  • QWIN$MAX - Maximizes the window.
  • QWIN$RESTORE - Restores the minimized window to its previous size.
  • QWIN$SET - Sets the window's position and size according to the other values in qwinfo.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, nonzero (unless called from INITIALSETTINGS). If called from INITIALSETTINGS, the following occurs:

  • SETWSIZEQQ always returns -1.
  • Only QWIN$SET will work.

The position and dimensions of child windows are expressed in units of character height and width. The position and dimensions of the frame window are expressed in screen pixels.

The height and width specified for a frame window reflects the actual size in pixels of the frame window including any borders, menus, and status bar at the bottom.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: Using QuickWin, GETWSIZEQQ, INITIALSETTINGS

Example

 USE DFLIB
 LOGICAL(4)     result
 INTEGER(2)     numfonts, fontnum
 TYPE (qwinfo)  winfo
 TYPE (xycoord) pos
 ! Maximize frame window
 winfo%TYPE = QWIN$MAX
 result =     SETWSIZEQQ(QWIN$FRAMEWINDOW, winfo)
 ! Maximize child window
 result =   SETWSIZEQQ(0, winfo)
 numfonts = INITIALIZEFONTS( )
 fontnum =  SETFONT ('t''Arial''h50w34i')
 CALL MOVETO (INT2(10), INT2(30), pos)
 CALL OUTGTEXT("BIG Window")
 END


SHAPE

Inquiry Intrinsic Function (Generic): Returns the shape of an array or scalar argument.

Syntax

result = SHAPE (source [, kind])

source
(Input) Is a scalar or array (of any data type). It must not be an assumed-size array, a disassociated pointer, or an allocatable array that is not allocated.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is a rank-one integer array whose size is equal to the rank of source. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

The value of the result is the shape of source.

The setting of compiler options that specify integer size can affect the result of this function.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SIZE

Examples

SHAPE (2) has the value of a rank-one array of size zero.

If B is declared as B(2:4, -3:1), then SHAPE (B) has the value (3, 5).

The following shows another example:

 INTEGER VEC(2)
 REAL array(3:10, -1:3)
 VEC = SHAPE(array)
 WRITE(*,*) VEC ! prints   8       5
 END
 !
 ! Check if a mask is conformal with an array
 REAL, ALLOCATABLE :: A(:,:,:)
 LOGICAL, ALLOCATABLE :: MASK(:,:,:)
 INTEGER B(3), C(3)
 LOGICAL conform
 ALLOCATE (A(5, 4, 3))
 ALLOCATE (MASK(3, 4, 5))
 ! Check if MASK and A allocated. If they are, check
 ! that they have the same shape (conform).
 IF(ALLOCATED(A) .AND. ALLOCATED(MASK)) THEN
   B = SHAPE(A); C = SHAPE(MASK)
   IF ((B(1) .EQ. C(1)) .AND. (B(2) .EQ. C(2))       &
        .AND. (B(3) .EQ. C(3))) THEN
      conform = .TRUE.
   ELSE
      conform = .FALSE.
   END IF
 END IF
 WRITE(*,*) conform  ! prints F
 END


SHARED (TU*X only)

Parallel Directive Clause: Specifies variables that will be shared by all the threads in a team.

Syntax

SHARED (list)

list
Is the name of one or more variables or common blocks that are accessible to the scoping unit. Subobjects cannot be specified. Each name must be separated by a comma, and a named common block must appear between slashes (/ /).

All threads within a team access the same storage area for SHARED data.


SHORT

Portability Function: Converts an INTEGER(4) value into an equivalent INTEGER(2) type.

Module: USE DFPORT

Syntax

result = SHORT (int4)

int4
(Input) INTEGER(4). Value to be converted.

Results:

The result is of type INTEGER(2). The result is equal to the lower 16 bits of int4. If the int4 value is greater than 32,767, the converted INTEGER(2) value is not equal to the original.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: INT, TYPE, Portability Library

Example

      USE DFPORT
      INTEGER(4) this_one
      INTEGER(2) that_one
      READ(*,*) this_one
      THAT_ONE = SHORT(THIS_ONE)
      WRITE(*,10) THIS_ONE, THAT_ONE
 10   FORMAT (X," Long integer: ", I16, " Short integer: ", I16)
      END


SIGN

Elemental Intrinsic Function (Generic): Returns the absolute value of the first argument times the sign of the second argument.

Syntax

result = SIGN (a, b)

a
(Input) Must be of type integer or real.

b
Must have the same type and kind parameters as a.

Results:

The result type is the same as a. The value of the result is | a | if b >= zero and -| a | if b < zero.

If b is of type real and zero, the value of the result is |a|. However, if the processor can distinguish between positive and negative real zero and the /assume:minus0 compiler option is specified, the following occurs:

  • If b is positive real zero, the value of the result is |a|.
  • If b is negative real zero, the value of the result is -|a|.
Specific Name | Argument Type | Result Type
 | INTEGER(1) | INTEGER(1)
IISIGN | INTEGER(2) | INTEGER(2)
ISIGN 1 | INTEGER(4) | INTEGER(4)
KISIGN | INTEGER(8) | INTEGER(8)
SIGN | REAL(4) | REAL(4)
DSIGN | REAL(8) | REAL(8)
QSIGN 2 | REAL(16) | REAL(16)
1 Or JISIGN. For compatibility with older versions of Fortran, ISIGN can also be specified as a generic function. 2 VMS and U*X

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ABS

Examples

SIGN (4.0, -6.0) has the value -4.0.

SIGN (-5.0, 2.0) has the value 5.0.

The following shows another example:

 c = SIGN (5.2, -3.1)   ! returns -5.2
 c = SIGN (-5.2, -3.1)  ! returns -5.2
 c = SIGN (-5.2, 3.1)   ! returns  5.2


SIN

Elemental Intrinsic Function (Generic): Produces the sine of x.

Syntax

result = SIN (x)

x
(Input) Must be of type real or complex. It must be in radians and is treated as modulo 2*pi. (If x is of type complex, its real part is regarded as a value in radians.)

Results:

The result type is the same as x.

Specific Name | Argument Type | Result Type
SIN | REAL(4) | REAL(4)
DSIN | REAL(8) | REAL(8)
QSIN 1 | REAL(16) | REAL(16)
CSIN 2 | COMPLEX(4) | COMPLEX(4)
CDSIN 3 | COMPLEX(8) | COMPLEX(8)
CQSIN 1 | COMPLEX(16) | COMPLEX(16)
1 VMS and U*X 2 The setting of compiler option /real_size can affect CSIN. 3 This function can also be specified as ZSIN.

Examples

SIN (2.0) has the value 0.9092974.

SIN (0.8) has the value 0.7173561.


SIND

Elemental Intrinsic Function (Generic): Produces the sine of x.

Syntax

result = SIND (x)

x
(Input) Must be of type real. It must be in degrees and is treated as modulo 360.

Results:

The result type is the same as x.

Specific Name | Argument Type | Result Type
SIND | REAL(4) | REAL(4)
DSIND | REAL(8) | REAL(8)
QSIND 1 | REAL(16) | REAL(16)
1 VMS and U*X

Examples

SIND (2.0) has the value 3.4899496E-02.

SIND (0.8) has the value 1.3962180E-02.


SINH

Elemental Intrinsic Function (Generic): Produces a hyperbolic sine.

Syntax

result = SINH (x)

x
(Input) Must be of type real.

Results:

The result type is the same as x.

Specific Name | Argument Type | Result Type
SINH | REAL(4) | REAL(4)
DSINH | REAL(8) | REAL(8)
QSINH 1 | REAL(16) | REAL(16)
1 VMS and U*X

Examples

SINH (2.0) has the value 3.626860.

SINH (0.8) has the value 0.8881060.


SIGNAL

Portability Function: Controls interrupt signal handling. Changes the action for a specified signal.

Module: USE DFPORT

Syntax

result = SIGNAL (signum, proc, flag)

signum
(Input) INTEGER(4). Number of the signal to change. The numbers and symbolic names are listed in a table below.

proc
(Input) Name of a signal-processing routine. It must be declared EXTERNAL. This routine is called only if flag is negative.

flag
(Input) INTEGER(4). If negative, the user's proc routine is called. If 0, the signal retains its default action; if 1, the signal should be ignored.

Results:

The result is of type INTEGER(4). The result is the previous value of proc associated with the specified signal. For example, if the previous value of proc was SIG_IGN, the return value is also SIG_IGN. You can use this return value in subsequent calls to SIGNAL if the signal number supplied is invalid, if the flag value is greater than 1, or to restore a previous action definition.

A return value of SIG_ERR indicates an error, in which case a call to IERRNO returns EINVAL. If the signal number supplied is invalid, or if the flag value is greater than 1, SIGNAL returns -(EINVAL) and a call to IERRNO returns EINVAL.

An initial signal handler is in place at startup for SIGFPE (signal 8); its address is returned the first time SIGNAL is called for SIGFPE. No other signals have initial signal handlers.

Be careful when you use SIGNALQQ or the C signal function to set a handler, and then use the Portability SIGNAL function to retrieve its value. If SIGNAL returns an address that was not previously set by a call to SIGNAL, you cannot use that address with either SIGNALQQ or C's signal function, nor can you call it directly. You can, however, use the return value from SIGNAL in a subsequent call to SIGNAL. This allows you to restore a signal handler, no matter how the original signal handler was set.

All signal handlers are called with a single integer argument, that of the signal number actually received. Usually, when a process receives a signal, it terminates. With the SIGNAL function, a user procedure is called instead. The signal handler routine must accept the signal number integer argument, even if it does not use it. If the routine does not accept the signal number argument, the stack will not be properly restored after the signal handler has executed.

Because signal-handler routines are usually called asynchronously when an interrupt occurs, it is possible that your signal-handler function will get control when a run-time operation is incomplete and in an unknown state. There are certain restrictions as to which functions you can use in your signal-handler routine:

  • Do not do either low-level (such as FGETC) or high-level (such as READ) I/O.
  • Do not call heap routines or any routine that uses the heap routines (such as MALLOC and ALLOCATE).
  • Do not use any function that generates a system call (such as TIME).

SIGKILL can be neither caught nor ignored.

The following table lists signals, their names and values:

Symbolic name | Number | Description
SIGABRT | 6 | Abnormal termination
SIGFPE | 8 | Floating-point error
SIGKILL | 9 | Kill process
SIGILL | 4 | Illegal instruction
SIGINT | 2 | CTRL+C signal
SIGSEGV | 11 | Illegal storage access
SIGTERM | 15 | Termination request

The default action for all signals is to terminate the program with exit code.

ABORT does not assert the SIGABRT signal. The only way to assert SIGABRT or SIGTERM is to use KILL.

SIGNAL can be used to catch SIGFPE exceptions, but it cannot be used to access the error code that caused the SIGFPE. To do this, use SIGNALQQ instead.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SIGNALQQ

Example

    USE dfport
    EXTERNAL h_abort
    INTEGER(4) iret1, iret2, procnum
    iret1 = SIGNAL(SIGABRT, h_abort, -1)
    WRITE(*,*) 'Set signal handler. Return = ', iret1

    iret2 = KILL(procnum, SIGABRT)
    WRITE(*,*) 'Raised signal. Return = ', iret2
    END
 !
 !  Signal handler routine
 !
    INTEGER(4) FUNCTION h_abort (sig_num)
    INTEGER(4) sig_num

    WRITE(*,*) 'In signal handler for SIG$ABORT'
    WRITE(*,*) 'signum = ', sig_num
    h_abort = 1
    END


SIGNALQQ

Run-Time Function: Registers the function to be called if an interrupt signal occurs.

Module: USE DFLIB

Syntax

result = SIGNALQQ (sig, func)

sig
(Input) INTEGER(2). Interrupt type. One of the following constants, defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory):

  • SIG$ABORT - Abnormal termination
  • SIG$FPE - Floating-point error
  • SIG$ILL - Illegal instruction
  • SIG$INT - CTRL+C SIGNAL
  • SIG$SEGV - Illegal storage access
  • SIG$TERM - Termination request

func
(Input) Function to be executed on interrupt. It must be declared EXTERNAL.

Results:

The result is of type INTEGER(4). The result is a positive integer if successful; otherwise, -1 (SIG$ERR).

SIGNALQQ installs the function func as the handler for a signal of the type specified by sig. If you do not install a handler, the system by default terminates the program with exit code 3 when an interrupt signal occurs.

The argument func is the name of a function and must be declared with either the EXTERNAL or IMPLICIT statements, or have an explicit interface. A function described in an INTERFACE block is EXTERNAL by default, and does not need to be declared EXTERNAL.

Note: All signal-handler functions must be declared with the cDEC$ ATTRIBUTES C option.

When an interrupt occurs, except a SIG$FPE interrupt, the sig argument SIG$INT is passed to func, and then func is executed.

When a SIG$FPE interrupt occurs, the function func is passed two arguments: SIG$FPE and the floating-point error code (for example, FPE$ZERODIVIDE or FPE$OVERFLOW) which identifies the type of floating-point exception that occurred. The floating-point error codes begin with the prefix FPE$ and are defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory. Floating-point exceptions are described and discussed in The Floating-Point Environment in the Programmer's Guide.

If func returns, the calling process resumes execution immediately after the point at which it received the interrupt signal. This is true regardless of the type of interrupt or operating mode.

Because signal-handler routines are normally called asynchronously when an interrupt occurs, it is possible that your signal-handler function will get control when a run-time operation is incomplete and in an unknown state. Therefore, do not call heap routines or any routine that uses the heap routines (for example, I/O routines, ALLOCATE, and DEALLOCATE).

To test your signal handler routine you can generate interrupt signals by calling RAISEQQ, which causes your program either to branch to the signal handlers set with SIGNALQQ, or to perform the system default behavior if SIGNALQQ has set no signal handler.

The example below demonstrates a signal handler for SIG$ABORT. A sample signal handler for SIG$FPE is given in Handling Floating-Point Exceptions in the Programmer's Guide.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RAISEQQ, SIGNAL, KILL, GETEXCEPTIONPTRSQQ

Example

 !  This program shows a signal handler for
 !  SIG$ABORT
 USE DFLIB
 INTERFACE
   FUNCTION h_abort (signum)
     !DEC$ATTRIBUTES C :: h_abort
     INTEGER(4) h_abort
     INTEGER(2) signum
   END FUNCTION
 END INTERFACE

 INTEGER(2) i2ret
 INTEGER(4) i4ret

 i4ret = SIGNALQQ(SIG$ABORT, h_abort)
 WRITE(*,*) 'Set signal handler. Return = ', i4ret

 i2ret = RAISEQQ(SIG$ABORT)
 WRITE(*,*) 'Raised signal. Return = ', i2ret
 END
 !
 !      Signal handler routine
 !
 INTEGER(4) FUNCTION h_abort (signum)
   !DEC$ATTRIBUTES C :: h_abort
   INTEGER(2) signum
   WRITE(*,*) 'In signal handler for SIG$ABORT'
   WRITE(*,*) 'signum = ', signum
   h_abort = 1
 END


SINGLE (TU*X only)

OpenMP Parallel Compiler Directive: Specifies that a block of code is to be executed by only one thread in the team.

Syntax

c$OMP SINGLE [clause[[,] clause] ... ]
block
c$OMP END SINGLE [NOWAIT]

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

clause
Is one of the following:

  • FIRSTPRIVATE (list)
  • PRIVATE (list)

block
Is a structured block (section) of statements or constructs. You cannot branch into or out of the block.

Rules and Behavior

Threads in the team that are not executing this directive wait at the END SINGLE directive unless NOWAIT is specified.

SINGLE directives must be encountered by all threads in a team or by none at all. It must also be encountered in the same order by all threads in a team.

See Also: Parallel Directives for Tru64 UNIX Systems, OpenMP Fortran API Compiler Directives (TU*X only), Compaq Fortran Parallel Compiler Directives (TU*X only)

Examples

In the following example, the first thread that encounters the SINGLE directive executes subroutines OUTPUT and INPUT:

  c$OMP PARALLEL DEFAULT(SHARED)
        CALL WORK(X)
  c$OMP BARRIER
  c$OMP SINGLE
        CALL OUTPUT(X)
        CALL INPUT(Y)
  c$OMP END SINGLE
        CALL WORK(Y)
  c$OMP END PARALLEL

You should not make assumptions as to which thread executes the SINGLE section. All other threads skip the SINGLE section and stop at the barrier at the END SINGLE construct. If other threads can proceed without waiting for the thread executing the SINGLE section, you can specify NOWAIT in the END SINGLE directive.


SINGLE PROCESS (TU*X only)

Compaq Fortran Parallel Compiler Directive: Specifies a block of code to be executed by only one thread in a team. This directive is the same as the OpenMP Fortran API SINGLE directive except that LOCAL is permitted as an alternative spelling for the PRIVATE clause.

See Also: Parallel Directives for Tru64 UNIX Systems, Compaq Fortran Parallel Compiler Directives (TU*X only), OpenMP Fortran API Compiler Directives (TU*X only)


SIZE

Inquiry Intrinsic Function (Generic): Returns the total number of elements in an array, or the extent of an array along a specified dimension.

Syntax

result = SIZE (array [, dim] [, kind])

array
(Input) Must be an array (of any data type). It must not be a disassociated pointer or an allocatable array that is not allocated. It can be an assumed-size array if dim is present with a value less than the rank of array.

dim
(Optional; input) Must be a scalar integer with a value in the range 1 to n, where n is the rank of array.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is a scalar of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

If dim is present, the result is the extent of dimension dim in array; otherwise, the result is the total number of elements in array.

The setting of compiler options that specify integer size can affect the result of this function.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SHAPE

Examples

If B is declared as B(2:4, -3:1), then SIZE (B, DIM=2) has the value 5 and SIZE (B) has the value 15.

The following shows another example:

 REAL(8) array (3:10, -1:3)
 INTEGER i
 i = SIZE(array, DIM = 2) ! returns 5
 i = SIZE(array)          ! returns 40


SIZEOF

Inquiry Intrinsic Function (Specific): Returns the number of bytes of storage used by the argument. This is a specific function that has no generic function associated with it. It must not be passed as an actual argument.

Syntax

result = SIZEOF (x)

x
Can be a scalar or array (of any data type). It must not be an assumed-size array.

Results:

The result is of type INTEGER(4) on ia32 processors; INTEGER(8) on Alpha and ia64 processors. The result value is the number of bytes of storage used by x.

Examples

SIZEOF (3.44)              ! has the value 4
SIZEOF ('SIZE')            ! has the value 4


SLEEP

Portability Subroutine: Suspends the execution of a process for a specified interval.

Module: USE DFPORT

Syntax

CALL SLEEP (time)

time
(Input) INTEGER(4). Length of time, in seconds, to suspend the calling process.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SLEEPQQ

Example

 USE DFPORT
 integer(4) hold_time
 hold_time = 1 !lets the loop execute
 DO WHILE (hold_time .NE. 0)
   write(*,'(A)') "Enter the number of seconds to suspend"
   read(*,*) hold_time
   CALL SLEEP (hold_time)
 END DO
 END


SLEEPQQ

Run-Time Subroutine: Delays execution of the program for a specified duration.

Module: USE DFLIB

Syntax

CALL SLEEPQQ (duration)

duration
(Input) INTEGER(4). Number of milliseconds the program is to sleep (delay program execution).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

 USE DFLIB
 INTEGER(4) delay, freq, duration
 delay    = 2000
 freq     = 4000
 duration = 1000
 CALL SLEEPQQ(delay)
 CALL BEEPQQ(freq, duration)
 END


SNGL

See REAL function.


SORTQQ

Run-Time Subroutine: Sorts a one-dimensional array. The array elements cannot be derived types or record structures.

Module: USE DFLIB

Syntax

CALL SORTQQ (adrarray, count, size)

adrarray
(Input) INTEGER(4). Address of the array (returned by LOC).

count
(Input; output) INTEGER(4). On input, number of elements in the array to be sorted. On output, number of elements actually sorted.

size
(Input) INTEGER(4). Positive constant less than 32,767 that specifies the kind of array to be sorted. The following constants, defined in DFLIB.F90 (in the \DF98\INCLUDE subdirectory), specify type and kind for numeric arrays:

Constant | Type of array
SRT$INTEGER1 | INTEGER(1)
SRT$INTEGER2 | INTEGER(2) or equivalent
SRT$INTEGER4 | INTEGER(4) or equivalent
SRT$REAL4 | REAL(4) or equivalent
SRT$REAL8 | REAL(8) or equivalent

If the value provided in size is not a symbolic constant and is less than 32,767, the array is assumed to be a character array with size characters per element.

To be certain that SORTQQ is successful, compare the value returned in count to the value you provided. If they are the same, then SORTQQ sorted the correct number of elements.

Caution: The location of the array must be passed by address using the LOC function. This defeats Fortran type-checking, so you must make certain that the count and size arguments are correct.

If you pass invalid arguments, SORTQQ attempts to sort random parts of memory. If the memory it attempts to sort is allocated to the current process, that memory is sorted; otherwise, the operating system intervenes, the program is halted, and you get a General Protection Violation message.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: BSEARCHQQ, LOC

Example

 !    Sort a 1-D array
 !
 USE DFLIB
 INTEGER(2) array(10)
 INTEGER(2) i
 DATA ARRAY /143, 99, 612, 61, 712, 9112, 6, 555, 2223, 67/
 !    Sort the array
 Call SORTQQ (LOC(array), 10, SRT$INTEGER2)
 !    Display the sorted array
 DO i = 1, 10
   WRITE (*, 9000) i, array (i)
 9000 FORMAT(1X, ' Array(',I2, '): ', I5)
 END DO
 END


SPACING

Elemental Intrinsic Function (Generic): Returns the absolute spacing of model numbers near the argument value.

Syntax

result = SPACING (x)

x
(Input) Must be of type real.

Results:

The result type is the same as x. The result has the value be-p. Parameters b, e, and p are defined in Model for Real Data. If the result value is outside of the real model range, the result is TINY(x).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: TINY, RRSPACING, Data Representation Models

Examples

If 3.0 is a REAL(4) value, SPACING (3.0) has the value 2-22.

The following shows another example:

 REAL(4) res4
 REAL(8) res8, r2
 res4 = SPACING(3.0)   ! returns 2.384186E-07
 res4 = SPACING(-3.0)  ! returns 2.384186E-07
 r2   = 487923.3
 res8 = SPACING(r2)    ! returns 5.820766091346741E-011


SPLITPATHQQ

Run-Time Function: Breaks a file path or directory path into its components.

Module: USE DFLIB

Syntax

result = SPLITPATHQQ (path, drive, dir, name, ext)

path
(Input) Character*(*). Path to be broken into components. Forward slashes (/), backslashes (\), or both can be present in path.

drive
(Output) Character*(*). Drive letter followed by a colon.

dir
(Output) Character*(*). Path of directories, including the trailing slash.

name
(Output) Character*(*). Name of file or, if no file is specified in path, name of the lowest directory. If a filename, does not include an extension.

ext
(Output) Character*(*). Filename extension, if any, including the leading period (.).

Results:

The result is of type INTEGER(4). The result is the length of dir.

The path parameter can be a complete or partial file specification.

$MAXPATH is a symbolic constant defined in module DFLIB.F90 (in the \DF98\INCLUDE subdirectory) as 260.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: FULLPATHQQ

Example

 USE DFLIB
 CHARACTER($MAXPATH) buf
 CHARACTER(3)        drive
 CHARACTER(256)      dir
 CHARACTER(256)      name
 CHARACTER(256)      ext
 CHARACTER(256)      file

 INTEGER(4)          length

 buf = 'b:\fortran\test\runtime\tsplit.for'
 length = SPLITPATHQQ(buf, drive, dir, name, ext)
 WRITE(*,*) drive, dir, name, ext
 file = 'partial.f90'
 length = SPLITPATHQQ(file, drive, dir, name, ext)
 WRITE(*,*) drive, dir, name, ext

 END


SPORT_CANCEL_IO

Run-Time Function: Cancels any I/O in progress to the specified port.

Module: USE DFLIB

Syntax

iresult = SPORT_CANCEL_IO (port)

port
(Input) Integer. The port number.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

Note: This call also kills the thread that keeps an outstanding read operation to the serial port. This call must be done before any of the port characteristics are modified.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4) iresult
iresult = SPORT_CANCEL_IO( 2 )
END


SPORT_CONNECT

Run-Time Function: Establishes the connection to a serial port and defines certain usage parameters.

Module: USE DFLIB

Syntax

iresult = SPORT_CONNECT (port [, options])

port
(Input) Integer. The port number of connection. The routine will open COMn, where n is the port number specified.

options
(Optional; input) Integer. Defines the connection options. These options define how the nnn_LINE routines will work and also effect the data that is passed to the user. If more than one option is specified, the operator .OR. should be used between each option. Options are as follows:

Option | Description
DL_TOSS_CR | Removes carriage return (CR) characters on input.
DL_TOSS_LF | Removes linefeed (LF) characters on input.
DL_OUT_CR | Causes SPORT_WRITE_LINE to add a CR to each record written.
DL_OUT_LF | Causes SPORT_WRITE_LINE to add a LF to each record written.
DL_TERM_CR | Causes SPORT_READ_LINE to terminate READ when a CR is encountered.
DL_TERM_LF | Causes SPORT_READ_LINE to terminate READ when a LF is encountered.
DL_TERM_CRLF | Causes SPORT_READ_LINE to terminate READ when CR+LF is encountered.

Passing a value of zero is the same as the following:

  (DL_OUT_CR .OR. DL_TERM_CR .OR. DL_TOSS_CR .OR. DL_TOSS_LF)

This specifies to remove carriage returns and linefeeds on input, to follow output lines with a carriage return, and to return input lines when a carriage return is encountered.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPORT_RELEASE, Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4) iresult
iresult =  SPORT_CONNECT( 2, 0 )
END


SPORT_GET_HANDLE

Run-Time Function: Returns the Win32 handle associated with the communications port. This is the handle that was returned by the CreateFile Win32 API.

Module: USE DFLIB

Syntax

iresult = SPORT_GET_HANDLE (port, handle)

port
(Input) Integer. The port number.

handle
(Output) INTEGER(4). The Win32 handle that was returned from CreatFile( ) on the serial port. This handle can be used with other Win32 functions to set non-standard parameters for the communications port.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4) iresult
INTEGER(4) handle
iresult =  SPORT_GET_HANDLE( 2, handle )
END


SPORT_GET_STATE

Run-Time Function: Returns the baud rate, parity, data bits setting, and stop bits setting of the communications port.

Module: USE DFLIB

Syntax

iresult = SPORT_GET_STATE (port [, baud] [, parity] [, dbits] [, sbits])

port
(Input) Integer. The port number.

baud
(Optional; output) Integer. The baud rate of the port.

parity
(Optional; output) Integer. The parity setting of the port (0-4 = no, odd, even, mark, space).

dbits
(Optional; output) Integer. The data bits for the port.

sbits
(Optional; output) Integer. The stop bits for the port (0, 1, 2 = 1, 1.5, 2).

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPORT_SET_STATE, Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4) iresult
INTEGER    baud
INTEGER    parity
INTEGER    dbits
INTEGER    sbits

iresult =  SPORT_GET_STATE( 2, baud, parity, dbits, sbits )
END


SPORT_GET_TIMEOUTS

Run-Time Function: Returns the user selectable timeouts for the serial port.

Module: USE DFLIB

Syntax

iresult = SPORT_GET_TIMEOUTS (port [, rx_int] [, tx_tot_mult] [, tx_tot_const])

port
(Input) Integer. The port number.

rx_int
(Optional; output) INTEGER(4). The receive interval timeout value.

tx_tot_mult
(Optional; output) INTEGER(4). The transmit multiplier part of the timeout value.

tx_tot_const
(Optional; output) INTEGER(4). The transmit constant part of the timeout value.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPORT_SET_TIMEOUTS, Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4) iresult
INTEGER*4  rx_int
INTEGER*4  tx_tot_mult
INTEGER*4  tx_tot_const

iresult =  SPORT_GET_TIMEOUTS( 2, rx_int, tx_tot_mult, tx_tot_const )
END


SPORT_PEEK_DATA

Run-Time Function: Returns information about the availability of input data.

Module: USE DFLIB

Syntax

iresult = SPORT_PEEK_DATA (port [, present] [, count])

port
(Input) Integer. The port number.

present
(Optional; output) Integer. 1 if data is present, 0 if no data has been read.

count
(Optional; output) Integer. The count of characters that will be returned by SPORT_READ_DATA.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

Note: CR and LF characters may not be returned depending on the mode specified in the SPORT_CONNECT( ) call.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPORT_CONNECT, SPORT_READ_DATA, SPORT_PEEK_LINE, Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4) iresult
INTEGER    present
INTEGER    count

iresult =  SPORT_PEEK_DATA( 2, present, count )
END


SPORT_PEEK_LINE

Run-Time Function: Returns information about the availability of input records.

Module: USE DFLIB

Syntax

iresult = SPORT_PEEK_LINE (port [, present] [, count])

port
(Input) Integer. The port number.

present
(Optional; output) Integer. 1 if data is present, 0 if no data has been read.

count
(Optional; output) Integer. The count of characters that will be returned by SPORT_READ_DATA.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

This routine will only return when a line terminator has been seen - as defined by the mode specified in the SPORT_CONNECT( ) call.

Note: CR and LF characters may not be returned depending on the mode specified in the SPORT_CONNECT( ) call.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPORT_CONNECT, SPORT_READ_DATA, SPORT_PEEK_DATA, Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4) iresult
INTEGER    present
INTEGER    count

iresult =  SPORT_PEEK_LINE( 2, present, count )
END


SPORT_PURGE

Run-Time Function: Executes the Win32 API communications function PurgeComm on the specified port.

Module: USE DFLIB

Syntax

iresult = SPORT_PURGE (port, function)

port
(Input) Integer. The port number.

function
(Input) INTEGER(4). The function for PurgeComm (see the Win32 documentation).

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFWINTY
USE DFLIB
INTEGER(4) iresult
iresult =  SPORT_PURGE( 2, (PURGE_TXABORT .or. PURGE_RXABORT) )
END


SPORT_READ_DATA

Run-Time Function: Reads available data from the specified port. This routine stalls until at least one character has been read.

Module: USE DFLIB

Syntax

iresult = SPORT_READ_DATA (port, buffer [, count])

port
(Input) Integer. The port number.

buffer
(Input) Character*(*). The data that was read.

count
(Optional; input) Integer. The count of bytes read.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

Note: CR and LF characters may not be returned depending on the mode specified in the SPORT_CONNECT( ) call.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPORT_CONNECT, SPORT_PEEK_DATA, SPORT_READ_LINE, SPORT_WRITE_DATA, Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4)      iresult
INTEGER         count
CHARACTER*1024  rbuff

iresult = SPORT_READ_DATA( 2, rbuff, count )
END


SPORT_READ_LINE

Run-Time Function: Reads a record from the specified port. This routine stalls until at least one record has been read.

Module: USE DFLIB

Syntax

iresult = SPORT_READ_LINE (port, buffer [, count])

port
(Input) Integer. The port number.

buffer
(Input) Character*(*). The data that was read.

count
(Optional; input) Integer. The count of bytes read.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

This routine will only return when a line terminator has been seen - as defined by the mode specified in the SPORT_CONNECT( ) call.

Note: CR and LF characters may not be returned depending on the mode specified in the SPORT_CONNECT( ) call.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPORT_CONNECT, SPORT_PEEK_LINE, SPORT_READ_DATA, SPORT_WRITE_LINE, Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4)      iresult
INTEGER         count
CHARACTER*1024  rbuff

iresult = SPORT_READ_LINE( 2, rbuff, count )
END


SPORT_RELEASE

Run-Time Function: Releases a serial port that was previously connected to (by using SPORT_CONNECT).

Module: USE DFLIB

Syntax

iresult = SPORT_RELEASE (port)

port
(Input) Integer. The port number.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPORT_CONNECT, Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4) iresult
iresult =  SPORT_RELEASE( 2 )
END


SPORT_SET_STATE

Run-Time Function: Sets the baud rate, parity, data bits setting, and stop bits setting of the communications port.

Module: USE DFLIB

Syntax

iresult = SPORT_SET_STATE (port [, baud] [, parity] [, dbits] [, sbits])

port
(Input) Integer. The port number.

baud
(Optional; input) Integer. The baud rate of the port.

parity
(Optional; input) Integer. The parity setting of the port (0-4 = no, odd, even, mark, space).

dbits
(Optional; input) Integer. The data bits for the port.

sbits
(Optional; input) Integer. The stop bits for the port (0, 1, 2 = 1, 1.5, 2).

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

The following restrictions apply:

  • The number of data bits must be 5 to 8 bits.
  • The use of 5 data bits with 2 stop bits is an invalid combination, as is 6, 7, or 8 data bits with 1.5 stop bits.
Note: This routine must not be used when any I/O is pending. Since a read operation is always pending after any I/O has been started, you must first call SPORT_CANCEL_IO before port parameters can be changed.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPORT_CANCEL_IO, SPORT_GET_STATE, Using the Serial I/O Port Routines, Communications, Communications Functions, SetCommState

Example

USE DFLIB
INTEGER(4) iresult
iresult =  SPORT_SET_STATE( 2, 9600, 0, 7, 1 )
END


SPORT_SET_TIMEOUTS

Run-Time Function: Sets the user selectable timeouts for the serial port.

Module: USE DFLIB

Syntax

iresult = SPORT_SET_TIMEOUTS (port [, rx_int] [, tx_tot_mult] [, tx_tot_const])

port
(Input) Integer. The port number.

rx_int
(Optional; input) INTEGER(4). The receive interval timeout value.

tx_tot_mult
(Optional; input) INTEGER(4). The transmit multiplier part of the timeout value.

tx_tot_const
(Optional; input) INTEGER(4). The transmit constant part of the timeout value.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

Note: This routine must not be used when any I/O is pending. Since a read operation is always pending after any I/O has been started, you must first call SPORT_CANCEL_IO before port parameters can be changed.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPORT_CANCEL_IO, SPORT_GET_TIMEOUTS, Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4) iresult
iresult =  SPORT_SET_TIMEOUTS( 2, 100, 0, 1000 )
END


SPORT_SHOW_STATE

Run-Time Function: Displays the state of a port to standard output.

Module: USE DFLIB

Syntax

iresult = SPORT_SHOW_STATE (port, level)

port
(Input) Integer. The port number.

level
(Input) Integer. Controls the level of detail displayed as follows:

0 | Basic one line display
1 | Basic information
2 | Add modem signal control flow information
3 | Add XON/XOFF information
4 | Add event character information
11 | Add timeout information
901 | Add debug information

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

Note: This routine must not be used when any I/O is pending. Since a read operation is always pending after any I/O has been started, you must first call SPORT_CANCEL_IO before port parameters can be changed.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPORT_CANCEL_IO, Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4) iresult
iresult =  SPORT_SHOW_STATE( 2, 0 )
END


SPORT_SPECIAL_FUNC

Run-Time Function: Executes the Win32 API communications function EscapeCommFunction on the specified port.

Module: USE DFLIB

Syntax

iresult = SPORT_SPECIAL_FUNC (port, function)

port
(Input) Integer. The port number.

function
(Input) INTEGER(4). The function to perform.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4) iresult
iresult =  SPORT_SPECIAL_FUNC( 2, ? )
END


SPORT_WRITE_DATA

Run-Time Function: Outputs data to the specified port.

Module: USE DFLIB

Syntax

iresult = SPORT_WRITE_DATA (port, data [, count])

port
(Input) Integer. The port number.

data
(Input) Character*(*). The data to be output.

count
(Optional; input) Integer. The count of bytes to write. If the value is zero, this number is computed by scanning the data backwards looking for a non-blank character.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPORT_WRITE_LINE, SPORT_READ_DATA, Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4) iresult
iresult =  SPORT_WRITE_DATA( 2, 'ATZ'//CHAR(13), 0 )
END


SPORT_WRITE_LINE

Run-Time Function: Outputs data, followed by a record terminator, to the specified port.

Module: USE DFLIB

Syntax

iresult = SPORT_WRITE_LINE (port, data [, count])

port
(Input) Integer. The port number.

data
(Input) Character*(*). The data to be output.

count
(Optional; input) Integer. The count of bytes to write. If the value is zero, this number is computed by scanning the data backwards looking for a non-blank character.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, a Win32 error value.

After the data is output, a line terminator character is added based on the mode used during the SPORT_CONNECT( ) call.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SPORT_CONNECT, SPORT_WRITE_DATA, SPORT_READ_DATA, Using the Serial I/O Port Routines, Communications, Communications Functions

Example

USE DFLIB
INTEGER(4) iresult
iresult = SPORT_WRITE_LINE( 2, 'ATZ', 0 )
END


SPREAD

Transformational Intrinsic Function (Generic): Creates a replicated array with an added dimension by making copies of existing elements along a specified dimension.

Syntax

result = SPREAD (source, dim, ncopies)

source
(Input) Must be a scalar or array (of any data type). The rank must be less than 7.

dim
(Input) Must be scalar and of type integer. It must have a value in the range 1 to n + 1 (inclusive), where n is the rank of source.

ncopies
Must be scalar and of type integer. It becomes the extent of the additional dimension in the result.

Results:

The result is an array of the same type as source and of rank that is one greater than source.

If source is an array, each array element in dimension dim of the result is equal to the corresponding array element in source.

If source is a scalar, the result is a rank-one array with ncopies elements, each with the value source.

If ncopies <= zero, the result is an array of size zero.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: PACK, RESHAPE

Examples

SPREAD ("B", 1, 4) is the character array (/"B", "B", "B", "B"/).

B is the array (3, 4, 5) and NC has the value 4.

SPREAD (B, DIM=1, NCOPIES=NC) produces the array

  [ 3  4  5 ]
  [ 3  4  5 ]
  [ 3  4  5 ]
  [ 3  4  5 ].
SPREAD (B, DIM=2, NCOPIES=NC) produces the array
  [3  3  3  3 ]
  [4  4  4  4 ]
  [5  5  5  5 ].

The following shows another example:

 INTEGER AR1(2, 3), AR2(3, 2)
 AR1 = SPREAD((/1,2,3/),DIM= 1,NCOPIES= 2) ! returns
                                           ! 1 2 3
                                           ! 1 2 3
 AR2 = SPREAD((/1,2,3/), 2, 2) ! returns   1 1
                               !           2 2
                               !           3 3


SQRT

Elemental Intrinsic Function (Generic): Derives the square root of its argument.

Syntax

result = SQRT (x)

x
(Input) must be of type real or complex. If x is type real, its value must be greater than or equal to zero.

Results:

The result type is the same as x. The result has a value equal to the square root of x. A result of type complex is the principal value, with the real part greater than or equal to zero. When the real part of the result is zero, the imaginary part is greater than or equal to zero.

Specific Name | Argument Type | Result Type
SQRT | REAL(4) | REAL(4)
DSQRT | REAL(8) | REAL(8)
QSQRT 1 | REAL(16) | REAL(16)
CSQRT 2 | COMPLEX(4) | COMPLEX(4)
CDSQRT 3 | COMPLEX(8) | COMPLEX(8)
CQSQRT 1 | COMPLEX(16) | COMPLEX(16)
1 VMS and U*X 2 The setting of compiler option /real_size can affect CSQRT. 3 This function can also be specified as ZSQRT.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Examples

SQRT (16.0) has the value 4.0.

SQRT (3.0) has the value 1.732051.

The following shows another example:

 ! Calculate the hypotenuse of a right triangle
 ! from the lengths of the other two sides.
 REAL sidea, sideb, hyp
 sidea = 3.0
 sideb = 4.0
 hyp = SQRT (sidea**2 + sideb**2)
 WRITE (*, 100) hyp
 100 FORMAT (/ ' The hypotenuse is ', F10.3)
 END


SRAND

Portability Subroutine: Seeds the random number generator used with IRAND and RAND.

Module: USE DFPORT

Syntax

CALL SRAND (iseed)
CALL SRAND (rseed)

iseed
(Input) INTEGER(4). Any value.

rseed
Input) REAL(4). Any value.

SRAND seeds the random number generator used with IRAND and RAND. Calling SRAND is equivalent to calling IRAND or RAND with a new seed.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RAND, IRAND, RANDOM_NUMBER, RANDOM_SEED

Example

 !  How many random numbers out of 100 will be between .5 and .6?
    USE DFPORT
    ICOUNT = 0
    CALL SRAND(123.4567)
    DO I = 1, 100
      X = RAND(0.0)
      IF ((X>.5).AND.(x<.6)) ICOUNT = ICOUNT + 1
    END DO
    WRITE(*,*) ICOUNT, "numbers between .5 and .6!"


SSWRQQ (ia32 only)

Run-Time Subroutine: Returns the floating-point processor status word. This routine is only available on ia32 processors.

Module: USE DFLIB

Syntax

CALL SSWRQQ (status)

status
(Output) INTEGER(2). Floating-point processor status word.

SSWRQQ performs the same function as the run-time subroutine GETSTATUSFPQQ and is provided for compatibility.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LCWRQQ, GETSTATUSFPQQ

Example

 USE DFLIB
 INTEGER(2) status
 CALL SSWRQQ (status)


STAT

Portability Function: Returns detailed information about a file.

Module: USE DFPORT

Syntax

result = STAT (name, statb)

name
(Input) Character*(*). Name of the file to examine.

statb
(Output) INTEGER(4). One-dimensional array with a size of 12.

Results:

The result is of type INTEGER(4). The result is zero if the inquiry was successful; otherwise, the error code ENOENT (the specified file could not be found). For a list of other error codes, see IERRNO.

The elements of statb contain the following values:

Element | Description | Notes
statb(1) | Device file resides on | Always 0
statb(2) | File Inode number | Always 0
statb(3) | Access mode of the file | (See following table)
statb(4) | Number of hard links | Always 1
statb(5) | User ID of owner | Always 1
statb(6) | Group ID of owner | Always 1
statb(7) | Raw device file resides on | Always 0
statb(8) Size of the file in bytes
statb(9) | Time when the file was last accessed | (Only available on non-FAT file systems; undefined on FAT systems)
statb(10) Time when the file was last modified
statb(11) | Time of last file status change | Same as stat(10)
statb(12) | Blocksize | Always 1

Times are in the same format returned by the TIME function (number of seconds since 00:00:00 Greenwich mean time, January 1, 1970).

Access mode (the third element of statb) is a bitmap consisting of an IOR of the following constants:

Symbolic name | Constant | Description | Notes
S_IFMT O'0170000' Type of File
S_IFDIR O'0040000' Directory
S_IFCHR | O'0020000' | Character Special | Never set
S_IFBLK | O'0060000' | Block Special | Never set
S_IFREG O'0100000' Regular
S_IFLNK | O'0120000' | Symbolic Link | Never set
S_IFSOCK | O'0140000' | Socket | Never set
S_ISUID | O'0004000' | Set User ID on Execution | Never set
S_ISGID | O'0002000' | Set Group ID on Execution | Never set
S_ISVTX | O'0001000' | Save Swapped Text | Never set
S_IRWXU O'0000700' Owner's File Permissions
S_IRUSR,
S_IREAD 		O'0000400' Owner Read Permission Always true
S_IWUSR,
S_IWRITE 		O'0000200' Owner Write Permission
S_IXUSR,
S_IEXEC 		O'0000100' Owner Execute Permission Based on file extension (.EXE, .COM, .CMD, or .BAT)
S_IRWXG | O'0000070' | Group's File Permissions | Same as S_IRWXU
S_IRGRP | O'0000040' | Group Read Permission | Same as S_IRUSR
S_IWGRP | O'0000020' | Group Write Permission | Same as S_IWUSR
S_IXGRP | O'0000010' | Group Execute Permission | Same as S_IXUSR
S_IRWXO | O'0000007' | Other's File Permissions | Same as S_IRWXU
S_IROTH | O'0000004' | Other Read Permission | Same as S_IRUSR
S_IWOTH | O'0000002' | Other Write Permission | Same as S_IWUSR
S_IXOTH | O'0000001' | Other Execute Permission | Same as S_IXUSR

STAT returns the same information as FSTAT, but accesses files by name instead of external unit number.

Note: The INQUIRE statement also provides information about file properties.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: INQUIRE, GETFILEINFOQQ

Example

 USE DFPORT
 CHARACTER*12 file_name
 INTEGER(4) info_array(12)
 print *, 'Enter file to examine: '
 read *, file_name
 ISTATUS = STAT (file_name, info_array)
 if (.not. istatus) then
   print *, info_array
 else
   print *, 'Error = ',istatus
 end if
 end


Statement Function

Statement: Defines a function in a single statement in the same program unit in which the procedure is referenced.

Syntax

fun ([d-arg [, d-arg] ...]) = expr

fun
Is the name of the statement function.

d-arg
Is a dummy argument. A dummy argument can appear only once in any list of dummy arguments, and its scope is local to the statement function.

expr
Is a scalar expression defining the computation to be performed.

Named constants and variables used in the expression must have been declared previously in the specification part of the scoping unit or made accessible by use or host association.

If the expression contains a function reference, the function must have been defined previously in the same program unit.

A statement function reference takes the following form:

fun ([a-arg [, a-arg] ...])

fun
Is the name of the statement function.

a-arg
Is an actual argument.

Rules and Behavior

When a statement function reference appears in an expression, the values of the actual arguments are associated with the dummy arguments in the statement function definition. The expression in the definition is then evaluated. The resulting value is used to complete the evaluation of the expression containing the function reference.

The data type of a statement function can be explicitly defined in a type declaration statement. If no type is specified, the type is determined by implicit typing rules in effect for the program unit.

Actual arguments must agree in number, order, and data type with their corresponding dummy arguments.

Except for the data type, declarative information associated with an entity is not associated with dummy arguments in the statement function; for example, declaring an entity to be an array or to be in a common block does not affect a dummy argument with the same name.

The name of the statement function cannot be the same as the name of any other entity within the same program unit.

Any reference to a statement function must appear in the same program unit as the definition of that function.

A statement function reference must appear as (or be part of) an expression. The reference cannot appear on the left side of an assignment statement.

A statement function must not be provided as a procedure argument.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: FUNCTION, Argument Association, Use and Host Association

Examples

The following are examples of statement functions:

  REAL VOLUME, RADIUS
  VOLUME(RADIUS) = 4.189*RADIUS**3

  CHARACTER*10 CSF,A,B
  CSF(A,B) = A(6:10)//B(1:5)

The following example shows a statement function and some references to it:

  AVG(A,B,C) = (A+B+C)/3.
  ...
  GRADE = AVG(TEST1,TEST2,XLAB)
  IF (AVG(P,D,Q) .LT. AVG(X,Y,Z)) STOP
  FINAL = AVG(TEST3,TEST4,LAB2)       ! Invalid reference; implicit
  ...                                 ! type of third argument does not
  ...                                 ! match implicit type of dummy argument

Implicit typing problems can be avoided if all arguments are explicitly typed.

The following statement function definition is invalid because it contains a constant, which cannot be used as a dummy argument:

  REAL COMP, C, D, E
  COMP(C,D,E,3.) = (C + D - E)/3.

The following shows another example:

  Add (a, b) = a + b
  REAL(4) y, x(6)
  . . .
  DO n = 2, 6
    x(n) = Add (y, x(n-1))
  END DO


STATIC

Statement and Attribute: Controls the storage allocation of variables in subprograms (as does AUTOMATIC). Variables declared as STATIC and allocated in memory reside in the static storage area, rather than in the stack storage area.

The STATIC attribute can be specified in a type declaration statement or a STATIC statement, and takes one of the following forms:

Syntax

Type Declaration Statement:

type, [att-ls,] STATIC [att-ls,] :: v [, v] ...

Statement:

STATIC [::] v [, v] ...

type
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

v
Is the name of a variable or an array specification. It can be of any type.

Rules and Behavior

STATIC declarations only affect how data is allocated in storage.

If you want to retain definitions of variables upon reentry to subprograms, you must use the SAVE attribute.

By default, the compiler allocates local variables of non-recursive subprograms, except for allocatable arrays, in the static storage area. The compiler may choose to allocate a variable in temporary (stack or register) storage if it notices that the variable is always defined before use. Appropriate use of the SAVE attribute can prevent compiler warnings if a variable is used before it is defined.

To change the default for variables, specify them as AUTOMATIC or specify RECURSIVE in one of the following ways:

  • As a keyword in a FUNCTION or SUBROUTINE statement
  • As a compiler option
  • As an option in an OPTIONS statement

To override any compiler option that may affect variables, explicitly specify the variables as STATIC.

Note: Variables that are data-initialized, and variables in COMMON and SAVE statements are always static. This is regardless of whether a compiler option specifies recursion.

A variable cannot be specified as STATIC more than once in the same scoping unit.

If the variable is a pointer, STATIC applies only to the pointer itself, not to any associated target.

Some variables cannot be specified as STATIC. The following table shows these restrictions:

Variable | STATIC
Dummy argument | No
Automatic object | No
Common block item | Yes
Use-associated item | No
Function result | No
Component of a derived type | No

A variable can be specified with both the STATIC and SAVE attributes.

If a variable is in a module's outer scope, it can be specified as STATIC.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: AUTOMATIC, SAVE, Type declaration statements, Compatible attributes, RECURSIVE, /recursive, OPTIONS, POINTER, Modules and Module Procedures

Examples

The following example shows a type declaration statement specifying the STATIC attribute:

INTEGER, STATIC :: ARRAY_A

The following example uses a STATIC statement:

...
CONTAINS
 INTEGER FUNCTION REDO_FUNC
   INTEGER I, J(10), K
   REAL C, D, E(30)
   AUTOMATIC I, J, K(20)
   STATIC C, D, E
   ...
 END FUNCTION
...

 INTEGER N1, N2
 N1 = -1
 DO WHILE (N1)
   N2 = N1*2
   call sub1(N1, N2)
   read *, N1
 END DO
 CONTAINS
 SUBROUTINE sub1 (iold, inew)
 INTEGER, intent(INOUT):: iold
 integer, STATIC ::N3
 integer, intent(IN) :: inew
 if (iold .eq. -1) then
   N3 = iold
 end if
 print *, 'New: ', inew, 'N3: ',N3
 END subroutine
 !
 END


STOP

Statement: Terminates program execution before the end of the program unit.

Syntax

STOP [stop-code]

stop-code
(Optional) A message. It can be either of the following:

  • A scalar character constant of type default character.
  • A string of up to six digits; leading zeros are ignored. (Fortran 95/90 and FORTRAN 77 limit digits to five.)

Effect on Windows Systems

If you specify stop-code, the effect differs depending on its form, as follows:

  • If stop-code is specified as a character constant, the STOP statement writes the specified message to the standard error device and terminates program execution. The program returns a status of zero to the operating system.

  • If stop-code is specified as a string of digits, the STOP statement writes the following to the standard error device and terminates program execution:
      Return code stop-code
    In QuickWin programs, the following is displayed in a message box:
      Program terminated with Exit Code stop-code

    In both cases, the program returns a status of stop-code to the operating system as an integer.

If you do not specify stop-code, the STOP statement writes the following default message to the standard error device and terminates program execution:

  Stop - Program terminated.

The program returns a status of zero to the operating system.

Effect on OpenVMS Systems

If you specify stop-code, the STOP statement displays the specified message at your terminal, terminates program execution, and returns control to the operating system.

If you do not specify stop-code, no message is displayed.

Effect on Tru64 UNIX and Linux Systems

If you specify stop-code, the STOP statement writes the specified message to the standard error device and terminates program execution. The program returns a status of zero to the operating system.

If you do not specify stop-code, no message is output.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: EXIT

Examples

The following examples show valid STOP statements:

STOP 98
STOP 'END OF RUN'

DO
  READ *, X, Y
  IF (X > Y) STOP 5555
END DO

The following shows another example:

      OPEN(1,FILE='file1.dat', status='OLD', ERR=100)
      . . .
 100  STOP 'ERROR DETECTED!'
      END


STRICT and NOSTRICT

General Compiler Directive: STRICT disables language features not found in the language standard specified on the command line (Fortran 95 or Fortran 90). NOSTRICT (the default) enables these features.

Syntax

c DEC$ STRICT
c DEC$ NOSTRICT

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

If STRICT is specified and no language standard is specified on the command line, the default is to disable features not found in Fortran 90.

The STRICT and NOSTRICT directives can appear only appear at the top of a program unit. A program unit is a main program, an external subroutine or function, a module or a block data program unit. STRICT and NOSTRICT cannot appear between program units, or at the beginning of internal subprograms. They do not affect any modules invoked with the USE statement in the program unit that contains them.

The following forms are also allowed: !MS$STRICT and !MS$NOSTRICT

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: General Compiler Directives, /stand

Example

 ! NOSTRICT by default
 TYPE stuff
   INTEGER(4) k
   INTEGER(4) m
   CHARACTER(4) name
 END TYPE stuff
 TYPE (stuff) examp
 DOUBLE COMPLEX cd  ! non-standard data type, no error
 cd =(3.0D0, 4.0D0)
 examp.k = 4        ! non-standard component designation,
                    ! no error
 END
 SUBROUTINE STRICTDEMO( )
   !DEC$ STRICT
    TYPE stuff
     INTEGER(4) k
     INTEGER(4) m
     CHARACTER(4) name
    END TYPE stuff
    TYPE (stuff) samp
    DOUBLE COMPLEX cd   ! ERROR
    cd =(3.0D0, 4.0D0)
    samp.k = 4          ! ERROR
 END SUBROUTINE


STRUCTURE...END STRUCTURE

Statement: Defines the field names, types of data within fields, and order and alignment of fields within a record structure. Fields and structures can be initialized, but records cannot be initialized.

Syntax

STRUCTURE [/structure-name/] [field-namelist]
field-declaration
[field-declaration]
. . .
[field-declaration]
END STRUCTURE

structure-name
Is the name used to identify a structure, enclosed by slashes.

Subsequent RECORD statements use the structure name to refer to the structure. A structure name must be unique among structure names, but structures can share names with variables (scalar or array), record fields, PARAMETER constants, and common blocks.

Structure declarations can be nested (contain one or more other structure declarations). A structure name is required for the structured declaration at the outermost level of nesting, and is optional for the other declarations nested in it. However, if you wish to reference a nested structure in a RECORD statement in your program, it must have a name.

Structure, field, and record names are all local to the defining program unit. When records are passed as arguments, the fields in the defining structures within the calling and called subprograms must match in type, order, and dimension.

field-namelist
Is a list of fields having the structure of the associated structure declaration. A field namelist is allowed only in nested structure declarations.

field-declaration
Also called the declaration body. A field-declaration consists of any combination of the following:

  • Type declarations

    These are ordinary Fortran data type declarations.

  • Substructure declarations

    A field within a structure can be a substructure composed of atomic fields, other substructures, or a combination of both.

  • Union declarations

    A union declaration is composed of one or more mapped field declarations.

  • PARAMETER statements

    PARAMETER statements can appear in a structure declaration, but cannot be given a data type within the declaration block.

    Type declarations for PARAMETER names must precede the PARAMETER statement and be outside of a STRUCTURE declaration, as follows:

       INTEGER*4 P
 STRUCTURE /ABC/
   PARAMETER (P=4)
   REAL*4 F
 END STRUCTURE
   REAL*4 A(P)

Rules and Behavior

The Fortran 90 derived type replaces STRUCTURE and RECORD constructs, and should be used in writing new code. See Derived type and TYPE.

Unlike type declaration statements, structure declarations do not create variables. Structured variables (records) are created when you use a RECORD statement containing the name of a previously declared structure. The RECORD statement can be considered as a kind of type declaration statement. The difference is that aggregate items, not single items, are being defined.

Within a structure declaration, the ordering of both the statements and the field names within the statements is important, because this ordering determines the order of the fields in records.

In a structure declaration, each field offset is the sum of the lengths of the previous fields, so the length of the structure is the sum of the lengths of its fields. The structure is packed; you must explicitly provide any alignment that is needed by including, for example, unnamed fields of the appropriate length.

By default, fields are aligned on natural boundaries; misaligned fields are padded as necessary. To avoid padding of records, you should lay out structures so that all fields are naturally aligned.

To pack fields on arbitrary byte boundaries, you must specify a compiler option. You can also specify alignment for fields by using the OPTIONS or PACK general directive.

A field name must not be the same as any intrinsic or user-defined operator (for example, EQ cannot be used as a field name).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Derived type, TYPE, MAP...END MAP, RECORD, UNION...END UNION, PACK Directive, OPTIONS Directive, Data Types, Constants, and Variables, Record Structures

Examples

An item can be a RECORD statement that references a previously defined structure type:

 STRUCTURE /full_address/
   RECORD  /full_name/ personsname
   RECORD  /address/   ship_to
   INTEGER*1           age
   INTEGER*4           phone
 END STRUCTURE

You can specify a particular item by listing the sequence of items required to reach it, separated by a period (.). Suppose you declare a structure variable, shippingaddress, using the full_address structure defined in the previous example:

 RECORD /full_address/ shippingaddress

In this case, the age item would then be specified by shippingaddress.age, the first name of the receiver by shippingaddress.personsname.first_name, and so on.

In the following example, the declaration defines a structure named APPOINTMENT. APPOINTMENT contains the structure DATE (field APP_DATE) as a substructure. It also contains a substructure named TIME (field APP_TIME, an array), a CHARACTER*20 array named APP_MEMO, and a LOGICAL*1 field named APP_FLAG.

 STRUCTURE /DATE/
   INTEGER*1 DAY, MONTH
   INTEGER*2 YEAR
 END STRUCTURE

 STRUCTURE /APPOINTMENT/
   RECORD /DATE/     APP_DATE
   STRUCTURE /TIME/  APP_TIME (2)
     INTEGER*1       HOUR, MINUTE
   END STRUCTURE
   CHARACTER*20      APP_MEMO (4)
   LOGICAL*1         APP_FLAG
 END STRUCTURE

The length of any instance of structure APPOINTMENT is 89 bytes.

The following figure shows the memory mapping of any record or record array element with the structure APPOINTMENT.

Memory Map of Structure APPOINTMENT


SUBROUTINE

Statement: The initial statement of a subroutine subprogram. A subroutine subprogram is invoked in a CALL statement or by a defined assignment statement, and does not return a particular value.

Syntax

[prefix] SUBROUTINE name [([d-arg-list])]

prefix
(Optional) Is one of the following:

type [keyword]
keyword [type]

type
Is a data type specifier.

keyword
Is one of the following:

Keyword | Meaning
RECURSIVE | Permits direct recursion to occur.
PURE | Asserts that the procedure has no side effects.
ELEMENTAL | Restricted form of pure procedure that acts on one array element at a time.

name
Is the name of the subroutine.

d-arg-list
Is a list of one or more dummy arguments or alternate return specifiers (*).

Rules and Behavior

A subroutine is invoked by a CALL statement or defined assignment. When a subroutine is invoked, dummy arguments (if present) become associated with the corresponding actual arguments specified in the call.

Execution begins with the first executable construct or statement following the SUBROUTINE statement. Control returns to the calling program unit once the END statement (or a RETURN statement) is executed.

A subroutine subprogram cannot contain a FUNCTION statement, a BLOCK DATA statement, a PROGRAM statement, or another SUBROUTINE statement. ENTRY statements can be included to provide multiple entry points to the subprogram.

You need an interface block for a subroutine when:

  • Calling arguments use argument keywords.
  • Some arguments are optional.
  • A dummy argument is an assumed-shape array, a pointer, or a target.
  • The subroutine extends intrinsic assignment.
  • The subroutine can be referenced by a generic name.
  • The subroutine is in a dynamic-link library.

If the subroutine is in a DLL and is called from your program, use the option DLLEXPORT or DLLIMPORT, which you can specify with the ATTRIBUTES directive.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: FUNCTION, INTERFACE, PURE, ELEMENTAL, CALL, RETURN, ENTRY, Argument Association, Program Units and Procedures, General Rules for Function and Subroutine Subprograms, Obsolescent and Deleted Language Features

Examples

The following example shows a subroutine:

Main Program          Subroutine
CALL HELLO_WORLD      SUBROUTINE HELLO_WORLD
...                   PRINT *, "Hello World"
END                   END SUBROUTINE

The following example uses alternate return specifiers to determine where control transfers on completion of the subroutine:

Main Program                          Subroutine
    CALL CHECK(A,B,*10,*20,C)             SUBROUTINE CHECK(X,Y,*,*,Q)
    TYPE *, 'VALUE LESS THAN ZERO'        ...
    GO TO 30                          50  IF (Z)  60,70,80
10  TYPE*, 'VALUE EQUALS ZERO'        60  RETURN
    GO TO 30                          70  RETURN 1
20  TYPE*, 'VALUE MORE THAN ZERO'     80  RETURN 2
30  CONTINUE                              END
    ...

The SUBROUTINE statement argument list contains two dummy alternate return arguments corresponding to the actual arguments *10 and *20 in the CALL statement argument list.

The value of Z determines the return, as follows:

  • If Z < zero, a normal return occurs and control is transferred to the first executable statement following CALL CHECK in the main program.

  • If Z = = zero, the return is to statement label 10 in the main program.

  • If Z > zero, the return is to statement label 20 in the main program.

(An alternate return is an obsolescent feature in Fortran 90 and Fortran 95.)

The following shows another example:

     SUBROUTINE GetNum (num, unit)
     INTEGER num, unit
 10  READ (unit, '(I10)', ERR = 10) num
     END


SUBTITLE

General Compiler Directive: Specifies a string for the subtitle field of a listing header.

Syntax

c DEC$ SUBTITLE string

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

string
Is a character constant containing up to 31 printable characters.

Rules and Behavior

To enable the SUBTITLE directive, you must specify the compiler option that produces a source listing file.

When SUBTITLE appears on a page of a listing file, the specified string appears in the listing header of the following page.

If the directive appears more than once on a page, the last directive is the one in effect for the following page.

If the directive does not specify a string, no change occurs in the listing file header.

The following form is also allowed: !MS$SUBTITLE:string

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: TITLE, MESSAGE, General Compiler Directives

Example

 !DEC$ TITLE:'Program MATHSTAT'
 REAL epsilon, delta
 INTEGER i1, i2, i3
 CALL STAT(epsilon, delta)
 CALL MATH (i1, i2, i3)
 END
 SUBROUTINE STAT(a, b)
   !DEC$ SUBTITLE:'Subroutine STAT'
   REAL a, b
   CALL statpack(a, b)
   !DEC$ SUBTITLE:''
 END SUBROUTINE STAT

 SUBROUTINE MATH(a, b, c)
   !DEC$ SUBTITLE:'Subroutine MATH'
   INTEGER a, b, c
   a = b * c
   !DEC$ SUBTITLE:''
 END SUBROUTINE MATH


SUM

Transformational Intrinsic Function (Generic): Returns the sum of all the elements in an entire array or in a specified dimension of an array.

Syntax

result = SUM (array [, dim] [, mask])

array
(Input) Must be an array of type integer, real, or complex.

dim
(Optional; input) Must be a scalar integer with a value in the range 1 to n, where n is the rank of array.

mask
(Optional; input) Must be of type logical and conformable with array.

Results:

The result is an array or a scalar of the same data type as array.

The result is a scalar if dim is omitted or array has rank one.

The following rules apply if dim is omitted:

  • If SUM(array) is specified, the result is the sum of all elements of array. If array has size zero, the result is zero.

  • If SUM(array, MASK=mask) is specified, the result is the sum of all elements of array corresponding to true elements of mask. If array has size zero, or every element of mask has the value .FALSE., the result is zero.

The following rules apply if dim is specified:

  • If array has rank one, the value is the same as SUM(array [,MASK=mask]).

  • An array result has a rank that is one less than array, and shape (d1, d2, ..., ddim-1, ddim+1, ..., dn), where (d1, d2, ..., dn) is the shape of array.

  • The value of element (s1, s2, ..., sdim-1, sdim+1, ..., sn) of SUM(array, dim [,mask]) is equal to SUM(array (s1, s2, ..., sdim-1, :, sdim+1, ..., sn) [,MASK = mask (s1, s2, ..., sdim-1, :, sdim+1, ..., sn)].

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: PRODUCT

Examples

SUM ((/2, 3, 4/)) returns the value 9 (sum of 2 + 3 + 4). SUM ((/2, 3, 4/), DIM=1) returns the same result.

SUM (B, MASK=B .LT. 0.0) returns the arithmetic sum of the negative elements of B.

C is the array

  [ 1  2  3 ]
  [ 4  5  6 ].

SUM (C, DIM=1) returns the value (5, 7, 9), which is the sum of all elements in each column. 5 is the sum of 1 + 4 in column 1. 7 is the sum of 2 + 5 in column 2, and so forth.

SUM (C, DIM=2) returns the value (6, 15), which is the sum of all elements in each row. 6 is the sum of 1 + 2 + 3 in row 1. 15 is the sum of 4 + 5 + 6 in row 2.

The following shows another example:

 INTEGER array (2, 3), i, j(3)
 array = RESHAPE((/1, 2, 3, 4, 5, 6/), (/2, 3/))
 !  array is  1 3 5
 !            2 4 6
 i = SUM((/ 1, 2, 3 /))        ! returns 6
 j = SUM(array, DIM = 1)       ! returns [3 7 11]
 WRITE(*,*) i, j
 END


SYSTEM

Portability Function: Sends a command to the shell as if it had been typed at the command line.

Module: USE DFPORT

Syntax

result = SYSTEM (string)

string
(Input) Character*(*). Operating system command.

Results:

The result is of type INTEGER(4). The result is the exit status of the shell command. If -1, use IERRNO to retrieve the error. Errors can be one of the following:

  • E2BIG: The argument list is too long.
  • ENOENT: The command interpreter cannot be found.
  • ENOEXEC: The command interpreter file has an invalid format and is not executable.
  • ENOMEM: Not enough system resources are available to execute the command.

On WNT systems, the calling process waits until the command terminates. On W9* systems, the calling process does not currently wait in all cases; however, this may change in future implementations. To insure compatibility and consistent behavior, an image can be invoked directly by using the Win32 API CreateProcess( ) in your Fortran code.

Commands run with the SYSTEM routine are run in a separate shell. Defaults set with the SYSTEM function, such as current working directory or environment variables, do not affect the environment the calling program runs in.

The command line character limit for the SYSTEM function is the same limit that your operating system command interpreter accepts.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SYSTEMQQ

Example

   USE DFPORT
   INTEGER(4) I, errnum
   I = SYSTEM("dir > file.lst")
   If (I .eq. -1) then
     errnum = ierrno( )
     print *, 'Error ', errnum
   end if
   END


SYSTEM_CLOCK

Intrinsic Subroutine: Returns integer data from a real-time clock.

Syntax

CALL SYSTEM_CLOCK ([count] [, count_rate] [, count_max])

count
(Optional; output) Must be scalar and of type default integer. It is set to a value based on the current value of the processor clock. The value is increased by one for each clock count until the value count_max is reached, and is reset to zero at the next count. (count lies in the range 0 to count_max.)

count_rate
(Optional; output) Must be scalar and of type default integer. It is set to the number of processor clock counts per second.

If default integer is INTEGER(2), count_rate is 1000. If default integer is INTEGER(4), count_rate is 10000. If default integer is INTEGER(8), count_rate is 1000000.

count_max
(Optional; output) Must be scalar and of type default integer. It is set to the maximum value that count can have, HUGE(0).

SYSTEM_CLOCK returns the number of seconds from 00:00 Coordinated Universal Time (CUT) on 1 JAN 1970. The number is returned with no bias. To get the elapsed time, you must call SYSTEM_CLOCK twice, and subtract the starting time value from the ending time value.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE_AND_TIME, HUGE, GETTIM

Examples

Consider the following:

  integer(2) :: ic2, crate2, cmax2
  integer(4) :: ic4, crate4, cmax4
  call system_clock(count=ic2, count_rate=crate2, count_max=cmax2)
  call system_clock(count=ic4, count_rate=crate4, count_max=cmax4)
  print *, ic2, crate2, cmax2
  print *, ic4, crate4, cmax4
  end

This program was run on Thursday Dec 11, 1997 at 14:23:55 EST and produced the following output:

  13880   1000  32767
  1129498807       10000  2147483647


SYSTEMQQ

Run-Time Function: Executes a system command by passing a command string to the operating system's command interpreter.

Module: USE DFLIB

Syntax

result = SYSTEMQQ (commandline)

commandline
(Input) Character*(*). Command to be passed to the operating system.

Results:

The result is of type LOGICAL(4). The result is .TRUE. if successful; otherwise, .FALSE..

The SYSTEMQQ function lets you pass operating-system commands as well as programs. SYSTEMQQ refers to the COMSPEC and PATH environment variables that locate the command interpreter file (usually named COMMAND.COM).

On WNT systems, the calling process waits until the command terminates. On W9* systems, the calling process does not currently wait in all cases; however, this may change in future implementations. To insure compatibility and consistent behavior, an image can be invoked directly by using the Win32 API CreateProcess( ) in your Fortran code.

If the function fails, call GETLASTERRORQQ to determine the reason. One of the following errors can be returned:

  • ERR$2BIG - The argument list exceeds 128 bytes, or the space required for the environment formation exceeds 32K.
  • ERR$NOINT - The command interpreter cannot be found.
  • ERR$NOEXEC - The command interpreter file has an invalid format and is not executable.
  • ERR$NOMEM - Not enough memory is available to execute the command; or the available memory has been corrupted; or an invalid block exists, indicating that the process making the call was not allocated properly.

The command line character limit for the SYSTEMQQ function is the same limit that your operating system command interpreter accepts.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SYSTEM

Example

 USE DFLIB
 LOGICAL(4) result
 result = SYSTEMQQ('copy c:\bin\fmath.dat &
                         c:\dat\fmath2.dat')


TAN

Elemental Intrinsic Function (Generic): Produces the tangent of x.

Syntax

result = TAN (x)

x
(Input) Must be of type real. It must be in radians and is treated as modulo 2 * pi.

Results:

The result type is the same as x.

Specific Name | Argument Type | Result Type
TAN | REAL(4) | REAL(4)
DTAN | REAL(8) | REAL(8)
QTAN 1 | REAL(16) | REAL(16)
1 VMS and U*X

Examples

TAN (2.0) has the value -2.185040.

TAN (0.8) has the value 1.029639.


TAND

Elemental Intrinsic Function (Generic): Produces the tangent of x.

Syntax

result = TAND (x)

x
(Input) Must be of type real. It must be in degrees and is treated as modulo 360.

Results:

The result type is the same as x.

Specific Name | Argument Type | Result Type
TAND | REAL(4) | REAL(4)
DTAND | REAL(8) | REAL(8)
QTAND 1 | REAL(16) | REAL(16)
1 VMS and U*X

Examples

TAND (2.0) has the value 3.4920771E-02.

TAND (0.8) has the value 1.3963542E-02.


TANH

Elemental Intrinsic Function (Generic): Produces a hyperbolic tangent.

Syntax

result = TANH (x)

x
(Input) Must be of type real.

Results:

The result type is the same as x.

Specific Name | Argument Type | Result Type
TANH | REAL(4) | REAL(4)
DTANH | REAL(8) | REAL(8)
QTANH 1 | REAL(16) | REAL(16)
1 VMS and U*X

Examples

TANH (2.0) has the value 0.9640276.

TANH (0.8) has the value 0.6640368.


TARGET

Statement and Attribute: Specifies that an object can become the target of a pointer (it can be pointed to).

The TARGET attribute can be specified in a type declaration statement or a TARGET statement, and takes one of the following forms:

Syntax

Type Declaration Statement:

type, [att-ls,] TARGET [, att-ls] :: object [(a-spec)] [, object [(a-spec)]] ...

Statement:

TARGET [::] object [(a-spec)] [, object [(a-spec)]] ...

type
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

object
Is the name of the object. The object must not be declared with the PARAMETER attribute.

a-spec
(Optional) Is an array specification.

Rules and Behavior

A pointer is associated with a target by pointer assignment or by an ALLOCATE statement.

If an object does not have the TARGET attribute or has not been allocated (using an ALLOCATE statement), no part of it can be accessed by a pointer.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: ALLOCATE, ASSOCIATED, POINTER, Pointer Assignments, Pointer Association, Type Declarations, Compatible attributes

Examples

The following example shows type declaration statements specifying the TARGET attribute:

TYPE(SYSTEM), TARGET :: FIRST
REAL, DIMENSION(20, 20), TARGET :: C, D

The following is an example of a TARGET statement:

TARGET :: C(50, 50), D

The following fragment is from the program POINTER2.F90 in the \DF\SAMPLES\TUTORIAL subdirectory:

 ! An example of pointer assignment.
     REAL, POINTER :: arrow1 (:)
     REAL, POINTER :: arrow2 (:)
     REAL, ALLOCATABLE, TARGET :: bullseye (:)

     ALLOCATE (bullseye (7))
     bullseye = 1.
     bullseye (1:7:2) = 10.
     WRITE (*,'(/1x,a,7f8.0)') 'target ',bullseye

     arrow1 => bullseye
     WRITE (*,'(/1x,a,7f8.0)') 'pointer',arrow1
     . . .


TASKCOMMON (TU*X only)

Compaq Fortran Parallel Compiler Directive: Makes named common blocks private to a thread but global within the thread. This directive is the same as the OpenMP Fortran API THREADPRIVATE directive except that slashes (/ /) do not have to be used to delimit named common blocks.

See Also: Parallel Directives for Tru64 UNIX Systems, Compaq Fortran Parallel Compiler Directives (TU*X only), OpenMP Fortran API Compiler Directives (TU*X only)


THREADPRIVATE (TU*X only)

OpenMP Parallel Compiler Directive: Specifies named common blocks to be private (local) to a thread; they are global within the thread.

Syntax

c$OMP THREADPRIVATE (/cb/ [, /cb/] ...)

c
Is one of the following: C (or c), !, or * (see Syntax Rules for Parallel Directives).

cb
Is the name of the common block you want made private to a thread. Only named common blocks can be made thread private. Note that the slashes ( / ) are required.

Rules and Behavior

Each thread gets its own copy of the common block, so data written to the common block by one thread is not directly visible to other threads.

During serial portions and MASTER sections of the program, accesses are to the master thread copy of the common block. On entry to the first parallel region, data in the THREADPRIVATE common blocks should be assumed to be undefined unless a COPYIN clause is specified in the PARALLEL directive.

When a common block (which is initialized using DATA statements) appears in a THREADPRIVATE directive, each thread copy is initialized once prior to its first use. For subsequent parallel regions, data in THREADPRIVATE common blocks are guaranteed to persist only if the dynamic threads mechanism has been disabled and if the number of threads are the same for all the parallel regions.

A THREADPRIVATE common block or its constituent variables can appear only in a COPYIN clause. They are not permitted in a PRIVATE, FIRSTPRIVATE, LASTPRIVATE, SHARED, or REDUCTION clause. They are not affected by the DEFAULT clause.

See Also: Parallel Directives for Tru64 UNIX Systems, OpenMP Fortran API Compiler Directives (TU*X only), Compaq Fortran Parallel Compiler Directives (TU*X only)

Examples

In the following example, the common blocks BLK1 and FIELDS are specified as thread private:

        COMMON /BLK/ SCRATCH
        COMMON /FIELDS/ XFIELD, YFIELD, ZFIELD
  c$OMP THREADPRIVATE(/BLK/,/FIELDS/)
  c$OMP PARALLEL DEFAULT(PRIVATE) COPYIN(/BLK1/,ZFIELD)


TIME

TIME can be used as an intrinsic subroutine or as a portability routine.

TIME Intrinsic Subroutine

Intrinsic Subroutine: Returns the current time as set within the system.

Syntax

CALL TIME (buf)

buf
Is a 8-byte variable, array, array element, or character substring.

The date is returned as a 8-byte ASCII character string taking the form hh:mm:ss, where:

hh is the 2-digit hour
mm is the 2-digit minute
ss is the 2-digit second

If buf is of numeric type and smaller than 8 bytes, data corruption can occur.

If buf is of character type, its associated length is passed to the subroutine. If buf is smaller than 8 bytes, the subroutine truncates the date to fit in the specified length. If an array of type character is passed, the subroutine stores the date in the first array element, using the element length, not the length of the entire array.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE_AND_TIME

Example

CHARACTER*1 HOUR(8)
...
CALL TIME (HOUR)

The length of the first array element in CHARACTER array HOUR is passed to the TIME subroutine. The subroutine then truncates the time to fit into the 1-character element, producing an incorrect result.

TIME Portability Routine

Portability Function and Subroutine: The function returns the system time, in seconds, since 00:00:00 Greenwich mean time, January 1, 1970. The subroutine fills a parameter with the current time as a string in the format hh:mm:ss.

Module: USE DFPORT

Function Syntax:

result = TIME( )

Subroutine Syntax:

CALL TIME (string)

string
(Output) Character*(*). Current time, based on a 24-hour clock, in the form hh:mm:ss, where hh, mm, and ss are two-digit representations of the current hour, minutes past the hour, and seconds past the minute, respectively.

Results:

The result is of type INTEGER(4). The result is the number of seconds that have elapsed since 00:00:00 Greenwich mean time, January 1, 1970.

The value returned by this function is used as input to other Portability date and time functions.

You can use both the function and subroutine versions of TIME only if your program includes the USE DFPORT statement.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: DATE_AND_TIME

Example

 USE DFPORT
 INTEGER(4) int_time
 character*8 char_time
 int_time = TIME( )
 call TIME(char_time)
 print *, 'Integer: ', int_time, 'time: ', char_time
 END


TIMEF

Portability Function: Returns the number of seconds since the first time it is called, or zero.

Module: USE DFPORT

Syntax

result = TIMEF( )

Results:

The result is of type REAL(8). The result is the number of seconds that have elapsed since the first time TIMEF was called. The first time called, TIMEF returns 0.0D0.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Date and Time Procedures

Example

 USE DFPORT
 INTEGER i, j
 REAL(8) elapsed_time
 elapsed_time = TIMEF( )
 DO i = 1, 100000
    j = j + 1
 END DO
 elapsed_time = TIMEF( )
 PRINT *, elapsed_time
 END


TINY

Inquiry Intrinsic Function (Generic): Returns the smallest number in the model representing the same type and kind parameters as the argument.

Syntax

result = TINY (x)

x
(Input) Must be of type real; it can be scalar or array valued.

Results:

The result is a scalar with the same type and kind parameters as x. The result has the value bemin-1. Parameters b and emin are defined in Model for Real Data.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: HUGE, Data Representation Models

Examples

If X is of type REAL(4), TINY (X) has the value 2-126.

The following shows another example:

 REAL(8) r, result
 r = 487923.3D0
 result = TINY(r)   ! returns 2.225073858507201E-308


TITLE

General Compiler Directive: Specifies a string for the title field of a listing header.

Syntax

c DEC$ TITLE string

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

string
Is a character constant containing up to 31 printable characters.

Rules and Behavior

To enable the TITLE directive, you must specify the compiler option that produces a source listing file.

When TITLE appears on a page of a listing file, the specified string appears in the listing header of the following page.

If the directive appears more than once on a page, the last directive is the one in effect for the following page.

If the directive does not specify a string, no change occurs in the listing file header.

The following form is also allowed: !MS$TITLE:string

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SUBTITLE, General Compiler Directives

Example

 !DEC$ TITLE:'Program MATHSTAT Version 3.0 9/02/96'
 INTEGER i, j, k
 REAL a, b, c
 CALL hilbert(i, j, k)
 CALL erf(a, b, c)
 END


TRACEBACKQQ

Run-Time Subroutine: Provides traceback information. Uses the Visual Fortran run-time library traceback facility to generate a stack trace showing the program call stack as it appeared at the time of the call to TRACEBACKQQ( ).

Module: USE DFLIB

Syntax

CALL TRACEBACKQQ ([string] [, user_exit_code] [, status] [, eptr])

string
(Optional; input) CHARACTER*(*). A message string to precede the traceback output. It is recommended that the string be no more than 80 characters (one line) since that length appears better on output. However, this limit is not a restriction and it is not enforced. The string is output exactly as specified; no formatting or interpretation is done.

If this argument is omitted, no header message string is produced.

user_exit_code
(Optional; input) INTEGER(4). An exit code. Two values are predefined:

  • A value of -1 causes the run-time system to return execution to the caller after producing traceback.
  • A value of zero (the default) causes the application to abort execution.

Any other specified value causes the application to abort execution and return the specified value to the operating system.

status
(Optional; input) INTEGER(4). A status value. If specified, the run-time system returns the status value to the caller indicating that the traceback process was successful. The default is not to return status.

Note that a returned status value is only an indication that the "attempt" to trace the call stack was completed successfully, not that it produced a useful result.

You can include the file iosdef.for in your program to obtain symbolic definitions for the possible return values. A return value of FOR$IOS_SUCCESS (0) indicates success.

eptr
(Optional; input) Cray pointer. It is required if calling from a user-specified exception filter. If omitted, the default in null.

To trace the stack after an exception has occurred, the runtime support needs access to the exception information supplied to the filter by the operating system.

The eptr argument is a pointer to T_EXCEPTION_POINTERS, returned by the Win32 API GetExceptionInformation( ), which is usually passed to a C try/except filter function. This argument must be null if you are not passing a valid pointer to T_EXCEPTION_POINTERS. For more information, see Obtaining Traceback Information with TRACEBACKQQ in the Programmer's Guide.

The TRACEBACKQQ routine provides a standard way for an application to initiate a stack trace. It can be used to report application detected errors, debugging, and so forth. It uses the stack trace support in the Visual Fortran run-time library, and produces the same output that the run-time library produces for unhandled errors and exceptions.

The error message string normally included by the run-time system is replaced with the user-supplied message text, or omitted if no string is specified. Traceback output is directed to the target destination appropriate for the application type, just as it is when traceback is initiated internally by the run-time system.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: GETEXCEPTIONPTRSQQ, Obtaining Traceback Information with TRACEBACKQQ, Using Traceback Information, Run-Time Message Display and Format

Examples

Consider the following:

  CALL TRACEBACKQQ( )

This example generates a traceback report with no leading header message, from wherever the call site is, and aborts execution.

The following is another example:

  CALL TRACEBACKQQ("My application message string")

This example generates a traceback report with the user-supplied string as the header, and aborts execution.

The following is another example:

  CALL TRACEBACKQQ(STRING="Bad value for TEMP",USER_EXIT_CODE=123)

This example generates a traceback report with the user-supplied string as the header, and aborts execution, returning a status code of 123 to the operating system.

The following is another example:

  ...
  INTEGER(4) RTN_STS
  INCLUDE 'IOSDEF.FOR'
  ...
  CALL TRACEBACKQQ(USER_EXIT_CODE=-1,STATUS=RTN_STS)
  IF (RTN_STS .EQ. FOR$IOS_SUCCESS) THEN
    PRINT *,'TRACEBACK WAS SUCCESSFUL'
  END IF
  ...

This example generates a traceback report with no header string, and returns to the caller to continue execution of the application. If the traceback process succeeds, a status will be returned in variable RTN_STS.

For more examples, including one showing a Cray pointer, see Obtaining Traceback Information with TRACEBACKQQ in the Programmer's Guide.


TRAILZ

Elemental Intrinsic Function (Generic): Returns the number of trailing zero bits in an integer.

Syntax

result = TRAILZ (i)

i
Integer.

Results:

The result type is the same as i. The result value is the number of trailing zeros in the binary representation of the integer i.

The model for the interpretation of an integer value as a sequence of bits is shown in Model for Bit Data.

Example

Consider the following:

  INTEGER*8 J, TWO
  PARAMETER (TWO=2)
  DO J= -1, 40
    TYPE *, TRAILZ(TWO**J)  ! Prints 64, then 0 up to
  ENDDO                     !   40 (trailing zeros)
  END


TRANSFER

Transformational Intrinsic Function (Generic): Converts the bit pattern of the first argument according to the type and kind parameters of the second argument.

Syntax

result = TRANSFER (source, mold [, size])

source
(Input) Must be a scalar or array (of any data type).

mold
(Input) Must be a scalar or array (of any data type). It provides the type characteristics (not a value) for the result.

size
(Optional; input) Must be scalar and of type integer. It provides the number of elements for the output result.

Results:

The result has the same type and type parameters as mold.

If mold is a scalar and size is omitted, the result is a scalar.

If mold is an array and size is omitted, the result is a rank-one array. Its size is the smallest that is possible to hold all of source.

If size is present, the result is a rank-one array of size size.

If the physical representation of the result is larger than source, the result contains source's bit pattern in its right-most bits; the left-most bits of the result are undefined.

If the physical representation of the result is smaller than source, the result contains the right-most bits of source's bit pattern.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Examples

TRANSFER (1082130432, 0.0) has the value 4.0 (on processors that represent the values 4.0 and 1082130432 as the string of binary digits 0100 0000 1000 0000 0000 0000 0000 0000).

TRANSFER ((/2.2, 3.3, 4.4/), ((0.0, 0.0))) results in a scalar whose value is (2.2, 3.3).

TRANSFER ((/2.2, 3.3, 4.4/), (/(0.0, 0.0)/)) results in a complex rank-one array of length 2. Its first element is (2.2,3.3) and its second element has a real part with the value 4.4 and an undefined imaginary part.

TRANSFER ((/2.2, 3.3, 4.4/), (/(0.0, 0.0)/), 1) results in a complex rank-one array having one element with the value (2.2, 3.3).

The following shows another example:

 COMPLEX CVECTOR(2), CX(1)
 !  The next statement sets CVECTOR to
 !  [ 1.1 + 2.2i, 3.3 + 0.0i ]
 CVECTOR = TRANSFER((/1.1, 2.2, 3.3, 0.0/), &
                    (/(0.0, 0.0)/))
 !  The next statement sets CX to [ 1.1 + 2.2i ]
 CX = TRANSFER((/1.1, 2.2, 3.3/) , (/(0.0, 0.0)/), &
               SIZE= 1)
 WRITE(*,*) CVECTOR
 WRITE(*,*) CX
 END


TRANSPOSE

Transformational Intrinsic Function (Generic): Transposes an array of rank two.

Syntax

result = TRANSPOSE (matrix)

matrix
(Input) Must be a rank-two array (of any data type).

Results:

The result is a rank-two array with the same type and kind parameters as matrix. Its shape is (n, m), where (m, n) is the shape of matrix. For example, if the shape of matrix is (4,6), the shape of the result is (6,4).

Element (i, j) of the result has the value matrix (j, i), where i is in the range 1 to n, and j is in the range 1 to m.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: RESHAPE, PRODUCT

Examples

B is the array

  [ 2  3  4 ]
  [ 5  6  7 ]
  [ 8  9  1 ].
TRANSPOSE (B) has the value
  [ 2  5  8 ]
  [ 3  6  9 ]
  [ 4  7  1 ].

The following shows another example:

 INTEGER array(2, 3), result(3, 2)
 array = RESHAPE((/1, 2, 3, 4, 5, 6/), (/2, 3/))
 ! array is  1  3  5
 !           2  4  6
 result = TRANSPOSE(array)
 ! result is 1  2
 !           3  4
 !           5  6
 END


TRIM

Transformational Intrinsic Function (Generic): Returns the argument with trailing blanks removed.

Syntax

result = TRIM (string)

string
(Input) Must be a scalar of type character.

Results:

The result is of type character with the same kind parameter as string. Its length is the length of string minus the number of trailing blanks in string.

The value of the result is the same as string, except any trailing blanks are removed. If string contains only blank characters, the result has zero length.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LEN_TRIM

Examples

In these examples, the symbol - represents a blank.

TRIM ('--NAME----') has the value '--NAME'.

TRIM ('--C--D-----') has the value '--C--D'.

The following shows another example:

 ! next line prints 28
 WRITE(*, *) LEN("I have blanks behind me       ")
 ! the next line prints 23
 WRITE(*,*) LEN(TRIM("I have blanks behind me       "))
 END


TYPE

Statement: Declares a variable to be a derived type. For more information, see Derived Type.

Example

 !   DERIVED.F90
 !   Define a derived-type structure,
 !   type variables, and assign values

     TYPE member
       INTEGER age
       CHARACTER (LEN = 20) name
     END TYPE member

     TYPE (member) :: george
     TYPE (member) :: ernie

     george     = member( 33, 'George Brown' )
     ernie%age  = 56
     ernie%name = 'Ernie Brown'

     WRITE (*,*) george
     WRITE (*,*) ernie
     END


Type Declarations

Statement: Explicitly specifies the properties of data objects or functions.

Syntax

A type declaration statement has the general form:

type [ [, att ] ... :: ] v [/c-list/] [, v [/c-list/] ] ...

type
Is one of the following data type specifiers:

BYTE
INTEGER [ kind-selector ]
REAL [ kind-selector ]
DOUBLE PRECISION
COMPLEX [ kind-selector ]
DOUBLE COMPLEX
CHARACTER [ char-selector ]
LOGICAL [ kind-selector ]
TYPE (derived-type-name)

In the optional kind selector "([KIND=]k)", k is the kind parameter. It must be an acceptable kind parameter for that data type. If the kind selector is not present, entities declared are of default type.

Kind parameters for intrinsic numeric and logical data types can also be specified using the *n format, where n is the length (in bytes) of the entity; for example, INTEGER*4.

See each data type for further information on that type.

att
Is one of the following attribute specifiers:

ALLOCATABLE | INTRINSIC | PUBLIC 1
AUTOMATIC OPTIONAL SAVE
DIMENSION PARAMETER STATIC
EXTERNAL POINTER TARGET
INTENT | PRIVATE 1 | VOLATILE
1 These are access specifiers.

You can also declare any attribute separately as a statement.

v
Is the name of a data object or function. It can optionally be followed by:

  • An array specification, if the object is an array.

    In a function declaration, an array must be a deferred-shape array if it has the POINTER attribute; otherwise, it must be an explicit-shape array.

  • A character length, if the object is of type character.

  • An initialization expression or, for pointer objects, => NULL( ).

A function name must be the name of an intrinsic function, external function, function dummy procedure, or statement function.

c-list
Is a list of constants, as in a DATA statement. If v is the name of a constant or an initialization expression, the c-list cannot be present.

The c-list cannot specify more than one value unless it initializes an array. When initializing an array, the c-list must contain a value for every element in the array.

Rules and Behavior

Type declaration statements must precede all executable statements.

In most cases, a type declaration statement overrides (or confirms) the implicit type of an entity. However, a variable that appears in a DATA statement and is typed implicitly can appear in a subsequent type declaration only if that declaration confirms the implicit typing.

The double colon separator (::) is required only if the declaration contains an attribute specifier or initialization; otherwise it is optional.

If att appears, c-list cannot be specified; for example:

  INTEGER I /2/              ! Valid
  INTEGER, SAVE :: I /2/     ! Invalid

The same attribute must not appear more than once in a given type declaration statement, and an entity cannot be given the same attribute more than once in a scoping unit.

If the PARAMETER attribute is specified, the declaration must contain an initialization expression.

If => NULL( ) is specified for a pointer, its initial association status is disassociated.

A variable (or variable subobject) can only be initialized once in an executable program.

If a declaration contains an initialization expression, but no PARAMETER attribute is specified, the object is a variable whose value is initially defined. The object becomes defined with the value determined from the initialization expression according to the rules of intrinsic assignment.

The presence of initialization implies that the name of the object is saved, except for objects in named common blocks or objects with the PARAMETER attribute.

The following objects cannot be initialized in a type declaration statement:

  • A dummy argument
  • A function result
  • An object in a named common block (unless the type declaration is in a block data program unit)
  • An object in blank common
  • An allocatable array
  • An external name
  • An intrinsic name
  • An automatic object
  • An object that has the AUTOMATIC attribute

An object can have more than one attribute. The following table lists the compatible attributes:

Compatible Attributes

Attribute | Compatible with:
ALLOCATABLE | AUTOMATIC, DIMENSION 1, PRIVATE, PUBLIC, SAVE, STATIC, TARGET, VOLATILE
AUTOMATIC | ALLOCATABLE, DIMENSION, POINTER, TARGET, VOLATILE
DIMENSION | ALLOCATABLE, AUTOMATIC, INTENT, OPTIONAL, PARAMETER, POINTER, PRIVATE, PUBLIC, SAVE, STATIC, TARGET, VOLATILE
EXTERNAL | OPTIONAL, PRIVATE, PUBLIC
INTENT | DIMENSION, OPTIONAL, TARGET, VOLATILE
INTRINSIC | PRIVATE, PUBLIC
OPTIONAL | DIMENSION, EXTERNAL, INTENT, POINTER, TARGET, VOLATILE
PARAMETER | DIMENSION, PRIVATE, PUBLIC
POINTER | AUTOMATIC, DIMENSION 1, OPTIONAL, PRIVATE, PUBLIC, SAVE, STATIC, VOLATILE
PRIVATE | ALLOCATABLE, DIMENSION, EXTERNAL, INTRINSIC, PARAMETER, POINTER, SAVE, STATIC, TARGET, VOLATILE
PUBLIC | ALLOCATABLE, DIMENSION, EXTERNAL, INTRINSIC, PARAMETER, POINTER, SAVE, STATIC, TARGET, VOLATILE
SAVE | ALLOCATABLE, DIMENSION, POINTER, PRIVATE, PUBLIC, STATIC, TARGET, VOLATILE
STATIC | ALLOCATABLE, DIMENSION, POINTER, PRIVATE, PUBLIC, SAVE, TARGET, VOLATILE
TARGET | ALLOCATABLE, AUTOMATIC, DIMENSION, INTENT, OPTIONAL, PRIVATE, PUBLIC, SAVE, STATIC, VOLATILE
VOLATILE | ALLOCATABLE, AUTOMATIC, DIMENSION, INTENT, OPTIONAL, POINTER, PRIVATE, PUBLIC, SAVE, STATIC, TARGET
1 With deferred shape

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: CHARACTER, COMPLEX, Derived Type, DOUBLE COMPLEX, DOUBLE PRECISION, INTEGER, LOGICAL, REAL, IMPLICIT, RECORD, STRUCTURE...END STRUCTURE, TYPE, Type Declaration Statements

Examples

The following show valid type declaration statements:

DOUBLE PRECISION B(6)
INTEGER(KIND=2) I
REAL(KIND=4) X, Y
REAL(4) X, Y
LOGICAL, DIMENSION(10,10) :: ARRAY_A, ARRAY_B
INTEGER, PARAMETER :: SMALLEST = SELECTED_REAL_KIND(6, 70)
REAL(KIND (0.0)) M
COMPLEX(KIND=8) :: D
TYPE(EMPLOYEE) :: MANAGER
REAL, INTRINSIC :: COS
CHARACTER(15) PROMPT
CHARACTER*12, SAVE :: HELLO_MSG
INTEGER COUNT, MATRIX(4,4), SUM
LOGICAL*2 SWITCH
REAL :: X = 2.0

TYPE (NUM), POINTER :: FIRST => NULL()

The following shows more examples:

 REAL a (10)
 LOGICAL, DIMENSION (5, 5) :: mask1, mask2
 COMPLEX :: cube_root = (-0.5, 0.867)
 INTEGER, PARAMETER :: short = SELECTED_INT_KIND (4)
 REAL (KIND (0.0D0)) a1
 REAL (KIND = 2) b
 COMPLEX (KIND = KIND (0.0D0)) :: c
 INTEGER (short) k ! Range at least -9999 to 9999
 TYPE (member) :: george


UBOUND

Inquiry Intrinsic Function (Generic): Returns the upper bounds for all dimensions of an array, or the upper bound for a specified dimension.

Syntax

result = UBOUND (array [, dim] [, kind])

array
(Input) Must be an array (of any data type). It must not be an allocatable array that is not allocated, or a disassociated pointer. It can be an assumed-size array if dim is present with a value less than the rank of array.

dim
(Optional; input) Must be a scalar integer with a value in the range 1 to n, where n is the rank of array.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

If dim is present, the result is a scalar. Otherwise, the result is a rank-one array with one element for each dimension of array. Each element in the result corresponds to a dimension of array.

If array is an array section or an array expression that is not a whole array or array structure component, UBOUND(array, dim) has a value equal to the number of elements in the given dimension.

If array is a whole array or array structure component, UBOUND(array, dim) has a value equal to the upper bound for subscript dim of array (if dim is nonzero). If dim has size zero, the corresponding element of the result has the value zero.

The setting of compiler options that specify integer size can affect the result of this function.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: LBOUND

Examples

Consider the following:

  REAL ARRAY_A (1:3, 5:8)
  REAL ARRAY_B (2:8, -3:20)

UBOUND (ARRAY_A) is (3, 8). UBOUND (ARRAY_A, DIM=2) is 8.

UBOUND (ARRAY_B) is (8, 20). UBOUND (ARRAY_B (5:8, :)) is (4,24) because the number of elements is significant for array section arguments.

The following shows another example:

  REAL ar1(2:3, 4:5, -1:14), vec1(35)
  INTEGER res1(3), res2, res3(1)
  res1 = UBOUND (ar1)          ! returns [3, 5, 14]
  res2 = UBOUND (ar1, DIM= 3)  ! returns 14
  res3 = UBOUND (vec1)         ! returns 35
  END


UNION...END UNION

Statements: Define a data area that can be shared intermittently during program execution by one or more fields or groups of fields. A union declaration must be within a structure declaration.

Each unique field or group of fields is defined by a separate map declaration.

Syntax

UNION
map-declaration
map-declaration
[map-declaration]
. . .
[map-declaration]
END UNION

map-declaration
Takes the following form:

MAP
field-declaration
[field-declaration]
. . .
[field-declaration]
END MAP

field-declaration
Is a structure declaration or RECORD statement contained within a union declaration, a union declaration contained within a union declaration, or the declaration of a data field (having a data type) within a union. It can be of any intrinsic or derived type.

Rules and Behavior

As with normal Fortran type declarations, data can be initialized in field declaration statements in union declarations. However, if fields within multiple map declarations in a single union are initialized, the data declarations are initialized in the order in which the statements appear. As a result, only the final initialization takes effect and all of the preceding initializations are overwritten.

The size of the shared area established for a union declaration is the size of the largest map defined for that union. The size of a map is the sum of the sizes of the fields declared within it.

Manipulating data by using union declarations is similar to using EQUIVALENCE statements. The difference is that data entities specified within EQUIVALENCE statements are concurrently associated with a common storage location and the data residing there; with union declarations you can use one discrete storage location to alternately contain a variety of fields (arrays or variables).

With union declarations, only one map declaration within a union declaration can be associated at any point in time with the storage location that they share. Whenever a field within another map declaration in the same union declaration is referenced in your program, the fields in the prior map declaration become undefined and are succeeded by the fields in the map declaration containing the newly referenced field.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: STRUCTURE...END STRUCTURE, Record Structures

Examples

In the following example, the structure WORDS_LONG is defined. This structure contains a union declaration defining two map fields. The first map field consists of three INTEGER*2 variables (WORD_0, WORD_1, and WORD_2), and the second, an INTEGER*4 variable, LONG:

 STRUCTURE /WORDS_LONG/
   UNION
     MAP
       INTEGER*2  WORD_0, WORD_1, WORD_2
     END MAP
     MAP
       INTEGER*4  LONG
     END MAP
   END UNION
 END STRUCTURE

The length of any record with the structure WORDS_LONG is 6 bytes. The following figure shows the memory mapping of any record with the structure WORDS_LONG:

Memory Map of Structure WORDS_LONG

In the following example, note how the first 40 characters in the string2 array are overlayed on 4-byte integers, while the remaining 20 are overlayed on 2-byte integers:

  UNION
     MAP
       CHARACTER*20 string1, CHARACTER*10 string2(6)
     END MAP
     MAP
       INTEGER*2 number(10), INTEGER*4 var(10), INTEGER*2
 +      datum(10)
     END MAP
  END UNION


UNLINK

Portability Function: Deletes the file given by path.

Module: USE DFPORT

Syntax

result = UNLINK (name)

name
(Input) Character*(*). Path of the file to delete. The path can use forward (/) or backward (\) slashes as path separators and can contain drive letters.

Results:

The result is of type INTEGER(4). The result is zero if successful; otherwise, an error code. Errors can be one of the following:

  • ENOENT: The specified file could not be found.
  • EACCES: The specified file is read-only.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SYSTEM, DELDIRQQ

Example

 USE DFPORT
 INTEGER(4) ISTATUS
 CHARACTER*20 dirname
 READ *, dirname
 ISTATUS = UNLINK (dirname)
 IF (ISTATUS) then
    print *, 'Error ', ISTATUS
 END IF
 END


UNLOCK

Statement: Frees a record in a relative or sequential file that was locked by a previous READ statement.

Syntax

UNLOCK ([UNIT=]io-unit [, ERR=label] [, IOSTAT=i-var])
UNLOCK io-unit

io-unit
Is an external unit specifier.

label
Is the label of the branch target statement that receives control if an error occurs.

i-var
Is a scalar integer variable that is defined as a positive integer if an error occurs and zero if no error occurs.

If no record is locked, the UNLOCK statement has no effect.

See Also: Data Transfer I/O Statements, Branch Specifiers

Examples

The following statement frees any record previously read and locked in the file connected to I/O unit 4:

  UNLOCK 4

Consider the following statement:

  UNLOCK (UNIT=9, IOSTAT=IOS, ERR=10)

This statement frees any record previously read and locked in the file connected to unit 9. If an error occurs, control is transferred to the statement labeled 10, and a positive integer is stored in variable IOS.


UNPACK

Transformational Intrinsic Function (Generic): Takes elements from a rank-one array and unpacks them into another (possibly larger) array under the control of a mask.

Syntax

result = UNPACK (vector, mask, field)

vector
(Input) Must be a rank-one array (of any data type). Its size must be at least t, where t is the number of true elements in mask.

mask
(Input) Must be a logical array. It determines where elements of vector are placed when they are unpacked.

field
(Input) Must be of the same type and type parameters as vector and conformable with mask. Elements in field are inserted into the result array when the corresponding mask element has the value false.

Results:

The result is an array with the same shape as mask, and the same type and type parameters as vector.

Elements in the result array are filled in array element order. If element i of mask is true, the corresponding element of the result is filled by the next element in vector. Otherwise, it is filled by field (if field is scalar) or the ith element of field (if field is an array).

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: PACK, RESHAPE, SHAPE

Examples

N is the array

  [ 0  0  1 ]
  [ 1  0  1 ]
  [ 1  0  0 ],
P is the array (2, 3, 4, 5), and Q is the array
  [ T  F  F ]
  [ F  T  F ]
  [ T  T  F ].
UNPACK (P, MASK=Q, FIELD=N) produces the result
  [ 2  0  1 ]
  [ 1  4  1 ]
  [ 3  5  0 ].
UNPACK (P, MASK=Q, FIELD=1) produces the result
  [ 2  1  1 ]
  [ 1  4  1 ]
  [ 3  5  1 ].

The following shows another example:

 LOGICAL mask (2, 3)
 INTEGER vector(3) /1, 2, 3/, AR1(2, 3)
 mask = RESHAPE((/.TRUE.,.FALSE.,.FALSE.,.TRUE.,&
                  .TRUE.,.FALSE./), (/2, 3/))
 ! vector = [1 2 3] and mask =  T F T
 !                              F T F
 AR1 = UNPACK(vector, mask, 8)  ! returns  1 8 3
                                !          8 2 8
 END


UNPACKTIMEQQ

Run-Time Subroutine: Unpacks a packed time and date value into its component parts.

Module: USE DFLIB

Syntax

CALL UNPACKTIMEQQ (timedate, iyr, imon, iday, ihr, imin, isec)

timedate
(Input) INTEGER(4). Packed time and date information.

iyr
(Output) INTEGER(2). Year (xxxx AD).

imon
(Output) INTEGER(2). Month (1 - 12).

iday
(Output) INTEGER(2). Day (1 - 31).

ihr
(Output) INTEGER(2). Hour (0 - 23).

imin
(Output) INTEGER(2). Minute (0 - 59).

isec
(Output) INTEGER(2). Second (0 - 59).

GETFILEINFOQQ returns time and date in a packed format. You can use UNPACKTIMEQQ to unpack these values. Use PACKTIMEQQ to repack times for passing to SETFILETIMEQQ. Packed times can be compared using relational operators.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: PACKTIMEQQ, GETFILEINFOQQ

Example

 USE DFLIB
 CHARACTER(80)    file
 TYPE (FILE$INFO) info
 INTEGER(4) handle, result
 INTEGER(2) iyr, imon, iday, ihr, imin, isec

 file = 'd:\f90ps\bin\t???.*'
 handle = FILE$FIRST
 result = GETFILEINFOQQ(file, info, handle)
 CALL UNPACKTIMEQQ(info%lastwrite, iyr, imon,&
                   iday, ihr, imin, isec)
 WRITE(*,*) iyr, imon, iday
 WRITE(*,*) ihr, imin, isec
 END


UNREGISTERMOUSEEVENT

QuickWin Function: Removes the callback routine registered for a specified window by an earlier call to REGISTERMOUSEEVENT.

Module: USE DFLIB

Syntax

result = UNREGISTERMOUSEEVENT (unit, mouseevents)

unit
(Input) INTEGER(4). Unit number of the window whose callback routine on mouse events is to be unregistered.

mouseevents
(Input) INTEGER(4). One or more mouse events handled by the callback routine to be unregistered. Symbolic constants (defined in DFLIB.F90 in the \DF98\INCLUDE subdirectory) for the possible mouse events are:

  • MOUSE$LBUTTONDOWN - Left mouse button down
  • MOUSE$LBUTTONUP - Left mouse button up
  • MOUSE$LBUTTONDBLCLK - Left mouse button double-click
  • MOUSE$RBUTTONDOWN - Right mouse button down
  • MOUSE$RBUTTONUP - Right mouse button up
  • MOUSE$RBUTTONDBLCLK - Right mouse button double-click
  • MOUSE$MOVE - Mouse moved

Results:

The result is of type INTEGER(4). The result is zero or a positive integer if successful; otherwise, a negative integer that can be one of the following:

  • MOUSE$BADUNIT - The unit specified is not open, or is not associated with a QuickWin window.
  • MOUSE$BADEVENT - The event specified is not supported.

Once you call UNREGISTERMOUSEEVENT, QuickWin no longer calls the callback routine specified earlier for the window when mouse events occur. Calling UNREGISTERMOUSEEVENT when no callback routine is registered for the window has no effect.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: Using QuickWin, REGISTERMOUSEEVENT, WAITONMOUSEEVENT


UNROLL

General Compiler Directive: Tells the compiler's optimizer how many times to unroll a DO loop. It can only be applied to iterative DO loops.

Syntax

c DEC$ UNROLL [(n)]

c
Is one of the following: C (or c), !, or *. (See Syntax Rules for General Directives.)

n
Is an integer constant. The range of n is 0 through 255.

Rules and Behavior

The UNROLL directive must precede the DO statement for each DO loop it affects. No source code lines, other than the following, can be placed between the UNROLL directive statement and the DO statement:

  • An IVDEP directive
  • A PARALLEL DO directive (TU*X only)
  • A PDO directive (TU*X only)
  • Placeholder lines
  • Comment lines
  • Blank lines

If n is specified, the optimizer unrolls the loop n times. If n is omitted, or if it is outside the allowed range, the optimizer picks the number of times to unroll the loop.

The UNROLL directive overrides any setting of loop unrolling from the command line.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: General Compiler Directives


USE

Statement: Gives a program unit accessibility to public entities in a module.

Syntax

USE name [, rename-list ] ...
USE name, ONLY : [, only-list ]

name
Is the name of the module.

rename-list
Is one or more items having the following form:

local-name => mod-name

local-name
Is the name of the entity in the program unit using the module.

mod-name
Is the name of a public entity in the module.

only-list
Is the name of a public entity in the module or a generic identifier (a generic name, defined operator, or defined assignment).
An entity in the only-list can also take the form:

[local-name =>] mod-name

Rules and Behavior

If the USE statement is specified without the ONLY option, the program unit has access to all public entities in the named module.

If the USE statement is specified with the ONLY option, the program unit has access to only those entities following the option.

If more than one USE statement for a given module appears in a scoping unit, the following rules apply:

  • If one USE statement does not have the ONLY option, all public entities in the module are accessible, and any rename-lists and only-lists are interpreted as a single, concatenated rename-list.

  • If all the USE statements have ONLY options, all the only-lists are interpreted as a single, concatenated only-list. Only those entities named in one or more of the only-lists are accessible.

If two or more generic interfaces that are accessible in a scoping unit have the same name, the same operator, or are both assignments, they are interpreted as a single generic interface. Otherwise, multiple accessible entities can have the same name only if no reference to the name is made in the scoping unit.

The local names of entities made accessible by a USE statement must not be respecified with any attribute other than PUBLIC or PRIVATE. The local names can appear in namelist group lists, but not in a COMMON or EQUIVALENCE statement.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Program Units and Procedures, USE Statement (more examples)

Examples

The following shows examples of the USE statement:

MODULE MOD_A
  INTEGER :: B, C
  REAL E(25,5), D(100)
END MODULE MOD_A
...
SUBROUTINE SUB_Y
  USE MOD_A, DX => D, EX => E   ! Array D has been renamed DX and array E
  ...                           ! has been renamed EX. Scalar variables B
END SUBROUTINE SUB_Y            ! and C are also available to this subrou-
...                             ! tine (using their module names).
SUBROUTINE SUB_Z
  USE MOD_A, ONLY: B, C         ! Only scalar variables B and C are
  ...                           !   available to this subroutine
END SUBROUTINE SUB_Z
...

The following example shows a module containing common blocks:

MODULE COLORS
  COMMON /BLOCKA/ C, D(15)
  COMMON /BLOCKB/ E, F
  ...
END MODULE COLORS
...
FUNCTION HUE(A, B)
  USE COLORS
  ...
END FUNCTION HUE

The USE statement makes all of the variables in the common blocks in module COLORS available to the function HUE.

To provide data abstraction, a user-defined data type and operations to be performed on values of this type can be packaged together in a module. The following example shows such a module:

MODULE CALCULATION
  TYPE ITEM
    REAL :: X, Y
  END TYPE ITEM

  INTERFACE OPERATOR (+)
    MODULE PROCEDURE ITEM_CALC
  END INTERFACE

CONTAINS
  FUNCTION ITEM_CALC (A1, A2)
    TYPE(ITEM) A1, A2, ITEM_CALC
    ...
  END FUNCTION ITEM_CALC
  ...
END MODULE CALCULATION

PROGRAM TOTALS
USE CALCULATION
TYPE(ITEM) X, Y, Z
  ...
  X = Y + Z
  ...
END

The USE statement allows program TOTALS access to both the type ITEM and the extended intrinsic operator + to perform calculations.

The following shows another example:

 ! Module containing original type declarations
 MODULE geometry
 type square
    real side
    integer border
 end type
 type circle
    real radius
    integer border
 end type
 END MODULE

 ! Program renames module types for local use.
 PROGRAM test
 USE GEOMETRY,LSQUARE=>SQUARE,LCIRCLE=>CIRCLE
 ! Now use these types in declarations
 type (LSQUARE) s1,s2
 type (LCIRCLE) c1,c2,c3


%VAL

Built-in Function: Changes the form of an actual argument. Passes the argument as an immediate value.

Syntax

result = %VAL (a)

a
(Input) An expression, record name, procedure name, array, character array section, or array element.

The argument is passed as follows:

  • On ia32 processors, as a 32-bit immediate value. If the argument is integer (or logical) and shorter than 32 bits, it is sign-extended to a 32-bit value. For complex data types, %VAL passes two 32-bit arguments.

  • On Alpha and ia64 processors, as a 64-bit immediate value. If the argument is integer (or logical) and shorter than 64 bits, it is sign-extended to a 64-bit value. For complex data types, %VAL passes two 64-bit arguments.

You must specify %VAL in the actual argument list of a CALL statement or function reference. You cannot use it in any other context.

The following table lists the Compaq Fortran defaults for argument passing, and the allowed uses of %VAL:

Actual Argument Data Type | Default | %VAL
Expressions:
Logical | REF | Yes1
Integer | REF | Yes1
REAL(4) | REF | Yes
REAL(8) | REF | Yes2
REAL(16) 3 | REF | No
COMPLEX(4) | REF | Yes
COMPLEX(8) | REF | Yes
COMPLEX(16) 3 | REF | No
Character | See table note4 | No
Hollerith | REF | No
Aggregate5 | REF | No
Derived | REF | No
Array Name:
Numeric | REF | No
Character | See table note4 | No
Aggregate5 | REF | No
Derived | REF | No
Procedure Name:
Numeric | REF | No
Character | See table note4 | No
1 If a logical or integer value occupies less than 64 (Alpha and ia64 processors) or 32 (ia32 processors) bits of storage, it is converted to the correct size by sign extension. Use the ZEXT intrinsic function if zero extension is desired. 2 Alpha only 3 VMS, U*X 4 On Windows, Tru64 UNIX, and Linux systems, a character argument is passed by address and hidden length. 5 In Compaq Fortran record structures

The %VAL, %REF, and %DESCR functions override related cDEC$ ATTRIBUTE settings.

See Also: CALL, %REF, %DESCR

Example

  CALL SUB(2, %VAL(2))

Constant 2 is passed by reference. The second constant 2 is passed by immediate value.


VERIFY

Elemental Intrinsic Function (Generic):Verifies that a set of characters contains all the characters in a string by identifying the first character in the string that is not in the set.

Syntax

result = VERIFY (string, set [, back] [, kind])

string
(Input) Must be of type character.

set
(Input) Must be of type character with the same kind parameter as string.

back
(Optional; input)Must be of type logical.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

If back is omitted (or is present with the value false) and string has at least one character that is not in set, the value of the result is the position of the leftmost character of string that is not in set.

If back is present with the value true and string has at least one character that is not in set, the value of the result is the position of the rightmost character of string that is not in set.

If each character of string is in set or the length of string is zero, the value of the result is zero.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: SCAN

Examples

VERIFY ('CDDDC', 'C') has the value 2.

VERIFY ('CDDDC', 'C', BACK=.TRUE.) has the value 4.

VERIFY ('CDDDC', 'CD') has the value zero.

The following shows another example:

 INTEGER(4) position

 position = VERIFY ('banana', 'nbc')  ! returns 2
 position = VERIFY ('banana', 'nbc', BACK=.TRUE.)
                                      ! returns 6
 position = VERIFY ('banana', 'nbca') ! returns 0


VIRTUAL

Statement: Has the same form and effect as the DIMENSION statement. It is included for compatibility with PDP-11 FORTRAN.


VOLATILE

Statement and Attribute: Specifies that the value of an object is entirely unpredictable, based on information local to the current program unit. It prevents objects from being optimized during compilation.

The VOLATILE attribute can be specified in a type declaration statement or a VOLATILE statement, and takes one of the following forms:

Syntax

Type Declaration Statement:

type, [att-ls, ] VOLATILE [, att-ls] :: object [, object] ...

Statement:

VOLATILE object [, object] ...

type
Is a data type specifier.

att-ls
Is an optional list of attribute specifiers.

object
Is the name of an object, or the name of a common block enclosed in slashes.

Rules and Behavior

A variable or COMMON block must be declared VOLATILE if it can be read or written in a way that is not visible to the compiler. For example:

  • If an operating system feature is used to place a variable in shared memory (so that it can be accessed by other programs), the variable must be declared VOLATILE.

  • If a variable is accessed or modified by a routine called by the operating system when an asynchronous event occurs, the variable must be declared VOLATILE.

If an array is declared VOLATILE, each element in the array becomes volatile. If a common block is declared VOLATILE, each variable in the common block becomes volatile.

If an object of derived type is declared VOLATILE, its components become volatile.

If a pointer is declared VOLATILE, the pointer itself becomes volatile.

A VOLATILE statement cannot specify the following:

  • A procedure
  • A function result
  • A namelist group

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: Type Declarations, Compatible attributes

Examples

The following example shows a type declaration statement specifying the VOLATILE attribute:

  INTEGER, VOLATILE :: D, E

The following example shows a VOLATILE statement:

  PROGRAM TEST
  LOGICAL(KIND=1) IPI(4)
  INTEGER(KIND=4) A, B, C, D, E, ILOOK
  INTEGER(KIND=4) P1, P2, P3, P4
  COMMON /BLK1/A, B, C
  VOLATILE /BLK1/, D, E
  EQUIVALENCE(ILOOK, IPI)
  EQUIVALENCE(A, P1)
  EQUIVALENCE(P1, P4)

The named common block, BLK1, and the variables D and E are volatile. Variables P1 and P4 become volatile because of the direct equivalence of P1 and the indirect equivalence of P4.


WAITONMOUSEEVENT

QuickWin Function: Waits for the specified mouse input from the user.

Module: USE DFLIB

Syntax

result = WAITONMOUSEEVENT (mouseevents, keystate, x, y)

mouseevents
(Input) INTEGER(4). One or more mouse events that must occur before the function returns. Symbolic constants for the possible mouse events are:

  • MOUSE$LBUTTONDOWN - Left mouse button down
  • MOUSE$LBUTTONUP - Left mouse button up
  • MOUSE$LBUTTONDBLCLK - Left mouse button double-click
  • MOUSE$RBUTTONDOWN - Right mouse button down
  • MOUSE$RBUTTONUP - Right mouse button up
  • MOUSE$RBUTTONDBLCLK - Right mouse button double-click
  • MOUSE$MOVE - Mouse moved

keystate
(Output) INTEGER(4). Bitwise inclusive OR of the state of the mouse duing the event. The value returned in keystate can be any or all of the following symbolic constants:

  • MOUSE$KS_LBUTTON - Left mouse button down during event
  • MOUSE$KS_RBUTTON - Right mouse button down during event
  • MOUSE$KS_SHIFT - SHIFT key held down during event
  • MOUSE$KS_CONTROL - CONTROL key held down during event

x
(Output) INTEGER(4). X position of the mouse when the event occurred.

y
(Output) INTEGER(4). Y position of the mouse when the event occurred.

Results:

The result is of type INTEGER(4). The result is the symbolic constant associated with the mouse event that occurred if successful. If the function fails, it returns the constant MOUSE$BADEVENT, meaning the event specified is not supported.

WAITONMOUSEEVENT does not return until the specified mouse input is received from the user. While waiting for a mouse event to occur, the status bar changes to read "Mouse input pending in XXX", where XXX is the name of the window. When a mouse event occurs, the status bar returns to its previous value.

A mouse event must happen in the window that had focus when WAITONMOUSEEVENT was initially called. Mouse events in other windows will not end the wait. Mouse events in other windows cause callbacks to be called for the other windows, if callbacks were previously registered for those windows.

For every BUTTONDOWN or BUTTONDBLCLK event there is an associated BUTTONUP event. When the user double clicks, four events happen: BUTTONDOWN and BUTTONUP for the first click, and BUTTONDBLCLK and BUTTONUP for the second click. The difference between getting BUTTONDBLCLK and BUTTONDOWN for the second click depends on whether the second click occurs in the double click interval, set in the system's CONTROL PANEL/MOUSE.

Compatibility

QUICKWIN GRAPHICS LIB

See Also: REGISTERMOUSEEVENT, UNREGISTERMOUSEEVENT, Using QuickWin


WHERE

Statement and Contruct: Lets you use masked array assignment, which performs an array operation on selected elements. This kind of assignment applies a logical test to an array on an element-by-element basis.

Syntax

Statement:

WHERE (mask-expr1) assign-stmt

Contruct:

[name:] WHERE (mask-expr1)
[where-body-stmt] ...
[ELSEWHERE (mask-expr2) [name]
[where-body-stmt] ...]
[ELSEWHERE [name]
[where-body-stmt] ...]
END WHERE [name]

mask-expr1, mask-expr2
Are logical array expressions (called mask expressions).

assign-stmt
Is an assignment statement of the form: array variable = array expression.

name
Is the name of the WHERE construct.

where-body-stmt
Is one of the following:

  • An assign-stmt

    The assignment can be a defined assignment only if the routine implementing the defined assignment is elemental.

  • A WHERE statement or construct

Rules and Behavior

If a construct name is specified in a WHERE statement, the same name must appear in the corresponding END WHERE statement. The same construct name can optionally appear in any ELSEWHERE statement in the construct. (ELSEWHERE cannot specify a different name.)

In each assignment statement, the mask expression, the variable being assigned to, and the expression on the right side, must all be conformable. Also, the assignment statement cannot be a defined assignment.

Only the WHERE statement (or the first line of the WHERE construct) can be labeled as a branch target statement.

The following shows an example using a WHERE statement:

  INTEGER A, B, C
  DIMENSION A(5), B(5), C(5)
  DATA A /0,1,1,1,0/
  DATA B /10,11,12,13,14/
  C = -1

  WHERE(A .NE. 0) C = B / A

The resulting array C contains: -1,11,12,13, and -1.

The assignment statement is only executed for those elements where the mask is true. Think of the mask expression as being evaluated first into a logical array that has the value true for those elements where A is positive. This array of trues and falses is applied to the arrays A, B and C in the assignment statement. The right side is only evaluated for elements for which the mask is true; assignment on the left side is only performed for those elements for which the mask is true. The elements for which the mask is false do not get assigned a value.

In a WHERE construct, the mask expression is evaluated first and only once. Every assignment statement following the WHERE is executed as if it were a WHERE statement with "mask-expr1" and every assignment statement following the ELSEWHERE is executed as if it were a WHERE statement with ".NOT. mask-expr1". If ELSEWHERE specifies "mask-expr2", it is executed as "(.NOT. mask-expr1) .AND. mask-expr2" during the processing of the ELSEWHERE statement.

You should be careful if the statements have side effects, or modify each other or the mask expression.

The following is an example of the WHERE construct:

  DIMENSION PRESSURE(1000), TEMP(1000), PRECIPITATION(1000)
  WHERE(PRESSURE .GE. 1.0)
    PRESSURE = PRESSURE + 1.0
    TEMP = TEMP - 10.0
  ELSEWHERE
    PRECIPITATION = .TRUE.
  ENDWHERE

The mask is applied to the arguments of functions on the right side of the assignment if they are considered to be elemental functions. Only elemental intrinsics are considered elemental functions. Transformational intrinsics, inquiry intrinsics, and functions or operations defined in the subprogram are considered to be nonelemental functions.

Consider the following example using LOG, an elemental function:

  WHERE(A .GT. 0)  B = LOG(A)

The mask is applied to A, and LOG is executed only for the positive values of A. The result of the LOG is assigned to those elements of B where the mask is true.

Consider the following example using SUM, a nonelemental function:

  REAL A, B
  DIMENSION A(10,10), B(10)
  WHERE(B .GT. 0.0)  B = SUM(A, DIM=1)

Since SUM is nonelemental, it is evaluated fully for all of A. Then, the assignment only happens for those elements for which the mask evaluated to true.

Consider the following example:

  REAL A, B, C
  DIMENSION A(10,10), B(10), C(10)
  WHERE(C .GT. 0.0)  B = SUM(LOG(A), DIM=1)/C

Because SUM is nonelemental, all of its arguments are evaluated fully regardless of whether they are elemental or not. In this example, LOG(A) is fully evaluated for all elements in A even though LOG is elemental. Notice that the mask is applied to the result of the SUM and to C to determine the right side. One way of thinking about this is that everything inside the argument list of a nonelemental function does not use the mask, everything outside does.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: FORALL, Arrays

Examples

  REAL(4) a(20)
  . . .
  WHERE (a > 0.0)
    a = LOG (a)
       !LOG is invoked only for positive elements
  END WHERE


WRAPON

Graphics Function: Controls whether text output with the OUTTEXT function wraps to a new line or is truncated when the text output reaches the edge of the defined text window.

Module: USE DFLIB

Syntax

result = WRAPON (option)

option
(Input) INTEGER(2). Wrap mode. One of the following symbolic constants:

  • $GWRAPOFF - Truncates lines at right edge of window border.
  • $GWRAPON - Wraps lines at window border, scrolling if necessary.

Results:

The result is of type INTEGER(2). The result is the previous value of option.

WRAPON does not affect font routines such as OUTGTEXT.

Compatibility

STANDARD GRAPHICS QUICKWIN GRAPHICS LIB

See Also: OUTTEXT, SCROLLTEXTWINDOW, SETTEXTPOSITION, SETTEXTWINDOW

Example

 USE DFLIB
 INTEGER(2) row, status2
 INTEGER(4) status4
 TYPE ( rccoord ) curpos
 TYPE ( windowconfig ) wc
 LOGICAL status

 status = GETWINDOWCONFIG( wc )
 wc%numtextcols = 80
 wc%numxpixels  = -1
 wc%numypixels  = -1
 wc%numtextrows = -1
 wc%numcolors   = -1
 wc%fontsize    = -1
 wc%title = "This is a test"C
 wc%bitsperpixel = -1
 status = SETWINDOWCONFIG( wc )
 status4= SETBKCOLORRGB(#FF0000 )
 CALL CLEARSCREEN( $GCLEARSCREEN )

 !  Display wrapped and unwrapped text in text windows.
 CALL SETTEXTWINDOW( INT2(1),INT2(1),INT2(5),INT2(25))
 CALL SETTEXTPOSITION(INT2(1),INT2(1), curpos )
 status2 = WRAPON( $GWRAPON )
 status4 = SETTEXTCOLORRGB(#00FF00)
 DO i = 1, 5
    CALL OUTTEXT( 'Here text does wrap. ')
 END DO
 CALL SETTEXTWINDOW(INT2(7),INT2(10),INT2(11),INT2(40))
 CALL SETTEXTPOSITION(INT2(1),INT2(1),curpos)
 status2 = WRAPON( $GWRAPOFF )
 status4 = SETTEXTCOLORRGB(#008080)
 DO row = 1, 5
    CALL SETTEXTPOSITION(INT2(row), INT2(1), curpos )
    CALL OUTTEXT('Here text does not wrap. ')
    CALL OUTTEXT('Here text does not wrap.')
 END DO
 READ (*,*) ! Wait for ENTER to be pressed
 END


WRITE

Statement: Transfers output data to external sequential, direct-access, or internal records.

Syntax

Sequential

Formatted:

WRITE (eunit, format [, advance] [, iostat] [, err]) [io-list]

Formatted - List-Directed:

WRITE (eunit, * [, iostat] [, err]) [io-list]

Formatted - Namelist:

WRITE (eunit, nml-group [, iostat] [, err])

Unformatted:

WRITE (eunit [, iostat] [, err]) [io-list]

Direct-Access

Formatted:

WRITE (eunit, format, rec [, iostat] [, err]) [io-list]

Unformatted:

WRITE (eunit, rec [, iostat] [, err]) [io-list]

Indexed (VMS only)

Formatted:

WRITE (eunit, format, [, iostat] [, err]) [io-list]

Unformatted:

WRITE (eunit, [, iostat] [, err]) [io-list]

Internal

WRITE (iunit, format [, iostat] [, err]) [io-list]

eunit
Is an external unit specifier, optionally prefaced by UNIT=. UNIT= is required if eunit is not the first specifier in the list.

format
Is a format specifier. It is optionally prefaced by FMT= if format is the second specifier in the list and the first specifier indicates a logical or internal unit specifier without the optional keyword UNIT=.

For internal WRITEs, an asterisk (*) indicates list-directed formatting. For direct-access WRITEs, an asterisk is not permitted.

advance
Is an advance specifier (ADVANCE=c-expr). If the value of c-expr is 'YES', the statement uses advancing input; if the value is 'NO', the statement uses nonadvancing input. The default value is 'YES'.

iostat
Is the name of a variable to contain the completion status of the I/O operation. Optionally prefaced by IOSTAT=.

err
Are branch specifiers if an error (ERR=label) condition occurs.

io-list
Is an I/O list: the names of the variables, arrays, array elements, or character substrings from which or to which data will be transferred. Optionally an implied-DO list.

form
Is the nonkeyword form of a format specifier (no FMT=).

*
Is the format specifier indicating list-directed formatting. (It can also be specified as FMT=*.)

nml-group
Is the namelist group specification for namelist I/O. Optionally prefaced by NML=. NML= is required if nml-group is not the second I/O specifier.

rec
Is the cell number of a record to be accessed directly. Optionally prefaced by REC=.

iunit
Is an internal unit specifier, optionally prefaced by UNIT=. UNIT= is required if iunit is not the first specifier in the list.

It must be a character variable. It must not be an array section with a vector subscript.

If a parameter of the WRITE statement is an expression that calls a function, that function must not execute an I/O statement or the EOF intrinsic function, because the results are unpredictable.

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

See Also: I/O Lists, I/O Control List, Forms for Sequential WRITE Statements, Forms for Direct-Access WRITE Statements, Forms for Indexed WRITE Statements (VMS only), Forms and Rules for Internal WRITE Statements, READ, PRINT, OPEN, I/O Formatting

Example

 ! write to file
 open(1,FILE='test.dat')
 write (1, '(A20)') namedef
 ! write with FORMAT statement
 WRITE (*, 10) (n, SQRT(FLOAT(n)), FLOAT(n)**(1.0/3.0), n = 1, 100)
 10 FORMAT (I5, F8.4, F8.5)
 !
 WRITE(6,'("Expected ",F12.6)') 2.0


XOR

Elemental Intrinsic Function (Generic): See IEOR.

Example

 INTEGER i, j, k
 i = 3             ! 011
 j = 5             ! 101
 k = XOR(i, j)     ! returns 6 = 110


ZEXT

Elemental Intrinsic Function (Generic): Extends the argument with zeros. This function is used primarily for bit-oriented operations.

Syntax

result = ZEXT (x [, kind])

x
(Input) Must be of type logical or integer.

kind
(Optional; input) Must be a scalar integer initialization expression.

Results:

The result is of type integer. If kind is present, the kind parameter of the result is that specified by kind; otherwise, the kind parameter of the result is that of default integer. If the processor cannot represent the result value in the kind of the result, the result is undefined.

The result value is x extended with zeros and treated as an unsigned value.

The storage requirements for integer constants are never less than two bytes. Integer constants within the range of constants that can be represented by a single byte still require two bytes of storage.

The setting of compiler option /integer_size can affect ZEXT.

Specific Name | Argument Type | Result Type
IZEXT | LOGICAL(1) | INTEGER(2)
 | LOGICAL(2) | INTEGER(2)
 | INTEGER(1) | INTEGER(2)
 | INTEGER(2) | INTEGER(2)
JZEXT | LOGICAL(1) | INTEGER(4)
 | LOGICAL(2) | INTEGER(4)
 | LOGICAL(4) | INTEGER(4)
 | INTEGER(1) | INTEGER(4)
 | INTEGER(2) | INTEGER(4)
 | INTEGER(4) | INTEGER(4)
KZEXT | LOGICAL(1) | INTEGER(8)
 | LOGICAL(2) | INTEGER(8)
 | LOGICAL(4) | INTEGER(8)
 | LOGICAL(8) | INTEGER(8)
 | INTEGER(1) | INTEGER(8)
 | INTEGER(2) | INTEGER(8)
 | INTEGER(4) | INTEGER(8)
 | INTEGER(8) | INTEGER(8)

Compatibility

CONSOLE STANDARD GRAPHICS QUICKWIN GRAPHICS WINDOWS DLL LIB

Example

Consider the following example:

  INTEGER(2) W_VAR  /'FFFF'X/
  INTEGER(4) L_VAR
  L_VAR = ZEXT( W_VAR )

This example stores an INTEGER(2) quantity in the low-order 16 bits of an INTEGER(4) quantity, with the resulting value of L_VAR being '0000FFFF'X. If the ZEXT function had not been used, the resulting value would have been 'FFFFFFFF'X, because W_VAR would have been converted to the left-hand operand's data type by sign extension.


Glossary

A - B - C - D - E - F - G - H - I - K - L - M - N - O - P - Q - R - S - T - U - V - W - Z


Glossary A

absolute pathname
On Windows, Tru64 UNIX, and Linux systems, a directory path specified in fixed relationship to the root directory. On Tru64 UNIX and Linux systems, the first character is a slash (/). On Windows systems, the first character is a backslash (\).
active screen buffer
The screen buffer that is currently displayed in a console's window.
active window
A top-level window of the application with which the user is working. The Windows system identifies the active window by highlighting its title bar and border.
actual argument
An expression, variable, procedure, or alternate return specifier that is specified in a subroutine or function reference. The value is passed from the calling program unit to a subprogram.
adjustable array
An explicit-shape array that is a dummy argument to a subprogram. The term is from FORTRAN-77. See also explicit-shape array.
aggregate reference
A reference to a record structure field.
allocatable array
A named array that has the ALLOCATABLE attribute. Once space has been allocated for this type of array, the array has a shape and can be defined (and redefined) or referenced. It is an error to allocate an allocatable array that is currently allocated.
allocation status
Indicates whether an allocatable array or pointer is allocated. An allocation status is one of: allocated, deallocated, or undefined. An undefined allocation status means an array can no longer be referenced, defined, allocated, or deallocated. See also association status.
alphanumeric
Pertaining to letters and digits.
alternate key
On OpenVMS systems, an optional key within the data records in an indexed file, which can be used to build an alternate index.
alternate return
A subroutine argument that permits control to branch immediately to some position other than the statement following the call. The actual argument in an alternate return is the statement label to which control should be transferred. (An alternate return is an obsolescent feature in Fortran 90.)
ANSI
The American National Standards Institute. An organization through which accredited organizations create and maintain voluntary industry standards.
argument
See actual argument and dummy argument.
argument association
The relationship (or "matching up") between an actual argument and dummy argument during the execution of a procedure reference.
argument keyword
The name of a dummy (formal) argument. It can be used in a procedure reference before the equals sign [keyword = actual argument] provided the procedure has an explicit interface. This association allows actual arguments to appear in any order.

Argument keywords are supplied for many of the intrinsic procedures.
array
A set of scalar data that all have the same type and kind type parameters. An array can be referenced by element (using a subscript), by section (using a section subscript list), or as a whole. An array has a rank (up to 7), bounds, size, and a shape.

An individual array element is a scalar object. An array section, which is itself an array, is a subset of the entire array.

Contrast with scalar. See also bounds, conformable, shape, size, whole array, and zero-sized array.
array constructor
A mechanism used to specify a sequence of scalar values that produce a rank-one array.

To construct an array of rank greater than one, you must apply the RESHAPE intrinsic function to the array constructor.
array element
A scalar (individual) item in an array. An array element is identified by the array name followed by one or more subscripts in parentheses, indicating the element's position in the array. For example, B(3) or A(2,5).
array pointer
A pointer to an array. See also array and pointer.
array section
A subobject (or portion) of an array. It consists of the set of array elements or substrings of this set. The set (or section subscript list) is specified by subscripts, subscript triplets, and vector subscripts. If the set does not contain at least one subscript triplet or vector subscript, the reference indicates an array element, not an array.
array specification
A program statement specifying an array name and the number of dimensions the array contains (its rank). An array specification can appear in a DIMENSION or COMMON statement, or in a type declaration statement.
ASCII
The American Standard Code for Information Interchange. A 7-bit character encoding scheme associating an integer from 0 through 127 with 128 characters.
assignment
A statement in the form variable = expression. The statement assigns (stores) the value of an expression on the right of an equal sign to the storage location of the variable to the left of the equal sign. In the case of Fortran 95/90 pointers, the storage location is assigned, not the pointer itself.
association
The mechanism that permits an entity to be referenced by different names in the same or in different scoping units. The principal kinds of association are argument association, host association, pointer association, storage association, and use association.
association status
Indicates whether or not a pointer is associated with a target. An association status is one of: undefined, associated, or disassociated. An undefined association status means a pointer can no longer be referenced, defined, or deallocated. An undefined pointer can, however, be allocated, nullified, or pointer assigned to a new target. See also allocation status.
assumed-length character argument
A dummy argument that assumes the length attribute of the corresponding actual argument. An asterisk (*) specifies the length of the dummy character argument.
assumed-shape array
A dummy argument array that assumes the shape of its associated actual argument array.
assumed-size array
A dummy array that takes the size of the actual argument passed to it. The rank, extents, and bounds of the dummy array are specified in its declaration, except for the upper bound (which is specified by a *) and the extent of the last dimension.
attribute
A property of a data object that can be specified in a type declaration statement. These properties determine how the data object can be used in a program.

Most attributes can be alternatively specified in statements. For example, the DIMENSION statement has the same meaning as the DIMENSION attribute appearing in a type declaration statement.
automatic array
An explicit-shape array that is a local variable in a subprogram. It is not a dummy argument, and has bounds that are nonconstant specification expressions. The bounds (and shape) are determined at entry to the procedure by evaluating the bounds expressions. See also automatic object.
automatic object
A local data object that is created upon entry to a subprogram and disappears when the execution of the subprogram is completed. There are two kinds of automatic objects: arrays (of any data type) and objects of type CHARACTER. Automatic objects cannot be saved or initialized.

An automatic object is not a dummy argument, but is declared with a specification expression that is not a constant expression. The specification expression can be the bounds of the array or the length of the character object.


Glossary B

background process
On Tru64 UNIX and Linux systems, a process for which the command interpreter is not waiting. Its process group differs from that of its controlling terminal, so it is blocked from most terminal access. Contrast with foreground process.
background window
Any window created by a thread other than the foreground thread.
batch process
On OpenVMS systems, a process that runs without user interaction. Contrast with interactive process.
big endian
A method of data storage in which the least significant bit of a numeric value spanning multiple bytes is in the highest addressed byte. Contrast with little endian.
binary constant
A constant that is a string of binary (base 2) digits (0 or 1) enclosed by apostrophes or quotation marks and preceded by the letter B.
binary operator
An operator that acts on a pair of operands. The exponentiation, multiplication, division, and concatenation operators are binary operators.
bit constant
A constant that is a binary, octal, or hexadecimal number.
bit field
A contiguous group of bits within a binary pattern; they are specified by a starting bit position and length. Some intrinsic functions (for example, IBSET and BTEST) and the intrinsic subroutine MVBITS operate on bit fields.
bitmap
An array of bits that contains data that describes the colors found in a rectangular region on the screen (or the rectangular region found on a page of printer paper).
blank common
A common block (one or more contiguous areas of storage) without a name. Common blocks are defined by a COMMON statement.
block
A group of statements or constructs that is treated as an integral unit. For example, a block can be a group of constructs or statements that perform a task; the task can be executed once, repeatedly, or not at all.
block data program unit
A program unit, containing a BLOCK DATA statement and its associated specification statements, that establishes common blocks and assigns initial values to the variables in named common blocks. In FORTRAN 77, this was called a block data subprogram.
bounds
The range of subscript values for elements of an array. The lower bound is the smallest subscript value in a dimension, and the upper bound is the largest subscript value in that dimension. Array bounds can be positive, zero, or negative.

These bounds are specified in an array specification. See also array specification.
brush
A bitmap that is used to fill the interior of closed shapes, polygons, ellipses, and paths.
brush origin
A coordinate that specifies the location of one of the pixels in a brush's bitmap. The Windows system maps this pixel to the upper left corner of the window that contains the object to be painted. See also bitmap.
byte-order mark
A special Unicode character (0xFEFF) that is placed at the beginning of Unicode text files to indicate that the text is in Unicode format.
byte reversed
A Unicode file in which the most significant byte is first (as on Motorola architectures).


Glossary C

carriage-control character
A character in the first position of a printed record that determines the vertical spacing of the output line.
character constant
A constant that is a string of printable ASCII characters enclosed by apostrophes (') or quotation marks (").
character expression
A character constant, variable, function value, or another constant expression, separated by a concatenation operator (//); for example, DAY// ' FIRST'.
character set
A mapping of characters to their identifying numeric values. See also multibyte character set.
character storage unit
The unit of storage for holding a scalar value of default character type (and character length one) that is not a pointer. One character storage unit corresponds to one byte of memory.
character string
A sequence of contiguous characters; a character data value. See also character constant.
character substring
One or more contiguous characters in a character string.
child process
A process (child) initiated by another process (the parent). The child process can operate independently from the parent process. Further, the parent process can suspend or terminate without affecting the child process. See also parent process.
child window
A window that has the WS_CHILD style. A child window always appears within the client area of its parent window. See also parent window.
column-major order
See order of subscript progression.
comment
Text that documents or explains a program. In free source form, a comment begins with an exclamation point (!), unless it appears in a Hollerith or character constant.

In fixed and tab source form, a comment begins with a letter C or an asterisk (*) in column 1. A comment can also begin with an exclamation point anywhere in a source line (except in a Hollerith or character constant) or in column 6 of a fixed-format line. The comment extends from the exclamation point to the end of the line.

The compiler does not process comments, but shows them in program listings. See also compiler directive.
common block
A physical storage area shared by one or more program units. This storage area is defined by a COMMON statement. If the common block is given a name, it is a named common block; if it is not given a name, it is a blank common.
compilation unit
The source file or files that are compiled together to form a single object file, possibly using interprocedural optimization across source files. Only one f90 command is used for each compilation, but one f90 command can specify that multiple compilation units be used.
compiler directive
A structured comment that tells the compiler to perform certain tasks when it compiles a source program unit. Compiler directives are usually compiler-specific. (Some Fortran compilers call these directives "metacommands".)
complex constant
A constant that is a pair of real or integer constants representing a complex number; the pair is separated by a comma and enclosed in parentheses. The first constant represents the real part of the number; the second constant represents the imaginary part.

The following types of complex constants are available on all systems: COMPLEX (COMPLEX(4)) and DOUBLE COMPLEX (COMPLEX(8)). On OpenVMS, Tru64 UNIX, and Linux systems, COMPLEX(16) is also available.
complex type
A data type that represents the values of complex numbers. The value is expressed as a complex constant. See also data type.
component
A part of a derived-type definition. There must be at least one component (intrinsic or derived type) in every derived-type definition.
concatenate
The combination of two items into one by placing one of the items after the other. In Fortran 95/90, the concatenation operator (//) is used to combine character items. See also character expression.
conformable
Pertains to dimensionality. Two arrays are conformable if they have the same shape. A scalar is conformable with any array.
console
An interface that provides input and output to character-mode applications.
constant
A data object whose value does not change during the execution of a program; the value is defined at the time of compilation. A constant can be named (using the PARAMETER attribute or statement) or unnamed. An unnamed constant is called a literal constant. The value of a constant can be numeric or logical, or it can be a character string. Contrast with variable.
constant expression
An expression whose value does not change during program execution.
construct
A block of statements, beginning with CASE, DO, IF, FORALL, or WHERE statement, and ending with the appropriate termination statement.
contiguous
Pertaining to entities that are adjacent (next to one another) without intervening blanks (spaces); for example, contiguous characters or contiguous areas of storage.
control character
A character string, usually with an ASCII value between 0 and 31, used to communicate with devices such as printers, modems, and the like.
control edit descriptor
A format descriptor that directly displays text or affects the conversions performed by subsequent data edit descriptors. Except for the slash descriptor, control edit descriptors are nonrepeatable.
control statement
A statement that alters the normal order of execution by transferring control to another part of a program unit or a subprogram. A control statement can be conditional (such as the IF construct or computed GO TO statement) or unconditional (such as the STOP or GO TO statement).
critical section
An object used to synchronize the threads of a single process. Only one thread at a time can own a critical-section object.


Glossary D

data abstraction
A style of programming in which you define types to represent objects in your program, define a set of operations for objects of each type, and restrict the operations to only this set, making the types abstract. The Fortran 95/90 modules, derived types, and defined operators, support this programming paradigm.
data edit descriptor
A repeatable format descriptor that causes the transfer or conversion of data to or from its internal representation. In FORTRAN-77, this term was called a field descriptor.
data entity
A data object that has a data type. It is the result of the evaluation of an expression, or the result of the execution of a function reference (the function result).
data item
A unit of data (or value) to be processed. Includes constants, variables, arrays, character substrings, or records.
data object
A constant, variable, or part (subobject) of a constant or variable. Its type may be specified implicitly or explicitly.
data type
The properties and internal representation that characterize data and functions. Each intrinsic and user-defined data type has a name, a set of operators, a set of values, and a way to show these values in a program. The basic intrinsic data types are integer, real, complex, logical, and character. The data value of an intrinsic data type depends on the value of the type parameter. See also type parameter.
data type length specifier
The form *n appended to Compaq Fortran-specific data type names. For example, in REAL*4, the *4 is the data type length specifier.
deadlock
A bug where the execution of thread A is blocked indefinitely waiting for thread B to perform some action, while thread B is blocked waiting for thread A. For example, two threads on opposite ends of a named pipe can become deadlocked if each thread waits to read data written by the other thread. A single thread can also deadlock itself. See also thread.
declaration
A statement or series of statements which specify attributes and properties of named entities, such as specifying the data type of named data objects. Declaration is a synonym for specification.
decorated name
An internal representation of a procedure name or variable name that contains information about where it is declared; for procedures, the information includes how it is called. Decorated names are mainly of interest in mixed-language programming, when calling Fortran routines from other languages.
default character
The kind type for character constants if no kind type parameter is specified. Currently, the only kind type parameter for character constants is CHARACTER(1), the default character kind.
default complex
The kind type for complex constants if no kind type parameter is specified. The default complex kind is affected by the compiler option specifying real size. If no compiler option is specified, default complex is COMPLEX(8) (COMPLEX*8). See also default real.
default integer
The kind type for integer constants if no kind type parameter is specified. The default integer kind is affected by compiler options specifying integer size. If no compiler option is specified, default integer is INTEGER(4) (INTEGER*4).

If a command line option affecting integer size has been specified, the integer has the kind specified, unless it is outside the range of the kind specified by the option. In this case, the kind type of the integer is the smallest integer kind which can hold the integer.
default logical
The kind type for logical constants if no kind type parameter is specified. The default logical kind is affected by compiler options specifying integer size. If no compiler option is specified, default logical is LOGICAL(4) (LOGICAL*4). See also default integer.
default real
The kind type for real constants if no kind type parameter is specified. The default real kind is affected by the compiler option specifying real size. If no compiler option is specified, default real is REAL(4) (REAL*4).
If a real constant is encountered that is outside the range for the default, an error occurs.
deferred-shape array
An array pointer (an array with the POINTER attribute) or an allocatable array (an array with the ALLOCATABLE attribute). The size in each dimension is determined by pointer assignment or when the array is allocated.

The declared bounds are specified by a colon (:).
definable
A property of variables. A variable is definable if its value can be changed by the appearance of its name or designator on the left of an assignment statement. An example of a variable that is not definable is an allocatable array that has not been allocated.
define
(1) To give a value to a data object during program execution. (2) To declare derived types and procedures.
defined assignment
An assignment statement that is not intrinsic, but is defined by a subroutine and an interface block. See also derived type.
defined operation
An operation that is not intrinsic, but is defined by a function subprogram containing a generic interface block with the specifier OPERATOR. See also interface block.
denormalized number
A computational floating-point result smaller than the lowest value in the normal range of a data type (the smallest representable normalized number). You cannot write a constant for a denormalized number.
derived type
A data type that is user-defined and not intrinsic. It requires a type definition to name the type and specify its components (which can be intrinsic or user-defined types). A structure constructor can be used to specify a value of derived type. A component of a structure is referenced using a percent sign (%).

Operations on objects of derived types (structures) must be defined by a function with an OPERATOR interface. Assignment for derived types can be defined intrinsically, or be redefined by a subroutine with an ASSIGNMENT interface. Structures can be used as procedure arguments and function results, and can appear in input and output lists. Also called a user-defined type. See also record, the first definition.
designator
A name that references a subobject (part of an object). A designator is the name of the object followed by a selector that selects the subobject. For example, B(3) is a designator for an array element. Also called a subobject designator. See also selector and subobject.
dimension
A range of values for one subscript or index of an array. An array can have from 1 to 7 dimensions. The number of dimensions is the rank of the array.
dimension bounds
See bounds.
direct access
A method for retrieving or storing data in which the data (record) is identified by the record number, or the position of the record in the file. The record is accessed directly (nonsequentially); therefore, all information is equally accessible. Also called random access. Contrast with sequential access.
DLL
See Dynamic Link Library.
double-byte character set (DBCS)
A mapping of characters to their identifying numeric values, in which each value is 2 bytes wide. Double-byte character sets are sometimes used for languages that have more than 256 characters. See also multibyte character set.
double-precision constant
A processor approximation to the value of a real number that occupies 8 bytes of memory and can assume a positive, negative, or zero value. The precision is greater than a constant of real (single-precision) type. For the precise ranges of the double-precision constants, see Data Representation in the Programmer's Guide. See also denormalized number.
driver program
On Windows, Tru64 UNIX, and Linux systems, a program that is the user interface to the language compiler. It accepts command line options and file names and causes one or more language utilities or system programs to process each file.
dummy aliasing
The sharing of memory locations between dummy (formal) arguments and other dummy arguments or COMMON variables that are assigned.
dummy argument
A variable whose name appears in the parenthesized list following the procedure name in a FUNCTION statement, a SUBROUTINE statement, an ENTRY statement, or a statement function statement. A dummy argument takes the value of the corresponding actual argument in the calling program unit (through argument association). Also called a formal argument.
dummy array
A dummy argument that is an array.
dummy pointer
A dummy argument that is a pointer.
dummy procedure
Is a dummy argument that is specified as a procedure or appears in a procedure reference. The corresponding actual argument must be a procedure.
Dynamic Link Library (DLL)
A separate source module compiled and linked independently of the applications that use it. Applications access the DLL through procedure calls. The code for a DLL is not included in the user's executable image, but the compiler automatically modifies the executable image to point to DLL procedures at run time.


Glossary E

edit descriptor
A descriptor in a format specification. It can be a data edit descriptor, control edit descriptor, or string edit descriptor. See also control edit descriptor, data edit descriptor, and string edit descriptor.
element
See array element.
elemental
Pertains to an intrinsic operation, intrinsic procedure, or assignment statement that is independently applied to either of the following:
  • The elements of an array
  • Corresponding elements of a set of conformable arrays and scalars
end-of-file
The condition that exists when all records in a file open for sequential access have been read.
entity
A general term referring to any Fortran 95/90 concept; for example, a constant, a variable, a program unit, a statement label, a common block, a construct, an I/O unit and so forth.
environment variable
A symbolic variable that represents some element of the operating system, such as logical names (on OpenVMS systems) or a path, a filename, or other literal data.

For example, the environment variable PATH represents the directories to search for executable files.
error number
An integer value denoting an I/O error condition, obtained by using the IOSTAT keyword in an I/O statement.
escape character
The character whose ascii value is 27, usually part of a string used to communicate commands to devices such as printers. See also control character.
exceptional values
For floating-point numbers, values outside the range of normalized numbers, including denormal (subnormal) numbers, infinity, Not-a-Number (NaN) values, zero, and other architecture-defined numbers.
executable construct
A CASE, DO, IF, WHERE, or FORALL construct.
executable program
A set of program units that include only one main program.
executable statement
A statement that specifies an action to be performed or controls one or more computational instructions.
explicit interface
A procedure interface whose properties are known within the scope of the calling program, and do not have to be assumed. These properties are the names of the procedure and its dummy arguments, the attributes of a procedure (if it is a function), and the attributes and order of the dummy arguments.

The following have explicit interfaces:
  • Internal and module procedures (explicit by definition)
  • Intrinsic procedures
  • External procedures that have an interface block
  • External procedures that are defined by the scoping unit and are recursive
  • Dummy procedures that have an interface block
explicit-shape array
An array whose rank and bounds are specified when the array is declared.
expression
Is either a data reference or a computation, and is formed from operands, operands, and parentheses. The result of an expression is either a scalar value or an array of scalar values.
extent
The size of (number of elements in) one dimension of an array.
external file
A sequence of records that exists in a medium external to the executing program.
external procedure
A procedure that is contained in an external subprogram. External procedures can be used to share information (such as source files, common blocks, and public data in modules) and can be used independently of other procedures and program units. Also called an external routine.
external subprogram
A subroutine or function that is not contained in a main program, module, or another subprogram. A module is not a subprogram.


Glossary F

field
Can be either of the following:
  • A set of contiguous characters, considered as a single item, in a record or line.
  • A substructure of a STRUCTURE declaration.
field descriptor
See data edit descriptor.
field separator
The comma (,) or slash (/) that separates edit descriptors in a format specification.
field width
The total number of characters in the field. See also field, the first definition.
file
A collection of logically related records. If the file is in internal storage, it is an internal file; if the file is on an input/output device, it is an external file.
file access
The way records are accessed (and stored) in a file. The Fortran 95/90 file access modes are sequential and direct. On OpenVMS systems, you can also use a keyed mode of access.
file handle
On Tru64 UNIX, Linux, and Windows systems, a unique identifier that the system assigns to a file when the file is opened or created. A file handle is valid until the file is closed.
file organization
The way records in a file are physically arranged on a storage device. Fortran 95/90 files can have sequential or relative organization. On OpenVMS systems, files can also have indexed organization.
fixed-length record type
A file format in which all the records are the same length.
focus window
Window to which keyboard input is directed.
foreground process
On Tru64 UNIX and Linux systems, a process for which the command interpreter is waiting. Its process group is the same as that of its controlling terminal, so the process is allowed to read from or write to the terminal. Contrast with background process.
foreground window
The window with which the user is currently working. The system assigns a slightly higher priority to the thread that created the foreground window than it does to other threads.
foreign file
An unformatted file that contains data from a foreign platform, such as data from a CRAY, IBM, or big endian IEEE machine.
format
A specific arrangement of data. A FORMAT statement specifies how data is to be read or written.
format specification
The part of a FORMAT statement that specifies explicit data arrangement. It is a list within parentheses that can include edit descriptors and field separators. A character expression can also specify format; the expression must evaluate to a valid format specification.
formatted data
Data written to a file by using formatted I/O statements. Such data contains ASCII representations of binary values.
formatted I/O statement
An I/O statement specifying a format for data transfer. The format specified can be explicit (specified in a format specification) or implicit (specified using list-directed or namelist formatting). Contrast with unformatted I/O statement. See also list-directed I/O statement and namelist I/O statement.
frame window
The outermost parent window in QuickWin.
function
A series of statements that perform some operation and return a single value (through the function or result name) to the calling program unit. A function is invoked by a function reference in a main program unit or a subprogram unit.

In Fortran 95/90, a function can be used to define a new operator or extend the meaning of an intrinsic operator symbol. The function is invoked by the appearance of the new or extended operator in the expression (along with the appropriate operands). For example, the symbol * can be defined for logical operands, extending its intrinsic definition for numeric operands. See also function subprogram, statement function, and subroutine.
function reference
Used in an expression to invoke a function, it consists of the function name and its actual arguments. A function reference returns a value (through the function or result name) which is used to evaluate the calling expression.
function result
The result value associated with a particular execution or call to a function. This result can be of any data type (including derived type) and can be array-valued. In a FUNCTION statement, the RESULT option can be used to give the result a name different from the function name. This option is required for a recursive function that directly calls itself.
function subprogram
A sequence of statements beginning with a FUNCTION (or optional OPTIONS) statement that is not in an interface block and ending with the corresponding END statement. See also function.


Glossary G

generic identifier
A generic name, operator, or assignment specified in an INTERFACE statement that is associated with all of the procedures within the interface block. Also called a generic specification.
global entity
An entity (a program unit, common block, or external procedure) that can be used with the same meaning throughout the executable program. A global entity has global scope; it is accessible throughout an executable program. See also local entity.
global section
A data structure (for example, global COMMON) or shareable image section potentially available to all processes in the system.


Glossary H

handle
A value (often, but not always, a 32-bit integer) that identifies some operating system resource, for example, a window or a process. The handle value is returned from an operating system call when the resource is created; your program then passes that value as an argument to subsequent operating system routines to identify which resource is being accessed.

Your program should consider the handle value a "private" type and not try to interpret it as having any specific meaning (for example, an address).
hexadecimal constant
A constant that is a string of hexadecimal (base 16) digits (range 0 to 9, or an uppercase or lowercase letter in the range A to F) enclosed by apostrophes or quotation marks and preceded by the letter Z.
High Performance Fortran
An extended version of Fortran 90 with features supporting parallel processing. Compaq Fortran supports full High Performance Fortran (HPF), and compiles HPF programs for parallel execution.
Hollerith constant
A constant that is a string of printable ASCII characters preceded by nH, where n is the number of characters in the string (including blanks and tabs).
host
Either the main program or subprogram that contains an internal procedure, or the module that contains a module procedure. The data environment of the host is available to the (internal or module) procedure.
host association
The process by which a module procedure, internal procedure, or derived-type definition accesses the entities of its host.


Glossary I

implicit interface
A procedure interface whose properties (the collection of names, attributes, and arguments of the procedure) are not known within the scope of the calling program, and have to be assumed. The information is assumed by the calling program from the properties of the procedure name and actual arguments in the procedure call.
implicit typing
The mechanism by which the data type for a variable is determined by the beginning letter of the variable name.
import library
A .LIB file that contains information about one or more dynamic-link libraries (DLLs), but does not contain the DLL's executable code. The linker uses an import library when building an executable module of a process, to provide the information needed to resolve the external references to DLL functions.
index
Can be any of the following:
  • The variable used as a loop counter in a DO statement.
  • An intrinsic function specifying the starting position of a substring inside a string.
  • On OpenVMS systems, an internal data structure that provides a guide, based on key values, to file components in an indexed file.
indexed file organization
On OpenVMS systems, a file organization that allows random retrieval of records by key value and sequential retrieval of records within the key of reference. Each file contains records and a primary key index; it can also optionally have one or more alternate key indexes.
initialize
The assignment of an initial value to a variable.
initialization expression
A form of constant expression that is used to specify an initial value for an entity.
inlining
An optimization that replaces a subprogram reference (CALL statement or function invocation) with the replicated code of the subprogram.
input/output (I/O)
The data that a program reads or writes. Also, devices to read and write data.
inquiry function
An intrinsic function whose result depends on properties of the principal argument, not the value of the argument.
integer constant
A constant that is a whole number with no decimal point. It can have a leading sign and is interpreted as a decimal number.
intent
An attribute of a dummy argument that is not a procedure or a pointer. It indicates whether the argument is used to transfer data into the procedure, out of the procedure, or both.
interactive process
A process that must periodically get user input to do its work. Contrast with background process or batch process.
interface
The properties of a procedure, consisting of: specifications of the attributes for a function result, the specification of dummy argument attributes, and the information in the procedure heading.
interface block
The sequence of statements starting with an INTERFACE statement and ending with the corresponding END INTERFACE statement.
interface body
The sequence of statements in an interface block starting with a FUNCTION or SUBROUTINE statement and ending with the corresponding END statement. Also called a procedure interface body.
internal file
The designated internal storage space (or variable buffer) that is manipulated during input and output. An internal file can be a character variable, character array, character array element, or character substring. In general, an internal file contains one record. However, an internal file that is a character array has one record for each array element.
internal procedure
A procedure (other than a statement function) that is contained within an internal subprogram. The program unit containing an internal procedure is called the host of the internal procedure. The internal procedure (which appears between a CONTAINS and END statement) is local to its host and inherits the host's environment through host association.
internal subprogram
A subprogram contained in a main program or another subprogram.
intrinsic
Describes entities defined by the Fortran 95/90 language (such as data types and procedures). Intrinsic entities can be used freely in any scoping unit.
intrinsic procedure
A subprogram supplied as part of the Fortran 95/90 library that performs array, mathematical, numeric, character, bit manipulation, and other miscellaneous functions. Intrinsic procedures are automatically available to any Fortran 95/90 program unit (unless specifically overridden by an EXTERNAL statement or a procedure interface block). Also called a built-in or library procedure.
invoke
To call upon; used especially with reference to subprograms. For example, to invoke a function is to execute the function.
iteration count
The number of executions of the DO range, which is determined as follows:
[(terminal value - initial value + increment value) / increment value]


Glossary K

key
On OpenVMS systems, a value in a file of indexed organization that the system uses to build indexes into the file. Each key is identified by its location within the component, its length, and its data type. Also called the key field. See also alternate key, index, and primary key.
keyed access
On OpenVMS systems, a method for retrieving or writing data in which the data (a record) is identified by specifying the information in a key field of the record. See also key.
key of reference
On OpenVMS systems, a key used to determine the index to use when sequentially accessing components of an indexed file. See also key, indexed file organization, and sequential access.
keyword
(1) Part of the syntax of a statement (syntax keyword). These keywords are not reserved. (2) A dummy argument name.
kind type parameter
Indicates the range of an intrinsic data type. For real and complex types, it also indicates precision. If a specific kind type parameter is not specified (for example, INTEGER), the kind type is the default for that type (for example, default integer). See also default character, default complex, default integer, default logical, and default real.


Glossary L

label
An integer, from 1 to 5 digits long, that is used to identify a statement. For example, labels can be used to refer to a FORMAT statement or branch target statement.
language extension
A Compaq Fortran language element or interpretation that is not part of the Fortran 95 standard.
lexical token
A sequence of one or more characters that have an indivisible interpretation. A lexical token is the smallest meaningful unit (a basic language element) of a Fortran 95/90 statement; for example, constants, and statement keywords.
line
A source form record consisting of 0 or more characters. A standard Fortran 95/90 line is limited to a maximum of 132 characters.
linker
A system program that creates an executable program from one or more object files produced by a language compiler or assembler. The linker resolves external references, acquires referenced library routines, and performs other processing required to create OpenVMS executable images or Tru64 UNIX, Linux, and Windows executable files.
list-directed I/O statement
An implicit, formatted I/O statement that uses an asterisk (*) specifier rather than an explicit format specification. See also formatted I/O statement and namelist I/O statement.
listing
A printed copy of a program.
literal constant
A constant without a name. In Fortran 77, this was called simply a constant.
little endian
A method of data storage in which the least significant bit of a numeric value spanning multiple bytes is in the lowest addressed byte. This is the method used on Compaq systems. Contrast with big endian.
local entity
An entity that can be used only within the context of a subprogram (its scoping unit); for example, a statement label. A local entity has local scope. See also global entity.
local optimization
Refers to enabling local optimizations within the source program unit, recognition of common expressions, and integer multiplication and division expansion (using shifts). The order of compilation of procedures is determined from the call graph. See also optimization.
local symbol
A name defined in a program unit that is not accessible outside of that program unit.
logical constant
A constant that specifies the value .TRUE. or .FALSE..
logical expression
An integer or logical constant, variable, function value, or another constant expression, joined by a relational or logical operator. The logical expression is evaluated to a value of either true or false. For example, .NOT. 6.5 + (B .GT. D).
logical operator
A symbol that represents an operation on logical expressions. The logical operators are .AND., .OR., .NEQV., .XOR., .EQV., and .NOT..
logical unit
A channel in memory through which data transfer occurs between the program and the device or file. See also unit identifier.
longword
Four contiguous bytes (32 bits) starting on any addressable byte boundary. Bits are numbered 0 to 31. The address of the longword is the address of the byte containing bit 0. When the longword is interpreted as a signed integer, bit 31 is the sign bit. The value of signed integers is in the range -2**31 to 2**31-1. The value of unsigned integers is in the range 0 to 2**32-1.
loop
A group of statements that are executed repeatedly until an ending condition is reached.


Glossary M

main program
A program unit containing a PROGRAM statement (or not containing a SUBROUTINE, FUNCTION, or BLOCK DATA statement). The main program is the first program unit to receive control when a program is run, and exercises control over subprograms. Contrast with subprogram.
makefile
On Tru64 UNIX and Linux systems, an argument to the make command containing a sequence of entries that specify dependencies. On Windows systems, a file passed to the NMAKE utility containing a sequence of entries that specify dependencies. The contents of a makefile override the system built-in rules for maintaining, updating, and regenerating groups of programs.

For more information on makefiles for Tru64 UNIX and Linux systems, see make(1). For more information on makefiles for Windows systems, see Building Projects with NMAKE in the Programmer's Guide.
many-one array section
An array section with a vector subscript having two or more elements with the same value.
metacommand
See compiler directive.
misaligned data
Data not aligned on a natural boundary. See also natural boundary.
module
A program unit that contains specifications and definitions that other program units can access (unless the module entities are declared PRIVATE). Modules are referenced in USE statements.
module procedure
A subroutine or function defined within a module subprogram (the module procedure's host). The module procedure appears between a CONTAINS and END statement in its host module, and inherits the host module's environment through host association. A module procedure can be declared PRIVATE to the module; it is public by default.
module subprogram
A subprogram that is contained in a module. (It cannot be an internal subprogram.)
multibyte character set
A character set in which each character is identified by using more than one byte. Although Unicode characters are 2 bytes wide, the Unicode character set is not referred to by this term.
multitasking
The ability of an operating system to execute several programs (tasks) at once.
multithreading
The ability of an operating system to execute different parts of a program, called threads, simultaneously.
If the system supports parallel processing, multiple processors may be used to execute the threads.


Glossary N

name
Identifies an entity within a Fortran program unit (such as a variable, function result, common block, named constant, procedure, program unit, namelist group, or dummy argument). In FORTRAN 77, this term was called a symbolic name.
name association
Pertains to argument, host, or use association.
named common block
A common block (one or more contiguous areas of storage) with a name. Common blocks are defined by a COMMON statement.
named constant
A constant that has a name. In FORTRAN 77, this term was called a symbolic constant.
namelist I/O statement
An implicit, formatted I/O statement that uses a namelist group specifier rather than an explicit format specifier. See also formatted I/O statement and list-directed I/O statement.
NaN
Not-a-Number. The condition that results from a floating-point operation that has no mathematical meaning; for example, zero divided by zero.
natural boundary
The virtual address of a data item that is the multiple of the size of its data type. For example, a REAL(8) (REAL*8) data item aligned on natural boundaries has an address that is a multiple of eight.
naturally aligned record
A record that is aligned on a hardware-specific natural boundary; each field is naturally aligned. (For more information, see Data Alignment Considerations in the Programmer's Guide.) Contrast with packed record.
nesting
The placing of one entity (such as a construct, subprogram, format specification, or loop) inside another entity of the same kind. For example, nesting a loop within another loop (a nested loop), or nesting a subroutine within another subroutine (a nested subroutine).
nonexecutable statement
A Fortran 95/90 statement that describes program attributes, but does not cause any action to be taken when the program is executed.
nonsignaled
The state of an object used for synchronization in one of the wait functions is either signaled or nonsignaled. A nonsignaled state can prevent the wait function from returning. See also wait function.
numeric expression
A numeric constant, variable, or function value, or combination of these, joined by numeric operators and parentheses, so that the entire expression can be evaluated to produce a single numeric value. For example, -L or X+(Y-4.5*Z).
numeric operator
A symbol designating an arithmetic operation. In Fortran 95/90, the symbols +, -, *, /, and ** are used to designate addition, subtraction, multiplication, division, and exponentiation, respectively.
numeric storage unit
The unit of storage for holding a non-pointer scalar value of type default real, default integer, or default logical. One numeric storage unit corresponds to 4 bytes of memory.
numeric type
Integer, real, or complex type.


Glossary O

object
(1) An internal structure that represents a system resource such as a file, a thread, or a graphic image. (2) A data object.
object file
The binary output of a language processor (such as an assembler or compiler), which can either be executed or used as input to the linker.
obsolescent feature
A feature of FORTRAN 77 that is considered to be redundant in Fortran 90. These features are still in frequent use.
octal constant
A constant that is a string of octal (base 8) digits (range of 0 to 7) enclosed by apostrophes or quotation marks and preceded by the letter O.
operand
The passive element in an expression on which an operation is performed. Every expression must have at least one operand. For example, in I .NE. J, I and J are operands. Contrast with operator.
operation
A computation involving one or two operands.
operator
The active element in an expression that performs an operation. An expression can have zero or more operators. Intrinsic operators are arithmetic (+, -, *, /, and **) or logical (.AND., .NOT., and so on). For example, in I .NE. J, .NE. is the operator.

Executable programs can define operators which are not intrinsic.
optimization
The process of producing efficient object or executing code that takes advantage of the hardware architecture to produce more efficient execution.
optional argument
A dummy argument that has the OPTIONAL attribute (or is included in an OPTIONAL statement in the procedure definition). Such an argument does not have to be associated with an actual argument.
order of subscript progression
A characteristic of a multidimensional array in which the leftmost subscripts vary most rapidly. Also called column-major order.
overflow
An error condition occurring when an arithmetic operation yields a result that is larger than the maximum value in the range of a data type.


Glossary P

packed record
A record that starts on an arbitrary byte boundary; each field starts in the next unused byte. Contrast with naturally aligned record.
pad
The filling of unused positions in a field or character string with dummy data (such as zeros or blanks).
parallel processing
The simultaneous use of more than one processor (CPU) to execute a program.
parameter
Can be either of the following:
  • In general, any quantity of interest in a given situation; often used in place of the term "argument".
  • A Fortran 95/90 named constant.
parent process
A process that initiates and controls another process (child). The parent process defines the environment for the child process. Further, the parent process can suspend or terminate without affecting the child process. See also child process.
parent window
A window that has one or more child windows. See also child window.
pathname
On Windows, Tru64 UNIX, and Linux systems, the path from the root directory to a subdirectory or file. See also root.
pipe
On Windows, Tru64 UNIX, and Linux systems, a connection that allows one program to get its input directly from the output of another program.
platform
A combination of operating system and hardware that provides a distinct environment in which to use a software product (for example, Tru64 UNIX on Alpha processors).
pointer
Is one of the following:
  • A Fortran 95/90 pointer
    A data object that has the POINTER attribute. To be referenced or defined, it must be "pointer-associated" with a target (have storage space associated with it). If the pointer is an array, it must be pointer-associated to have a shape. See also pointer association.
  • A Compaq Fortran pointer
    A data object that contains the address of its paired variable. This is also called an integer pointer or a Cray® pointer.
pointer assignment
The association of a pointer with a target by the execution of a pointer assignment statement or the execution of an assignment statement for a data object of derived type having the pointer as a subobject.
pointer association
The association of storage space to a Fortran 95/90 pointer by means of a target. A pointer is associated with a target after pointer assignment or the valid execution of an ALLOCATE statement.
precision
The number of significant digits in a real number. See also double-precision constant, kind type parameter, and single-precision constant.
primary
The simplest form of an expression. A primary can be any of the following data objects:
  • A constant
  • A constant subobject (parent is a constant)
  • A variable (scalar, structure, array, or pointer; an array cannot be assumed size)
  • An array constructor
  • A structure constructor
  • A function reference
  • An expression in parentheses
primary key
On OpenVMS systems, the required key within the data records of an indexed file. This key is used to determine the placement of records within the file and to build the primary index.
primary thread
The initial thread of a process. Also called the main thread or thread 1. See also thread.
procedure
A computation that can be invoked during program execution. It can be a subroutine or function, an internal, external, dummy or module procedure, or a statement function. A subprogram can define more than one procedure if it contains an ENTRY statement. See also subprogram.
procedure interface
The statements that specify the name and characteristics of a procedure, the name and attributes of each dummy argument, and the generic identifier (if any) by which the procedure can be referenced. If these properties are all known to the calling program, the procedure interface is explicit; otherwise it is implicit.
process object
A virtual address space, security profile, a set of threads that execute in the address space of the process, and a set of resources visible to all threads executing in the process. Several thread objects can be associated with a single process.
program unit
The fundamental component of an executable program. A sequence of statements and comment lines. It can be a main program, a module, an external subprogram, or a block data program unit.


Glossary Q

quadword
Four contiguous words (64 bits) starting on any addressable byte boundary. Bits are numbered 0 to 63. (Bit 63 is used as the sign bit.) A quadword is identified by the address of the word containing the low-order bit (bit 0). The value of a signed quadword integer is in the range -2**63 to 2**63-1.


Glossary R

random access
See direct access.
rank
The number of dimensions of an array. A scalar has a rank of zero.
rank-one object
A data structure comprising scalar elements with the same data type and organized as a simple linear sequence. See also scalar.
real constant
A constant that is a number written with a decimal point, exponent, or both. It can have single precision (REAL(4)) or double precision (REAL(8)). On OpenVMS, Tru64 UNIX, and Linux systems, it can also have quad precision (REAL(16)).
record
Can be either of the following:
  • A set of logically related data items (in a file) that is treated as a unit; such a record contains one or more fields. This definition applies to I/O records and items that are declared in a record structure.
  • One or more data items that are grouped in a structure declaration and specified in a RECORD statement.
record access
The method used to store and retrieve records in a file.
record structure declaration
A block of statements that define the fields in a record. The block begins with a STRUCTURE statement and ends with END STRUCTURE. The name of the structure must be specified in a RECORD statement.
record type
The property that determines whether records in a file are all the same length, of varying length, or use other conventions to define where one record ends and another begins.
recursion
Pertains to a subroutine or function that directly or indirectly references itself.
reference
Can be any of the following:
  • For a data object, the appearance of its name, designator, or associated pointer where the value of the object is required. When an object is referenced, it must be defined.
  • For a procedure, the appearance of its name, operator symbol, or assignment symbol that causes the procedure to be executed. Procedure reference is also called "calling" or "invoking" a procedure.
  • For a module, the appearance of its name in a USE statement.
relational expression
An expression containing one relational operator and two operands of numeric or character type. The result is a value that is true or false. For example, A-C .GE. B+2 or DAY .EQ. 'MONDAY'.
relational operator
The symbols used to express a relational condition or expression. The relational operators are (.EQ., .NE., .LT., .LE., .GT., and .GE.).
relative file organization
A file organization that consists of a series of component positions, called cells, numbered consecutively from 1 to n. Compaq Fortran uses these numbered, fixed-length cells to calculate the component's physical position in the file.
relative pathname
On Tru64 UNIX, Linux, and Windows systems, a directory path expressed in relation to any directory other than the root directory. Contrast with absolute pathname.
root
On Windows systems, the top-level directory on a disk drive; it is represented by a backslash (\). For example, C:\ is the root directory for drive C.

On Tru64 UNIX and Linux systems, the top-level directory in the file system; it is represented by a slash (/).
run time
The time during which a computer executes the statements of a program.


Glossary S

saved object
A variable that retains its association status, allocation status, definition status, and value after execution of a RETURN or END statement in the scoping unit containing the declaration.
scalar
Pertaining to data items with a rank of zero. A single data object of any intrinsic or derived data type. Contrast with array. See also rank-one object.
scalar memory reference
A reference to a scalar variable, scalar record field, or array element that resolves into a single data item (having a data type) and can be assigned a value with an assignment statement. It is similar to a scalar reference, but it excludes constants, character substrings, and expressions.
scalar reference
A reference to a scalar variable, scalar record field, derived-type component, array element, constant, character substring, or expression that resolves into a single data item having a data type.
scalar variable
A variable name specifying one storage location.
scale factor
A number indicating the location of the decimal point in a real number and, if there is no exponent, the size of the number on input.
scope
The portion of a program in which a declaration or a particular name has meaning. Scope can be global (throughout an executable program), scoping unit (local to the scoping unit), or statement (within a statement, or part of a statement).
scoping unit
The part of the program in which a name has meaning. It is one of the following:
  • A program unit or subprogram
  • A derived-type definition
  • A procedure interface body
Scoping units cannot overlap, though one scoping unit can contain another scoping unit. The outer scoping unit is called the host scoping unit.
screen coordinates
Coordinates relative to the upper left corner of the screen.
section subscript
A subscript list (enclosed in parentheses and appended to the array name) indicating a portion (section) of an array. At least one of the subscripts in the list must be a subscript triplet or vector subscript. The number of section subscripts is the rank of the array. See also array section, subscript, subscript triplet, and vector subscript.
seed
A value (which can be assigned to a variable) that is required in order to properly determine the result of a calculation; for example, the argument i in the random number generator (RAN) function syntax:
y = RAN (i)
selector
A mechanism for designating the following:
  • Part of a data object (an array element or section, a substring, a derived type, or a structure component)
  • The set of values for which a CASE block is executed
sequence
A set ordered by a one-to-one correspondence with the numbers 1 through n, where n is the total number of elements in the sequence. A sequence can be empty (contain no elements).
sequential access
A method for retrieving or storing data in which the data (record) is read from, written to, or removed from a file based on the logical order (sequence) of the record in the file. (The record cannot be accessed directly.) Contrast with direct access.
sequential file organization
A file organization in which records are stored one after the other, in the order in which they were written to the file.
shape
The rank and extents of an array. Shape can be represented by a rank-one array (vector) whose elements are the extents in each dimension.
shape conformance
Pertains to the rule concerning operands of binary intrinsic operations in expressions: to be in shape conformance, the two operands must both be arrays of the same shape, or one or both of the operands must be scalars.
short field termination
The use of a comma (,) to terminate the field of a numeric data edit descriptor. This technique overrides the field width (w) specification in the data edit descriptor and therefore avoids padding of the input field. The comma can only terminate fields less than w characters long. See also data edit descriptor.
signal
The software mechanism used to indicate that an exception condition (abnormal event) has been detected. For example, a signal can be generated by a program or hardware error, or by request of another program.
single-precision constant
A processor approximation of the value of a real number that occupies 4 bytes of memory and can assume a positive, negative, or zero value. The precision is less than a constant of double-precision type. For the precise ranges of the single-precision constants, see Data Representation in the Programmer's Guide. See also denormalized number.
size
The total number of elements in an array (the product of the extents).
source file
A program or portion of a program library, such as an object file, or image file.
specification expression
A restricted expression that is of type integer and has a scalar value. This type of expression appears only in the declaration of array bounds and character lengths.
specification statement
A nonexecutable statement that provides information about the data used in the source program. Such a statement can be used to allocate and initialize variables, arrays, records, and structures, and define other characteristics of names used in a program.
statement
An instruction in a programming language that represents a step in a sequence of actions or a set of declarations. In Fortran 95/90, an ampersand can be used to continue a statement from one line to another, and a semicolon can be used to separate several statements on one line.
There are two main classes of statements: executable and nonexecutable.
statement entity
An entity identified by a lexical token whose scope is a single statement or part of a statement.
statement function
A function whose definition is contained in a single statement.
statement function definition
A statement that defines a statement function. Its form is the statement function name (followed by its optional dummy arguments in parentheses), followed by an equal sign (=), followed by a numeric, logical, or character expression.

A statement function definition must precede all executable statements and follow all specification statements.
statement keyword
A word that begins the syntax of a statement. All program statements (except assignment statements and statement function definitions) begin with a statement keyword. Examples are INTEGER, DO, IF, and WRITE.
statement label
See label.
static variable
A variable whose storage is allocated for the entire execution of a program.
storage association
The relationship between two storage sequences when the storage unit of one is the same as the storage unit of the other. Storage association is provided by the COMMON and EQUIVALENCE statements. For modules, pointers, allocatable arrays, and automatic data objects, the SEQUENCE statement defines a storage order for structures.
storage location
An addressable unit of main memory.
storage sequence
A sequence of any number of consecutive storage units. The size of a storage sequence is the number of storage units in the storage sequence. A sequence of storage sequences forms a composite storage sequence. See also storage association and storage unit.
storage unit
In a storage sequence, the number of storage units needed to represent one real, integer, logical, or character value. See also character storage unit, numeric storage unit, and storage sequence.
stride
The increment between subscript values that can optionally be specified in a subscript triplet. If it is omitted, it is assumed to be one.
string edit descriptor
A format descriptor that transfers characters to an output record.
structure
Can be either of the following:
  • A scalar data object of derived (user-defined) type.
  • An aggregate entity containing one or more fields or components.
structure component
Can be either of the following:
  • One of the components of a structure.
  • An array whose elements are components of the elements of an array of derived type.
structure constructor
A mechanism that is used to specify a scalar value of a derived type. A structure constructor is the name of the type followed by a parenthesized list of values for the components of the type.
subobject
Part of a data object (parent object) that can be referenced and defined separately from other parts of the data object. A subobject can be an array element, an array section, a substring, a derived type, or a structure component. Subobjects are referenced by designators and can be considered to be data objects themselves. See also designator.
subobject designator
See designator.
subprogram
A user-written function or subroutine subprogram that can be invoked from another program unit to perform a specific task. Note that in FORTRAN 77, a block data program unit was also called a subprogram.
subroutine
A procedure that can return many values, a single value, or no value to the calling program unit (through arguments). A subroutine is invoked by a CALL statement in another program unit.

In Fortran 95/90, a subroutine can also be used to define a new form of assignment (defined assignment), which is different from those intrinsic to Fortran 90. Such assignments are invoked with assignment syntax (using the = symbol) rather than the CALL statement. See also function, statement function, and subroutine subprogram.
subroutine subprogram
A sequence of statements starting with a SUBROUTINE (or optional OPTIONS) statement and ending with the corresponding END statement. See also subroutine.
subscript
A scalar integer expression (enclosed in parentheses and appended to the array name) indicating the position of an array element. The number of subscripts is the rank of the array. See also array element.
subscript triplet
An item in a section subscript list specifying a range of values for the array section. A subscript triplet contains at least one colon and has three optional parts: a lower bound, an upper bound, and a stride. Contrast with vector subscript. See also array section and section subscript.
substring
A contiguous portion of a scalar character string. Do not confuse this with the substring selector in an array section, where the result is another array section, not a substring.
symbolic name
See name.
syntax
The formal structure of a statement or command string.


Glossary T

target
The named data object associated with a pointer (in the form pointer-object => target). A target is declared in a type declaration statement that contains the TARGET attribute. See also pointer and pointer association.
thread
Part of a program that can run at the same time as other parts, usually with some form of communication and/or synchronization among the threads. See also multithreading.
transformational function
An intrinsic function that is not an elemental or inquiry function. A transformational function usually changes an array actual argument into a scalar result or another array, rather than applying the argument element by element.
truncation
Can be either of the following:
  • A technique that approximates a numeric value by dropping its fractional value and using only the integer portion.
  • The process of removing one or more characters from the left or right of a number or string.
type declaration statement
A nonexecutable statement specifying the data type of one or more variables: an INTEGER, REAL, DOUBLE PRECISION, COMPLEX, DOUBLE COMPLEX, CHARACTER, LOGICAL, or TYPE statement. Also called a type declaration or type specification.
type parameter
Defines an intrinsic data type. The type parameters are kind and length. The kind type parameter (KIND=) specifies the range for the integer data type, the precision and range for real and complex data types, and the machine representation method for the character and logical data types. The length type parameter (LEN=) specifies the length of a character string. See also kind type parameter.


Glossary U

ultimate component
For a derived type or a structure, a component that is of intrinsic type or has the POINTER attribute, or an ultimate component of a component that is a derived type and does not have the POINTER attribute.
unary operator
An operator that operates on one operand. For example, the minus sign in -A and the .NOT. operator in .NOT. (J .GT. K).
undefined
For a data object, the property of not having a determinate value.
underflow
An error condition occurring when the result of an arithmetic operation yields a result that is smaller than the minimum value in the range of a data type. For example, in unsigned arithmetic, underflow occurs when a result is negative. See also denormalized number.
unformatted data
Data written to a file by using unformatted I/O statements; for example, binary numbers.
unformatted I/O statement
An I/O statement that does not contain format specifiers and therefore does not translate the data being transferred. Contrast with formatted I/O statement.
unformatted record
A record that is transmitted in internal format between internal and external storage.
unit identifier
The identifier that specifies an external unit or internal file. The identifier can be any one of the following:
  • An integer expression whose value must be zero or positive
  • An asterisk (*) that corresponds to the default (or implicit) I/O unit
  • The name of a character scalar memory reference or character array name reference for an internal file
Also called a device code, or logical unit number.
unspecified storage unit
A unit of storage for holding a pointer or a scalar that is not a pointer and is of type other than default integer, default character, or default real.
use association
The process by which the entities in a module are made accessible to other scoping units (through a USE statement in the scoping unit).
user-defined type
See derived type.


Glossary V

variable
A data object (stored in a memory location) whose value can change during program execution. A variable can be a named data object, an array element, an array section, a structure component, or a substring. In FORTRAN 77, a variable was always scalar and named. Contrast with constant.
variable format expression
A numeric expression enclosed in angle brackets (<>) that can be used in a FORMAT statement. If necessary, it is converted to integer type before use.
variable-length record type
A file format in which records may be of different lengths.
vector subscript
A rank-one array of integer values used as a section subscript to select elements from a parent array. Unlike a subscript triplet, a vector subscript specifies values (within the declared bounds for the dimension) in an arbitrary order. Contrast with subscript triplet. See also array section and section subscript.


Glossary W

wait function
A function that blocks the execution of a calling thread until a specified set of conditions has been satisfied.
whole array
An array reference (for example, in a type declaration statement) that consists of the array name alone, without subscript notation. Whole array operations affect every element in the array. See also array.


Glossary Z

zero-sized array
An array with at least one dimension that has at least one extent of zero. A zero-sized array has a size of zero and contains no elements. See also array.


Error Messages

This section contains information on the following:

  • Visual Fortran Run-Time Messages
  • Linker Messages (LNKxxxx)
  • BSCMAKE Messages (BKxxxx)
  • C Run-Time Errors (Rxxxx)
  • CVPACK Messages (CKxxxx)
  • CVTRES Messages (CVTxxxx)
  • Math Messages (M6xxx)
  • NMAKE Messages (Uxxxx)
  • Profiler Messages (PRFxxxx)
  • Resource Compiler Messages (RCxxxx)
  • Resource Compiler Messages (RWxxxx)


Visual Fortran Run-Time Errors

This section describes Visual Fortran run-time error messages. For each error, the tables in the following sections provide the error number, the severity code, error message text, condition symbol name, and a detailed description of the errors.

The severity of the message determines whether program execution continues:

Severity | Description
severe | Must be corrected. The program's execution is terminated when the error is encountered, unless the program's I/O statements use the END, EOR, or ERR branch specifiers to transfer control, perhaps to a routine that uses the IOSTAT specifier.
error | Should be corrected. The program might continue execution, but the output from this execution may be incorrect.
warning | Should be investigated. The program continues execution, but output from this execution may be incorrect.
info | For informational purposes only; the program continues.

When a severe error occurs for which no recovery method (such as ERR, END, or EOR) is specified:

  • The severe error message is displayed
  • A hexadecimal dump of the call stack (program counter trace) is displayed
  • Program execution stops

To prevent program terminationn of a severe error, consider including an I/O error-handling specifier (see Methods of Handling Errors).

For information about where a message is displayed (depends on the project type) and related information, see Run-Time Message Display and Format.

The following sections describe the run-time errors in detail:

  • Run-Time Errors having no numbers and errors 1 through 30
  • Run-Time Errors 31 through 60
  • Run-Time Errors 61 through 108
  • Run-Time Errors 120 through 300
  • Run-Time Errors 540 through 569
  • Run-Time Errors 570 through 614
  • Run-Time Errors 615 through 656
  • Run-Time Errors 657 through 689
  • Run-Time Errors 690 through 719
  • Run-Time Errors 720 through 759

Related topics:

  • Default Run-Time Error Processing

  • Handling Run-Time Errors

  • Locating Run-Time Errors

  • Run-Time Environment Variables

  • The Floating-Point Environment


Run-Time Errors Having No Numbers and Errors 1 Through 30

This section describes in detail Visual Fortran run-time errors having no numbers and run-time error numbers 1 through 30.

In the following table, the first column lists error numbers returned to IOSTAT variables when an I/O error is detected.

The first line of the second column provides the message as it is displayed (following forrtl:), including the severity level, message number, and the message text. The following lines of the second column contain the status condition symbol (such as FOR$IOS_INCRECTYP) and an explanation of the message.

For information about the severity levels, see the Introduction.

Number Severity Level, Number, and Message Text; Condition Symbol and Explanation
None1 info: Fortran error message number is nnn

The Compaq Fortran message catalog file was not found on this system. This error has no condition symbol.
None1 warning: Could not open message catalog: for_msg.cat

The Compaq Fortran message catalog file was not found on this system. This error has no condition symbol.
None1 Insufficient memory to open Fortran RTL catalog: message 41

The Compaq Fortran message catalog file could not be opened because of insufficient virtual memory. For more information, see error 41. This error has no condition symbol.
11 severe (1): Not a Fortran-specific error

FOR$IOS_NOTFORSPE. An error in the user program or in the RTL was not a Compaq Fortran-specific error and was not reportable through any other Compaq Fortran run-time messages.

8 severe (8): Internal consistency check failure

FOR$IOS_BUG_CHECK. Internal error. Please check that the program is correct. Recompile if an error existed in the program. If this error persists, submit a problem report.
9 severe (9): Permission to access file denied

FOR$IOS_PERACCFIL. Check the permissions of the specified file and whether the network device is mapped and available. Make sure the correct file and device was being accessed. Change the protection, specific file, or process used before rerunning the program.
10 severe (10): Cannot overwrite existing file

FOR$IOS_CAVOVEEXI. Specified file xxx already exists when OPEN statement specified STATUS='NEW' (create new file) using I/O unit x. Make sure correct file name, directory path, unit, and so forth were specified in the source program. Decide whether to:

  • Rename or remove the existing file before rerunning the program.
  • Modify the source file to specify different file specification, I/O unit, or OPEN statement STATUS.
111 info (11): Unit not connected

FOR$IOS_UNINOTCON. The specified unit was not open at the time of the attempted I/O operation. Check if correct unit number was specified. If appropriate, use an OPEN statement to explicitly open the file (connect the file to the unit number).
17 severe (17): Syntax error in NAMELIST input

FOR$IOS_SYNERRNAM. The syntax of input to a namelist-directed READ statement was incorrect.

18 severe (18): Too many values for NAMELIST variable

FOR$IOS_TOOMANVAL. An attempt was made to assign too many values to a variable during a namelist READ statement.

19 severe (19): Invalid reference to variable in NAMELIST input

FOR$IOS_INVREFVAR. One of the following conditions occurred:

  • The variable was not a member of the namelist group.
  • An attempt was made to subscript a scalar variable.
  • A subscript of the array variable was out-of-bounds.
  • An array variable was specified with too many or too few subscripts for the variable.
  • An attempt was made to specify a substring of a noncharacter variable or array name.
  • A substring specifier of the character variable was out-of-bounds.
  • A subscript or substring specifier of the variable was not an integer constant.
  • An attempt was made to specify a substring by using an unsubscripted array variable.
20 severe (20): REWIND error

FOR$IOS_REWERR. One of the following conditions occurred:

  • The file was not a sequential file.
  • The file was not opened for sequential or append access.
  • The Compaq Fortran RTL I/O system detected an error condition during execution of a REWIND statement.
21 severe (21): Duplicate file specifications

FOR$IOS_DUPFILSPE. Multiple attempts were made to specify file attributes without an intervening close operation. A DEFINE FILE statement was followed by another DEFINE FILE statement or an OPEN statement.
22 severe (22): Input record too long

FOR$IOS_INPRECTOO. A record was read that exceeded the explicit or default record length specified when the file was opened. To read the file, use an OPEN statement with a RECL= value (record length) of the appropriate size.

23 severe (23): BACKSPACE error

FOR$IOS_BACERR. The Compaq Fortran RTL I/O system detected an error condition during execution of a BACKSPACE statement.

241 severe (24): End-of-file during read

FOR$IOS_ENDDURREA. One of the following conditions occurred:

  • A Compaq Fortran RTL I/O system end-of-file condition was encountered during execution of a READ statement that did not contain an END, ERR, or IOSTAT specification.
  • An end-of-file record written by the ENDFILE statement was encountered during execution of a READ statement that did not contain an END, ERR, or IOSTAT specification.
  • An attempt was made to read past the end of an internal file character string or array during execution of a READ statement that did not contain an END, ERR, or IOSTAT specification.
This error is returned by END and ERRSNS.
25 severe (25): Record number outside range

FOR$IOS_RECNUMOUT. A direct access READ, WRITE, or FIND statement specified a record number outside the range specified when the file was opened.
26 severe (26): OPEN or DEFINE FILE required

FOR$IOS_OPEDEFREQ. A direct access READ, WRITE, or FIND statement was attempted for a file when no prior DEFINE FILE or OPEN statement with ACCESS='DIRECT' was performed for that file.
27 severe (27): Too many records in I/O statement

FOR$IOS_TOOMANREC. An attempt was made to do one of the following:

  • Read or write more than one record with an ENCODE or DECODE statement.
  • Write more records than existed.
28 severe (28): CLOSE error

FOR$IOS_CLOERR. An error condition was detected by the Compaq Fortran RTL I/O system during execution of a CLOSE statement.
29 severe (29): File not found

FOR$IOS_FILNOTFOU. A file with the specified name could not be found during an open operation.
30 severe (30): Open failure

FOR$IOS_OPEFAI. An error was detected by the Compaq Fortran RTL I/O system while attempting to open a file in an OPEN, INQUIRE, or other I/O statement. This message is issued when the error condition is not one of the more common conditions for which specific error messages are provided. It can occur when an OPEN operation was attempted for one of the following:

  • Segmented file that was not on a disk or a raw magnetic tape
  • Standard I/O file that had been closed
1Identifies errors not returned by IOSTAT.


Run-Time Errors 31 Through 60

This section describes in detail Visual Fortran run-time errors 31 through 60.

In the following table, the first column lists error numbers returned to IOSTAT variables when an I/O error is detected.

The first line of the second column provides the message as it is displayed (following forrtl:), including the severity level, message number, and the message text. The following lines of the second column contain the status condition symbol (such as FOR$IOS_INCRECTYP) and an explanation of the message.

For information about severity levels, see the Introduction.

Number Severity Level, Number, and Message Text; Condition Symbol and Explanation
31 severe (31): Mixed file access modes

FOR$IOS_MIXFILACC. An attempt was made to use any of the following combinations:

  • Formatted and unformatted operations on the same unit
  • An invalid combination of access modes on a unit, such as direct and sequential
  • A Compaq Fortran RTL I/O statement on a logical unit that was opened by a program coded in another language
32 severe (32): Invalid logical unit number

FOR$IOS_INVLOGUNI. A logical unit number greater than 2,147,483,647 or less than zero was used in an I/O statement.
33 severe (33): ENDFILE error

FOR$IOS_ENDFILERR. One of the following conditions occurred:

  • The file was not a sequential organization file with variable-length records.
  • The file was not opened for sequential, append, or direct access.
  • An unformatted file did not contain segmented records.
  • The Compaq Fortran RTL I/O system detected an error during execution of an ENDFILE statement.
34 severe (34): Unit already open

FOR$IOS_UNIALROPE. A DEFINE FILE statement specified a logical unit that was already opened.
35 severe (35): Segmented record format error

FOR$IOS_SEGRECFOR. An invalid segmented record control data word was detected in an unformatted sequential file. The file was probably either created with RECORDTYPE='FIXED' or 'VARIABLE' in effect, or was created by a program written in a language other than Fortran or Fortran 90.
36 severe (36): Attempt to access non-existent record

FOR$IOS_ATTACCNON. A direct-access READ or FIND statement attempted to access beyond the end of a relative file (or a sequential file on disk with fixed-length records) or access a record that was previously deleted from a relative file.
37 severe (37): Inconsistent record length

FOR$IOS_INCRECLEN. An attempt was made to open a direct access file without specifying a record length.
38 severe (38): Error during write

FOR$IOS_ERRDURWRI. The Compaq Fortran RTL I/O system detected an error condition during execution of a WRITE statement.
39 severe (39): Error during read

FOR$IOS_ERRDURREA. The Compaq Fortran RTL I/O system detected an error condition during execution of a READ statement.
40 severe (40): Recursive I/O operation

FOR$IOS_RECIO_OPE. While processing an I/O statement for a logical unit, another I/O operation on the same logical unit was attempted, such as a function subprogram that performs I/O to the same logical unit that was referenced in an expression in an I/O list or variable format expression.

411,2 severe (41): Insufficient virtual memory

FOR$IOS_INSVIRMEM. The Compaq Fortran RTL attempted to exceed its available virtual memory while dynamically allocating space. To overcome this problem, investigate increasing the data limit (Control Panel, System, Performance Tab, Virtual Memory). Before you try to run this program again, wait until the new system resources take effect.

42 severe (42): No such device

FOR$IOS_NO_SUCDEV. A pathname included an invalid or unknown device name when an OPEN operation was attempted.
43 severe (43): File name specification error

FOR$IOS_FILNAMSPE. A pathname or file name given to an OPEN or INQUIRE statement was not acceptable to the Compaq Fortran RTL I/O system.

44 severe (44): Inconsistent record type

FOR$IOS_INCRECTYP. The RECORDTYPE value in an OPEN statement did not match the record type attribute of the existing file that was opened.
45 severe (45): Keyword value error in OPEN statement

FOR$IOS_KEYVALERR. An improper value was specified for an OPEN or CLOSE statement specifier requiring a value.

46 severe (46): Inconsistent OPEN/CLOSE parameters

FOR$IOS_INCOPECLO. Specifications in an OPEN or CLOSE statement were inconsistent. Some invalid combinations follow:

  • READONLY or ACTION='READ' with STATUS='NEW' or STATUS='SCRATCH'
  • READONLY with STATUS='REPLACE', ACTION='WRITE', or ACTION='READWRITE'
  • ACCESS='APPEND' with READONLY, ACTION='READ', STATUS='NEW', or STATUS='SCRATCH'
  • DISPOSE='SAVE', 'PRINT', or 'SUBMIT' with STATUS='SCRATCH'
  • DISPOSE='DELETE' with READONLY
  • CLOSE statement STATUS='DELETE' with OPEN statement READONLY
  • ACCESS='APPEND' with STATUS='REPLACE'
  • ACCESS='DIRECT' with POSITION='APPEND' or 'ASIS'
47 severe (47): Write to READONLY file

FOR$IOS_WRIREAFIL. A write operation was attempted to a file that was declared ACTION='READ' or READONLY in the OPEN statement that is currently in effect.
48 severe (48): Invalid argument to Fortran Run-Time Library

FOR$IOS_INVARGFOR. The compiler passed an invalid or improperly coded argument to the Compaq Fortran RTL. This can occur if the compiler is newer than the RTL in use.
51 severe (51): Inconsistent file organization

FOR$IOS_INCFILORG. The file organization specified in an OPEN statement did not match the organization of the existing file.
53 severe (53): No current record

FOR$IOS_NO_CURREC. Attempted to execute a REWRITE statement to rewrite a record when the current record was undefined. To define the current record, execute a successful READ statement. You can optionally perform an INQUIRE statement on the logical unit after the READ statement and before the REWRITE statement. No other operations on the logical unit may be performed between the READ and REWRITE statements.

55 severe (55): DELETE error

FOR$IOS_DELERR. An error condition was detected by the Compaq Fortran RTL I/O system during execution of a DELETE statement.
57 severe (57): FIND error

FOR$IOS_FINERR. The Compaq Fortran RTL I/O system detected an error condition during execution of a FIND statement.
583 info (58): Format syntax error at or near xx

FOR$IOS_FMTSYN. Check the statement containing xx, a character substring from the format string, for a format syntax error. For more information, see the FORMAT statement.

594 severe (59): List-directed I/O syntax error

FOR$IOS_LISIO_SYN. The data in a list-directed input record had an invalid format, or the type of the constant was incompatible with the corresponding variable. The value of the variable was unchanged.
60 severe (60): Infinite format loop

FOR$IOS_INFFORLOO. The format associated with an I/O statement that included an I/O list had no field descriptors to use in transferring those values.
1Identifies errors that can be returned by STAT in an ALLOCATE statement.

2Identifies errors that can be returned by STAT in a DEALLOCATE statement.

3Identifies errors not returned by IOSTAT.

4The ERR transfer is taken after completion of the I/O statement for error number 59. The resulting file status and record position are the same as if no error had occurred. However, other I/O errors take the ERR transfer as soon as the error is detected, so file status and record position are undefined.


Run-Time Errors 61 Through 108

This section describes in detail Visual Fortran run-time errors 61 through 108.

In the following table, the first column lists error numbers returned to IOSTAT variables when an I/O error is detected.

The first line of the second column provides the message as it is displayed (following forrtl:), including the severity level, message number, and the message text. The following lines of the second column contain the status condition symbol (such as FOR$IOS_INCRECTYP) and an explanation of the message.

For information about the severity levels, see the Introduction.

Number Severity Level, Number, and Message Text; Condition Symbol and Explanation
61 severe or info1 (61): Format/variable-type mismatch

FOR$IOS_FORVARMIS2. An attempt was made either to read or write a real variable with an integer field descriptor (I, L, O, Z, B), or to read or write an integer or logical variable with a real field descriptor (D, E, or F). To suppress this error message, see the description of /check:noformat.

62 severe (62): Syntax error in format

FOR$IOS_SYNERRFOR. A syntax error was encountered while the RTL was processing a format stored in an array or character variable.
63 error or info1 (63): Output conversion error

FOR$IOS_OUTCONERR2. During a formatted output operation, the value of a particular number could not be output in the specified field length without loss of significant digits. When this situation is encountered, the overflowed field is filled with asterisks to indicate the error in the output record. If no ERR address has been defined for this error, the program continues after the error message is displayed. To suppress this error message, see the description of /check:nooutput_conversion.

64 severe (64): Input conversion error

FOR$IOS_INPCONERR2. During a formatted input operation, an invalid character was detected in an input field, or the input value overflowed the range representable in the input variable. The value of the variable was set to zero.
65 error (65): Floating invalid

FOR$IOS_FLTINV. During an arithmetic operation, the floating-point values used in a calculation were invalid for the type of operation requested or invalid exceptional values. For example, the error can occur if you request a log of the floating-point values 0.0 or a negative number. For certain arithmetic expressions, specifying the /check:nopower option can suppress this message.

66 severe (66): Output statement overflows record

FOR$IOS_OUTSTAOVE. An output statement attempted to transfer more data than would fit in the maximum record size.

67 severe (67): Input statement requires too much data

FOR$IOS_INPSTAREQ. Attempted to read more data than exists in a record with an unformatted READ statement or with a formatted sequential READ statement from a file opened with a PAD specifier value of 'NO'.
68 severe (68): Variable format expression value error

FOR$IOS_VFEVALERR2. The value of a variable format expression was not within the range acceptable for its intended use; for example, a field width was less than or equal to zero. A value of 1 was assumed, except for a P edit descriptor, for which a value of zero was assumed.

703 severe (70): Integer overflow

FOR$IOS_INTOVF. During an arithmetic operation, an integer value exceeded byte, word, or longword range. The result of the operation was the correct low-order part. See the Data Representation chapter in the Programmer's Guide for ranges of the various integer data types. Consider specifying a larger integer data size (modify source program or, for an INTEGER declaration, possibly use the /integer_size:size option).

713 severe (71): Integer divide by zero

FOR$IOS_INTDIV. During an integer arithmetic operation, an attempt was made to divide by zero. The result of the operation was set to the dividend, which is equivalent to division by 1.
723 error (72): Floating overflow

FOR$IOS_FLTOVF. During an arithmetic operation, a floating-point value exceeded the largest representable value for that data type. See the Data Representation chapter in the Programmer's Guide for ranges of the various data types.

733 error (73): Floating divide by zero

FOR$IOS_FLTDIV. During a floating-point arithmetic operation, an attempt was made to divide by zero.
743 error (74): Floating underflow

FOR$IOS_FLTUND. During an arithmetic operation, a floating-point value became less than the smallest finite value for that data type. Depending on the values of the /fpe: n option, the underflowed result was either set to zero or allowed to gradually underflow. See the Data Representation chapter in the Programmer's Guide for ranges of the various data types.

753 error (75): Floating point exception

FOR$IOS_SIGFPE. A floating-point exception occurred. Possible causes include:

  • Division by zero
  • Overflow
  • An invalid operation, such as subtraction of infinite values, multiplication of zero by infinity without signs), division of zero by zero or infinity by infinity
  • Conversion of floating-point to fixed-point format when an overflow prevents conversion
773 severe (77): Subscript out of range

FOR$IOS_SUBRNG. An array reference was detected outside the declared array bounds.
783 error (78): Process killed

FOR$IOS_SIGTERM. The process received a signal requesting termination of this process. Determine the source of this software termination signal.

793 error (79): Process quit

FOR$IOS_SIGQUIT. The process received a signal requesting termination of itself. Determine the source of this quit signal.
953 info (95): Floating-point conversion failed

FOR$IOS_FLOCONFAI. The attempted unformatted read or write of nonnative floating-point data failed because the floating-point value:

  • Exceeded the allowable maximum value for the equivalent native format and was set equal to infinity (plus or minus)
  • Was infinity (plus or minus) and was set to infinity (plus or minus)
  • Was invalid and was set to not a number (NaN)

Very small numbers are set to zero (0). This error could be caused by the specified nonnative floating-point format not matching the floating-point format found in the specified file. Check the following:

  • The correct file was specified.
  • The record layout matches the format Compaq Fortran is expecting.
  • The ranges for the data being used (see Data Representation).
  • The correct nonnative floating-point data format was specified (see Converting Unformatted Numeric Data).
108 Severe (108): Cannot stat file

FOR$IOS_CANSTAFILE. Make sure correct file and unit were specified.

1For errors 61 and 63, the severity depends on the /check:keywords used during compilation command.

2The ERR transfer is taken after completion of the I/O statement for error numbers 61, 63, 64, and 68. The resulting file status and record position are the same as if no error had occurred. However, other I/O errors take the ERR transfer as soon as the error is detected, so file status and record position are undefined.

3Identifies errors not returned by IOSTAT.


Run-Time Errors 120 Through 300

This section describes in detail Visual Fortran run-time errors 120 through 300.

In the following table, the first column lists error numbers returned to IOSTAT variables when an I/O error is detected.

The first line of the second column provides the message as it is displayed (following forrtl:), including the severity level, message number, and the message text. The following lines of the second column contain the status condition symbol (such as FOR$IOS_INCRECTYP) and an explanation of the message.

For information about the severity levels, see the Introduction.

Number Severity Level, Number, and Message Text; Condition Symbol and Explanation
120 severe (120): Operation requires seek ability

FOR$IOS_OPEREQSEE. Attempted an operation on a file that requires the ability to perform seek operations on that file. Make sure the correct unit, directory path, and file were specified.
1381 severe (138): Array index out of bounds

FOR$IOS_BRK_RANGE. An array subscript is outside the dimensioned boundaries of that array. Recompile with the /check:bounds option set.

1391 severe: (139): Array index out of bounds for index nn

FOR$IOS_BRK_RANGE2. An array subscript is outside the dimensioned boundaries of that array. Recompile with the /check:bounds option set.

1401 error (140): Floating inexact

FOR$IOS_FLTINE. A floating-point arithmetic or conversion operation gave a result that differs from the mathematically exact result. This trap is reported if the rounded result of an IEEE operation is not exact.

1441 severe (144): Reserved operand

FOR$IOS_ROPRAND. The Compaq Fortran RTL encountered a reserved operand while executing your program. Please report the problem to Compaq.

1451 severe (145): Assertion error

FOR$IOS_ASSERTERR. The Compaq Fortran RTL encountered an assertion error. Please report the problem to Compaq.

1461 severe (146): Null pointer error

FOR$IOS_NULPTRERR. Attempted to use a pointer that does not contain an address. Modify the source program, recompile, and relink.

1471 severe (147): Stack overflow

FOR$IOS_STKOVF. The Compaq Fortran RTL encountered a stack overflow while executing your program. See the Section "Guidelines for Programs That Use Large Data Arrays" in the post-installation part of Compaq Visual Fortran Installing and Getting Started.

1481 severe (148): String length error

FOR$IOS_STRLENERR. During a string operation, an integer value appears in a context where the value of the integer is outside the permissible string length range. Recompile with the /check:bounds option.

1491 severe (149): Substring error

FOR$IOS_SUBSTRERR. An array subscript is outside the dimensioned boundaries of an array. Recompile with the /check:bounds option.

1501 severe (150): Range error

FOR$IOS_RANGEERR. An integer value appears in a context where the value of the integer is outside the permissible range.

1511,2 severe (151): Allocatable array is already allocated

FOR$IOS_INVREALLOC. An allocatable array must not already be allocated when you attempt to allocate it. You must deallocate the array before it can again be allocated.

1521 severe (152): Unresolved contention for DEC Fortran RTL global resource

FOR$IOS_RESACQFAI. Failed to acquire a Compaq Fortran RTL global resource for a reentrant routine. For a multithreaded program, the requested global resource is held by a different thread in your program. For a program using asynchronous handlers, the requested global resource is held by the calling part of the program (such as main program) and your asynchronous handler attempted to acquire the same global resource.

1531,3 severe (153): Allocatable array or pointer is not allocated

FOR$IOS_INVDEALLOC. A Fortran 90 allocatable array or pointer must already be allocated when you attempt to deallocate it. You must allocate the array or pointer before it can again be deallocated.

1541 severe(154): Array index out of bounds

FOR$IOS_RANGE. An array subscript is outside the dimensioned boundaries of that array. Recompile with the /check:bounds option set.
1551 severe(155): Array index out of bounds for index nn

FOR$IOS_RANGE2. An array subscript is outside the dimensioned boundaries of that array. Recompile with the /check:bounds option set.
1561 severe(156): GENTRAP code = hex dec

FOR$IOS_DEF_GENTRAP. The Compaq Fortran RTL has detected an unknown GENTRAP code. The cause is most likely a software problem due to memory corruption, or software signalling an exception with an incorrect exception code. Try recompiling with the /check:bounds option set to see if that finds the problem.
1571 severe(157): Program Exception - access violation

FOR$IOS_ACCVIO. The program tried to read from or write to a virtual address for which it does not have the appropriate access. Try recompiling with the /check:bounds and /warn:argument_checking options set, to see if the problem is an out-of-bounds memory reference or a argument mismatch that causes data to be treated as an address.

Other causes of this error include:

  • Mismatches in C vs. STDCALL calling mechanisms, causing the stack to become corrupted
  • References to unallocated pointers
  • Attempting to access a protected (for example, read-only) address
1581 severe(158): Program Exception - datatype misalignment

FOR$IOS_DTYPE_MISALIGN. The Compaq Fortran RTL has detected data that is not aligned on a natural boundary for the data type specified. For example, a REAL(8) data item aligned on natural boundaries has an address that is a multiple of 8. To ensure naturally aligned data, use the /alignment option. For more information on alignment, see Data Alignment Considerations in the Programmer's Guide.

This is an operating system error. See your operating system documentation for more information.
1591 severe(159): Program Exception - breakpoint

FOR$IOS_PGM_BPT. The Compaq Fortran RTL has encountered a breakpoint in the program.

This is an operating system error. See your operating system documentation for more information.
1601 severe(160): Program Exception - single step

FOR$IOS_PGM_SS. A trace trap or other single-instruction mechanism has signaled that one instruction has been executed.

This is an operating system error. See your operating system documentation for more information.
1611 severe(161): Program Exception - array bounds exceeded

FOR$IOS_PGM_BOUNDS. The program tried to access an array element that is outside the specified boundaries of the array. Recompile with the /check:bounds option set.
1621 severe(162): Program Exception - denormal floating-point operand

FOR$IOS_PGM_DENORM. A floating-point arithmetic or conversion operation has a denormalized number as an operand. A denormalized number is smaller than the lowest value in the normal range for the data type specified. See the Data Representation chapter in the Programmer's Guide for ranges for floating-point types.

Either locate and correct the source code causing the denormalized value or, if a denormalized value is acceptable, specify a different value for the /fpe compiler option to allow program continuation.
1631 severe(163): Program Exception - floating stack check

FOR$IOS_PGM_FLTSTK. During a floating-point operation, the floating-point register stack on ia32 systems overflowed or underflowed. This is a fatal exception. The most likely cause is calling a REAL function as if it were an INTEGER function or subroutine, or calling an INTEGER function or subroutine as if it were a REAL function.

Carefully check that the calling code and routine being called agree as to how the routine is declared. If you are unable to resolve the issue, please send a problem report with an example to Compaq.
1641 severe(164): Program Exception - integer divide by zero

FOR$IOS_PGM_INTDIV. During an integer arithmetic operation, an attempt was made to divide by zero. Locate and correct the source code causing the integer divide by zero.
1651 severe(165): Program Exception - integer overflow

FOR$IOS_PGM_INTOVF. During an arithmetic operation, an integer value exceeded the largest representable value for that data type. See the Data Representation chapter in the Programmer's Guide for ranges for INTEGER types.

This message appears when /check:overflow was specified and an integer overflow appears.
1661 severe(166): Program Exception - privileged instruction

FOR$IOS_PGM_PRIVINST. The program tried to execute an instruction whose operation is not allowed in the current machine mode.

This is an operating system error. See your operating system documentation for more information.
1671 severe(167): Program Exception - in page error

FOR$IOS_PGM_INPGERR. The program tried to access a page that was not present, so the system was unable to load the page. For example, this error might occur if a network connection was lost while trying to run a program over the network.

This is an operating system error. See your operating system documentation for more information.
1681 severe(168): Program Exception - illegal instruction

FOR$IOS_PGM_ILLINST. The program tried to execute an invalid instruction.

This is an operating system error. See your operating system documentation for more information.
1691 severe(169): Program Exception - noncontinuable exception

FOR$IOS_PGM_NOCONTEXCP. The program tried to continue execution after a noncontinuable exception occurred.

This is an operating system error. See your operating system documentation for more information.
1701 severe(170): Program Exception - stack overflow

FOR$IOS_PGM_STKOVF. The Compaq Fortran RTL has detected a stack overflow while executing your program. See your Release Notes for information on how to increase stack size.
1711 severe(171): Program Exception - invalid disposition

FOR$IOS_PGM_INVDISP. An exception handler returned an invalid disposition to the exception dispatcher. Programmers using a high-level language should never encounter this exception.

This is an operating system error. See your operating system documentation for more information.
1721 severe(172): Program Exception - exception code = hex dec

FOR$IOS_PGM_EXCP_CODE. The Compaq Fortran RTL has detected an unknown exception code.

This is an operating system error. See your operating system documentation for more information.
1731,3 severe(173): A pointer passed to DEALLOCATE points to an array that cannot be deallocated

FOR$IOS_INVDEALLOC2. A pointer that was passed to DEALLOCATE pointed to an explicit array, an array slice, or some other type of memory that could not be deallocated in a DEALLOCATE statement. Only whole arrays previous allocated with an ALLOCATE statement may be validly passed to DEALLOCATE.
1751 severe(175): DATE argument to DATE_AND_TIME is too short (LEN=n), required LEN=8

FOR$IOS_SHORTDATEARG. The number of characters associated with the DATE argument to the DATE_AND_TIME intrinsic was shorter than the required length. You must increase the number of characters passed in for this argument to be at least 8 characters in length. Verify that the TIME and ZONE arguments also meet their minimum lengths.
1761 severe(176): TIME argument to DATE_AND_TIME is too short (LEN=n), required LEN=10

FOR$IOS_SHORTTIMEARG. The number of characters associated with the TIME argument to the DATE_AND_TIME intrinsic was shorter than the required length. You must increase the number of characters passed in for this argument to be at least 10 characters in length. Verify that the DATE and ZONE arguments also meet their minimum lengths.
1771 severe(177): ZONE argument to DATE_AND_TIME is too short (LEN=n), required LEN=5

FOR$IOS_SHORTZONEARG. The number of characters associated with the ZONE argument to the DATE_AND_TIME intrinsic was shorter than the required length. You must increase the number of characters passed in for this argument to be at least 5 characters in length. Verify that the DATE and TIME arguments also meet their minimum lengths.
1781 severe(178): Divide by zero

FOR$IOS_DIV. A floating-point or integer divide-by-zero exception occurred.
1791,2 severe(179): Cannot allocate array - overflow on array size calculation

FOR$IOS_ARRSIZEOVF. An attempt to dynamically allocate storage for an array failed because the required storage size exceeds addressable memory.
2011 severe (201): Intel Pentium fdiv flaw detected, please update the processor

FOR$IOS_FLAWEDPENT. The Fortran run-time system detected a flawed Pentium® processor. Please contact Intel® to upgrade your processor. To allow program execution to continue when this condition occurs, set the environment variable FOR_RUN_FLAWED_PENTIUM to true and rerun the program. For more information, see Intel Pentium Floating-Point Flaw.
256 severe (256): Unformatted I/O to unit open for formatted transfers

FOR$IOS_UNFIO_FMT. Attempted unformatted I/O to a unit where the OPEN statement (FORM specifier) indicated the file was formatted. Check that the correct unit (file) was specified. If the FORM specifier was not present in the OPEN statement and the file contains unformatted data, specify FORM='UNFORMATTED'in the OPEN statement. Otherwise, if appropriate, use formatted I/O (such as list-directed or namelist I/O).

257 severe (257): Formatted I/O to unit open for unformatted transfers

FOR$IOS_FMTIO_UNF. Attempted formatted I/O (such as list-directed or namelist I/O) to a unit where the OPEN statement indicated the file was unformatted (FORM specifier). Check that the correct unit (file) was specified. If the FORM specifier was not present in the OPEN statement and the file contains formatted data, specify FORM='FORMATTED' in the OPEN statement. Otherwise, if appropriate, use unformatted I/O.

259 severe (259): Sequential-access I/O to unit open for direct access

FOR$IOS_SEQIO_DIR. The OPEN for this unit number specified direct access and the I/O statement specifies sequential access. Check the OPEN statement and make sure the I/O statement uses the correct unit number and type of access.

For more information on OPEN and other statements, see the A to Z Reference in the online Language Reference or the printed Compaq Fortran Language Reference Manual.
264 severe (264): operation requires file to be on disk or tape

FOR$IOS_OPEREQDIS. Attempted to use a BACKSPACE statement on such devices as a terminal.
265 severe (265): operation requires sequential file organization and access

FOR$IOS_OPEREQSEQ. Attempted to use a BACKSPACE statement on a file whose organization was not sequential or whose access was not sequential. A BACKSPACE statement can only be used for sequential files opened for sequential access.

2661 error (266): Fortran abort routine called

FOR$IOS_PROABOUSE. The program called the abort routine to terminate itself.

2681 severe (268): End of record during read

FOR$IOS_ENDRECDUR. An end-of-record condition was encountered during execution of a nonadvancing I/O READ statement that did not specify the EOR branch specifier.

2961 info(296): nn floating inexact traps

FOR$IOS_FLOINEEXC. The total number of floating-point inexact data traps encountered during program execution was nn. This summary message appears at program completion.
2971 info (297): nn floating invalid traps

FOR$IOS_FLOINVEXC. The total number of floating-point invalid data traps encountered during program execution was nn. This summary message appears at program completion.
2981 info (298): nn floating overflow traps

FOR$IOS_FLOOVFEXC. The total number of floating-point overflow traps encountered during program execution was nn. This summary message appears at program completion.
2991 info (299): nn floating divide-by-zero traps

FOR$IOS_FLODIV0EXC. The total number of floating-point divide-by-zero traps encountered during program execution was nn. This summary message appears at program completion.
3001 info (300): nn floating underflow traps

FOR$IOS_FLOUNDEXC. The total number of floating-point underflow traps encountered during program execution was nn. This summary message appears at program completion.
1Identifies errors not returned by IOSTAT.

2Identifies errors that can be returned by STAT in an ALLOCATE statement.

3Identifies errors that can be returned by STAT in a DEALLOCATE statement.


Run-Time Errors 540 Through 569

This section describes in detail Visual Fortran run-time errors 540 through 569.

In the following table, the first column lists error numbers returned to IOSTAT variables when an I/O error is detected.

The first line of the second column provides the message as it is displayed (following forrtl:), including the severity level, message number, and the message text. The following lines of the second column contain the status condition symbol (such as FOR$IOS_INCRECTYP) and an explanation of the message.

For information about severity levels, see the Introduction.

Number Severity Level, Number, and Message Text; Condition Symbol and Explanation
540 severe (540): Array or substring subscript expression out of range

FOR$IOS_F6096. An expression used to index an array was smaller than the lower dimension bound or larger than the upper dimension bound.
541 severe (541): CHARACTER substring expression out of range

FOR$IOS_F6097. An expression used to index a character substring was illegal.

542 severe (542): Label not found in assigned GOTO list

FOR$IOS_F6098. The label assigned to the integer-variable name was not specified in the label list of the assigned GOTO statement.
543 severe (543): INTEGER arithmetic overflow

FOR$IOS_F6099. This error occurs whenever integer arithmetic results in overflow.
544 severe (544): INTEGER overflow on input

FOR$IOS_F6100. An integer item exceeded the legal size limits.

An INTEGER(1) item must be in the range -127 to 128. An INTEGER(2) item must be in the range -32,767 to 32,768. An INTEGER(4) item must be in the range -2,147,483,647 to 2,147,483,648.

545 severe (545): Invalid INTEGER

FOR$IOS_F6101. Either an illegal character appeared as part of an integer, or a numeric character larger than the radix was used in an alternate radix specifier.
546 severe (546): REAL indefinite (uninitialized or previous error)

FOR$IOS_F6102. An invalid real number was read from a file, an internal variable, or the console. This can happen if an invalid number is generated by passing an illegal argument to an intrinsic function -- for example, SQRT(-1) or ASIN(2). If the invalid result is written and then later read, the error will be generated.
547 severe (547): Invalid REAL

FOR$IOS_F103. An illegal character appeared as part of a real number.
548 severe (548): REAL math overflow

FOR$IOS_F6104. A real value was too large. Floating-point overflows in either direct or emulated mode generate NaN (Not-A-Number) exceptions, which appear in the output field as asterisks (*) or the letters NAN.

550 severe (550): INTEGER assignment overflow

FOR$IOS_F6106. This error occurs when assignment to an integer is out of range. This message appears only if the /check:bounds option is used in compiling.
551 severe (551): Formatted I/O not consistent with OPEN options

FOR$IOS_F6200. The program tried to perform formatted I/O on a unit opened with FORM='UNFORMATTED' or FORM='BINARY'.

552 severe (552): List-directed I/O not consistent with OPEN options

FOR$IOS_F6201. The program tried to perform list-directed I/O on a file that was not opened with FORM='FORMATTED' and ACCESS='SEQUENTIAL'.

553 severe (553): Terminal I/O not consistent with OPEN options

FOR$IOS_F6202. When a special device such as CON, LPT1, or PRN is opened in an OPEN statement, its access must be sequential and its format must be either formatted or binary. By default ACCESS='SEQUENTIAL' and FORM='FORMATTED' in OPEN statements.

To generate this error the device's OPEN statement must contain an option not appropriate for a terminal device, such as ACCESS='DIRECT' or FORM='UNFORMATTED'.
554 severe (554): Direct I/O not consistent with OPEN options

FOR$IOS_F6203. A REC= option was included in a statement that transferred data to a file that was opened with the ACCESS='SEQUENTIAL' option.

555 severe (555): Unformatted I/O not consistent with OPEN options

FOR$IOS_F6204. If a file is opened with FORM='FORMATTED', unformatted or binary data transfer is prohibited.

556 severe (556): A edit descriptor expected for CHARACTER

FOR$IOS_F6205. The A edit descriptor was not specified when a character data item was read or written using formatted I/O.

557 severe (557): E, F, D, or G edit descriptor expected for REAL

FOR$IOS_F6206. The E, F, D, or G edit descriptor was not specified when a real data item was read or written using formatted I/O.

558 severe (558): I edit descriptor expected for INTEGER

FOR$IOS_F6207. The I edit descriptor was not specified when an integer data item was read or written using formatted I/O.

559 severe (559): L edit descriptor expected for LOGICAL

FOR$IOS_F6208. The L edit descriptor was not specified when a logical data item was read or written using formatted I/O.

560 severe (560): File already open: parameter mismatch

FOR$IOS_F6209. An OPEN statement specified a connection between a unit and a filename that was already in effect. In this case, only the BLANK= option can have a different setting.

561 severe (561): Namelist I/O not consistent with OPEN options

FOR$IOS_F6210. The program tried to perform namelist I/O on a file that was not opened with FORM='FORMATTED' and ACCESS='SEQUENTIAL'.

562 severe (562): IOFOCUS option illegal with non-window unit

FOR$IOS_F6211. IOFOCUS was specified in an OPEN or INQUIRE statement for a non-window unit. The IOFOCUS option can only be used when the unit opened or inquired about is a QuickWin child window.

563 severe (563): IOFOCUS option illegal without QuickWin

FOR$IOS_F6212. IOFOCUS was specified in an OPEN or INQUIRE statement for a non-QuickWin application. The IOFOCUS option can only be used when the unit opened or inquired about is a QuickWin child window.

564 severe (564): TITLE illegal with non-window unit

FOR$IOS_F6213. TITLE was specified in an OPEN or INQUIRE statement for a non-window unit. The TITLE option can only be used when the unit opened or inquired about is a QuickWin child window.

565 severe (565): TITLE illegal without QuickWin

FOR$IOS_F6214. TITLE was specified in an OPEN or INQUIRE statement for a non-QuickWin application. The TITLE option can only be used when the unit opened or inquired about is a QuickWin child window.

566 severe (566): KEEP illegal for scratch file

FOR$IOS_F6300. STATUS='KEEP' was specified for a scratch file; this is illegal because scratch files are automatically deleted at program termination.
567 severe (567): SCRATCH illegal for named file

FOR$IOS_F6301. STATUS='SCRATCH' should not be used in a statement that includes a filename.

568 severe (568): Multiple radix specifiers

FOR$IOS_F6302. More than one alternate radix for numeric I/O was specified. F6302 can indicate an error in spacing or a mismatched format for data of different radices.
569 severe (569): Illegal radix specifier

FOR$IOS_F6303. A radix specifier was not between 2 and 36, inclusive. Alternate radix constants must be of the form n#ddd... where n is a radix from 2 to 36 inclusive and ddd... are digits with values less than the radix. For example, 3#12 and 34#7AX are valid constants with valid radix specifiers. 245#7A and 39#12 do not have valid radix specifiers and generate error 569 if input.


Run-Time Errors 570 Through 614

This section describes in detail Visual Fortran run-time errors 570 through 614.

In the following table, the first column lists error numbers returned to IOSTAT variables when an I/O error is detected.

The first line of the second column provides the message as it is displayed (following forrtl:), including the severity level, message number, and the message text. The following lines of the second column contain the status condition symbol (such as FOR$IOS_INCRECTYP) and an explanation of the message.

For information about severity levels, see the Introduction.

Number Severity Level, Number, and Message Text; Condition Symbol and Explanation
570 severe (570): Illegal STATUS value

FOR$IOS_F6304. An illegal value was used with the STATUS option.

STATUS accepts the following values:

  • 'KEEP' or 'DELETE' when used with CLOSE statements
  • 'OLD', 'NEW', 'SCRATCH', or 'UNKNOWN' when used with OPEN statements
571 severe (571): Illegal MODE value

FOR$IOS_F6305. An illegal value was used with the MODE option.

MODE accepts the values 'READ', 'WRITE', or 'READWRITE'.
572 severe (572): Illegal ACCESS value

FOR$IOS_F6306. An illegal value was used with the ACCESS option.

ACCESS accepts the values 'SEQUENTIAL' and 'DIRECT'.
573 severe (573): Illegal BLANK value

FOR$IOS_F6307. An illegal value was used with the BLANK option.

BLANK accepts the values 'NULL' and 'ZERO'.

574 severe (574): Illegal FORM value

FOR$IOS_F6308. An illegal value was used with the FORM option.

FORM accepts the following values: 'FORMATTED', 'UNFORMATTED', and 'BINARY'.

575 severe (575): Illegal SHARE value

FOR$IOS_F6309. An illegal value was used with the SHARE option.

SHARE accepts the values 'COMPAT', 'DENYRW', 'DENYWR', 'DENYRD', and 'DENYNONE'.

577 severe (577): Illegal record number

FOR$IOS_F6311. An invalid number was specified as the record number for a direct-access file.

The first valid record number for direct-access files is 1.

578 severe (578): No unit number associated with *

FOR$IOS_F6312. In an INQUIRE statement, the NUMBER option was specified for the file associated with * (console).

580 severe (580): Illegal unit number

FOR$IOS_F6314. An illegal unit number was specified.

Legal unit numbers can range from 0 through 2**31-1, inclusive.

581 severe (581): Illegal RECL value

FOR$IOS_F6315. A negative or zero record length was specified for a direct file.

The smallest valid record length for direct files is 1.

582 severe (582): Array already allocated

FOR$IOS_F6316. The program attempted to ALLOCATE an already allocated array.

583 severe (583): Array size zero or negative

FOR$IOS_F6317. The size specified for an array in an ALLOCATE statement must be greater than zero.

584 severe (584): Non-HUGE array exceeds 64K

FOR$IOS_F6318.
585 severe (585): Array not allocated

FOR$IOS_F6319. The program attempted to DEALLOCATE an array that was never allocated.
586 severe (586): BACKSPACE illegal on terminal device

FOR$IOS_F6400. A BACKSPACE statement specified a unit connected to a terminal device such as a terminal or printer.

587 severe (587): EOF illegal on terminal device

FOR$IOS_F6401. An EOF intrinsic function specified a unit connected to a terminal device such as a terminal or printer.

588 severe (588): ENDFILE illegal on terminal device

FOR$IOS_F6402. An ENDFILE statement specified a unit connected to a terminal device such as a terminal or printer.

589 severe (589): REWIND illegal on terminal device

FOR$IOS_F6403. A REWIND statement specified a unit connected to a terminal device such as a terminal or printer.

590 severe (590): DELETE illegal for read-only file

FOR$IOS_F6404. A CLOSE statement specified STATUS='DELETE' for a read-only file.

591 severe (591): External I/O illegal beyond end of file

FOR$IOS_F6405. The program tried to access a file after executing an ENDFILE statement or after it encountered the end-of-file record during a read operation.

A BACKSPACE, REWIND, or OPEN statement must be used to reposition the file before execution of any I/O statement that transfers data.

592 severe (592): Truncation error: file closed

FOR$IOS_F6406.
593 severe (593): Terminal buffer overflow

FOR$IOS_F6407. More than 131 characters were input to a record of a unit connected to the terminal (keyboard). Note that the operating system may impose additional limits on the number of characters that can be input to the terminal in a single record.

594 severe (594): Comma delimiter disabled after left repositioning

FOR$IOS_F6408. If you have record lengths that exceed the buffer size associated with the record, (for instance, the record is a file with the buffer set by BLOCKSIZE in the OPEN statement), either you should not do left tabbing within the record, or you should not use commas as field delimiters. This is because commas are disabled as input field delimiters if left tabbing leaves the record positioned in a previous buffer.

For example, consider you have a file LONG.DAT that is one continuous record with data fields separated by commas. You then set the buffer associated with the file to 512 bytes, read more than one buffer size of data, tab left to data in the previous buffer, and attempt to read further data, as follows:

    INTEGER value(300)
    OPEN (1, FILE = 'LONG.DAT', BLOCKSIZE = 512)
    READ (1, 100) (value(i), i = 1, 300)
100 FORMAT (290I2,TL50,10I2)
In this case, error 594 occurs.
599 severe (599): File already connected to a different unit

FOR$IOS_F6413. The program tried to connect an already connected file to a new unit.

A file can be connected to only one unit at a time.

600 severe (600): Access not allowed

FOR$IOS_F6414.

This error can be caused by one of the following:

  • The filename specified in an OPEN statement was a directory.
  • An OPEN statement tried to open a read-only file for writing.
  • The file was opened with SHARE='DENYRW' by another process.
601 severe (601): File already exists

FOR$IOS_F6415. An OPEN statement specified STATUS='NEW' for a file that already exists.

602 severe (602): File not found

FOR$IOS_F6416. An OPEN statement specified STATUS='OLD' for a specified file or a directory path that does not exist.

603 severe (603): Too many open files

FOR$IOS_F6417. The program exceeded the number of open files the operating system allows.
604 severe (604): Too many units connected

FOR$IOS_F6418. The program exceeded the number of units that can be connected at one time. Units are connected with the OPEN statement.

605 severe (605): Illegal structure for unformatted file

FOR$IOS_F6419. The file was opened with FORM='UNFORMATTED' and ACCESS='SEQUENTIAL', but its internal physical structure was incorrect or inconsistent. Possible causes: the file was created in another mode or by a non-Fortran program.

606 severe (606): Unknown unit number

FOR$IOS_F6420. A statement such as BACKSPACE or ENDFILE specified a file that had not yet been opened. (The READ and WRITE statements do not cause this problem because they prompt you for a file if the file has not been opened yet.)

607 severe (607): File read-only or locked against writing

FOR$IOS_F6421. The program tried to transfer data to a file that was opened in read-only mode or locked against writing.

The error message may indicate a CLOSE error when the fault is actually coming from WRITE. This is because the error is not discovered until the program tries to write buffered data when it closes the file.

608 severe (608): No space left on device

FOR$IOS_F6422. The program tried to transfer data to a file residing on a device (such as a hard disk) that was out of storage space.

609 severe (609): Too many threads

FOR$IOS_F6423. Too many threads were active simultaneously. At most, 32 threads can be active at one time. Close any unnecessary processes or child windows within your application.
610 severe (610): Invalid argument

FOR$IOS_F6424.
611 severe (611): BACKSPACE illegal for SEQUENTIAL write-only files

FOR$IOS_F6425. The BACKSPACE statement is not allowed in files opened with MODE='WRITE' (write-only status) because BACKSPACE requires reading the previous record in the file to provide positioning.

Resolve the problem by giving the file read access or by avoiding the BACKSPACE statement. Note that the REWIND statement is valid for files opened as write-only.

612 severe (612): File not open for reading or file locked

FOR$IOS_F6500. The program tried to read from a file that was not opened for reading or was locked.

613 severe (613): End of file encountered

FOR$IOS_F6501. The program tried to read more data than the file contains.

614 severe (614): Positive integer expected in repeat field

FOR$IOS_F6502. When the i*c form is used in list-directed input, the i must be a positive integer. For example, consider the following statement:

  READ(*,*) a, b
Input 2*56.7 is accepted, but input 2.1*56.7 returns error 614.


Run-Time Errors 615 Through 656

This section describes in detail Visual Fortran run-time errors 615 through 656.

In the following table, the first column lists error numbers returned to IOSTAT variables when an I/O error is detected.

The first line of the second column provides the message as it is displayed (following forrtl:), including the severity level, message number, and the message text. The following lines of the second column contain the status condition symbol (such as FOR$IOS_INCRECTYP) and an explanation of the message.

For information about severity levels, see the Introduction.

Number Severity Level, Number, and Message Text; Condition Symbol and Explanation
615 severe (615): Multiple repeat field

FOR$IOS_F6503. In list-directed input of the form i*c, an extra repeat field was used. For example, consider the following:

  READ(*,*) I, J, K
Input of 2*1*3 returns this error. The 2*1 means send two values, each 1; the *3 is an error.
616 severe (616): Invalid number in input

FOR$IOS_F6504. Some of the values in a list-directed input record were not numeric. For example, consider the following:

  READ(*,*) I, J
The preceding statement would cause this error if the input were: 123 'abc'.
617 severe (617): Invalid string in input

FOR$IOS_F6505. A string item was not enclosed in single quotation marks.

618 severe (618): Comma missing in COMPLEX input

FOR$IOS_F6506. When using list-directed input, the real and imaginary components of a complex number were not separated by a comma.

619 severe (619): T or F expected in LOGICAL read

FOR$IOS_F6507. The wrong format was used for the input field for logical data.

The input field for logical data consists of optional blanks, followed by an optional decimal point, followed by a T for true or F for false. The T or F may be followed by additional characters in the field, so that .TRUE. and .FALSE. are acceptable input forms.

620 severe (620): Too many bytes read from unformatted record

FOR$IOS_F6508. The program tried to read more data from an unformatted file than the current record contained. If the program was reading from an unformatted direct file, it tried to read more than the fixed record length as specified by the RECL option. If the program was reading from an unformatted sequential file, it tried to read more data than was written to the record.
621 severe (621): H or apostrophe edit descriptor illegal on input

FOR$IOS_F6509. Hollerith (H) or apostrophe edit descriptors were encountered in a format used by a READ statement.

622 severe (622): Illegal character in hexadecimal input

FOR$IOS_F6510. The input field contained a character that was not hexadecimal.

Legal hexadecimal characters are 0 - 9 and A - F.

623 severe (623): Variable name not found

FOR$IOS_F6511. A name encountered on input from a namelist record is not declared in the corresponding NAMELIST statement.

624 severe (624): Invalid NAMELIST input format

FOR$IOS_F6512. The input record is not in the correct form for namelist input.

625 severe (625): Wrong number of array dimensions

FOR$IOS_F6513. In namelist input, an array name was qualified with a different number of subscripts than its declaration, or a non-array name was qualified.
626 severe (626): Array subscript exceeds allocated area

FOR$IOS_F6514. A subscript was specified in namelist input which exceeded the declared dimensions of the array.

627 severe (627): Invalid subrange in NAMELIST input

FOR$IOS_F6515. A character item in namelist input was qualified with a subrange that did not meet the requirement that 1 <= e1 <= e2 <= len (where "len" is the length of the character item, "e1" is the leftmost position of the substring, and "e2" is the rightmost position of the substring).

628 severe (628): Substring range specified on non-CHARACTER item

FOR$IOS_F6516. A non-CHARACTER item in namelist input was qualified with a substring range.

629 severe (629): Internal file overflow

FOR$IOS_F6600. The program either overflowed an internal-file record or tried to write to a record beyond the end of an internal file.
630 severe (630): Direct record overflow

FOR$IOS_F6601. The program tried to write more than the number of bytes specified in the RECL option to an individual record of a direct-access file.
631 severe (631):Numeric field bigger than record size

FOR$IOS_F6602. The program tried to write a noncharacter item across a record boundary in list-directed or namelist output. Only character constants can cross record boundaries.

632 severe (632): Heap space limit exceeded

FOR$IOS_F6700. The program ran out of heap space. The ALLOCATE statement and various internal functions allocate memory from the heap. This error will be generated when the last of the heap space is used up.

633 severe (633): Scratch file name limit exceeded

FOR$IOS_F6701. The program exhausted the template used to generate unique scratch-file names. The maximum number of scratch files that can be open at one time is 26.

634 severe (634): D field exceeds W field in ES edit descriptor

FOR$IOS_F6970. The specified decimal length D exceeds the specified total field width W in an ES edit descriptor.
635 severe (635): D field exceeds W field in EN edit descriptor

FOR$IOS_F6971. The specified decimal length D exceeds the specified total field width W in an EN edit descriptor.
636 severe (636): Exponent of 0 not allowed in format

FOR$IOS_F6972.
637 severe (637): Integer expected in format

FOR$IOS_F6980. An edit descriptor lacked a required integer value. For example, consider the following:

      WRITE(*, 100) I, J
  100 FORMAT (I2, TL, I2)
The preceding code will cause this error because an integer is expected after TL.
638 severe (638): Initial left parenthesis expected in format

FOR$IOS_F6981. A format did not begin with a left parenthesis ( ( ).

639 severe (639): Positive integer expected in format

FOR$IOS_F6982. A zero or negative integer value was used in a format.

Negative integer values can appear only with the P edit descriptor. Integer values of 0 can appear only in the d and m fields of numeric edit descriptors.

640 severe (640): Repeat count on nonrepeatable descriptor

FOR$IOS_F6983. One or more BN, BZ, S, SS, SP, T, TL, TR, /, $, :, or apostrophe (') edit descriptors had repeat counts associated with them.

641 severe (641): Integer expected preceding H, X, or P edit descriptor

FOR$IOS_F6984. An integer did not precede a (nonrepeatable) H, X, or P edit descriptor.

The correct formats for these descriptors are nH, nX, and kP, respectively, where n is a positive integer and k is an optionally signed integer.

642 severe (642): N or Z expected after B in format

FOR$IOS_F6985. To control interpretation of embedded and trailing blanks within numeric input fields, you must specify BN (to ignore them) or BZ (to interpret them as zeros).
643 severe (643): Format nesting limit exceeded

FOR$IOS_F6986. More than 16 sets of parentheses were nested inside the main level of parentheses in a format.

644 severe (644): '.' expected in format

FOR$IOS_F6987. No period appeared between the w and d fields of a D, E, F, or G edit descriptor.

645 severe (645): Unexpected end of format

FOR$IOS_F6988. An incomplete format was used.

Improperly matched parentheses, an unfinished Hollerith (H) descriptor, or another incomplete descriptor specification can cause this error.

646 severe (646): Unexpected character in format

FOR$IOS_F6989. A character that cannot be interpreted as part of a valid edit descriptor was used in a format. For example, consider the following:

      WRITE(*, 100) I, J
  100 FORMAT (I2, TL4.5, I2)
The code will generate this error because TL4.5 is not a valid edit descriptor. An integer must follow TL.
647 severe (647): M field exceeds W field in I edit descriptor

FOR$IOS_F6990. In syntax Iw.m, the value of m cannot exceed the value of w.

648 severe (648): Integer out of range in format

FOR$IOS_F6991. An integer value specified in an edit descriptor was too large to represent as a 4-byte integer.

649 severe (649): format not set by ASSIGN

FOR$IOS_F6992. The format specifier in a READ, WRITE, or PRINT statement was an integer variable, but an ASSIGN statement did not properly assign it the statement label of a FORMAT statement in the same program unit.

650 severe (650): Separator expected in format

FOR$IOS_F6993. Within format specifications, edit descriptors must be separated by commas or slashes (/).
651 severe (651): %c or $: nonstandard edit descriptor in format

FOR$IOS_F6994.
652 severe (652): Z: nonstandard edit descriptor in format

FOR$IOS_F6995. Z is not a standard edit descriptor in format.

If you want to transfer hexadecimal values, you must use the edit descriptor form Zw[.m], where w is the field width and m is the minimum number of digits that must be in the field (including leading zeros).
653 severe (653): DOS graphics not supported under Windows NT

FOR$IOS_F6996.
654 severe (654): Graphics error

FOR$IOS_F6997. An OPEN statement in which IOFOCUS was TRUE, either explicitly or by default, failed because the new window could not receive focus. The window handle may be invalid, or closed, or there may be a memory resource problem.
655 severe (655): Using QuickWin is illegal in console application

FOR$IOS_F6998. A call to QuickWin from a console application was encountered during execution.

656 severe (656): Illegal 'ADVANCE' value

FOR$IOS_F6999. The ADVANCE option can only take the values 'YES' and 'NO'. ADVANCE='YES' is the default. ADVANCE is a READ statement option.


Run-Time Errors 657 Through 689

This section describes in detail Visual Fortran run-time errors 657 through 689.

In the following table, the first column lists error numbers returned to IOSTAT variables when an I/O error is detected.

The first line of the second column provides the message as it is displayed (following forrtl:), including the severity level, message number, and the message text. The following lines of the second column contain the status condition symbol (such as FOR$IOS_INCRECTYP) and an explanation of the message.

For information about severity levels, see the Introduction.

Number Severity Level, Number, and Message Text; Condition Symbol and Explanation
657 severe (657): DIM argument to SIZE out of range

FOR$IOS_F6702. The argument specified for DIM must be greater than or equal to 1, and less than or equal to the number of dimensions in the specified array. Consider the following:

  i = SIZE (array, DIM = dim)
In this case, 1 <= dim <= n, where n is the number of dimensions in array.
658 severe (657): Undefined POINTER used as argument to ASSOCIATED function

FOR$IOS_F6703. A POINTER used as an argument to the ASSOCIATED function must be defined; that is, assigned to a target, allocated, or nullified.
659 severe (659): Reference to uninitialized POINTER

FOR$IOS_F6704. Except in an assignment statement, a pointer must not be referenced until it has been initialized: assigned to a target, allocated or nullified.
660 severe (660): Reference to POINTER which is not associated

FOR$IOS_F6705. Except in an assignment statement and certain procedure references, a pointer must not be referenced until it has been associated: either assigned to a target or allocated.
661 severe (661): Reference to uninitialized POINTER 'pointer'

FOR$IOS_F6706. Except in an assignment statement, a pointer must not be referenced until it has been initialized: assigned to a target, allocated or nullified.
662 severe (662): reference to POINTER 'pointer' which is not associated

FOR$IOS_F6707. Except in an assignment statement and certain procedure references, a pointer must not be referenced until it has been associated: either assigned to a target or allocated.
663 severe (663): Out of range: substring starting position 'pos' is less than 1

FOR$IOS_F6708. A substring starting position must be a positive integer variable or expression that indicates a position in the string: at least 1 and no greater than the length of the string.
664 severe (664): Out of range: substring ending position 'pos' is greater than string length 'len'

FOR$IOS_F6709. A substring ending position must be a positive integer variable or expression that indicates a position in the string: at least 1 and no greater than the length of the string.
665 severe (665): Subscript 'n' of 'str' (value 'val') is out of range ('first:last')

FOR$IOS_F6710. The subscript for a substring within a string is not a valid string position: at least 1 and no greater than the length of the string.
666 severe (666): Subscript 'n' of 'str' (value 'val') is out of range ('first:*')

FOR$IOS_F6711. The subscript for a substring within a string is not a valid string position: at least 1 and no greater than the length of the string.
667 severe (667): VECTOR argument to PACK has incompatible character length

FOR$IOS_F6712. The character length of elements in the VECTOR argument to PACK is not the same as the character length of elements in the array to be packed.
668 severe (668): VECTOR argument to PACK is too small

FOR$IOS_F6713. The VECTOR argument to PACK must have at least as many elements as there are true elements in MASK (the array that controls packing).
669 severe (669): SOURCE and PAD arguments to RESHAPE have different character lengths

FOR$IOS_F6714. The character length of elements in the SOURCE and PAD arguments to PACK must be the same.
670 severe (670): Element 'n' of SHAPE argument to RESHAPE is negative

FOR$IOS_F6715. The SHAPE vector specifies the shape of the reshaped array. Since an array cannot have a negative dimension, SHAPE cannot have a negative element.
671 severe (671): SOURCE too small for specified SHAPE in RESHAPE, and no PAD

FOR$IOS_F6716. If there is no PAD array, the SOURCE argument to RESHAPE must have enough elements to make an array of the shape specified by SHAPE.
672 severe (672): Out of memory

FOR$IOS_F6717. The system ran out of memory while trying to make the array specified by RESHAPE. If possible, reset your virtual memory size through the Windows Control Panel, or close unneccessary applications and deallocate all allocated arrays that are no longer needed.
673 severe (673): SHAPE and ORDER arguments to RESHAPE have different sizes ('size1' and 'size2')

FOR$IOS_F6718. ORDER specifies the order of the array dimensions given in SHAPE, and they must be vectors of the same size.
674 severe (674): Element 'n' of ORDER argument to RESHAPE is out of range ('range')

FOR$IOS_F6719. The ORDER argument specifies the order of the dimensions of the reshaped array, and it must be a permuted list of (1, 2, ..., n) where n is the highest dimension in the reshaped array.
675 severe (675): Value 'val' occurs twice in ORDER argument to RESHAPE

FOR$IOS_F6720. The ORDER vector specifies the order of the dimensions of the reshaped array, and it must be a permuted list of (1, 2, ..., n) where n is the highest dimension in the reshaped array. No dimension can occur twice.
676 severe (676): Impossible nextelt overflow in RESHAPE

FOR$IOS_F6721.
677 severe (677): Invalid value 'dim' for argument DIM for SPREAD of rank 'rank' source

FOR$IOS_F6722. The argument specified for DIM to SPREAD must be greater than or equal to 1, and less than or equal to one larger than the number of dimensions (rank) of SOURCE. Consider the following statement:

  result = SPREAD (SOURCE= array, DIM = dim, NCOPIES = k)
In this case, 1 <= dim <= n + 1, where n is the number of dimensions in array.
678 severe (678): Complex zero raised to power zero

FOR$IOS_F6723. Zero of any type (complex, real, or integer) cannot be raised to zero power.
679 severe (679): Complex zero raised to negative power

FOR$IOS_F6724. Zero of any type (complex, real, or integer) cannot be raised to a negative power. Raising to a negative power inverts the operand.
680 severe (680): Impossible error in NAMELIST input

FOR$IOS_F6725.
681 severe (681):DIM argument to CSHIFT ('dim') is out of range

FOR$IOS_F6726. The optional argument DIM specifies the dimension along which to perform the circular shift, and must be greater than or equal to 1 and less than or equal to the number of dimensions in the array to be shifted. That is, 1 <= DIM <= n, where n is the number of dimensions in the array to be shifted.
682 severe (682): DIM argument ('dim') to CSHIFT is out of range (1:'n')

FOR$IOS_F6727. The optional argument DIM specifies the dimension along which to perform the circular shift, and must be greater than or equal to 1 and less than or equal to the number of dimensions in the array to be shifted. That is, 1 <= DIM <= n, where n is the number of dimensions in the array to be shifted.
683 severe (683): Shape mismatch (dimension 'dim') between ARRAY and SHIFT in CSHIFT

FOR$IOS_F6728. The SHIFT argument to CSHIFT must be either scalar or an array one dimension smaller than the shifted array. If an array, the shape of the SHIFT must conform to the shape of the array being shifted in every dimension except the one being shifted along.
684 severe (684): Internal error - bad arguments to CSHIFT_CA

FOR$IOS_F6729.
685 severe (685): Internal error - bad arguments to CSHIFT_CAA

FOR$IOS_F6730.
686 severe (686): DATE argument to DATE_AND_TIME is too short (LEN='len')

FOR$IOS_F6731. The character DATE argument must have a length of at least 8 to contain the complete value.
687 severe (687): TIME argument to DATE_AND_TIME is too short (LEN='len')

FOR$IOS_F6732. The character TIME argument must have a length of at least 10 to contain the complete value.
688 severe (688): ZONE argument to DATE_AND_TIME is too short (LEN='len')

FOR$IOS_F6733. The character ZONE argument must have a length of at least 5 to contain the complete value.
689 severe (689): VALUES argument to DATE_AND_TIME is too small ('size' elements)

FOR$IOS_F6734. The integer VALUES argument must be a one-dimensional array with a size of at least 8 to hold all returned values.


Run-Time Errors 690 Through 719

This section describes in detail Visual Fortran run-time errors 690 through 719.

In the following table, the first column lists error numbers returned to IOSTAT variables when an I/O error is detected.

The first line of the second column provides the message as it is displayed (following forrtl:), including the severity level, message number, and the message text. The following lines of the second column contain the status condition symbol (such as FOR$IOS_INCRECTYP) and an explanation of the message.

For information about severity levels, see the Introduction.

Number | Severity Level, Number, and Message Text; Condition Symbol and Explanation
690 | severe (690): Out of range: DIM argument to COUNT has value 'dim' FOR$IOS_F6735. The optional argument DIM specifies the dimension along which to count true elements of MASK, and must be greater than or equal to 1 and less than or equal to the number of dimensions in MASK. That is, 1 <= DIM <= n, where n is the number of dimensions in MASK.
691 | severe (691): Out of range: DIM argument to COUNT has value 'dim' with MASK of rank 'rank' FOR$IOS_F6736. The optional argument DIM specifies the dimension along which to count true elements of MASK, and must be greater than or equal to 1 and less than or equal to the number of dimensions (rank) in MASK. That is, 1 <= DIM <= n, where n is the number of dimensions in MASK.
692 | severe (692): Out of range: DIM argument to PRODUCT has value 'dim' FOR$IOS_F6737. The optional argument DIM specifies the dimension along which to compute the product of elements in an array, and must be greater than or equal to 1 and less than or equal to the number of dimensions in the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array holding the elements to be multiplied.
693 | severe (693): Out of range: DIM argument to PRODUCT has value 'dim' with ARRAY of rank 'rank' FOR$IOS_F6738. The optional argument DIM specifies the dimension along which to compute the product of elements in an array, and must be greater than or equal to 1 and less than or equal to the number of dimensions (rank) of the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array holding the elements to be multiplied.
694 | severe (694): Out of range: DIM argument to SUM has value 'dim' with ARRAY of rank 'rank' FOR$IOS_F6739. The optional argument DIM specifies the dimension along which to sum the elements of an array, and must be greater than or equal to 1 and less than or equal to the number of dimensions (rank) of the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array holding the elements to be summed.
695 | severe (695): Real zero raised to zero power FOR$IOS_F6740. Zero of any type (real, complex, or integer) cannot be raised to zero power.
696 | severe (696): Real zero raised to negative power FOR$IOS_F6741. Zero of any type (real, complex, or integer) cannot be raised to a negative power. Raising to a negative power inverts the operand.
697 | severe (697): Out of range: DIM argument to SUM has value 'dim' FOR$IOS_F6742. The optional argument DIM specifies the dimension along which to sum the elements of an array, and must be greater than or equal to 1 and less than or equal to the number of dimensions in the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array holding the elements to be summed.
698 | severe (698): DIM argument ('dim') to EOSHIFT is out of range (1:'n') FOR$IOS_F6743. The optional argument DIM specifies the dimension along which to perform an end-off shift in an array, and must be greater than or equal to 1 and less than or equal to the number of dimensions in the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array holding the elements to be shifted.
699 | severe (699): Shape mismatch (dimension 'dim') between ARRAY and BOUNDARY in EOSHIFT FOR$IOS_F6744. The BOUNDARY argument to EOSHIFT must be either scalar or an array one dimension smaller than the shifted array. If an array, the shape of the BOUNDARY must conform to the shape of the array being shifted in every dimension except the one being shifted along.
700 | severe (700): DIM argument to EOSHIFT is out of range ('dim') FOR$IOS_F6745. The optional argument DIM specifies the dimension along which to perform an end-off shift in an array, and must be greater than or equal to 1 and less than or equal to the number of dimensions in the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array holding the elements to be shifted.
701 | severe (701): Shape mismatch (dimension 'dim') between ARRAY and SHIFT in EOSHIFT FOR$IOS_F6746. The SHIFT argument to EOSHIFT must be either scalar or an array one dimension smaller than the shifted array. If an array, the shape of the SHIFT must conform to the shape of the array being shifted in every dimension except the one being shifted along.
702 | severe (702): BOUNDARY argument to EOSHIFT has wrong LEN ('len1 instead of len2') FOR$IOS_F6747. The character length of elements in the BOUNDARY argument and in the array being end-off shifted must be the same.
703 | severe (703): BOUNDARY has LEN 'len' instead of 'len' to EOSHIFT FOR$IOS_F6748.
704 | severe (704): Internal error - bad arguments to EOSHIFT FOR$IOS_F6749.
705 | severe (705): GETARG: value of argument 'num' is out of range FOR$IOS_F6750. The value used for the number of the command-line argument to retrieve with GETARG must be 0 or a positive integer. If the number of the argument to be retrieved is greater than the actual number of arguments, blanks are returned, but no error occurs.
706 | severe (706): FLUSH: value of LUNIT 'num' is out of range FOR$IOS_F6751. The unit number specifying which I/O unit to flush to its associated file must be an integer between 0 and 2**31-1, inclusive. If the unit number is valid, but the unit is not opened, error F6752 is generated.
707 | severe (707): FLUSH: Unit 'n' is not connected FOR$IOS_F6752. The I/O unit specified to be flushed to its associated file is not connected to a file.
708 | severe (708): Invalid string length ('len') to ICHAR FOR$IOS_F6753. The character argument to ICHAR must have length 1.
709 | severe (709): Invalid string length ('len') to IACHAR FOR$IOS_F6754. The character argument to IACHAR must have length 1.
710 | severe (710): Integer zero raised to negative power FOR$IOS_F6755. Zero of any type (integer, real, or complex) cannot be raised to a negative power. Raising to a negative power inverts the operand.
711 | severe (711): INTEGER zero raised to zero power FOR$IOS_F6756. Zero of any type (integer, real, or complex) cannot be raised to zero power.
712 | severe (712): SIZE argument ('size') to ISHFTC intrinsic out of range FOR$IOS_F6757. The argument SIZE must be positive and must not exceed the bit size of the integer being shifted. The bit size of this integer can be determined with the function BIT_SIZE.
713 | severe (713): SHIFT argument ('shift') to ISHFTC intrinsic out of range FOR$IOS_F6758. The argument SHIFT to ISHFTC must be an integer whose absolute value is less than or equal to the number of bits being shifted: either all bits in the number being shifted or a subset specified by the optional argument SIZE.
714 | severe (714): Out of range: DIM argument to LBOUND has value 'dim' FOR$IOS_F6759. The optional argument DIM specifies the dimension whose lower bound is to be returned, and must be greater than or equal to 1 and less than or equal to the number of dimensions in the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array.
715 | severe (715): Out of range: DIM argument ('dim') to LBOUND greater than ARRAY rank 'rank' FOR$IOS_F6760. The optional argument DIM specifies the dimension whose lower bound is to be returned, and must be greater than or equal to 1 and less than or equal to the number of dimensions (rank) in the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array.
716 | severe (716): Out of range: DIM argument to MAXVAL has value 'dim' FOR$IOS_F6761. The optional argument DIM specifies the dimension along which maximum values are returned, and must be greater than or equal to 1 and less than or equal to the number of dimensions in the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array.
717 | severe (717): Out of range: DIM argument to MAXVAL has value 'dim' with ARRAY of rank 'rank' FOR$IOS_F6762. The optional argument DIM specifies the dimension along which maximum values are returned, and must be greater than or equal to 1 and less than or equal to the number of dimensions (rank) in the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array.
718 | severe (718): Cannot allocate temporary array -- out of memory FOR$IOS_F6763. There is not enough memory space to hold a temporary array. Dynamic memory allocation is limited by several factors, including swap file size and memory requirements of other applications that are running. If you encounter an unexpectedly low limit, you might need to reset your virtual memory size through the Windows Control Panel or redefine the swap file size. Allocated arrays that are no longer needed should be deallocated.
719 | severe (719): Attempt to DEALLOCATE part of a larger object FOR$IOS_F6764. An attempt was made to DEALLOCATE a pointer to an array subsection or an element within a derived type. The whole data object must be deallocated; parts cannot be deallocated.


Run-Time Errors 720 Through 759

This section describes in detail Visual Fortran run-time errors 720 through 759.

In the following table, the first column lists error numbers returned to IOSTAT variables when an I/O error is detected.

The first line of the second column provides the message as it is displayed (following forrtl:), including the severity level, message number, and the message text. The following lines of the second column contain the status condition symbol (such as FOR$IOS_INCRECTYP) and an explanation of the message.

For information about severity levels, see the Introduction.

Number Severity Level, Number, and Message Text; Condition Symbol and Explanation
720 severe (720): Pointer in DEALLOCATE is ASSOCIATED with an ALLOCATABLE array

FOR$IOS_F6765. Deallocating a pointer associated with an allocatable target is illegal. Instead, deallocate the target the pointer points to, which frees memory and disassociates the pointer.
721 severe (721): Attempt to DEALLOCATE an object which was not allocated

FOR$IOS_F6766. You cannot deallocate an array unless it has been previously allocated. You cannot deallocate a pointer whose target was not created by allocation. The intrinsic function ALLOCATED can be used to determine whether an allocatable array is currently allocated.
722 severe (722): Cannot ALLOCATE scalar POINTER -- out of memory

FOR$IOS_F6767. There is not enough memory space to allocate the pointer.

Dynamic memory allocation is limited by several factors, including swap file size and memory requirements of other applications that are running. If you encounter an unexpectedly low limit, you might need to reset your virtual memory size through the Windows Control Panel or redefine the swap file size. Allocated arrays that are no longer needed should be deallocated.
723 severe (723): DEALLOCATE: object not allocated/associated

FOR$IOS_F6768. You cannot deallocate an array unless it has been previously allocated. You cannot deallocate a pointer whose target was not created by allocation, or a pointer that has undefined association status.

The intrinsic function ALLOCATED can be used to determine whether an allocatable array is currently allocated.
724 severe (724): Cannot ALLOCATE POINTER array -- out of memory

FOR$IOS_F6769. There is not enough memory space to allocate the POINTER array.

Dynamic memory allocation is limited by several factors, including swap file size and memory requirements of other applications that are running. If you encounter an unexpectedly low limit, you might need to reset your virtual memory size through the Windows Control Panel or redefine the swap file size. Allocated arrays that are no longer needed should be deallocated.
725 severe (725): DEALLOCATE: Array not allocated

FOR$IOS_F6770. It is illegal to DEALLOCATE an array that is not allocated. You can check the allocation status of an array before deallocating with the ALLOCATED function.
726 severe (726): DEALLOCATE: Character array not allocated

FOR$IOS_F6771. It is illegal to DEALLOCATE an array that is not allocated. You can check the allocation status of an array before deallocating with the ALLOCATED function.
727 severe (727): Cannot ALLOCATE allocatable array -- out of memory

FOR$IOS_F6772. There is not enough memory space to hold the array.

Dynamic memory allocation is limited by several factors, including swap file size and memory requirements of other applications that are running. If you encounter an unexpectedly low limit, you might need to reset your virtual memory size through the Windows Control Panel or redefine the swap file size. Allocated arrays that are no longer needed should be deallocated.
728 severe (728): Cannot allocate automatic object -- out of memory

FOR$IOS_F6773. There is not enough memory space to hold the automatic data object.

Dynamic memory allocation is limited by several factors, including swap file size and memory requirements of other applications that are running. If you encounter an unexpectedly low limit, you might need to reset your virtual memory size through the Windows Control Panel or redefine the swap file size. Allocated arrays that are no longer needed should be deallocated.

An automatic data object is an object that is declared in a procedure subprogram or interface, is not a dummy argument, and depends on a nonconstant expression. For example:

  SUBROUTINE  EXAMPLE (N)
     DIMENSION A (N, 5), B(10*N)
The arrays A and B in the example are automatic data objects.
729 severe (729): DEALLOCATE failure: ALLOCATABLE array is not ALLOCATED

FOR$IOS_F6774. It is illegal to DEALLOCATE an array that is not allocated. You can check the allocation status of an array before deallocating with the ALLOCATED function.
730 severe (730): Out of range: DIM argument to MINVAL has value 'dim'

FOR$IOS_F6775. The optional argument DIM specifies the dimension along which minimum values are returned, and must be greater than or equal to 1 and less than or equal to the number of dimensions in the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array.
731 severe (731): Out of range: DIM argument to MINVAL has value 'dim' with ARRAY of rank 'rank'

FOR$IOS_F6776. The optional argument DIM specifies the dimension along which minimum values are returned, and must be greater than or equal to 1 and less than or equal to the number of dimensions (rank) in the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array.
732 severe (732): P argument to MOD is double precision zero

FOR$IOS_F6777. MOD(A,P) is computed as A - INT(A/P) * P. So, P cannot be zero.
733 severe (733): P argument to MOD is integer zero

FOR$IOS_F6778. MOD(A,P) is computed as A - INT(A/P) * P. So, P cannot be zero.
734 severe (734): P argument to MOD is real zero

FOR$IOS_F6779. MOD(A,P) is computed as A - INT(A/P) * P. So, P cannot be zero.
735 severe (735): P argument to MODULO is real zero

FOR$IOS_F6780. MODULO(A,P) for real numbers is computed as A - FLOOR(A/P) * P. So, P cannot be zero.
736 severe (736): P argument to MODULO is zero

FOR$IOS_F6781. In the function, MODULO(A,P), P cannot be zero.
737 severe (737): Argument S to NEAREST is zero

FOR$IOS_F6782. The sign of the S argument to NEAREST(X,S) determines the direction of the search for the nearest number to X, and cannot be zero.
738 severe (738): Heap storage exhausted

FOR$IOS_F6783.
739 severe (739): PUT argument to RANDOM_SEED is too small

FOR$IOS_F6784. The integer array PUT must be greater than or equal to the number of integers the processor uses to set the seed value. This number can be determined by calling RANDOM_SEED with the SIZE argument. For example:

  INTEGER, ALLOCATABLE SEED
  CALL RANDOM_SEED( )           ! initialize processor
  CALL RANDOM_SEED(SIZE = K)    ! get size of seed
  ALLOCATE SEED(K)              ! allocate array
  CALL RANDOM_SEED(PUT = SEED)  ! set the seed
Note that RANDOM_SEED can be called with at most one argument at a time.
740 severe (740): GET argument to RANDOM_SEED is too small

FOR$IOS_F6785. The integer array GET must be greater than or equal to the number of integers the processor uses to set the seed value. This number can be determined by calling RANDOM_SEED with the SIZE argument. For example:

  INTEGER, ALLOCATABLE SEED
  CALL RANDOM_SEED( )           ! initialize processor
  CALL RANDOM_SEED(SIZE = K)    ! get size of seed
  ALLOCATE SEED(K)              ! allocate array
  CALL RANDOM_SEED(GET = SEED)  ! get the seed
Note that RANDOM_SEED can be called with at most one argument at a time.
741 severe (741): Recursive i/o reference

FOR$IOS_F6786.
742 severe (742): Argument to SHAPE intrinsic is not PRESENT

FOR$IOS_F6787.
743 severe (743): Out of range: DIM argument to UBOUND had value 'dim'

FOR$IOS_F6788. The optional argument DIM specifies the dimension whose upper bound is to be returned, and must be greater than or equal to 1 and less than or equal to the number of dimensions in the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array.
744 severe (744): DIM argument ('dim') to UBOUND greater than ARRAY rank 'rank'

FOR$IOS_F6789. The optional argument DIM specifies the dimension whose upper bound is to be returned, and must be greater than or equal to 1 and less than or equal to the number of dimensions (rank) in the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array.
745 severe (745): Out of range: UBOUND of assumed-size array with DIM==rank ('rank')

FOR$IOS_F6790. The optional argument DIM specifies the dimension whose upper bound is to be returned.

An assumed-size array is a dummy argument in a subroutine or function, and the upper bound of its last dimension is detemined by the size of actual array passed to it. Assumed-size arrays have no determined shape, and you cannot use UBOUND to determine the extent of the last dimension. You can use UBOUND to determine the upper bound of one of the fixed dimensions, in which case you must pass the dimension number along with the array name.
746 severe (746): Out of range: DIM argument ('dim') to UBOUND greater than ARRAY rank

FOR$IOS_F6791. The optional argument DIM specifies the dimension whose upper bound is to be returned, and must be greater than or equal to 1 and less than or equal to the number of dimensions (rank) in the array. That is, 1 <= DIM <= n, where n is the number of dimensions in array.
747 severe (747): Shape mismatch: Dimension 'shape' extents are 'ext1' and 'ext2'

FOR$IOS_F6792.
748 severe (748): Illegal POSITION value

FOR$IOS_F6793. An illegal value was used with the POSITION specifier.

POSITION accepts the following values:

  • 'ASIS' (the default)
  • 'REWIND' - on Fortran I/O systems, this is the same as 'ASIS'
  • 'APPEND'
749 severe (749): Illegal ACTION value

FOR$IOS_F6794. An illegal value was used with the ACTION specifier.

ACTION accepts the following values:

  • 'READ'
  • 'WRITE'
  • 'READWRITE' - the default
750 severe (750): DELIM= specifier not allowed for an UNFORMATTED file

FOR$IOS_F6795. The DELIM specifier is only allowed for files connected for formatted data transfer. It is used to delimit character constants in list-directed an namelist output.
751 severe (751): Illegal DELIM value

FOR$IOS_F6796. An illegal value was used with the DELIM specifier.

DELIM accepts the following values:

  • 'APOSTROPHE'
  • 'QUOTE'
  • 'NONE' - the default
752 severe (752): PAD= specifier not allowed for an UNFORMATTED file

FOR$IOS_F6797. The PAD specifier is only allowed for formatted input records. It indicates whether the formatted input record is padded with blanks when an input list and format specification requires more data than the record contains.
753 severe (753): Illegal PAD= value

FOR$IOS_F6798. An illegal value was used with the PAD specifier.

PAD accepts the following values:

  • 'NO'
  • 'YES' - the default
754 severe (754): Illegal CARRIAGECONTROL= value

FOR$IOS_F6799. An illegal value was used with the CARRIAGECONTROL specifier.

CARRIAGECONTROL accepts the following values:

  • 'FORTRAN' - default if /vms is specified or the unit is connected to a terminal or console
  • 'LIST' - default for formatted files
  • 'NONE' - default for unformatted files
755 severe (755): SIZE= specifier only allowed with ADVANCE='NO'

FOR$IOS_F6800. The SIZE specifier can only appear in a formatted, sequential READ statement that has the specifier ADVANCE='NO' (indicating nonadvancing input).
756 severe (756): Illegal character in binary input

FOR$IOS_F6801.
757 severe (757): Illegal character in octal input

FOR$IOS_F6802.
758 severe (758): End of record encountered

FOR$IOS_F6803.
759 severe (759): Illegal subscript in namelist input record

FOR$IOS_F6804.


Linker Tools Messages

The following topics cover linker tools errors and warnings (LNKnnnn), which can be generated LINK, LIB, DUMPBIN, and EDITBIN:

  • Linker Errors LNK1000 to LNK1149
  • Linker Errors LNK1152 to LNK1189
  • Linker Errors LNK1190 to LNK1581
  • Linker Errors LNK2001 to LNK2014
  • Linker Warnings LNK4001 to LNK4039
  • Linker Warnings LNK4040 to LNK4069
  • Linker Warnings LNK4070 to LNK4099
  • Linker Warnings LNK4102 to LNK4549
  • Linker Warnings LNK6001 to LNK6026
  • Corrupt Object File Explanation

Corrupt Object File Explanation:

Sometimes the linker is unable to process your object files because they are corrupt. Besides the usual causes of corrupt files such as network problems or exposing a floppy disk to a magnetic field, sometimes the compiler writes an incorrect object file, which you should report to technical support.

After you have ruled out a hardware, operating system, or network problem as the cause of the corrupt object file, you should try the tips below because sometimes by changing compiler options and recompiling, the compiler will write a non-corrupt object file. Here are some things to try when recompiling:

  • Turn off optimization with the /nooptimize (/Od, Disable) option.
  • Use a different code generation option. See the /tune (/G, Optimize for Processor) options.
  • Change the order of functions and global variables.

With Visual C++ mixed-language programs:

  • Disable incremental compilation with the /Gi- (Enable Incremental Compilation) option.
  • Disable minimal rebuild with the /Gm- (Enable Minimal Rebuild) option.
  • Compile with the /Gy (Enable Function-Level Linking) option to package functions.


Linker Errors LNK1000 to LNK1149

Linker Tools Error LNK1000
unknown error; consult documentation for technical support options
Note the circumstances of the error, try to isolate the problem and create a reproducible test case, then contact technical support.

Linker Tools Error LNK1101
incorrect MSPDBxx.DLL version; recheck installation of this product
The version of MSPDBxx.DLL available on your system does not match the version required by this tool.

Linker Tools Error LNK1102
out of memory
 There was not enough memory for the tool to run. Probably the paging file exceeded available disk space. If a shortage of disk space is not the cause, note the circumstances of the error, try to isolate the problem and create a reproducible test case, then request technical support.

Linker Tools Error LNK1103
debugging information corrupt; recompile module
 Probably the compilation was terminated before a valid object file was created. Recompile the given object file. If recompiling does not correct the problem, note the circumstances of the error, try to isolate the problem and create a reproducible test case, then consult technical support. See Corrupt Object File for more information.

Linker Tools Error LNK1104
cannot open file "filename"
 The tool could not open the given file. One of the following may be a cause:

  • There was not enough disk space.
  • The file does not exist.
  • The filename or its path was incorrectly specified.
  • The specified drive is invalid.
  • The file does not have the appropriate permissions.
  • The path for filename expands to more than 260 characters.
  • If the given file is named LNKn, which is a filename generated by the linker for a temporary file, then the directory specified in the TMP environment variable may not exist, or more than one directory is specified for the TMP environment variable. (Only one directory path should be specified for the TMP environment variable.)
  • If the error occurs on the executable filename, an earlier version of the executable may still be running. You will need to terminate the executable before linking it. In Windows NT (including Windows 2000) or Windows 95, you can use the utility PVIEW to look for and kill instances of the application.
  • If the error message occurs for a library name, and you recently ported the .MAK file from a previous Microsoft Visual C++ development environment, the library may no longer be valid. Ensure that the library still exists in this circumstance.
  • If the error message occurs for a library name such as CONSOLE.LIB, and you included object modules from an older Fortran development environment such as Microsoft Fortran PowerStation, recompile all source files with Visual Fortran to create new object files and libraries.

Linker Tools Error LNK1105
cannot close file "filename"
 The tool could not close the given file. Possibly there was insufficient disk space available.

Linker Tools Error LNK1106
invalid file or disk full: cannot seek to location
 The tool could not read or write to location in a memory-mapped file:

  • Your disk may be too full to complete the link. Free up some space and try the link again.
  • The error may be a result of trying to link over a network. Some networks do not fully support the memory-mapped files used by the linker. Try linking on your local disk to see if that fixes the problem.
  • There may be a bad block on your disk. Although the operating system and disk hardware should have detected such an error, you may want to run a disk checking program.

Linker Tools Error LNK1107
invalid or corrupt file: cannot read at location
 The tool could not read the file. Recreate the file.

Linker Tools Error LNK1108
cannot write file at location
 The tool could not write to the file. One of the following may be a cause:

  • There was not enough disk space to create the file.
  • The drive being written to was not available, possibly due to a network problem.

Linker Tools Error LNK1109
cannot remove file "filename"
 LIB could not delete the given file. Before LIB writes the new version of a library, it removes the existing library file. One of the following may be a cause:

  • The given file does not have the appropriate permissions.
  • The drive containing the file was not available, possibly due to a network problem.

Linker Tools Error LNK1110
cannot rename file "filename"
 LIB could not rename the given file. When LIB builds a new version of a library, it creates a temporary file, then renames the file. One of the following may be a cause:

  • The given file does not have the appropriate permissions.
  • The drive containing the file was not available, possibly due to a network problem.

Linker Tools Error LNK1111
invalid /BASE argument "argument"
 The /BASE option was incorrectly specified. Either no argument was specified or argument is not a number.

Linker Tools Error LNK1112
module machine type "type1" conflicts with target machine type "type2"
 The object files specified as input were compiled for different machine types.

Linker Tools Error LNK1113
invalid machine type
 The machine type specified in the object header is not valid. Probably the file is corrupt. Rebuild the object. See Corrupt Object File for more information.

Linker Tools Error LNK1115
/MACHINE option required
 LINK or LIB cannot determine the machine type for objects that are provided entirely from libraries. Either specify the /MACHINE option with the appropriate machine type or specify at least one object file in the input.

Linker Tools Error LNK1117
syntax error in option "option"
 The given option was not correctly specified.

Linker Tools Error LNK1118
syntax error in keyword statement
 The given module-definition statement was not correctly specified.

Linker Tools Error LNK1119
invalid ordinal number "argument"
 The argument following the at sign (@) in an ordinal specification was not a valid number. An ordinal number is an optional argument in either an /EXPORT option in a LINK or LIB command or an EXPORTS statement in a module-definition file. It is an index into the exports table. The number must be an integer in the range 1-65535.

Linker Tools Error LNK1120
number unresolved externals
 Error LNK1120 gives you a count (number) of unresolved externals for this link. The conditions that cause unresolved externals are described with error LNK2001 (see Linker Errors LNK2001 to LNK2014), which precedes this error message (once for each unresolved external).

Linker Tools Error LNK1121
duplicate ordinal number "number"
 The given ordinal number was specified more than once in either an /EXPORT option in a LINK or LIB command or an EXPORTS statement in a module-definition file. Ordinal numbers must be unique integers in the range 1-65535.

Linker Tools Error LNK1123
failure during conversion to COFF: file invalid or corrupt
 The object or resource could not be converted to COFF. This tool requires the format of all input files to be COFF. If an input file is not COFF, the tool runs a conversion tool, either CVTOMF (to convert 32-bit OMF objects) or CVTRES (to convert resource files). This error is preceded by errors or warnings from the conversion tool. One of the following may be a cause:

  • The file is corrupt.
  • The file is not a valid file type. An example of an invalid type is a 16-bit OMF object.

Linker Tools Error LNK1127
library is corrupt
 The library file is corrupt. Rebuild the library.

Linker Tools Error LNK1129
cannot find resolution for weak extern symbol
 The given weak external symbol does not have a default resolution. Probably the symbol table is corrupt. Rebuild the object file. See Corrupt Object File for more information.

Linker Tools Error LNK1130
Linker miscalc (base relocations off by number)
 There was not enough space in the image to write base relocations.

Linker Tools Error LNK1131
no library file specified
The LIB /EXTRACT command required a library as input, but a library filename was not specified.

Linker Tools Error LNK1132
invalid format for MS-DOS stub file "filename"
 The filename specified with the /STUB option was not a valid real-mode MS-DOS executable (.EXE) file.

Linker Tools Error LNK1136
invalid or corrupt file
 The input file either has a corrupt header or is zero size or abnormally small. See Corrupt Object File for more information.

Linker Tools Error LNK1137
invalid argument specified with /SECTION
 Either the name or the attributes argument to the /SECTION option is specified incorrectly.

Linker Tools Error LNK1140
too many modules for program database; relink with /PDB:NONE
 The project contains more than 4096 modules. One of the following is a solution:

  • Relink using /PDB:NONE.
  • Compile some modules without debugging information.
  • Reduce the number of modules.

Linker Tools Error LNK1141
failure during build of exports file
 LINK could not build the exports (.EXP) file. Causes of this error include system problems such as insufficient memory and syntax errors in options or module-definition statements. This error is preceded by another error that gives additional information.

Linker Tools Error LNK1143
invalid or corrupt file: no symbol for COMDAT section number
 The object file is corrupt. Rebuild the file. See Corrupt Object File for more information.

Linker Tools Error LNK1144
error with LINK_REPRO var; cannot open "filename"
 The linker could not create filename. One of the following may be a cause:

  • Check that you've set your LINK_REPRO environment variable to an existing directory and not the current directory.
  • Make sure there are no read-only files in the directory.
  • Make sure none of the files in the LINK_REPRO directory are open by another process, because the linker needs to write to them.

Linker Tools Error LNK1145
/MERGE created circular link for section "section"
 You attempted to merge a section into itself. Check the /MERGE options.

Linker Tools Error LNK1146
no argument specified with option "option"
 The given option requires an argument.

Linker Tools Error LNK1147
invalid number specified with option "option"
 The argument to the given option was specified incorrectly.

Linker Tools Error LNK1148
failure during conversion to COFF: cannot copy temp file filename
 EDITBIN could not convert the input file to COFF. When EDITBIN converts a file, it creates a temporary file, then copies the file. One of the following may be a cause:

  • The given file does not have the appropriate permissions.
  • There was not enough disk space to create the file.
  • The drive being written to was not available, possibly due to a network problem.

Linker Tools Error LNK1149
output filename matches input filename "filename"
 The output filename specified with the /OUT or /IMPLIB option was the same as an input file.

Return to Main Linker Error Page


Linker Errors LNK1152 to LNK1189

Linker Tools Error LNK1152
cannot resolve one or more undecorated symbols
 This error is preceded by one warning LNK4022 for each undecorated symbol that could not be resolved and by at least two warnings LNK4006 for the duplicate symbols found for the undecorated symbol.

Linker Tools Error LNK1153
/VXD command-line option required
 You attempted to build a virtual device driver without the /VXD option. Relink with the /VXD option.

Linker Tools Error LNK1154
specified import library filename matches exports file "filename"
 The filename specified with LINK /IMPORT or with LIB /DEF /OUT conflicted with the filename given by LINK or LIB to the exports file, which is formed from the base name of the main output file and the extension .EXP.

Linker Tools Error LNK1155
special symbol "symbol" already defined
 The given symbol is reserved for use by LINK.

Linker Tools Error LNK1156
.sbss section not supported
 An object file contained an .sbss section.

Linker Tools Error LNK1157
fixup overflow; offset of target symbol "symbol" greater than +-8MB
The VXD is too large, or the sections are not arranged properly.

Linker Tools Error LNK1158
cannot run "filename"
 The given executable file called by LINK is not in the directory that contains LINK and is not in a directory specified in the PATH environment variable.

Linker Tools Error LNK1159
no output file specified
 No name was specified for the main output file (executable file or DLL). LINK derives the default name of the output file from the base name of the first object file. If no object files are specified, and if the /OUT option is not used, this error occurs.

Linker Tools Error LNK1160
library with zero objects not allowed
 An attempt was made to remove an object from a library that contained only that object. The object was not removed.

Linker Tools Error LNK1161
invalid export specification
 Either the /EXPORT option or the EXPORTS module-definition statement incorrectly specified an export. A possible cause is a typing error.

Linker Tools Error LNK1162
expected aux symbol for comdat section number
 The linker expected to find an auxiliary symbol table for the indicated COMDAT but could not. The object file is probably corrupt. See Corrupt Object File for more information.

Linker Tools Error LNK1163
invalid selection for comdat section number
 The byte in the object file indicating the type of COMDAT section is invalid. The object file is probably corrupt. See Corrupt Object File for more information.

Linker Tools Error LNK1164
section section alignment (number) greater than /ALIGN value
 The alignment size for the given section in the object file exceeds the value specified with the /ALIGN option. The /ALIGN value must be a power of 2 and must equal or exceed the section alignment given in the object file. Either recompile with a smaller section alignment or increase the /ALIGN value.

Linker Tools Error LNK1165
link failed because of fixup errors
 The build failed due to fixup errors. The /FORCE or /FORCE:UNRESOLVED option overrides this error.

Linker Tools Error LNK1166
cannot adjust code at offset=offset, va=value
 LINK was unable to pad the code as required. Certain instructions are not allowed to cross page boundaries on some processors. LINK attempts to add pads to correct this situation. In this case, LINK could not work around the problem.

Linker Tools Error LNK1167
file contains relocs but header has no machine type
 A converted COFF object did not have a machine type specified in its header. One cause of this error is omitting a machine type when converting a .RES file in a separate step before linking.

Linker Tools Error LNK1168
cannot open filename for writing
 The given file does not have write permission.

Linker Tools Error LNK1169
one or more multiply defined symbols found
 The build failed due to multiple definitions of one or more symbols. This error is preceded by error LNK2005. The /FORCE or /FORCE:MULTIPLE option overrides this error.

Linker Tools Error LNK1170
line in command file contains limit or more characters
 The length of a line in a command file must be less than the given limit.

Linker Tools Error LNK1171
unable to load filename
 The given DLL was unavailable. The possible locations for the DLL are the current directory, the system directory, the Windows directory, and the directories specified in the PATH environment variable.

Linker Tools Error LNK1172
more than one object with the name "object" found; rename object(s) or relink /PDB:NONE
 A library contained two or more objects with the same name. Do one of the following:

  • Rename the objects using unique names and rebuild the library.
  • Link using the /PDB:NONE option.

Linker Tools Error LNK1173
unable to find entrypoint function in filename
 The given function does not exist in the given DLL.

Linker Tools Error LNK1174
unable to /REBASE filename; not a valid Win32 image
 The format of the given file was invalid.

Linker Tools Error LNK1175
failed to /REBASE filename
 The rebase operation failed on the given file.

Linker Tools Error LNK1177
TOC size limit exceeded
 The linker was unable to create a TOC (Table of Contents) in your image file. The limit is 2048 entries in the TOC.

Linker Tools Error LNK1178
missing MODEND record; file is invalid or corrupt
 The linker tool tried to convert an OMF object module to COFF format but could not find an expected MODEND (module end) record in the OMF object. The OMF object module is corrupt and needs to be recreated or recopied. See Corrupt Object File for more information.

Linker Tools Error LNK1179
invalid or corrupt file: duplicate comdat comdat
 An object module contained two or more COMDATs with the same name. One possible cause is if you use the Visual C++ /H option with the Visual C++ /Gy option. The /H option limits the length of external names, and the /Gy option packages functions in COMDATs.

Linker Tools Error LNK1180
insufficient disk space to complete link
 The linker tool was unable to complete a file operation since the operating system reported that the disk is full. Free up space on your local and network drives (if you are writing files there).

Linker Tools Error LNK1181
cannot open input file "filename"
 The linker tool could not find "filename" because it does not exist or the path was not found.

Linker Tools Error LNK1182
cannot have more than 64K exports
 You have reached the linker's limit of 65,536 exports.

Linker Tools Error LNK1183
invalid or corrupt file: extended relocation count number less than 65535
 The COFF object file is corrupt since it contains an extended relocation count that is less than 0xFFFF. See Corrupt Object File for more information.

Linker Tools Error LNK1184
invalid section name "section" specified in option or directive "option"
 You gave the linker an invalid section name in option. Invalid section names contain "$" or blanks.

Linker Tools Error LNK1185
invalid section name "section" specified
 You gave the linker an invalid section name in a .DEF file. Invalid section names contain "$" or blanks.

Linker Tools Error LNK1186
invalid or corrupt COFF object; reloc to undefined static symbol "symbol"
 Your COFF object module is corrupt since it contains a relocation entry for an undefined static symbol. See Corrupt Object File for more information.

Linker Tools Error LNK1187
Corrupt object - unmatched name relocation; ignored
 Your object file contains bad relocation information. Recopy or recreate the object file. See Corrupt Object File for more information.

Linker Tools Error LNK1188
BADFIXUPSECTION:: invalid fixup target "symbol"; possible zero length section
 This message is issued only for VxD links when the target of a relocation does not have a section. With LINK386 (an older version), an OMF GROUP record (generated by a MASM GROUP directive) may have been used to combine the zero length section with another non-zero length section. COFF format does not support the GROUP directive and zero-length sections. When LINK automatically converts this type of OMF objects to COFF, this error may occur.

Linker Tools Error LNK1189
LIBTOOMANYMEMBERS:: library limit of number objects exceeded
 The limit of 65535 objects or members in a library has been exceeded.

Return to Main Linker Error Page


Linker Errors LNK1190 to LNK1581

Linker Tools Error LNK1190
invalid fixup found, type type
 The object file has become corrupted. Recompile.

Linker Tools Error LNK1194
cannot delay-load dll name due to import of data symbol symbol name; relink without /DELAYLOAD:dll name
 You cannot delay load a DLL if data is imported from it.

Linker Tools Error LNK1195
target machine "machine" requires "option"
 Add the required option.

Linker Tools Error LNK1196
invalid or corrupt import object: unknown version
 The import library has become corrupted. Rebuild the library.

Linker Tools Error LNK1197
invalid or corrupt import object: unknown type
 The import library has become corrupted. Rebuild the library.

Linker Tools Error LNK1198
invalid or corrupt import object: unknown name type
 The import library has become corrupted. Rebuild the library.

Linker Tools Error LNK1199
invalid or corrupt import object: non-zero reserved fields
 The import library has become corrupted. Rebuild the library.

Linker Tools Error LNK1200
error reading program database "filename"
 The given program database (PDB) could not be read, probably because it is corrupted. If filename is the PDB for an object file, recompile the object file; use the /debug:full and /pdbfile options. If filename is the PDB for the main output file and this error occurred during an incremental link, delete the PDB and relink.

Linker Tools Error LNK1201
error writing to program database "filename"; check for insufficient disk space
 LINK could not write to the program database (PDB) for the output file. One of the following may be a cause:

  • The file is corrupted. Delete filename and relink.
  • There was not enough disk space to write to the file.
  • The drive being written to was not available, possibly due to a network problem.

Linker Tools Error LNK1202
"filename" missing debugging information for referencing module
 The given program database (PDB) for an object file was invalid. Recompile the object file; use CL's /Zi option.

Linker Tools Error LNK1203
"filename" missing current debugging information for referencing module
 The given program database (PDB) for an object file was invalid. Recompile the object file; use CL's /Zi option.

Linker Tools Error LNK1204
"filename" compiled /Yc /Yu /Z7; cannot create PDB; recompile with /Zi
 Multilayered program databases (PDBs) are not supported in combination with old-style debugging information. Recompile using CL's /Zi option.

Linker Tools Error LNK1206
cannot overwrite Visual C++ 1.0 PDB "filename"; delete and rebuild
 This version of LINK cannot write to an existing program database (PDB) created using older versions of the visual development environment. Delete filename and rebuild.

Linker Tools Error LNK1207
incompatible PDB format in "filename"; delete and rebuild
 This version of LINK cannot write to the existing program database (PDB). Delete filename and rebuild.

Linker Tools Error LNK1209
program database "filename" differs from previous link; relink or rebuild
 The given program database (PDB) is invalid and possibly corrupt. Relink. If filename is also the PDB for an object file, recompile to recreate the PDB.

Linker Tools Error LNK1210
insufficient memory for incremental link; relink with /INCREMENTAL:NO
 There was not enough virtual memory available for LINK to create the incremental status (.ILK) file.

Linker Tools Error LNK1211
precompiled type information not found; "filename" not linked or overwritten
 The given object file, compiled with /Yc, either was not specified in the LINK command or was overwritten.

Linker Tools Error LNK1212
error opening program database; file is in use
 The PDB is already in use by another application.

Linker Tools Error LNK1213
unexpected import object encountered
 The import library has become corrupted. Rebuild the library.

Linker Tools Error LNK1221
a subsystem can't be inferred and must be defined
 The linker does not have enough information to infer which subsystem you will target your application. To fix this error, use the /SUBSYSTEM option.

Linker Tools Error LNK1561
entry point must be defined
 The symbol specified by the /ENTRY option is not defined.

Linker Tools Error LNK1581
corrupted object or old compiler (bad Pcode entry point)
 Your object file contained a bad entry point. The object file is probably corrupt. See Corrupt Object File for more information.

Return to Main Linker Error Page


Linker Errors LNK2001 to LNK2014

Linker Tools Error LNK2001
unresolved external symbol "symbol"
 Code will generate this error message if it references something (like a function, variable, or label) that the linker cannot find in all the libraries and object files it searches. In general, there are two reasons this error occurs: what the code asks for doesn't exist (the symbol is spelled incorrectly or uses the wrong case, for example), or the code asks for the wrong thing (you are using mixed versions of the libraries; some from one version of the product, others from another version).

Depending on the calling convention used, an at sign (@) and a decimal number may be appended to the symbol name (see ATTRIBUTES Properties and Calling Conventions).

Numerous kinds of coding and build errors can cause LNK2001. Several specific causes are listed below, and some have more detailed explanations.

Coding Problems:

  • In Fortran programs, some of the causes of the LNK2001 message can be one of the following:

    • Calling a routine with a different number of arguments or the wrong argument types than it was declared. If an argument count mismatch is intentional, then use the Fortran OPTIONAL attribute (an explicit interface is required), or use !DEC$ ATTRIBUTES C to give the called routine the C attribute (this must be specified both in the calling routine and in the called routine). For more information, see the Programmer's Guide section on mixed-language programming.

    • Unresolved references to Visual Fortran library routine names can be caused by omitting the appropriate USE statement required by that routine. For example, calling the TRACEBACKQQ routine requires the USE DFLIB statement and DLGINIT requires USE DFLOGM. Similarly, a specific USE statement is needed to call IMSL routines and a specific INCLUDE statement is needed to call CXML routines.

    • Unresolved references to _WinMain@16 can be caused by specifying a project type as Fortran Windows for a traditional application (Fortran Windows applications require a WinMain function declaration and interface). In this case, create a new Fortran project with the correct project type (such as Fortran Console), copy the files to the new project directory, and add them to the new project (see Defining Your Project).

    • If the routine you are calling is a Win32 API routine, you may need to specify its library in Link tab, Object/Library modules field in the Project Settings dialog box (click Settings in the Project menu). To see which library is required, read the routines description and click on QuickView in the Platform SDK documentation (see Calling Win32 Routines and the Visual Fortran Windows Module).

  • Mismatched case in your code or module-definition (.DEF) file can cause LNK2001. For example, if you named a variable "var1" in one C++ source file and tried to access it as "VAR1" in another, you would receive this error. The solution is to exactly match the case of the symbol in all references.

  • A project that uses function inlining yet defines the functions in a .CPP file rather than in the header file can cause LNK2001.

  • If you are using C++, make sure to use extern "C" when calling a C function from a C++ program. By using extern "C" you force the use of the C naming convention. Be aware of compiler switches like /Tp or /Tc that force a file to be compiled as a C (/Tc) or C++ (/Tp) file no matter what the filename extension, or you may get different function names than you expect.

  • Attempting to reference functions or data that don't have external linkage causes LNK2001. In C++, inline functions and const data have internal linkage unless explicitly specified as extern.

  • A missing function body or variable will cause LNK2001. Having just a function prototype or extern declaration will allow the compiler to continue without error, but the linker will not be able to resolve your call to an address or reference to a variable because there is no function code or variable space reserved.

  • Name decoration incorporates the parameters of a function into the final decorated function name. Calling a function with parameter types that do not match those in the function declaration may cause LNK2001.

  • Incorrectly included prototypes will cause the compiler to expect a function body that is not provided. If you have both a class and non-class implementation of a function F, beware of C++ scope-resolution rules.

  • When using C++, make sure that you include the implementation of a specific function for a class and not just a prototype in the class definition.

  • Attempting to call a pure virtual function from the constructor or destructor of an abstract base class will cause LNK2001 since by definition a pure virtual function has no base class implementation.

  • Only global functions and variables are public.
    Functions declared with the static modifier by definition have file scope. Static variables have the same limitation. Trying to access any static variables from outside of the file in which they are declared can result in a compile error or LNK2001.
    A variable declared within a function (a local variable) can only be used within the scope of that function.
    C++ global constants have static linkage. This is different than C. If you try to use a global constant in C++ in multiple files you get error LNK2001. One alternative is to include the const initializations in a header file and include that header in your .CPP files when necessary, just as if it was a function prototype. Another alternative is to make the variable non-constant and use a constant reference when assessing it.

Compiling and Linking Problems:

  • The names of the run-time libraries needed at link time are included in the object file module by the compiler. If you use the /NOD (/NODEFAULTLIB) option, these libraries will not be linked into the project unless you have explicitly included them. Using /NOD will cause error LNK2001 in this case.

  • If you are using Unicode and MFC, you will get an unresolved external on _WinMain@16 if you don't create an entrypoint to wWinMainCRTStartup. Use the /ENTRY option or type this value in the Project Settings dialog box. (To find this option in the development environment, click Settings on the Project menu, then click the Link tab, and click Output in the Category box.)

  • See the following Microsoft Knowledge Base articles for more information (either search MSDN if it is installed or use a Web browser to search for the following article Q numbers at http://support.microsoft.com/support):

    • Q125750 "PRB: Error LNK2001: '_WinMain@16': Unresolved External Symbol"
    • Q131204 "PRB: Wrong Project Selection Causes LNK2001 on _WinMain@16"
    • Q100639 "Unicode Support in the Microsoft Foundation Class Library"

  • Linking code compiled with /MT with the library LIBC.LIB causes LNK2001 on _beginthread, _beginthreadex, _endthread, and _endthreadex.

  • When compiling with /MD, a reference to "func" in your source becomes a eference "__imp__func" in the object since all the run-time is now held within a DLL. If you try to link with the static libraries LIBC.LIB or LIBCMT.LIB, you will get LNK2001 on __imp__func. If you try to link with MSVCxx.LIB when compiling without /MD you will not always get LNK2001, but you will likely have other problems.

  • Linking code compiled with an explicit or implicit /ML to the LIBCMT.LIB causes LNK2001 on _errno.

  • Linking with the release mode libraries when building a debug version of an application can cause LNK2001. Similarly, using an /Mxd option (/MLd, /MTd, or /MDd) and/or defining _DEBUG and then linking with the release libraries will give you potential unresolved externals (among other problems). Linking a release mode build with the debug libraries will also cause similar problems.

  • Mixing versions of Microsoft libraries and compiler products can be problematic. A new compiler version's libraries may contain new symbols that cannot be found in the libraries included with previous versions. Use DUMPBIN to find out if a symbol is in a 32-bit object file or library.

  • There is currently no standard for C++ naming between compiler vendors or even between different versions of a compiler. Therefore linking object files compiled with other compilers may not produce the same naming scheme and thus cause error LNK2001.

  • Mixing inline and non-inline compile options on different modules can cause LNK2001. If a C++ library is created with function inlining turned on (/Ob1 or /Ob2) but the corresponding header file describing the functions has inlining turned off (no inline keyword), you will get this error. To prevent this problem, have the inline functions defined with inline in the header file you are going to include in other files.

  • If you are using the Visual C++ #pragma inline_depth compiler directive, make sure you have a value of 2 or greater set, and make sure you are using the /Ob1 or /Ob2 compiler option.

  • Omitting the LINK option /NOENTRY when creating a resource-only DLL will cause LNK2001.

  • Using incorrect /SUBSYSTEM or /ENTRY settings can cause LNK2001. For example, if you write a character-based application (a console application) and specify /SUBSYSTEM:WINDOWS, you will get an unresolved external for WinMain. For more information on these options and entry points, see the /SUBSYSTEM and /ENTRY linker options.

Export Problems:

  • When you are porting an application from 16 to 32 bits, LNK2001 can occur. The current 32-bit module-definition (.DEF) file syntax requires that __cdecl, __stdcall, and __fastcall functions be listed in the EXPORTS section without underscores (undecorated). This differs from the 16-bit syntax, where they must be listed with underscores (decorated). For more information, see the description of the EXPORTS section of module-definition files.

  • Any export listed in the .DEF file and not found will cause LNK2001. This could be because it does not exist, is spelled incorrectly, or uses decorated names (.DEF files do not take decorated names). This error message is followed by fatal error LNK1120.

The following sections give more detailed information on some of the issues named in the above list.

  • Missing function body or variable

    Having just a function prototype will allow the compiler to continue without error, but the linker will not be able to resolve your call to an address because there is no function code or variable space reserved. You will not see this error until you create an actual call to the function that the linker must resolve.

  • Name decoration

    Normally this refers to C++ naming conventions, but it applies to a number of non-C++ cases as well. C++ by default will use the name of a function, its parameters and its return type when calculating a name for a function.

    Use extern "C" when calling a C function from a C++ program. Extern "C" forces use of the C naming convention for non-class C++ functions.

Linker Tools Error LNK2003
gp relative fixup to symbol not in .sdata "module"
 The /Gt value specified when compiling an instance of a type differed from the value specified when compiling the reference to the type. Rebuild the object files with consistent values for /Gt. This error is followed by fatal error LNK1165.

Linker Tools Error LNK2004
gp relative fixup overflow; sdata section ("section") is too large
 The .sdata section was too large. Rebuild using smaller values for /Gt. This error is followed by fatal error LNK1165.

Linker Tools Error LNK2005
symbol already defined in object
 The given symbol, displayed in its decorated form, was multiply defined. One of the following may be a cause:

  • The most common cause of this error is accidentally linking with both the single-threaded and multithreaded libraries, or with both the static and dynamic libraries, or with both debug and non-debug versions. Ensure that the application project includes only the appropriate libraries and that any third-party libraries have appropriately created single-threaded or multithreaded versions, or appropriately created static or dynamic versions.

    The types of the Fortran and C libraries must match. For more information, see Specifying Consistent Library Types.

  • The given symbol was a packaged function (created by compiling with /Gy) and was included in more than one file but was changed between compilations. Recompile all files that include the symbol.

  • The given symbol was defined differently in two member objects in different libraries, and both member objects were used.

  • An absolute was defined twice, with a different value in each definition. This error is followed by fatal error LNK1169.

Linker Tools Error LNK2006
TOC relative fixup to symbol not in TOC "name"; fixup ignored
 LINK found an invalid fixup and ignored it.

Linker Tools Error LNK2007
TOC relative fixup overflow; TOC is too large; fixup ignored
 LINK found an invalid fixup and ignored it.

Linker Tools Error LNK2008
Fixup target is not aligned "alignment"
 LINK found a fixup target in your object file that was not aligned properly.

Linker Tools Error LNK2009
Fixup target must be absolute "name" w/o -FIXED; fixup ignored
 LINK found an invalid fixup and ignored it.

Linker Tools Error LNK2010
Duplicate IMGLUE relocations for "name"
 LINK found duplicate relocations for "name" in your object file. The object file is probably corrupt. See Corrupt Object File for more information.

Linker Tools Error LNK2011
precompiled object not linked in; image may not run
 If you use precompiled headers, LINK now requires that all of the object files created with precompiled headers must be linked in. If you have a source file that you use to generate a precompiled header for use with other source files, you now must include the object file created along with the precompiled header.

Linker Tools Error LNK2012
No NOP following relocationtype relocation to "symbol"
 TOCINDIRCALL and TOCCALLREL require a NOP following the instruction that has this type of relocation. This is mainly useful for compiler and assembler developers who use the Microsoft linker.

Linker Tools Error LNK2013
Fixup overflow. Target "symbol" is out of range
 This error occurs when the executable is too large or the error may indicate a problem with assembly code. To work around the problem:

  • Use shared libraries.
  • TOC space is required for global data accessed from a module other than where it is defined.
You can eliminate the TOC space by moving such data to the module where it is referenced. However, if data is referenced in multiple modules, then the TOC space cannot be eliminated to save space.

Linker Tools Error LNK2014
TLS relative fixup overflow; .tls section ("section") is too large
 The section created for thread-local storage (.tls) is too large. TLS data must fit in 32 KB. This data is created using the __declspec(thread) storage class modifier in the declaration and definition of that data. To work around the problem:

  • Reduce the amount of thread-local data in the code.
  • Use dynamic TLS by calling functions such as TlsAlloc and TlsFree.

Return to Main Linker Error Page


Linker Warnings LNK4001 to LNK4039

Linker Tools Warning LNK4001
no object files specified; libraries used
 The command did not specify any object files as input. The tool used objects from the libraries that were specified as input.

Linker Tools Warning LNK4002
symbol defined in object
 The given symbol, displayed in its decorated form, was specified in its undecorated form in object, but a unique match to a decorated symbol could not be found. This warning is always preceded by warning LNK4022 and followed by fatal error LNK1152.

Linker Tools Warning LNK4003
invalid library format; library ignored
 The file header for the input library was invalid. The tool did not use the library.

Linker Tools Warning LNK4005
no objects used from library library
 The library was specified in the command, but no references were resolved from that library.

Linker Tools Warning LNK4006
symbol already defined in object; second definition ignored
 The given symbol, displayed in its decorated form, was multiply defined. When this warning is encountered, symbol will be added twice, but only its first form will be used. Tips:

  • The given symbol may be a packaged function, created by compiling with /Gy. This symbol was included in more than one file but was changed between compilations. Recompile all files that include the symbol.
  • The given symbol may have been defined differently in two member objects in different libraries.
  • An absolute may have been defined twice, with a different value in each definition.
  • If the error message is received when combining libraries, symbol already exists in the library being added to.

Linker Tools Warning LNK4010
invalid version number "number"; default version assumed
 Either the major or the minor number in the specified version argument was not valid. Each part of a version specification must be an integer in the range 1-65535. Options that take a version argument include /SUBSYSTEM and /VERSION.

Linker Tools Warning LNK4011
unknown subsystem "argument"; default assumed
 The /SUBSYSTEM option was incorrectly specified. Either no argument was specified or argument did not have the expected syntax. The tool assumed an appropriate default.

Linker Tools Warning LNK4012
invalid value "argument", must be keywords; option ignored
 The given argument was not a valid keyword for the option it was specified with. The valid arguments are shown in the given list of keywords.

Linker Tools Warning LNK4013
image size imagesize exceeds specified maximum maxsize
 The base address file specified with the /BASE option listed the maximum size of the program as maxsize, but maxsize was less than the resulting image size of the program.

Linker Tools Warning LNK4014
cannot find member object "objectname"
 LIB could not find objectname in the library. The /REMOVE and /EXTRACT options require the full name of the member object that is to be deleted or copied to a file. The full name includes the path of the original object file. To see the full names of member objects in a library, use DUMPBIN /ARCHIVEMEMBERS or LIB /LIST.

Linker Tools Warning LNK4015
memorytype commit exceeds reserve; commit size set to size
 The value specified for the commit size for the memorytype exceeded the value specified for the reserve size. The tool assumed size as the value of the commit size.

Linker Tools Warning LNK4017
keyword statement not supported for the target platform; ignored
 The given module-definition statement is not supported by this version of the linker tools. The tool ignored the statement in the .DEF file.

Linker Tools Warning LNK4018
too many type indexes in PDB "filename", discarding subsequent type information
 There are more than 64K type indexes in the program database (PDB). The PDB might contain unneeded type information. Delete the existing PDB and rebuild. If the warning persists, then compile some modules without debugging information.

Linker Tools Warning LNK4019
corrupt string table (table end); new end assumed
 The object file is corrupt. The tool attempted to correct the problem. To prevent this warning, rebuild the object file. See Corrupt Object File for more information.

Linker Tools Warning LNK4022
cannot find unique match for symbol "symbol"
 LINK or LIB found multiple matches for the given undecorated symbol and it could not resolve the ambiguity. No output file (.EXE, .DLL, .EXP, or .LIB) is produced. This warning is followed by one warning LNK4006 for each duplicate symbol and is finally followed by fatal error LNK1152. To prevent this warning, specify the symbol in its decorated form. Run DUMPBIN on the object to see decorated names.

Linker Tools Warning LNK4023
base address address not a 64K multiple; assumed newaddress
 The base address specified with the /BASE option must be a multiple of 64K. The tool assumed a newaddress value for the base address.

Linker Tools Warning LNK4027
CVPACK error
 LINK called CVPACK to process the debugging information, but one of the following occurred:

  • The call failed. Be sure that CVPACK is in a directory specified in the PATH environment variable and that there is sufficient memory.
  • CVPACK issued an error. Errors generated by CVPACK have the form CKnnnn.

Linker Tools Warning LNK4028
option option is obsolete; ignored
 The given option is not supported. LINK ignored the option and continued the build.

Linker Tools Warning LNK4030
invalid file offset number for category; category not dumped
 DUMPBIN could not display information for the given category. Probably the file is invalid or corrupt. See Corrupt Object File for more information.

Linker Tools Warning LNK4031
no subsystem specified; CONSOLE assumed
 The /SUBSYSTEM option was not specified, and LINK was not able to determine a subsystem from the input files.

Linker Tools Warning LNK4033
converting object format from OMF to COFF
 The format of the object file is OMF. This tool requires COFF input. To permanently convert the file, run EDITBIN on the file with no options.

Linker Tools Warning LNK4037
"symbol" does not exist; ignored
 The symbol could not be ordered using the /ORDER option because it could not be found in the program. Check the specification of symbol in the ordering file.
Note: LINK cannot order static functions because static function names are not public symbol names. When /ORDER is specified, this linker warning is generated for each symbol, in the order file, that is either static or not found.

Linker Tools Warning LNK4038
displaying raw data in number units per line
 The /RAWDATA option was specified without a formatting argument. DUMPBIN assumed a format value of number units per line of the specified or assumed data type, as follows:

Data Type | Number
none | 16
BYTES | 16
SHORTS | 8
LONGS | 4

Linker Tools Warning LNK4039
section "name" specified with /SECTION option does not exist
 DUMPBIN or EDITBIN could not find a section called name in the input file. To see the sections in a file, run DUMPBIN with the /HEADERS option.

Return to Main Linker Error Page


Linker Warnings LNK4040 to LNK4069

Linker Tools Warning LNK4040
corrupt string table (size); string table ignored
 The string table in the object file is corrupt. The program may not run as expected. Rebuild the object file. See Corrupt Object File for more information.

Linker Tools Warning LNK4041
no edit options specified
 EDITBIN was run on the input file, but no options were used. If the file format was not COFF, EDITBIN attempted to convert it. Otherwise, EDITBIN took no action on the file.

Linker Tools Warning LNK4042
object specified more than once; extras ignored
 The same object file was specified more than once in the LINK or LIB command. The result is the same as if the file were specified only the first time.

Linker Tools Warning LNK4043
invalid /ALIGN value number (must be power of 2); assumed default
 The argument specified with the /ALIGN option was not a power of 2.

Linker Tools Warning LNK4044
unrecognized option "option"; ignored
 The given option is not a valid option for this tool. The tool ignored the option. To see a list of valid options, run the tool with no arguments or options.

Linker Tools Warning LNK4045
creating LINK_REPRO test case in dir "directory"
 The LINK_REPRO environment variable, when set, specifies a directory where the linker will copy object files, libraries, and other files. Microsoft can use these files to recreate internal linker errors. The linker will only copy files if LINK_REPRO is set. If this is not what you want to do, remove the LINK_REPRO environment variable by typing the following: set LINK_REPRO=

Linker Tools Warning LNK4046
LINK_REPRO is set to current directory; ignored
 The LINK_REPRO environment variable should not be set to the current directory. Create a new directory, set LINK_REPRO to the new directory, and rerun the linker.

Linker Tools Warning LNK4047
cannot edit library file "filename"; ignored
 EDITBIN cannot process a library file.

Linker Tools Warning LNK4048
Invalid format file; ignored
 EDITBIN could not process the file because it was not a valid object file, executable file, or dynamic-link library (DLL).

Linker Tools Warning LNK4049
exported symbol "symbol" also imported
 The symbol was both exported from and imported to the program. This warning is displayed when the LINK warning level (set by the /WARN option) is greater than 1.

Linker Tools Warning LNK4051
extra delimiter in /EXPORT specification
 The specification of the /EXPORT option ended with a comma (,).

Linker Tools Warning LNK4052
using .EXP file; ignoring .DEF file "filename"
 The .DEF file specified in the LINK command was ignored because an .EXP file was also specified. The .DEF file was already processed when the .EXP file was created and is not necessary in this step of the build process.

Linker Tools Warning LNK4055
invalid fixup found, address address; fixup ignored
 The object contained an invalid fixup. The resulting executable file will probably not run correctly. Rebuild the object file. See Corrupt Object File for more information.

Linker Tools Warning LNK4056
extra arguments ignored for option "option"
 The option was specified with too many arguments. The additional arguments were ignored.

Linker Tools Warning LNK4057
"library1" should precede "library2" in the link command line
 Check the order of your libraries. The developer of library1 determined that it should be searched by the linker before library2. For example, library1 might contain an updated version of a function in library2. If you specify library2 first, the linker will link in the old version rather than the newer version from library1.

Linker Tools Warning LNK4059
resourcefile already specified; additional resource file ignored
 Only one resource file is allowed. The first .RES file specified in the command was used.

Linker Tools Warning LNK4060
stub file missing full MS-DOS header; rebuild stub with /KNOWEAS 16-bit LINK option
 The MS-DOS application specified with the /STUB option does not have a full 40-byte header. The stub program may not run as expected. To rebuild the 16-bit stub with a full 40-byte header, use the undocumented /KNOWEAS option with the 16-bit LINK version 5.5x or higher.

Linker Tools Warning LNK4061
/NOSTUB ignored because no DOS stub is present
 EDITBIN could not remove the stub file because it could not find one in your executable file.

Linker Tools Warning LNK4062
"option" not compatible with "platform" target machine; option ignored
 The given option is not supported for the target platform of this build. LINK ignored the option and continued the build.

Linker Tools Warning LNK4064
conflicting subsystem; image may not run
 You tried to link in a library whose subsystem differs from your executable's subsystem value, and your executable file may not run. For more information on subsystems, see the /SUBSYSTEM linker option. Note: You will not receive this warning if one subsystem is CONSOLE and the the other's subsystem is WINDOWS.

Linker Tools Warning LNK4065
"function" cannot be ordered; ignored
 The given function was not compiled as a packaged function. Recompile using /Gy.

Linker Tools Warning LNK4066
DLL contains .sdata section
 One or more objects was compiled using /Gt. Objects compiled with /Gt cannot be used to create a DLL.

Linker Tools Warning LNK4067
ambiguous entry point; selected "entry"
 LINK found multiple entry points for the program. It assumed the given entry.

Linker Tools Warning LNK4068
/MACHINE not specified; defaulting to machinetype
 LINK did not find a machine specification. It assumed the given machine type. If the default is incorrect, resulting in fatal error LNK1112, relink using the /MACHINE option.

Linker Tools Warning LNK4069
cannot create map and/or checksum image; checksum set to 0
 This warning can occur if IMAGEHLP.DLL is not available.

Return to Main Linker Error Page


Linker Warnings LNK4070 to LNK4099

Linker Tools Warning LNK4070
/OUT:filename directive in .EXP differs from output filename "filename"; ignoring directive
 The filename specified in the NAME or LIBRARY statement when the .EXP file was created differs from the output filename that was either assumed by default or specified with the /OUT option. A client program that uses the resulting DLL might encounter problems.

Linker Tools Warning LNK4071
cannot be incrementally linked on subsequent links
 LINK found multiple definitions for one or more symbols, but /FORCE or /FORCE:MULTIPLE was used to create an output file regardless of errors. LINK deleted the incremental status (.ILK) file.

Linker Tools Warning LNK4072
section count count exceeds max (number); image may not run
 The number of sections (a COFF .EXE or .DLL file is composed of sections, similar to segments) in the output file is greater than the limit that can be handled by the loader.

You can view the names of the sections in your executable file by using the DUMPBIN program with the default /SUMMARY option. See the DUMPBIN Reference for more information. To reduce the number of sections in your executable file:

  • Remove unneeded data_seg, code_seg or alloc_text pragmas. See data_seg, code_seg, and alloc_text.
  • Use the /MERGE option with LINK to combine sections. See /MERGE.

Linker Tools Warning LNK4073
cannot create map for .ILK file; linking nonincrementally
 There was not a large enough contiguous space in shared memory for LINK to create the incremental status (.ILK) file. LINK performed a nonincremental build.

Linker Tools Warning LNK4074
unable to load filename; cannot checksum
 The linker tried to load the dynamic-link library filename but could not. A function in filename is used to checksum the executable file. One of the following may be a cause:

  • The linker could not find filename because it is not in the current directory or in a directory in the PATH environment variable.
  • There was a problem with filename. Recopy filename from the installation disks.

Linker Tools Warning LNK4075
ignoring "option1" due to "option2" specification
 The option2 specification overrides option1.

Linker Tools Warning LNK4076
invalid incremental status file "filename"; linking nonincrementally
 LINK cannot write to the incremental status (.ILK) file. Either filename is corrupt or it is not an incremental linking database. Remove the file and relink.

Linker Tools Warning LNK4077
exports file "filename" used; ignoring other export specifications
 The given exports file provides the program's exports. Exports specified by the /EXPORT option or the EXPORTS statement in a .DEF file were ignored.

Linker Tools Warning LNK4078
multiple "section" sections found with different attributes
 LINK found two or more sections that have the same name but different attributes. Probably an import library or exports file was created by a previous version of LINK or LIB. Recreate the file and relink.

Linker Tools Warning LNK4079
no write permission for incremental status file "filename"; linking nonincrementally
 LINK cannot write to the incremental status (.ILK) file because filename does not have the correct permissions.

Linker Tools Warning LNK4081
insufficient disk space; linking nonincrementally
 There is not enough space on disk for LINK to create or write to the incremental status (.ILK) file.

Linker Tools Warning LNK4082
unable to find entrypoint function in module; cannot checksum
 The function CheckSumMappedFile() does not exist in IMAGEHLP.DLL.

Linker Tools Warning LNK4083
module "name" does not exist; ignored
 The module "name" you gave in your order file does not exist. Check the spelling. For more information on order files, see the /ORDER linker option.

Linker Tools Warning LNK4084
total image size size exceeds max (256MB); image may not run
 The application exceeds the limit of 256 megabytes.

Linker Tools Warning LNK4085
more than number comments; skipping exestr
 This warning occurs when the linker tool is converting an OMF object to a COFF object. It indicates there are more than 256 comments in the OMF module.

Linker Tools Warning LNK4086
entrypoint 'function' is not __stdcall with 12 bytes of arguments; image may not run
 The entry point for a DLL must be __stdcall. Either recompile the function with the /Gz option or specify __stdcall or WINAPI when you define the function.

Linker Tools Warning LNK4087
CONSTANT keyword is obsolete; use DATA
 This warning occurs if you use CONSTANT with your exports in a module definition file or on the command line. Use DATA instead.

Linker Tools Warning LNK4088
image being generated due to /FORCE option; image may not run
 The linker encountered an error. Normally it deletes the image it created because the image may not run due to the error. Since you used the /FORCE option, however, the linker did not remove the image.

Linker Tools Warning LNK4089
all references to "dynamic-link library" discarded by /OPT:REF
 The linker discarded all packaged functions that referenced exports in dynamic-link library. As a result, dynamic-link library and its import library are unneeded.

Linker Tools Warning LNK4090
No IFGLUE relocation in module with branch to glue code "name"
 Your object file contained bad relocation information. Recopy or recreate the object file. See Corrupt Object File for more information.

Linker Tools Warning LNK4092
shared section "section" contains relocations; image may not run correctly
 The linker emits this warning whenever you have a shared section to warn you of a potentially serious problem. One way to share data between multiple processes is to mark a section as "shared." However, marking a section as shared can cause problems.

Linker Tools Warning LNK4093
Drive/Directory component ignored in "module-definition" statement
 Your module-definition (.DEF) file used a statement incorrectly. The LIBRARY or NAME statements cannot contain directory or drive information.

Linker Tools Warning LNK4094
filename is an MS-DOS executable; use EXEHDR to dump it
 The DUMPBIN program only works with COFF-format executable files. Use EXEHDR on MS-DOS executables. EXEHDR is included with Visual C++ 1.5.

Linker Tools Warning LNK4095
filename is an NE format executable; use EXEHDR to dump it
 The DUMPBIN program only works with COFF-format executable files. Use EXEHDR on NE format executables. EXEHDR is included with Visual C++ 1.5.

Linker Tools Warning LNK4096
/BASE value "number" is invalid for Windows 95; image may not run
 The base address you specified is invalid. Windows 95 executable files must have a base address greater than 0x400000. For more information on base addresses, see the /BASE linker option.

Linker Tools Warning LNK4097
duplicate name "name" in order file; using last one
 Order files specify the order you want the linker to load your functions. In your order file, a function appears more than once, so the linker ignored all references to it except the last. For more information on order files, see the /ORDER linker option.

Linker Tools Warning LNK4098
defaultlib "library" conflicts with use of other libs; use /NODEFAULTLIB:library
 You are trying to link with incompatible libraries.
Note: The run-time libraries now contain directives to prevent mixing different types. You'll receive this warning if you try to use different types or debug and non-debug versions of the run-time library in the same program. For example, if you compiled one file to use one kind of run-time library and another file to use another kind (for example, single-threaded versus multithreaded) and tried to link them, you will get this warning.

The types of the Fortran and C libraries must match. For more information, see Specifying Consistent Library Types.

You can use the linker's /VERBOSE:LIB switch to determine which libraries the linker is searching. If you receive LNK4098 and want to create an executable file that uses, for example, the single-threaded, non-debug run-time libraries, use the /VERBOSE:LIB option to find out which libraries the linker is searching. The linker should print LIBC.LIB and not LIBCMT.LIB, MSVCRT.LIB, LIBCD.LIB, LIBCMTD.LIB, or MSVCRTD.LIB as the libraries searched. You can tell the linker to ignore the the incorrect run-time libraries by typing the incorrect libraries in the Ignore Libraries text box on the Link tab of the Settings dialog box in the visual development environment or by using the /NODEFAULTLIB:library option with LINK for each library you want to ignore. See the /NODEFAULTLIB linker option for more information.

The table below shows which Visual C++ libraries should be ignored depending on which run-time library you want to use.

To use this run-time library | Ignore these libraries
Single-threaded (libc.lib) | libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib
Multithreaded (libcmt.lib) | libc.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib
Multithreaded using DLL (msvcrt.lib) | libc.lib, libcmt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib
Debug Single-threaded (libcd.lib) | libc.lib, libcmt.lib, msvcrt.lib, libcmtd.lib, msvcrtd.lib
Debug Multithreaded (libcmtd.lib) | libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, msvcrtd.lib
Debug Multithreaded using DLL (msvcrtd.lib) | libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib

For example, if you received this warning and you want to create an executable file that uses the non-debug, single-threaded version of the run-time libraries, you could use the following options with the linker:
/NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib
   /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib

Linker Tools Warning LNK4099
PDB "filename" was not found with "object/library" or at "path"; linking object as if no debug info
 The linker was unable to find your .PDB file. Copy it into the directory that contains object/library.

Return to Main Linker Error Page


Linker Warnings LNK4102 to LNK4549

Linker Tools Warning LNK4102
export of deleting destructor symbol name; image may not run correctly
 The program has attempted to export a deleting destructor. The resulting delete may occur across a DLL boundary such that a process can free memory that it does not own. Make sure that the given symbol is not listed in your .DEF file, and that the symbol is not listed as an argument of the /IMPORT or /EXPORT option in the linker command line.

Linker Tools Warning LNK4103
import of deleting destructor "symbol name"; image may not run correctly
 The program has attempted to import a deleting destructor. The resulting delete may occur across a DLL boundary such that a process can free memory that it does not own. Make sure that the given symbol is not listed in your .DEF file, and that the symbol is not listed as an argument of the /IMPORT or /EXPORT option in the linker command line.

Linker Tools Warning LNK4104
export of symbol "symbol" should be PRIVATE
 The symbol can be one of the following:

  • DllRegisterServer
  • DllRegisterServerEx
  • DllUnregisterServer
  • DllGetClassObject
  • DllCanUnloadNow
This warning is emitted when you are building an import library for a DLL and export one of the above functions without specifying it as PRIVATE in the module-definition file. In general these functions are exported for use only by OLE. Placing them in the import library can lead to unusual behavior when a program linked to the library incorrectly makes calls to them.

Linker Tools Warning LNK4105
no argument specified with option option; ignoring switch
 This warning occurs only when the /LIBPATH option is set. If no directory is specified with this option, then the linker ignores this option and generates this warning message. If you do not need to override the existing environmental library settings, remove the /LIBPATH option from the linker command line. If you want to use an alternate search path for libraries, specify the alternate path following the /LIBPATH option. For example: link /libpath:c:\foo\lib bar.obj would direct the linker to search for the required libraries in c:\foo\lib before searching in the default locations.

Linker Tools Warning LNK4106
"section name" section discarded due to "option" specification
 The option caused the linker to discard the section.

Linker Tools Warning LNK4107
"/option" not supported by this version of MSPDBxx.DLL; ignored
 MSPDBxx.DLL does not support the specified option.

Linker Tools Warning LNK4108
/ALIGN specified without /DRIVER or /VXD; image may not run
 The /ALIGN option has been specified without also specifying either /DRIVER or /VXD. Bad alignment can prevent the operating system from loading the final image. Do not use the /ALIGN option unless building a driver or vxd.

Linker Tools Warning LNK4194
/DELAYLOAD:dll name ignored
 The linker cannot delay load the requested DLL.

Linker Tools Warning LNK4195
unable to load dll name
 The linker could not load the requested DLL.

Linker Tools Warning LNK4197
export "exportname" specified multiple times; using first specification
 An export is specified in multiple, different ways. The linker uses the first specification and ignores the rest. Perhaps the same export is specified both on the command line (via export:) and in the .def file or listed twice in the .def file with different attributes. If an export is specified exactly the same way multiple times, the linker will not issue a warning.

Linker Tools Warning LNK4198
base key "keyname" not found - using default
 The keyname, specified in a /BASE option, does not appear in the base address file.

Linker Tools Warning LNK4199
/DELAYLOAD:dllname ignored; no imports found from dllname
 The linker ignores dllname because it does not need any of the functions that dllname exports.

Linker Tools Warning LNK4200
corrupt line number information in object file; ignored
 The line number information in the object file has become corrupted. Rebuild.

Linker Tools Warning LNK4543
Section "section" with invalid attributes ignored
 The linker could not determine the type of section and ignored it. Valid types for sections include text, data, bss, and rdata.

Linker Tools Warning LNK4544
Symbol "symbol" specified with /IMPORT not referenced in application - ignored
 You specified a symbol with the /IMPORT option but it was not referenced in your program so the linker ignored it.

Linker Tools Warning LNK4545
Container "container" specified with /IMPORT not referenced in application - ignored
 You specified an import library (container) with the /IMPORT option, but your program did not reference the library. The linker ignored the container.

Linker Tools Warning LNK4546
Mismatch in versions detected. Container may not load. Use /VERBOSE for details.
 The linker detected a problem with versions in your import libraries (containers). To find out which container (and its version number) is causing the problem, rerun LINK with the /VERBOSE option.

Linker Tools Warning LNK4547
Setting "versiontype" to version
 The linker set versiontype to version. Possible values for versiontype are CURRENTVER, OLDCODEVER, and OLDAPIVER.

Linker Tools Warning LNK4548
Ignoring "versiontype" version
 The linker ignored version information of versiontype. The possible values of versiontype are CURRENTVER, OLDCODEVER, and OLDAPIVER.

Linker Tools Warning LNK4549
shared library "library" does not have any exports
 The shared library was ignored since it contained no exports.

Return to Main Linker Error Page


Linker Warnings LNK6001 to LNK6026

Linker Tools Warning LNK6001
insufficient disk space; performing full link
 There was not enough space on disk for LINK to incrementally link the program. LINK attempted to correct the problem and recover disk space by running a full link to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6002
invalid .ILK file found; performing full link
 The incremental status (.ILK) file was not valid. Probably the previous incremental linking session was interrupted. LINK attempted to correct the problem by running a full link to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6003
LINK options changed; performing full link
 The options specified to the linker differed from the options used during the previous incremental linking session. LINK attempted to correct the problem by running a full link to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6004
filename not found or not built by the last incremental link; performing full link
 The given file was either deleted or changed since the last incremental linking session. LINK attempted to correct the problem by running a full link to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6005
exports changed; performing full link
 One or more exports were added or deleted since the last incremental linking session. LINK attempted to correct the problem by running a full link to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6006
program database pdbname missing; performing full link
 LINK could not find the program database (.PDB) file that it created during the last incremental linking session. LINK attempted to correct the problem by running a full link to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6008
object file added; performing full link
 An object file was added since the last incremental linking session. A full link was required in order to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6009
object file removed; performing full link
 An object file was removed since the last incremental linking session. A full link was required in order to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6010
library changed; performing full link
 A library was modified since the last incremental linking session. A full link was required in order to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6011
internal limit exceeded; performing full link
 An internal limit related to incremental linking was exceeded. LINK attempted to correct the problem by running a full link to recreate the incremental status (.ILK) file. One cause of this warning is an .ILK file that exceeds 8MB. If this size is due to the accumulation of dead space, that space will be recovered in a full link.

Linker Tools Warning LNK6012
precompiled types found; performing full link
 An object file was compiled with /Z7 and the program used a precompiled header. LINK attempted to incrementally link by running a full link to recreate the incremental status (.ILK) file. Rebuild the object file with /Zi.

Linker Tools Warning LNK6013
padding exhausted: performing full link
 An internal limit related to incremental linking was exceeded. LINK attempted to correct the problem by running a full link to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6014
symbol reference set changed; performing full link
 A reference to a symbol in a library was added since the last incremental linking session. A full link was required in order to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6015
bss (uninitialized data) change; performing full link
 A bss symbol was changed since the last incremental linking session. A full link was required in order to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6016
absolute symbol changed; performing full link
 The address of an absolute symbol was changed since the last incremental linking session. A full link was required in order to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6017
set of library modules referenced changed; performing full link
 A full link was required in order to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6018
multiple definitions found for "symbol"; performing full link
 A full link was required in order to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6019
directive changed; performing full link
 A directive was added or deleted since the last incremental linking session. A full link was required in order to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6020
ILK file not built by this linker; performing full link
 The version number of the .ILK file was incorrect for this version of LINK. LINK attempted to correct the problem by running a full link to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6021
performing full link
 A full link was required in order to create the incremental status (.ILK) file.

Linker Tools Warning LNK6022
unable to load .ILK file; performing full link
 The .incremental status (.ILK) file is unavailable because of the actions of another process.

Linker Tools Warning LNK6023
unable to extend map for .ILK file; performing full link
 The .incremental status (.ILK) file cannot be written to because of the actions of another process.

Linker Tools Warning LNK6024
Mac Resource File "filename" changed; performing full link
 A full link was required in order to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6025
unable to do comdat selection; performing full link
 A full link was required in order to recreate the incremental status (.ILK) file.

Linker Tools Warning LNK6026
obsolete DBI format found; performing full link
 A full link was required. The format of debugging information from Visual C++ version 4.0 or earlier. Code that was initially linked with version 4.0 and that is now linked with a later version thus has inconsistent debugging information. Therefore, a full link was performed to rectify the inconsistency.

Return to Main Linker Error Page


BSCMAKE Messages BK1500 through BK4503

The following descriptions cover BSCMAKE Error BK1500 through Warning BK4503:

BSCMAKE Error BK1500
UNKNOWN ERROR
 BSCMAKE detected an unknown error condition. Note the circumstances of the error, try to isolate the problem and create a reproducible test case, then report the circumstances to technical support.

BSCMAKE Error BK1501
unknown character 'character' in option 'option'
BSCMAKE did not recognize the given character specified for the given option.

BSCMAKE Error BK1502
incomplete specification for option 'option'
The given option did not contain the correct syntax.

BSCMAKE Error BK1503
cannot write to file 'filename' [: reason]
BSCMAKE could not write to the given file. This message may be followed by a reason from the operating system, giving additional information. One of the following may have occurred:

  • The disk was full.
  • A hardware error occurred.

BSCMAKE Error BK1504
cannot position in file 'filename' [: reason]
BSCMAKE could not move to a location in the given file. This message may be followed by a reason from the operating system, giving additional information. One of the following may have occurred:

  • The disk was full.
  • A hardware error occurred.
  • The file was truncated. Truncation can occur if the compiler runs out of disk space or is interrupted when it is creating the .SBR file.

BSCMAKE Error BK1505
cannot read from file 'filename' [: reason]
BSCMAKE could not read from the given file. This message may be followed by a reason from the operating system, giving additional information. One of the following may have occurred:

  • The file was corrupt.
  • The file was truncated. Truncation can occur if the compiler runs out of disk space or is interrupted when it is creating the .SBR file.

BSCMAKE Error BK1506
cannot open file 'filename' [: reason]
BSCMAKE could not open the given file. This message may be followed by a message from the operating system, giving additional information. One of the following may have occurred:

  • The file was locked by another process. If reason was Permission denied, the browser in the development environment might be using the file. Close the Browse window and repeat the build.
  • The disk was full.
  • A hardware error occurred.
  • The specified output file had the same name as an existing subdirectory.

BSCMAKE Error BK1507
cannot open temporary file 'filename' [: reason]
BSCMAKE could not open one of its temporary files. This message may be followed by a reason from the operating system, giving additional information. One of the following may have occurred:

  • The TMP environment variable was not set to a valid drive and directory.
  • The disk was full.

BSCMAKE Error BK1508
cannot delete temporary file 'filename' [: reason]
BSCMAKE could not delete one of its temporary files. This message may be followed by a reason from the operating system, giving additional information. One of the following may have occurred:

  • Another process had the file open.
  • A hardware error occurred.

BSCMAKE Error BK1509
out of heap space
BSCMAKE ran out of memory, including virtual memory. One of the following may be a solution:

  • Free some space on disk.
  • Increase the size of the Windows swap file. Consider using the Control Panel, System icon, Performance tab to increase your system's virtual memory, reboot, and retry.
  • Reduce the memory that BSCMAKE will require by using one or more options. Use /Ei or /Es to eliminate some input files. Use /Em to eliminate macro bodies.

BSCMAKE Error BK1510
corrupt .SBR file 'filename'
The given .SBR file is corrupt or does not have the expected format. Recompile to regenerate the .SBR file.

BSCMAKE Error BK1511
invalid response file specification
BSCMAKE did not understand the command-line specification for the response file. The specification was probably wrong or incomplete. For example, the following specification causes this error: bscmake @

BSCMAKE Error BK1512
filename: capacity exceeded
BSCMAKE could not build a browse information file because the number of definitions, references, modules, or other information exceeded the limit. One of the following may be a solution:

  • Exclude some information using the /Em, /Es, or /Ei option.
  • Omit the /Iu option, if it was used.

BSCMAKE Error BK1513
nonincremental update requires all .SBR files
An attempt was made to build a new browse information (.BSC) file, but one or more of the specified .SBR files was truncated. This message is always preceded by warning BK4502, which gives the name of the .SBR file that caused the error.
BSCMAKE can process a truncated, or zero-length, .SBR file only when a .BSC file already exists and is being incrementally updated. One of the following may be a cause:

  • The .BSC file was missing.
  • The wrong filename was specified.
  • The file was corrupted, and a full build was required.

BSCMAKE Error BK1514
all .SBR files truncated, none found in filename
 None of the .SBR files specified for an update was a part of the original browse information (.BSC) file. This message is always preceded by warning BK4502, which gives the name of the .SBR file that caused the error. One of the following may be a cause:

  • The wrong filename was specified.
  • The file was corrupted, and a full build was required.

BSCMAKE Error BK1515
'bscfile': incompatible version: cannot incrementally update
 The given browse information (.BSC) file was not created with this version of BSCMAKE. A .BSC file can be incrementally built only by the same version of BSCMAKE as the one used to fully build that file.

BSCMAKE Error BK1516
'bscfile' corrupt; cannot incrementally update
 The given browse information (.BSC) file was corrupted, possibly due to a system failure during the build. Delete the .BSC file, rebuild all .SBR files, then rebuild the .BSC file.

BSCMAKE Error BK1517
source file for 'filename' compiled with both /Yc and /Yu
 The given .SBR file refers to itself. Probably the file was recompiled with the /Yu option after compiling with /Yc. Reset the compiler options for the source file to /Yc, then rebuild all to generate new .SBR files for the project. Do not subsequently compile the same source file using /Yu.

BSCMAKE Warning BK4500
UNKNOWN WARNING
 An unknown warning condition was detected by BSCMAKE. Note the circumstances of the warning, try to isolate the problem and create a reproducible test case, then report it to technical support.

BSCMAKE Warning BK4501
ignoring unknown option 'option'
 BSCMAKE did not recognize the given option and ignored it.

BSCMAKE Warning BK4502
truncated .SBR file 'filename' not in filename
 The given zero-length .SBR file, specified during an update, was not originally part of the browse information (.BSC) file. If a zero-length file that is not part of the original build of the .BSC file is specified during a rebuild of that file, BSCMAKE issues this warning. One of the following may be a cause:

  • The wrong filename was specified.
  • The file was deleted. (Error BK1513 will result.)
  • The file was corrupted, requiring a full build.

BSCMAKE Warning BK4503
minor error in .SBR file 'filename' ignored
The given .SBR file contained an error that did not halt the build. However, the resulting .BSC file may not be correct. Recompile to regenerate the .SBR file.


C Run-Time Errors R6002 through R6025

The following descriptions cover C Run-Time Errors R6002 through R6025 for mixed-language programming:

C Run-Time Error R6002
floating-point support not loaded
The program needs the floating-point library, but the library was not linked to the program. One of the following may have occurred:

  • The program was compiled or linked with an option (such as /FPi87) that required a coprocessor, but the program was run on a machine that did not have a coprocessor installed.
  • A format string for a printf or scanf function contained a floating-point format specification, and the program did not contain any floating-point values or variables.
  • The compiler minimizes a program's size by loading floating-point support only when necessary. The compiler cannot detect floating-point format specifications in format strings, so it does not load the necessary floating-point routines.
  • Use a floating-point argument to correspond to the floating-point format specification, or perform a floating-point assignment elsewhere in the program. This causes floating-point support to be loaded.
  • In a mixed-language program, a C library was specified before a FORTRAN library when the program was linked. Relink and specify the C library last.

C Run-Time Error R6005
not enough memory on _exec
 Not enough memory was available to load the process being spawned. This error occurs when a child process that was spawned by one of the _exec library routines fails and the operating system cannot return control to the parent process.

C Run-Time Error R6006
invalid format on _exec
The file to be executed by one of the _exec functions was not in the correct format for an executable file. This error occurs when a child process that was spawned by one of the _exec library routines fails and the operating system cannot return control to the parent process.

C Run-Time Error R6007
invalid environment on _exec
During a call to an _exec function, the operating system found that the child process was given an invalid environment block. This error occurs when a child process that was spawned by one of the _exec library routines fails and the operating system cannot return control to the parent process.

C Run-Time Error R6008
not enough space for arguments
There was enough memory to load the program but not enough memory to create the argv array. One of the following may be a solution:

  • Increase the amount of virtual memory available to the program. Consider using the Control Panel, System icon, Performance tab to increase your system's virtual memory, reboot, and retry.
  • Reduce the number and size of command-line arguments.
  • Reduce the environment size by removing unnecessary variables.

C Run-Time Error R6009
not enough space for environment
There was enough memory to load the program but not enough memory to create the envp array. One of the following may be a solution:

  • Increase the amount of memory available to the program.
  • Reduce the number and size of command-line arguments.
  • Reduce the environment size by removing unnecessary variables.
If your program uses the compact, large, or huge memory model, this error may be avoided by using LINK's /CPARM:1 command-line option. This option causes unused near heap space to be allocated to the far heap.

C Run-Time Error R6016
not enough space for thread data
The program did not receive enough memory from the operating system to complete a _beginthread call. When a new thread is started, the library must create an internal database for the thread. If the database cannot be expanded with memory provided by the operating system, the thread will not begin and the calling process will stop.

C Run-Time Error R6017
unexpected multithread lock error
The process received an unexpected error while trying to access a C run-time multithread lock on a system resource. This error usually occurs if the process inadvertently alters the run-time heap data. However, it can also be caused by an internal error in the run-time or operating-system code.

C Run-Time Error R6018
unexpected heap error
The program encountered an unexpected error while performing a memory-management operation. This error usually occurs if the program inadvertently alters the run-time heap data. However, it can also be caused by an internal error in the run-time or operating-system code. If your compiler provides a library containing _heapchk and _heapwalk, you can use these functions to diagnose this error.

C Run-Time Error R6019
unable to open console device
The program called a console function declared in CONIO.H, but the operating system did not grant access to the console.

C Run-Time Error R6021
no main procedure
The program does not have a procedure called main. Make sure that all object and library modules have been linked into the executable.

C Run-Time Error R6024
not enough space for _onexit/atexit table
There was no memory available for the _onexit or atexit function. This error is caused by a low-memory condition.

C Run-Time Error R6025
pure virtual function call
No object has been instantiated to handle the pure virtual function call. This error is caused by calling a virtual function in an abstract base class through a pointer that is created by a cast to the type of the derived class, but is actually a pointer to the base class. This can occur when casting from a void* to a pointer to a class when the void* was created during the construction of the base class.


CVPACK Messages CK1001 through CK4010

The following descriptions cover CVPACK error CK1001 through warning CK4010:

CVPACK Fatal Error CK1001
out of memory
CVPACK ran out of memory. One of the following may be a solution:

  • Free some space on disk.
  • Increase the virtual memory available. Consider using the Control Panel, System icon, Performance tab to increase your system's virtual memory, reboot, and retry.
  • Recompile one or more of the object files without debugging information. If the file was compiled using /debug:full (or /Zi or /Z7), either use /debug:minimal (or /Zd) or do not use a debugging option.

CVPACK Fatal Error CK1002
out of memory
CVPACK ran out of memory. One of the following may be a solution:

  • Free some space on disk.
  • Increase the size of the Windows paging file, or the Windows swap file.
  • Recompile one or more of the object files without debugging information. If the file was compiled using /Zi or /Z7, either use /Zd or do not use a debugging option.

CVPACK Fatal Error CK1003
cannot open file : filename
CVPACK could not open the given file. One of the following may be a cause:

  • The file does not exist. Check the spelling of the filename and path.
  • The file was opened or deleted by another process.
  • There was not enough space on disk.

CVPACK Fatal Error CK1004
filename is read-only
The given file is a read-only file, or the path is on a read-only drive.

CVPACK Fatal Error CK1005
invalid executable file
CVPACK could not process the executable file. One of the following may be a cause:

  • The debugging information in the executable file is corrupt.
  • The executable file is a zero-length file.

CVPACK Fatal Error CK1006
invalid module module
The module does not have a valid format or is corrupt. Recompile and relink.

CVPACK Fatal Error CK1007
invalid table table in module module
The given table in the given object file is not valid, or the module is corrupt. Recompile and relink. If the error recurs, try using different options.

CVPACK Fatal Error CK1008
cannot write output file
 The disk is probably full. This error leaves a corrupt file on disk.

CVPACK Fatal Error CK1011
type information corrupt, recompile module modulename
The given object file contains corrupted information. Recompile. Try compiling with a different /debug keyword.

CVPACK Fatal Error CK1012
no debugging information
The executable file does not contain debugging information. Do one of the following:

  • To put at least minimal debugging information into the executable file, link using the /DEBUG option.
  • To include full debugging information in an object file, compile or assemble using the /Zi or /Z7 option.
  • To include minimal information and line numbers in an object file, compile or assemble using the /Zd option.

CVPACK Fatal Error CK1013
incompatible version of debugging information
 One of the following has occurred:

  • The executable file was linked using an obsolete or unsupported linker.
  • The executable file was already packed using a previous version of CVPACK.
  • The executable file is corrupt. Recompile and relink.

CVPACK Fatal Error CK1017
cannot find precompiled types file; relink with filename
The program used a precompiled header, but the program was linked without filename. This file is the object file that was created when the header was precompiled. If the program uses a library that was created using precompiled headers, then filename was not linked from the library. One of the following may be a solution:

  • Extract the object from the library and link it to the program explicitly.
  • Force LINK to include the object in the program by specifying the /INCLUDE option with a symbol from the object.
  • Change the source code so that code or data in filename is referenced either from an object file that uses the library or from another module that is being linked from the library.

CVPACK Fatal Error CK1018
userfile cannot use precompiled types file pctfile : type counts do not match
The userfile uses the precompiled types file pctfile, but pctfile does not contain the correct number of types for userfile. Recompile userfile and relink. If a makefile is used, check the makefile dependencies.

CVPACK Fatal Error CK1021
userfile cannot use precompiled types file pctfile : signatures do not match
 The userfile uses the precompiled types file pctfile, but the internal signature in pctfile does not match the internal signature in userfile. Probably pctfile was rebuilt but userfile was not rebuilt. Recompile userfile and relink. If a makefile is used, check the makefile dependencies.

CVPACK Fatal Error CK1022
cannot open program database pdbfile
CVPACK could not open the given program database (.PDB file). One of the following may be a cause:

  • The .PDB file does not exist. Check the spelling of the filename and path.
  • The .PDB file was opened or deleted by another process.
CVPACK and LINK look for .PDB files in the following locations in this order:
  1. Where the .EXE or .DLL resides (the absolute path written in the .OBJ file).
  2. Where the .OBJ or .DLL is opened from.
You cannot specify a .PDB file's name or location on the command line.

CVPACK Fatal Error CK1023
modulename cannot use program database pdbfile : module newer than database
 The .OBJ file modulename uses the .PDB file pdbfile, but pdbfile is older than modulename. Recompile and relink. If a makefile is used, check the makefile dependencies.

CVPACK Fatal Error CK1024
modulename cannot use program database pdbfile: signatures do not match
The .OBJ file modulename uses the .PDB file pdbfile, but the internal signature in pdbfile does not match the internal signature in modulename. Delete modulename, recompile, and relink. If a makefile is used, check the makefile dependencies.

CVPACK Fatal Error CK1025
incorrect COFF symbol table
CVPACK was unable to interpret the COFF symbols emitted by the compiler. Recompile and relink.

CVPACK Fatal Error CK1027
you have accessed an incorrect version of MSPDB60.DLL, recheck your installation

CVPACK Fatal Error CK1028
file compiled /Yc /Yu /Z7; cannot create debug info, recompile all with /Zi
You created two PCH files, one based on the other using the /Z7 compiler option. Only one precompiled type object can be referenced. The only way to use PCH files based on other PCH files is to use the /Zi compiler option to put all types in the .PDB file.

CVPACK Warning CK4001
file already packed
CVPACK took no action because the executable file has already been processed by this version of CVPACK.

CVPACK Warning CK4003
error in lexical scopes for module module; symbols deleted
The scoping of symbols in the given object module was corrupted. CVPACK deleted the symbols in the module. This is probably a compiler error. Recompile and relink the object file.

CVPACK Warning CK4004
unrecognized symbols discarded; recompile module modulename
The compiler generated an invalid symbol record in the modulename object file. CVPACK discarded the record. The debugger can run the resulting executable file. However, the symbol will be accessible only by the decorated name known to the linker, and display of the symbol will be limited. To see decorated names of identifiers, use DUMPBIN /UNDECORATE.

CVPACK Warning CK4005
unrecognized type converted to NULL; recompile module modulename
The compiler generated an invalid type record in the modulename object file. CVPACK discarded the record. The debugger can run the resulting executable file, but display of objects that reference the invalid type will be limited.

CVPACK Warning CK4006
type length limit exceeded; converted to NULL
A struct, enum, union, or class was too large for CVPACK to process. You can use the executable file with the debugger, but you cannot reference the object or type while debugging.

CVPACK Warning CK4007
unrecognized option /option; option ignored
The given option is not a valid CVPACK option. CVPACK ignored the specification and attempted to run using the rest of the command line.

CVPACK Warning CK4008
source line limit exceeded in module filename; source line info discarded
CVPACK could not translate the debugging information in the given filename module because filename was too large. CVPACK discarded the debugging information for this module. Break up the module into smaller files.

CVPACK Warning CK4009
exceeded 64K types at module; discarding subsequent types
The debugging information exceeded a CVPACK limit. One of the following may be a solution:

  • Compile some object files without debugging information.
  • Avoid including unneeded header files.
The checksum can be calculated only when running on WNT systems.

CVPACK Warning CK4010
cannot update checksum
The checksum can be calculated only when running on WNT systems.


CVTRES Messages CVT1100 through CVT4001

The following descriptions cover CVT1100 through warning CVT4001:

CVTRES Fatal Error CVT1100
duplicate resource -- type:type, name:name, language:language, flags:flags, size:size
The given resource was specified more than once.

CVTRES Fatal Error CVT1101
cannot open filename for reading
CVTRES could not open and read the given file. One of the following may be a cause:

  • The file does not exist. Check the spelling of the filename and path.
  • The file does not have read permission.
  • The file was opened or deleted by another process.
  • There was not enough space on disk.

CVTRES Fatal Error CVT1102
out of memory; size bytes required
There was not enough memory for CVTRES to complete the operation.

CVTRES Fatal Error CVT1103
cannot read filename
An unrecoverable error occurred when CVTRES attempted to read the given file. Possibly the file is corrupt.

CVTRES Fatal Error CVT1104
cannot get location in file
CVTRES could not determine the current location in the file. Possibly the file is corrupt.

CVTRES Fatal Error CVT1105
cannot seek in file
CVTRES could not go to a location in the file. Possibly the file is corrupt.

CVTRES Fatal Error CVT1106
cannot write to file
An unrecoverable error occurred when CVTRES attempted to write to the given file.

CVTRES Fatal Error CVT1107
filename is corrupt
The given file is not a valid resource file.

CVTRES Fatal Error CVT1108
cannot open filename for writing
CVTRES could not open and write to the given file. One of the following may be a cause:

  • The file does not exist. Check the spelling of the filename and path.
  • The file does not have write permission.
  • The file was opened or deleted by another process.
  • There was not enough space on disk.

CVTRES Warning CVT4001
machine type not specified; assumed type
CVTRES did not find a machine specification. It assumed the given machine type. If the default is incorrect, rerun CVTRES using the /MACHINE option.


Math Errors M6101 through M6205 (ia32 only)

The following descriptions cover Math Errors M6101 through M6205, which can occur on ia32 systems. All of these math errors terminate the program with an exit code of 3 (a severe error):

Math Error M6101
invalid
 An invalid operation occurred. This error usually occurs when the operand is NaN (not a number) or infinity.

Math Error M6102
denormal
 A very small floating-point number was generated, which may no longer be valid because of a loss of significance. Denormal floating-point exceptions are usually masked, causing them to be trapped and operated upon.

Math Error M6103
divide by 0
 A floating-point operation attempted to divide by zero.

Math Error M6104
overflow
 An overflow occurred in a floating-point operation.

Math Error M6105
underflow
 An underflow occurred in a floating-point operation. Underflow floating-point exceptions are usually masked, causing the underflowing value to be replaced by 0.0.

Math Error M6106
inexact
 Loss of precision occurred in a floating-point operation. This exception is usually masked. Many floating-point operations cause a loss of precision.

Math Error M6107
unemulated
 An attempt was made to execute a coprocessor instruction that is invalid or is not supported by the emulator.

Math Error M6108
square root
 The operand in a square-root operation was negative.

Note: The sqrt function in the C run-time library and the FORTRAN intrinsic function SQRT do not generate this error. The C sqrt function checks the argument before performing the operation and returns an error value if the operand is negative. The FORTRAN SQRT function generates the Math Error M6201.

Math Error M6110
stack overflow
 A floating-point expression caused a stack overflow on the 8087/287/387 coprocessor or the emulator. Stack-overflow floating-point exceptions are trapped up to a limit of seven levels in addition to the eight levels usually supported by the 8087/287/387 coprocessor.

Math Error M6111
stack underflow
 A floating-point operation resulted in a stack underflow on the 8087/287/387 coprocessor or the emulator. This error is often caused by a call to a long double function that does not return a value.

Math Error M6201
'function' : _DOMAIN error
 An argument to the given function was outside the domain of legal input values for that function. For example, the following statements generate this error:
result = sqrt(-1.0) // C statement
result = SQRT(-1.0) ! FORTRAN statement

Math Error M6202
'function' : _SING error
 An argument to the given function was a singularity value for this function. The function is not defined for that argument. For example, in FORTRAN the following statement generates this error:
result = LOG10(0.0)

Math Error M6203
'function' : _OVERFLOW error
 The given function result was too large to be represented.

Math Error M6205
'function' : _TLOSS error
 A total loss of significance (precision) occurred. This error may be caused by giving a very large number as the operand of sin, cos, or tan because the operand must be reduced to a number between 0 and 2*pi.


NMAKE Messages

The following topics cover NMAKE Error U1000 through Warning U4011:

  • NMAKE Errors U1000 to U1049
  • NMAKE Errors U1050 to U1100
  • NMAKE Error U2001 to Warning U4011


NMAKE Error U1000 through U1049

NMAKE Error U1000 through U1050

The following topics cover NMAKE Error U1000 through U1049:

NMAKE Fatal Error U1000
syntax error : ')' missing in macro invocation
 A left parenthesis, (, appeared without a matching right parenthesis, ), in a macro invocation. The correct form is $(name); $n is allowed for one-character names.

NMAKE Fatal Error U1001
syntax error : illegal character 'character' in macro
 The given character appeared in a macro but was not a letter, number, or underscore (_). If the colon (:) is omitted in a macro expansion, the following error occurs: syntax error : illegal character '=' in macro

NMAKE Fatal Error U1002
syntax error : invalid macro invocation '$'
 A single dollar sign ($) appeared without a macro name associated with it. The correct form is $(name). To specify a dollar sign, use a double dollar sign ($$) or precede the dollar sign with a caret (^).

NMAKE Fatal Error U1003
syntax error : '=' missing in macro
 A macro invocation contained a colon (:), which begins a substitution, but it did not contain an equal sign (=). The correct form is:
$(macroname:oldstring=newstring)

NMAKE Fatal Error U1004
syntax error : macro name missing
 One of the following occurred:

  • The name of a macro being defined was itself a macro invocation that expanded to nothing. For example, if the macro named ONE is undefined or has a null value, the following macro definition causes this error:
    $(ONE)=TWO

  • A macro invocation did not specify a name in the parentheses. The following specification causes this error:
    $()
    The syntax for using a macro is:
    $(name)

NMAKE Fatal Error U1005
syntax error : text must follow ':' in macro
A string substitution was specified for a macro, but the string to be changed in the macro was not specified.

NMAKE Fatal Error U1006
syntax error : missing closing double quotation mark
An opening double quotation mark (") appeared without a closing double quotation mark.

NMAKE Fatal Error U1007
double quotation mark not allowed in name
The specified target name or filename contained a double quotation mark ("). Double quotation marks can surround a filename but cannot be contained within it.

NMAKE Fatal Error U1017
unknown directive '!directive'
The specified directive is not one of the recognized directives.

NMAKE Fatal Error U1018
directive and/or expression part missing
The directive was incompletely specified. The expression part of the directive is required.

NMAKE Fatal Error U1019
too many nested !IF blocks
 The limit on nesting of !IF directives was exceeded. The !IF preprocessing directives include !IF, !IFDEF, !IFNDEF, !ELSE IF, !ELSE IFDEF, and !ELSE IFNDEF.

NMAKE Fatal Error U1020
end-of-file found before next directive
An expected directive was missing. For example, an !IF was not followed by an !ENDIF.

NMAKE Fatal Error U1021
syntax error : !ELSE unexpected
 An !ELSE directive was found that was not preceded by an !IF directive, or the directive was placed in a syntactically incorrect place. The !IF preprocessing directives include !IF, !IFDEF, !IFNDEF, !ELSE IF, !ELSE IFDEF, and !ELSE IFNDEF.

NMAKE Fatal Error U1022
missing terminating character for string/program invocation : 'char'
 One of the following occurred:

  • The closing double quotation mark (") in a string comparison in a directive was missing.
  • The closing bracket (]) in a program invocation in a directive was missing.

NMAKE Fatal Error U1023
syntax error in expression
An expression was invalid. Check the allowed operators and operator precedence.

NMAKE Fatal Error U1024
illegal argument to !CMDSWITCHES
An unrecognized command switch was specified.

NMAKE Fatal Error U1025
syntax error : !ENDIF unexpected
An !ENDIF directive was found that was not preceded by an !IF directive, or the directive was placed in a syntactically incorrect place. The !IF preprocessing directives include !IF, !IFDEF, !IFNDEF, !ELSE IF, !ELSE IFDEF, and !ELSE IFNDEF.

NMAKE Fatal Error U1031
filename missing (or macro is null)
An !INCLUDE directive was found, but the name of the file to be included was missing or a macro representing the filename expanded to nothing.

NMAKE Fatal Error U1033
syntax error : 'string' unexpected
The given string is not part of the valid syntax for a makefile. The following are examples of causes and results of this error:

  • If the closing set of angle brackets (<<) for an inline file are not at the beginning of a line, the following error occurs: syntax error : 'EOF' unexpected
  • If a macro definition in the makefile contained an equal sign (=) without a preceding name or if the name being defined is a macro that expands to nothing, the following error occurs: syntax error : '=' unexpected
  • If the semicolon (;) in a comment line in TOOLS.INI is not at the beginning of the line, the following error occurs: syntax error : ';' unexpected
  • If the makefile has been formatted by a word processor, the following error can occur: syntax error : ':' unexpected

NMAKE Fatal Error U1034
syntax error : separator missing
The colon (:) that separates targets and dependents is missing.

NMAKE Fatal Error U1035
syntax error : expected ':' or '=' separator
Either a colon (:) or an equal sign (=) was expected. Possible causes include the following:

  • A target was not followed by a colon.
  • A single-letter target was followed by a colon and no space (such as a:). NMAKE interpreted it as a drive specification.
  • An inference rule was not followed by a colon.
  • A macro definition was not followed by an equal sign.
  • A character followed a backslash (\) that was used to continue a command to a new line.
  • A string appeared that did not follow any NMAKE syntax rule.
  • The makefile was formatted by a word processor.

NMAKE Fatal Error U1036
syntax error : too many names to left of '='
Only one string is allowed to the left of a macro definition.

NMAKE Fatal Error U1037
syntax error : target name missing
A colon (:) was found before a target name was found. At least one target is required.

NMAKE Fatal Error U1038
internal error : lexer
Note the circumstances of the error, try to isolate the problem, create a reproducible test case, and report to technical support.

NMAKE Fatal Error U1039
internal error : parser
Note the circumstances of the error, try to isolate the problem, create a reproducible test case, and report to technical support.

NMAKE Fatal Error U1040
internal error : macro expansion
Note the circumstances of the error, try to isolate the problem, create a reproducible test case, and report to technical support.

NMAKE Fatal Error U1041
internal error : target building
Note the circumstances of the error, try to isolate the problem, create a reproducible test case, and report to technical support.

NMAKE Fatal Error U1042
internal error : expression stack overflow
Note the circumstances of the error, try to isolate the problem, create a reproducible test case, and report to technical support.

NMAKE Fatal Error U1043
internal error : temp file limit exceeded
Note the circumstances of the error, try to isolate the problem, create a reproducible test case, and report to technical support.

NMAKE Fatal Error U1045
spawn failed : message
A program or command called by NMAKE failed for the given reason.

NMAKE Fatal Error U1047
argument before ')' expands to nothing
The parentheses following the preprocessing operator DEFINED or EXIST either were empty or contained an argument that evaluated to a null string.

NMAKE Fatal Error U1048
cannot write to file 'filename'
NMAKE could not write to the given file. One cause of this error is a read-only file specified with /X.

NMAKE Fatal Error U1049
macro or inline file too long (maximum : 64K)
An inline file or a macro exceeded the limit of 64K.

Return to Main NMAKE Messages Page


NMAKE Error U1050 through U1100

The following topics cover NMAKE Error U1050 through U1100:

NMAKE Fatal Error U1050
message
The message specified with the !ERROR directive was displayed.

NMAKE Fatal Error U1051
out of memory
NMAKE ran out of memory, including virtual memory, because the makefile was too large or complex. One of the following may be a solution:

  • Free some space on disk.
  • Increase the size of the Windows paging file, or the Windows swap file.
  • If only part of the makefile is being used, either divide the makefile into separate files or use !IF preprocessing directives to limit the amount that NMAKE must process. The !IF directives include !IF, !IFDEF, !IFNDEF, !ELSE IF, !ELSE IFDEF, and !ELSE IFNDEF.

NMAKE Fatal Error U1052
file 'filename' not found
NMAKE could not find the given file, which was specified with one of the following:

  • /F option
  • !INCLUDE preprocessing directive
  • At sign (@) specifier for a response file
Check that the file exists and the filename is spelled correctly.

NMAKE Fatal Error U1053
file 'filename' unreadable
The file cannot be read. One of the following may be a cause:

  • The file is in use by another process.
  • A bad area exists on disk.
  • A bad file-allocation table exists.

NMAKE Fatal Error U1054
cannot create inline file 'filename'
NMAKE failed to create the given inline file. One of the following may be a cause:

  • A file by that name exists with a read-only attribute.
  • The disk is full.

NMAKE Fatal Error U1055
out of environment space
The operating system ran out of room for environment variables. Either increase the environment space or set fewer environment variables.

NMAKE Fatal Error U1056
cannot find command processor
The command processor was not in the path specified in the COMSPEC or PATH environment variables. NMAKE uses COMMAND.COM or CMD.EXE as a command processor when executing commands. It looks for the command processor first in the path set in COMSPEC. If COMSPEC does not exist, NMAKE searches the directories specified in PATH.

NMAKE Fatal Error U1057
cannot delete temporary file 'filename'
NMAKE failed to delete the temporary inline file.

NMAKE Fatal Error U1058
terminated by user
NMAKE was halted by Ctrl+C or Ctrl+BREAK.

NMAKE Fatal Error U1059
syntax error : '}' missing in dependent
A search path for a dependent was incorrectly specified. Either a space existed in the path or the closing brace (}) was omitted. The syntax for a directory specification for a dependent is {directories}dependent where directories specifies one or more paths, each separated by a semicolon (;). No spaces are allowed. If part or all of a search path is replaced by a macro, make sure no spaces exist in the macro expansion.

NMAKE Fatal Error U1060
unable to close file : 'filename'
NMAKE encountered an error while closing a file. One of the following may be a cause:

  • The file is a read-only file.
  • There is a locking or sharing violation.
  • The disk is full.

NMAKE Fatal Error U1061
/F option requires a filename
The /F command-line option must be followed by either a makefile name or a dash (-), which represents standard input.

NMAKE Fatal Error U1062
missing filename with /X option
The /X command-line option requires the name of the file to which diagnostic error output should be redirected. To use standard output, specify a dash (-) as the output filename.

NMAKE Fatal Error U1063
missing macro name before '='
A macro definition on the NMAKE command line contained an equal sign (=) without a preceding name. This error can occur if the macro name being defined is itself a macro that expands to nothing.

NMAKE Fatal Error U1064
MAKEFILE not found and no target specified
The NMAKE command line did not specify a makefile or a target, and the current directory did not contain a file named MAKEFILE. NMAKE requires either a makefile or a command-line target (or both). To make a makefile available to NMAKE, either specify the /F option or place a file named MAKEFILE in the current directory. NMAKE can create a command-line target by using an inference rule if a makefile is not provided.

NMAKE Fatal Error U1065
invalid option 'option'
The specified option is not a valid option for NMAKE.

NMAKE Fatal Error U1069
no match found for wildcard 'filename'
There is no file that matches the given filename, which was specified using one or more wildcards (* and ?). A target file that is specified using a wildcard must exist on disk.

NMAKE Fatal Error U1070
cycle in macro definition 'macroname'
The given macro definition contained a macro whose definition contained the given macro. Circular macro definitions are invalid. For example, the following macro definitions:

ONE=$(TWO)
TWO=$(ONE)

cause the following error:

cycle in macro definition 'TWO'

NMAKE Fatal Error U1071
cycle in dependency tree for target 'targetname'
A circular dependency exists in the dependency tree for the given target. The given target is a dependent of one of the dependents of the given target. Circular dependencies are invalid.

NMAKE Fatal Error U1072
cycle in include files : 'filename'
The given file includes a file that eventually includes the given file. Inclusions (using the !INCLUDE preprocessing directive) cannot be circular.

NMAKE Fatal Error U1073
don't know how to make 'targetname'
The specified target does not exist, and there is no command to execute or inference rule to apply. One of the following may be a solution:

  • Check the spelling of the target name.
  • If targetname is a pseudotarget, specify it as a target in another description block.
  • If targetname is a macro invocation, be sure it does not expand to a null string.

NMAKE Fatal Error U1076
name too long
A string exceeded one of the following limits:

  • A macro name cannot exceed 1024 characters.
  • A target name (including its path) cannot exceed 256 characters.
  • A command cannot exceed 2048 characters.

NMAKE Fatal Error U1077
'program' : return code 'value'
The given command or program called by NMAKE failed and returned the given exit code. To suppress this error and continue the NMAKE session, use the /I option, the .IGNORE dot directive, or the dash (-) command modifier. To continue the NMAKE session for unrelated parts of the dependency tree, use the /K option.

NMAKE Fatal Error U1078
constant overflow at 'expression'
The given expression contained a constant that exceeded the range - 2,147,483,648 to 2,147,483,647. The constant appeared in one of the following situations:

  • An expression specified with a preprocessing directive
  • An error level specified with the dash (-) command modifier

NMAKE Fatal Error U1079
illegal expression : divide by zero
An expression tried to divide by zero.

NMAKE Fatal Error U1080
operator and/or operand usage illegal
The expression incorrectly used an operator or operand. Check the allowed set of operators and their order of precedence.

NMAKE Fatal Error U1081
'filename' : program not found
NMAKE could not find the given program in order to run it. Make sure that the program is in a directory specified in the PATH environment variable and is not misspelled.

NMAKE Fatal Error U1082
'command' : cannot execute command; out of memory
There is not enough memory to execute the given command. One solution is to use the /N option to generate a batch file, then run the batch file instead of using NMAKE. In most cases the results will be the same.

NMAKE Fatal Error U1083
target macro 'target' expands to nothing
The given target is an invocation of a macro that has not been defined or has a null value. NMAKE cannot process a null target.

NMAKE Fatal Error U1084
cannot create temporary file 'filename'
NMAKE was unable to create the temporary file it needs when it processes the makefile. One of the following may be a cause:

  • The file already exists with a read-only attribute.
  • There is insufficient disk space to create the file.
  • The directory specified in the TMP environment variable does not exist.

NMAKE Fatal Error U1085
cannot mix implicit and explicit rules
A target and a pair of inference-rule extensions were specified on the same line. Targets cannot be named in inference rules.

NMAKE Fatal Error U1086
inference rule cannot have dependents
The colon (:) in an inference rule must be followed by one of the following:

  • Newline character
  • Semicolon (;), which can be followed by a command
  • Number sign (#), which can be followed by a comment

NMAKE Fatal Error U1087
cannot have : and :: dependents for same target
A target cannot be specified in both a single-colon (:) and a double-colon (::) dependency. To specify a target in multiple description blocks, use :: in each dependency line.

NMAKE Fatal Error U1088
invalid separator '::' on inference rule
An inference rule must be followed by a single colon (:).

NMAKE Fatal Error U1089
cannot have build commands for directive 'targetname'
Dot directives cannot be followed by commands. The dot directives are .IGNORE, .PRECIOUS, .SILENT, and .SUFFIXES.

NMAKE Fatal Error U1090
cannot have dependents for directive 'targetname'
Dot directives cannot be followed by dependents. The dot directives are .IGNORE, .PRECIOUS, .SILENT, and .SUFFIXES.

NMAKE Fatal Error U1092
too many names in rule
An inference rule cannot specify more than two extensions.

NMAKE Fatal Error U1093
cannot mix dot directives
Multiple dot directives cannot be specified on one line. The dot directives are .IGNORE, .PRECIOUS, .SILENT, and .SUFFIXES.

NMAKE Fatal Error U1094
syntax error : only (NO)KEEP allowed here
Something other than KEEP or NOKEEP appeared after the closing set of angle brackets (<<) specifying an inline file. Only KEEP, NOKEEP, or a newline character may follow the angle brackets. No spaces, tabs, or other characters may appear. KEEP preserves the inline file on disk. NOKEEP deletes the file after the NMAKE session. The default is NOKEEP.

NMAKE Fatal Error U1095
expanded command line 'commandline' too long
After macro expansion, the given command line exceeded the limit on length of command lines for the operating system. If the command is for a program that can accept command-line input from a file, change the command and supply input from either a file on disk or an inline file. For example, LINK and LIB accept input from a response file.

NMAKE Fatal Error U1096
cannot open inline file 'filename'
NMAKE could not create the given inline file. One of the following occurred:

  • The disk was full.
  • A file with that name exists as a read-only file.

NMAKE Fatal Error U1097
filename-parts syntax requires dependent
The current dependency does not have either an explicit dependent or an implicit dependent. Filename-parts syntax, which uses the percent (%) specifier, represents components of the first dependent of the current target.

NMAKE Fatal Error U1098
illegal filename-parts syntax in 'string'
The given string does not contain valid filename-parts syntax.

NMAKE Fatal Error U1099
stack overflow
The makefile being processed was too complex for the current stack allocation in NMAKE. NMAKE has an allocation of 0x3000 (12K). To increase NMAKE's stack allocation, run the EDITBIN utility with a larger stack option: EDITBIN /STACK:stacksize NMAKE.EXE where stacksize is a number greater than the current stack allocation in NMAKE.

NMAKE Fatal Error U1100
macro 'macroname' is illegal in the context of batch rule 'rule'
NMAKE generates this error when the command block of a batch-mode rule directly or indirectly references a special file macro that is not $<. $< is the only allowed macro for batch-mode rules.

Return to Main NMAKE Messages Page


NMAKE Error U2001 through Warning U4011

The following topics cover NMAKE Error U2001 through Warning U4011:

NMAKE Error U2001
no more file handles (too many files open)
NMAKE could not find a free file handle. One of the following may be a solution:

  • Reduce recursion in the build procedures.
  • On W9* systems, increase the number of file handles by changing the FILES setting in CONFIG.SYS to allow a larger number of open files. FILES=50 is the recommended setting.

NMAKE Warning U4001
command file can be invoked only from command line
A command file, which is invoked by the at-sign (@) specifier, cannot contain a specification for another command file. Such nesting is not allowed. The specification was ignored.

NMAKE Warning U4002
resetting value of special macro 'macroname'
The given predefined macro was redefined.

NMAKE Warning U4004
too many rules for target 'targetname'
More than one description block was specified for the given target using single colons (:) as separators. NMAKE executed the commands in the first description block and ignored later blocks. To specify the same target in multiple dependencies, use double colons (::) as the separator in each dependency line.

NMAKE Warning U4005
ignoring rule 'rule' (extension not in .SUFFIXES)
The given rule contained a suffix that is not specified in the .SUFFIXES list. NMAKE ignored the rule. This warning appears only when the /P option is used.

NMAKE Warning U4006
special macro undefined : 'macroname'
The given special macro name is undefined and expands to nothing.

NMAKE Warning U4007
filename 'filename' too long; truncating to 8.3
The base name of the given file has more than eight characters, or the extension has more than three characters. NMAKE truncated the name to an eight-character base and a three-character extension. If long filenames are supported by your file system, enclose the name in double quotation marks (").

NMAKE Warning U4008
removed target 'target'
NMAKE was interrupted while trying to build the given target, and the target file was incomplete. Because the target was not specified in the .PRECIOUS list, NMAKE deleted the file.

NMAKE Warning U4010
'target' : build failed; /K specified, continuing ...
A command in the commands block for the given target returned a nonzero exit code. The /K option told NMAKE to continue processing unrelated parts of the build and to issue an exit code 1 when the NMAKE session is finished. If the given target is itself a dependent for another target, NMAKE issues warning U4011 after this warning.

NMAKE Warning U4011
'target' : not all dependents available; target not built
A dependent of the given target either did not exist or was out-of-date, and a command for updating the dependent returned a nonzero exit code. The /K option told NMAKE to continue processing unrelated parts of the build and to issue an exit code 1 when the NMAKE session is finished. This warning is preceded by warning U4010 for each dependent that failed to be created or updated.

Return to Main NMAKE Messages Page


Profiler Errors PRF1005 through PRF4642

The following descriptions cover Profiler Errors PRF1005 through PRF4642:

Profiler Error PRF1005
fatal error -- common -- operating system ran out of memory
There is not enough memory to run this profiler module.

Profiler Error PRF1011
fatal error -- common -- cannot open file filename
The profiler module could not find the specified file.

Profiler Error PRF1012
fatal error -- common -- cannot read expected number of bytes from file filename
The profiler module could not read the expected number of bytes. This error is often caused by trying to profile an .EXE or .DLL file that was not linked with profiling enabled (/PROFILE linker command-line option).

Profiler Error PRF1013
fatal error -- common -- cannot write expected number of bytes to file filename
The profiler module could not write the expected number of bytes. Perhaps the disk is full or the file is read-only.

Profiler Error PRF1101
fatal error -- common -- missing option specifier
A / or - character was not followed by a command-line option specifier sequence. Check the command line.

Profiler Error PRF1102
fatal error -- common -- option: invalid option
An invalid option was found on the command line. Check the command line.

Profiler Error PRF1103
fatal error -- common -- option option requires an additional parameter.
This option was not followed by the correct number of parameters. Check the command line.

Profiler Error PRF1104
fatal error -- common -- option option requires a numeric parameter
A numeric parameter was expected for this option but was not found. Check the command line.

Profiler Error PRF1105
fatal error -- common -- option option specified more than number times
An option was specified too many times. Check the command line.

Profiler Error PRF1201
fatal error -- common -- missing filename after @
The @ character is supposed to be followed by a response filename. Check the command line.

Profiler Error PRF1202
fatal error -- common -- response files nested too deeply
 Response files can be nested eight deep. Perhaps a response file calls itself recursively.

Profiler Error PRF1301
fatal error -- common -- file filename has an incorrect (old) signature
A PBI, PBO, PBT, _XE, or _LL file does not contain the correct header bytes. Perhaps the file is corrupted or was created by an old version of the profiler.

Profiler Error PRF1302
fatal error -- common -- PBI file filename has an incorrect (old) version number
A PBI file does not contain the correct version number. Perhaps the file is corrupted or was created by an old version of the profiler.

Profiler Error PRF1303
fatal error -- common -- PBT file filename has an incorrect (old) version number
A PBT file does not contain the correct version number. Perhaps the file is corrupted or was created by an old version of the profiler.

Profiler Error PRF1304
fatal error -- common -- PBT or PBO file filename conflicts with current profiling state
There was an attempt to merge a PBT or a PBO file into another PBT file with a different profiling mode selected.

Profiler Error PRF1306
fatal error -- common -- PBT or PBO file filename is not derived from same PBI file
The PBT, PBO, and PBI files are not properly synchronized. Run PREP Phase I again.

Profiler Error PRF1307
fatal error -- common -- CPU type of module module is different from initial one
CPU types for different modules don't match. All modules must be compiled for the same CPU type.

Profiler Error PRF1401
fatal error -- common -- filename: not a portable executable file
Function profiling only: The specified executable file is not a standard executable file for Windows NT 4.0 or Windows 2000. Perhaps it is a 16-bit executable for Windows 3.x.

Profiler Error PRF1421
fatal error -- PREP I -- no input specified
There were no input modules specified for PREP Phase I. Check the command line.

Profiler Error PRF1422
fatal error -- PREP I -- syntax error in /EXC or /INC specification: specification
The /EXC and /INC options require function names or filenames. This specification could not be decoded. Check the command line.

Profiler Error PRF1423
fatal error -- PREP I -- number of modules exceeds number
The maximum number of modules has been exceeded. Restructure the merge procedure to include more stages.

Profiler Error PRF1424
fatal error -- PREP I -- Debugging information in filename is not the right format for profiling, relink with /PROFILE
Could not use debuggine information stored in the Program Database. Debug information, to be used, must be stored in the executable in old-style format. Relink with the /PROFILE option to do this.

Profiler Error PRF1425
fatal error -- PREP I -- filename: invalid runtime relocation, try relink
The profiler found bad relocation information in the program to be profiled. This is usually caused by using an obsolete version of the linker. Relink your code with the new profiler and run PREP again.

Profiler Error PRF1426
A fixed image executable cannot be profiled, relink file without the /fixed switch.
This error can also be caused by omitting the /PROFILE option on the LINK command line.

Profiler Error PRF1427
Executable image too large to profile - try breaking it down into smaller DLLs.
The executable cannot be profile at its present size.

Profiler Error PRF1441
fatal error -- PROFILE -- filename: not a valid Win32s executable file
Win32s only. The Win32s extension could not load this file. Perhaps the file is corrupted, has not been prepared for profiling, or is not a graphical user interface application. If the file were a 16-bit executable, error message 1401 would be issued.

Profiler Error PRF1442
fatal error -- PROFILE -- timestamp of executable has changed since PREP was run
The PBI file was created from an older EXE file. This means that the processed executable file has changed since it was originally created by PREP Phase I. Run PREP Phase I again.

Profiler Error PRF1443
fatal error -- PROFILE -- cannot run program filename
The profiler could not load the EXE file. Check that the original EXE file does run under Windows NT 4.0 or Windows 2000.

Profiler Error PRF1444
this version of Windows does not support this manner of profiling
The function timing (/ft) option is not supported for this version of the Windows system.

Profiler Error PRF1445
Line count and line coverage are not supported on Win32S.
The Win32S version of the profiler does not support line count or line coverage profiling.

Profiler Error PRF1461
fatal error -- PREP II -- no PBT output file specified
Neither the /OT nor /M option was specified. Check the command line.

Profiler Error PRF1462
fatal error -- PREP II -- no PBT input file specified
Neither the /IT nor /M option was specified. Check the command line.

Profiler Error PRF1463
fatal error -- PREP II -- module: different clock/sampling frequency
The sampling frequency for this module is different from that of other modules that were profiled. Rerun PROFILE again for all modules, using the same sampling frequency.

Profiler Error PRF1465
fatal error -- PREP II -- CPU type in PBT or PBO file filename conflicts with current one
 Occurs only during PREP merging. The CPU type does not match the CPU type used to generate the incoming PBT or PBO files. All profiler steps must be run on the same type of computer.

Profiler Error PRF1481
fatal error -- PLIST -- option inconsistent with sorting type
The options for PLIST depend on the kind of profiling being done. This error occurs, for example, when the Sort By Name option is specified for a line profiling run.

Profiler Error PRF1482
fatal error -- PREP or PROFILE -- abnormal termination in PREP or PROFILE detected, PLIST cannot continue
The files output by PREP or PROFILE were not valid because one of these utilities did not complete its task. This error is usually caused by an error during the execution of PREP or PROFILE, such as a missing .MAP file.

Profiler Error PRF1504
fatal error -- common -- illegal fixup address in mapfile filename
The mapfile lists all link-time fixups (including all the function call sites). This error indicates that one of the fixups was illegal, perhaps because the mapfile was not generated by the same link as the corresponding EXE (or DLL). This error is often preceded by the warning (PRF4528) about the EXE and mapfile timestamps being out of sync.

Profiler Error PRF1521
fatal error -- PREP I -- no functions were marked for profiling in module module
Function profiling only: at least one function must be included for profiling in each module. Check the /INC, /EXC, and /EXCALL options on the command line.

Profiler Error PRF1522
fatal error -- PREP I -- more than one function matched entry specification: funcname1 and funcname2
 Function profiling only: there were two or more functions with matching names. Perhaps these are C++ overloaded functions. Use decorated names to specify the functions.

Profiler Error PRF1523
fatal error -- PREP I -- filename is not profiled, and can not import modified version version
 For function-level profiles, PREP uses modified EXEs and DLLs, with modified names with extensions _XE and _LL. If any modules listed in the import table of a profiled module refer to another profiled module, but the imported module is itself not being profiled, then the import table of that imported module cannot be changed, and this error occurs. The solution is to include the offending module in the profile.

Profiler Error PRF1524
fatal error -- PREP I -- Debugging info in filename is not the right format for profiling, relink with /PROFILE
You must link executable files with profiling enabled (the /PROFILE linker option) to profile them. Change your linker options, rebuild, and re-run PREP.

Profiler Error PRF1542
fatal error -- PROFILE -- cannot set or delete environment variable var
Function profiling only: The specified environment variable was unavailable.

Profiler Error PRF1543
fatal error -- PROFILE -- NtQueryIntervalProfile: NT internal error number occurred
A Windows NT 4.0 or Windows 2000 error was detected.

Profiler Error PRF1544
fatal error -- PROFILE -- NtSetIntervalProfile: NT internal error number occurred
A Windows NT 4.0 or Windows 2000 error was detected.

Profiler Error PRF1545
fatal error -- PROFILE -- function sampling is no longer supported
Function sampling is not supported in this version. Use function timing to get more accurate results.

Profiler Error PRF1621
fatal error -- PREP I -- no debugging information in file filename
Line profiling only: debugging information must be included in the executable file. Run the compiler and linker again with the debugging options set.

Profiler Error PRF1622
fatal error -- PREP I -- no source lines marked for profiling in module module
Line profiling only: at least one line must be included for profiling in each module. Check the /INC, /EXC, and /EXCALL options on the command line.

Profiler Error PRF1641
fatal error -- PROFILE -- user-defined breakpoint found at address
Line profiling only: No breakpoints may be set in the executable modules being profiled. These are not breakpoints set by the debugger but rather embedded INT 3 instructions. This error is only fatal if the INT 3 instruction is encountered during the execution of your program.

Profiler Error PRF1642
fatal error -- PROFILE -- unexpected single-step exception occurred at address
Line profiling only: There was a problem with the executable file. Try relinking and rerunning PREP Phase I.

Profiler Error PRF1643
fatal error -- PROFILE -- an access violation occurred at address
Line profiling only: There was a problem with the executable file. Try relinking and rerunning PREP Phase I. Check the EXE file with the debugger.

Profiler Error PRF2541
error -- PROFILE -- cannot start sampler
Perhaps the executable program is too large.

Profiler Error PRF2542
error -- PROFILE -- cannot stop sampler
Perhaps the executable program is too large.

Profiler Error PRF4101
warning -- common -- option option overrides an earlier option
Two or more mutually exclusive switches were specified, or the same switch was specified more than once. The last switch takes precedence.

Profiler Error PRF4106
warning -- common -- function/source/object/lib name was never matched
The program element was not found. Make sure the name was spelled or decorated correctly.

Profiler Error PRF4107
warning -- common -- /SF option not valid for line-level or sample profiles
The start function option should be used only with function timing, function counting, or function coverage profiling.

Profiler Error PRF4111
warning -- common -- no error file (/E) specified for /A option
The /A option cannot be used without the /E option. The /A option is ignored and the error output sent to stdout.

Profiler Error PRF4421
warning -- PREP I -- an offset duplication was detected
There appears to be a problem with the (codeview) line number debug information. Perhaps there is an aliasing problem.

Profiler Error PRF4422
warning -- PREP I -- filename imports unknown module module
PREP searches for imported modules (mostly DLLs) in the following sequence:

  • Directory PREP itself lives in
  • Current directory
  • Windows directories
  • Directories on the path
Because the current directory depends on the profiler rather than on the profiled program, all modules might not be found. In most cases, this warning is not serious. However, if profiling leads to a GP fault (or to incorrect behavior), it might be necessary to include the "unknown module" in the profile.

Profiler Error PRF4423
warning -- PREP I -- filename: ignoring unknown runtime relocation type, verify linker version
(MIPS Specific) The profiler found bad relocation information in the program to be profiled. This is usually caused by using an obsolete version of the linker. Relink your code with the new profiler, and run PREP again.

Profiler Error PRF4481
warning -- PLIST -- clock frequency is zero
The clock frequency field in the PBT file has not been filled in yet, perhaps because the user has not done a profile yet, or has not merged his PBO file into his PBT file. Running PREP /M should fix the problem.

Profiler Error PRF4521
warning -- PREP I -- INIT environment variable not defined
The INIT environment variable should point to the directory that contains TOOLS.INI. Set the INIT environment variable to the directory containing your TOOLS.INI and rerun PREP.

Profiler Error PRF4522
warning -- PREP I -- 'publics' section not found in mapfile filename
The mapfile is corrupt.

Profiler Error PRF4523
warning -- PREP I -- 'static symbols' section not found in mapfile filename
The mapfile is corrupt.

Profiler Error PRF4524
warning -- PREP I -- entry function function not found
PREP could not find the specified start function (entry function) in the mapfile (see /SF switch). Perhaps the function name is misspelled.

Profiler Error PRF4525
warning -- PREP I -- cannot profile function function in file filename
A special function such as setjmp was specified.

Profiler Error PRF4526
warning -- PREP I -- module module already includes profiler DLL filename
The specified EXE or DLL already imports from PROFILER.DLL. The EXE (or DLL) may have been modified by PREP using the /OM switch and then renamed (from app._XE to app.EXE) before PREP was run again. Make sure that the module (EXE or DLL) specified is the original module and a module modified by PREP.

Profiler Error PRF4527
warning -- PREP I -- preferred load address not found in mapfile filename; assumed address
Current versions of the linker list the preferred load address (that is, when the EXE gets loaded at this address none of the run-time relocation addresses need to be fixed up). PREP needs this information. Somehow this information was missing from the mapfile. If the latest linker was used, the mapfile was probably edited. Regenerate the mapfile, retaining the line that states the preferred load address.

Profiler Error PRF4528
warning -- PREP I -- timestamps of mapfile filename and executable file do not match
The mapfile is not properly synchronized with the executable file. Relink and run PREP again.

Profiler Error PRF4541
warning -- PROFILE -- module not found in PBI file filename
An attempt was made to profile a program, but the EXE was not modified by PREP. This warning occurs while selectively profiling a DLL that is called by the EXE.

Profiler Error PRF4621
warning -- PREP I -- line number duplicated in file filename
There is a problem with the line number debug information. The same line number was identified with two different addresses. This is generally not serious.

Profiler Error PRF4641
warning -- PROFILE -- ReadProcessMemory: internal NT error number occurred
An internal error occurred. The profiler results may be meaningless.

Profiler Error PRF4642
warning -- PROFILE -- WriteProcessMemory: internal NT error number occurred
An internal error occurred. The profiler results may be meaningless.


Resource Compiler Messages

The following topics cover Resource Compiler Errors RC1000 through Warning RC4413:

  • Resource Compiler Errors RC1000 through RC1208
  • Resource Compiler Errors RC2001 through RC2129
  • Resource Compiler Errors RC2130 through RC2236
  • Resource Compiler Warnings RC4000 through RC4413

For information about Resource Compiler RWxxxx messages, see:

  • Resource Compiler Messages (RWxxxx)


Resource Compiler Errors RC1000 through RC1208

The following topics cover Resource Compiler Errors RC1000 through RC1208:

Resource Compiler Fatal Error RC1000
UNKNOWN FATAL ERROR
Note the circumstances of the error, try to isolate the problem, and create a reproducible test case, then report this information to technical support.

Resource Compiler Fatal Error RC1002
out of heap space
The Resource Compiler ran out of storage for items that it stores in its heap. One of the following may be a solution:

  • Increase the Windows swap file space. Consider using the Control Panel, System icon, Performance tab to increase your system's virtual memory, reboot, and retry.
  • Split the current file into two or more files and compile them separately.

Resource Compiler Fatal Error RC1003
error count exceeds number; stopping compilation
The number of errors was too great to continue compilation. Fix some errors and recompile.

Resource Compiler Fatal Error RC1004
unexpected end of file found
This error can be caused by omitting the linefeed and carriage return characters on the last line of a text file.

Resource Compiler Fatal Error RC1005
file not found: filename
The file specified in the RC command line was not found. Check to see whether the file has been moved to another directory and whether the filename or path is typed correctly. Files are searched for using the INCLUDE environment variable or the Directories setting.

Resource Compiler Fatal Error RC1007
unrecognized option 'option' in 'filename'
The specified option is not valid.

Resource Compiler Fatal Error RC1008
no input file specified
One or more source files must be specified on the Resource Compiler command line.

Resource Compiler Fatal Error RC1009
compiler limit : macros too deeply nested 'macro'
The Resource Compiler limit for macro nesting was exceeded. Revise the specified source file to decrease the nesting depth of its macros.

Resource Compiler Fatal Error RC1010
no output file specified
The Resource Compiler command line did not specify a filename for the compiled resource file.

Resource Compiler Fatal Error RC1011
compiler limit : 'identifier' : macro definition too big
The macro definition was longer than allowed. Try to split the definition into shorter definitions.

Resource Compiler Fatal Error RC1012
unmatched parenthesis : missing 'character'
The parentheses in a preprocessor directive were not matched. The missing character is either a left or right parenthesis.

Resource Compiler Fatal Error RC1013
mismatched parentheses
Make sure that every open parenthesis has a matching closing parenthesis.

Resource Compiler Fatal Error RC1014
too many include files : depth = 'level'
 The nesting depth of #include directives was too great. Open files can be included by the use of nested directives. The source file containing the directive is counted as one of the files.

Resource Compiler Fatal Error RC1015
cannot open include file 'filename'
The given include file either did not exist, could not be opened, or was not found. Make sure that the environment settings are valid and that the correct path for the file is specified. Ensure that sufficient file handles are available to the Resource Compiler. If the file is on a network drive, make sure that you have permissions to open the file.

Resource Compiler Fatal Error RC1016
#if[n]def expected an identifier
The #ifdef or #ifndef conditional compilation directive was not supplied with an identifier to evaluate. An identifier must be specified with the #ifdef and #ifndef directives.

Resource Compiler Fatal Error RC1017
invalid integer constant expression
The expression in an #if directive either did not exist or did not evaluate to a constant.

Resource Compiler Fatal Error RC1018
unexpected '#elif'
The #elif directive did not appear within an #if, #ifdef, or #ifndef construct. Make sure that there is an #if, #ifdef, or #ifndef statement in effect before this statement.

Resource Compiler Fatal Error RC1019
unexpected '#else'
The #else directive did not appear within an #if, #ifdef, or #ifndef construct. Make sure that there is an #if, #ifdef, or #ifndef statement in effect before this statement.

Resource Compiler Fatal Error RC1020
unexpected '#endif'
An #endif directive appeared without a matching #if, #ifdef, or #ifndef directive. Make sure that there is a matching #endif for each #if, #ifdef, and #ifndef statement.

Resource Compiler Fatal Error RC1021
invalid preprocessor command 'string'
The characters following the number sign (#) did not form a valid preprocessor directive. The number sign cannot be used as the first character in an identifier.

Resource Compiler Fatal Error RC1022
expected '#endif'
An #if, #ifdef, or #ifndef directive was not terminated with an #endif directive. Make sure that there is an #if, #ifdef, or #ifndef statement in effect before this statement.

Resource Compiler Fatal Error RC1023
cannot open source file 'filename'
The specified file either did not exist, could not be opened, or was not found. Make sure that the environment settings are valid and that the correct path for the file is specified. If this error appears without an error message, the Resource Compiler has run out of file handles.

Resource Compiler Fatal Error RC1047
"too many option options, 'string'"
The given option was specified too many times. The given string is the argument to the option that caused the error.

Resource Compiler Fatal Error RC1048
unknown option 'character' in 'option'
The given character was not a valid letter for the option.

Resource Compiler Fatal Error RC1049
invalid numerical argument 'string'
The Resource Compiler expected a numerical argument but received the given string. This error may be caused by giving a hexadecimal number without the necessary \x prefix or by a misformed floating-point number.

Resource Compiler Fatal Error RC1052
compiler limit : #if or #ifdef blocks nested too deeply
The program exceeded the maximum allowable nesting levels for #if and #ifdef directives. This error can be caused by include files that use these preprocessor directives.

Resource Compiler Fatal Error RC1067
compiler limit : identifier overflowed internal buffer
An internal compiler limit was exceeded.

Resource Compiler Fatal Error RC1101
no resource binary filename specified
The Rename Output (/fo) option was specified, but was not followed by filename. The following syntax must be used with the /fo option:
RC /fooutfilename infilename.rc

Resource Compiler Fatal Error RC1102
internal error : too many arguments to RCPP
Too many arguments were passed to the Resource Compiler preprocessor. Reduce the number of symbols defined with the Define Symbols (/d) option by defining them in your source. This error can also be caused by specifying too many include file search paths using the Include Search Path option (/i).

Resource Compiler Fatal Error RC1103
invalid switch, option
The specified option is not a valid Resource Compiler option.

Resource Compiler Fatal Error RC1105
invalid switch, option: too many /d switches
Too many symbols were defined using the Define Symbols (/d) option. Define some symbols in your source and recompile.

Resource Compiler Fatal Error RC1106
invalid switch: option
The specified option is not a valid Resource Compiler option. The following options are valid:

/r | Emit .RES file
/v | Verbose (print progress messages)
/d | Define a symbol
/fo | Rename .RES file
/l | Default language ID in hex
/I | Add a path for INCLUDE searches
/x | Ignore INCLUDE environment variable
/c | Define a code page used by NLS Conversion

Resource Compiler Fatal Error RC1107
invalid usage; use RC /? for Help
An invalid Resource Compiler option was specified. Valid options are one of the following: /r, /v, /d, /fo, /l, /i, /x, or /c:

Resource Compiler Fatal Error RC1109
error creating resource-name
Could not create specified .RES file. Make sure it is not being created on a read-only drive. Use the /V option to find out whether the file is being created.

Resource Compiler Fatal Error RC1110
could not open filename
RC could not open the specified resource script file. Make sure that the file exists.

Resource Compiler Fatal Error RC1116
RC terminating after preprocessor errors
The Resource Compiler halted due to other errors. Fix the other errors and recompile.

Resource Compiler Fatal Error RC1120
out of memory, needed number bytes
The Resource Compiler ran out of storage for items that it stores in its heap. Usually this is the result of having too many symbols. One of the following may be a solution:

  • Increase the Windows swap file space. Consider using the Control Panel, System icon, Performance tab to increase your system's virtual memory, reboot, and retry.
  • Eliminate unnecessary include files, especially unneeded #defines and function prototypes.
  • Split the current file into two or more files and compile them separately.

Resource Compiler Fatal Error RC1121
I/O error reading file
The Resource Compiler was not able to read a file. Check that the drive containing the file is available and that the file is valid.

Resource Compiler Fatal Error RC1122
I/O error writing file
The Resource Compiler could not write to a file. This error may be caused by insufficient disk space. You must have free space equivalent to about twice the size of the executable file you are creating. Other possible reasons for this error are:

  • Writing to a read-only volume
  • Writing to a bad sector
  • A sharing violation

Resource Compiler Fatal Error RC1123
I/O error seeking in file
The compiler was unable to complete an I/O operation.

Resource Compiler Fatal Error RC1201
invalid switch - missing include path after /i
The Specify Include Path (/i) option was specified, but was not followed by a path.

Resource Compiler Fatal Error RC1202
invalid switch - missing default language ID after /l
The Specify Default Language (/l) option was specified, but was not followed by a hexadecimal language ID.

Resource Compiler Fatal Error RC1203
invalid hexadecimal default language ID specified.
The Specify Default Language (/l) option was specified, but was followed by an invalid hexadecimal language ID. See the Platform SDK for a list of valid language IDs.

Resource Compiler Fatal Error RC1204
Invalid switch - missing code page after /c
The Specify Code Page (/c) option was specified, but it was not followed by a code page.

Resource Compiler Fatal Error RC1205
invalid code page
The Specify Code Page (/c) option was specified, but was followed by an invalid code page. See Code Pages in the the online documentation for more information.

Resource Compiler Fatal Error RC1206
specified code page at cmd line does not exist in registry
The Specify Code Page (/c) option was specified, but was followed by a code page whose location is not specified in the registry.

Resource Compiler Fatal Error RC1207
default code page is invalid
The code page specified by the RCCODEPAGE environment variable is not valid. See Code Pages in the online documentation for more information.

Resource Compiler Fatal Error RC1208
input file has .RES extension
The .RES extension is used for Resource Compiler output. The .RC extension should be used for Resource Compiler scripts.

Return to Main Resource Compiler Messages Page


Resource Compiler Errors RC2001 through RC2129

Resource Compiler Error RC2001
newline in constant
A string constant was continued on a second line without either a backslash (\) or closing and opening double quotation marks ("). To break a string constant that is on two lines in the source file, do one of the following:

  • End the first line with the line-continuation character, a backslash.
  • Close the string on the first line with a double quotation mark and open the string on the next line with another quotation mark.
It is not sufficient to end the first line with \n, the escape sequence for embedding a newline character in a string constant.

Resource Compiler Error RC2003
expected 'defined id'
An identifier was expected after the specified preprocessing keyword.

Resource Compiler Error RC2004
expected 'defined(id)'
An identifier was expected after the left parenthesis following the specified preprocessing keyword.

Resource Compiler Error RC2005
#line expected a line number, found 'token'
A #line directive lacked the required line-number specification.

Resource Compiler Error RC2006
#include expected a filename, found 'token'
 An #include directive lacked the required filename specification.

Resource Compiler Error RC2007
#define syntax
An identifier was expected following #define in a preprocessing directive.

Resource Compiler Error RC2008
'character' : unexpected in macro definition
The given character was found immediately following the name of the macro.

Resource Compiler Error RC2009
reuse of macro formal 'identifier'
The given identifier was used more than once in the formal parameter list of a macro definition.

Resource Compiler Error RC2010
'character' : unexpected in formal list
The given character was used incorrectly in the formal parameter list of a macro definition.

Resource Compiler Error RC2012
missing name following '<'
An #include directive lacked the required filename specification.

Resource Compiler Error RC2013
missing '>'
The closing angle bracket (>) was missing from an #include directive.

Resource Compiler Error RC2014
preprocessor command must start as first non-whitespace
Non-white-space characters appeared before the number sign (#) of a preprocessor directive on the same line.

Resource Compiler Error RC2015
too many chars in constant
A character constant contained more than two characters. Character constants are limited to one character (standard character constants) or two characters (long character constants). Note that an escape sequence (for example, \t for tab) is converted to a single character.

Resource Compiler Error RC2016
no closing single quote
A newline character was found before the closing single quotation mark of a character constant.

Resource Compiler Error RC2017
illegal escape sequence
An escape sequence appeared where one was not expected. An escape sequence - a backslash ( \ ) followed by a number or letter - may occur only in a character or string constant.

Resource Compiler Error RC2018
unknown character 'hexnumber'
The ASCII character corresponding to the given hexadecimal number appeared in the source file but is an illegal character. One possible cause of this error is corruption of the source file.

Resource Compiler Error RC2019
expected preprocessor directive, found 'character'
The given character followed a number sign (#), but it was not the first letter of a preprocessor directive.

Resource Compiler Error RC2020
illegal digit number for base radix
The specified digit is not a valid digit for the base specified by radix. Either the digit or the radix could be incorrect. Octal digits must be numbers from 0 to 7, and hexadecimal digits must be numbers from 0 to 9 or letters from A through E.

Resource Compiler Error RC2021
expected exponent value, not 'character'
The given character was used as the exponent of a floating-point constant but was not a valid number.

Resource Compiler Error RC2022
'number' : too big for character
The octal number following a backslash (\) in a character or string constant was too large to be represented as a character.

Resource Compiler Error RC2101
Invalid directive in preprocessed RC file
The RC file contains a #pragma directive. Use the #ifndef preprocessor directive with the RC_INVOKED constant that the Resource Compiler defines when it processes an include file. Place the #pragma directive inside a block of code that is not processed when the RC_INVOKED constant is defined. Code in the block is processed only by the C/C++ compiler and not by the Resource Compiler. The following sample code demonstrates this technique:

  #ifndef RC_INVOKED
  #pragma pack(2)  // C/C++ only, ignored by Resource Compiler
  #endif

The #pragma preprocessor directive has no meaning in an .RC file. The #include preprocessor directive is used frequently in an .RC file to include a header file (either a project-based custom header file or a standard header file provided by Microsoft with one of its products). Some of these include files contain the #pragma directive. Because a header file can include one or more other header files, the file that contains the offending #pragma directive may not be immediately obvious. The #ifndef RC_INVOKED technique can control including header files in project-based header files.

Resource Compiler Error RC2102
string literal too long
An RCDATA string exceeded the maximum allowable length.

Resource Compiler Error RC2103
unexpected end of file in string literal
An end of file was found before the end of a string. The string is probably missing a closing double quotation mark (").

Resource Compiler Error RC2104
undefined keyword or key name: key
The specified keyword or key name was not defined. If you encounter the following error message:
undefined keyword or key name: MFT_STRING

Open the file ...\mfc\include\AfxRes.h and add the following include directive:
#include <winresrc.h>

Resource Compiler Error RC2105
BEGIN expected in string table
The BEGIN keyword must immediately follow the ACCELERATORS keyword.

Resource Compiler Error RC2106
BEGIN expected in accelerator table
The BEGIN keyword must immediately follow the ACCELERATORS keyword.

Resource Compiler Error RC2107
expected numeric command value
RC was expecting a numeric idvalue field in the ACCELERATORS statement. Make sure that you have used a #define constant to specify the value and that the constant is spelled correctly.

Resource Compiler Error RC2108
unbalanced parentheses
An open parenthesis was not matched with a closing parenthesis.

Resource Compiler Error RC2109
expected numerical dialog constant
A DIALOG statement requires integer values for the x, y, width, and height fields. Make sure these values are included after the DIALOG keyword and that they are not negative.

Resource Compiler Error RC2110
expected numerical dialog constant
A DIALOG statement requires integer values for the x, y, width, and height fields. Make sure these values are included after the DIALOG keyword and that they are not negative.

Resource Compiler Error RC2111
invalid control type
Each CONTROL statement in a DIALOG statement must be one of the following: 3STATE, AUTO3, AUTOCHECK, AUTORADIO, BEDIT, CHECKBOX, COMBOBOX, CONTROL, CTEXT, DEFPUSHBUTTON, EDITTEXT, GROUPBOX, HEDIT, ICON, IEDIT, LISTBOX, LTEXT, PUSHBOX, PUSHBUTTON, RADIOBUTTON, RTEXT, SCROLLBAR, USERBUTTON. Make sure these CONTROL statements are spelled correctly.

Resource Compiler Error RC2112
BEGIN expected in dialog
The BEGIN keyword must immediately follow the DIALOG keyword.

Resource Compiler Error RC2113
END expected in dialog
The END keyword must occur at the end of a DIALOG statement. Make sure there are no open quotes left from the preceding statement.

Resource Compiler Error RC2114
expected control class name
The class field of a CONTROL statement in the DIALOG statement must be one of the following types: BUTTON, COMBOBOX, EDIT, LISTBOX, SCROLLBAR, STATIC, or user-defined. Make sure the class is spelled correctly.

Resource Compiler Error RC2115
text string or ordinal expected in control
The text field of a CONTROL statement in the DIALOG statement must be either a text string or an ordinal reference to the type of control is expected. If using an ordinal, make sure that you have a #define statement for the control.

Resource Compiler Error RC2116
expecting number for ID
Expecting a number for the id field of a control statement in the DIALOG statement. Make sure you have a number or #define statement for the control ID.

Resource Compiler Error RC2117
expected numeric point size
The pointsize field of the FONT option in the DIALOG statement must be an integer point size value.

Resource Compiler Error RC2118
expected font face name
The typeface field of the FONT option in the DIALOG statement must be an ASCII character string enclosed in double quotation marks. This field specifies the name of a font.

Resource Compiler Error RC2119
expecting quoted string in dialog title
The captiontext field of the CAPTION option in the DIALOG statement must be an ASCII character string enclosed in double quotation marks.

Resource Compiler Error RC2120
expecting quoted string in dialog class
The class field of the CLASS option in the DIALOG statement must be an integer or a string, enclosed in double quotation marks.

Resource Compiler Error RC2121
BEGIN expected in menu
The BEGIN keyword must immediately follow the MENU keyword.

Resource Compiler Error RC2122
unknown menu subtype
The item-definition field of the MENU statement can contain only MENUITEM and POPUP statements.

Resource Compiler Error RC2123
END expected in menu
The END keyword must come at the end of a MENU statement. Make sure you do not have any open quotation marks or a mismatched pair of BEGIN and END statements.

Resource Compiler Error RC2124
empty menus not allowed
An END keyword appears before any menu items are defined in the MENU statement. Empty menus are not permitted by the Resource Compiler. Make sure you do not have any open quotation marks within the MENU statement.

Resource Compiler Error RC2125
expected ID value for menuitem
The MENU statement must contain a menuID field, which specifies the name or number that identifies the menu resource.

Resource Compiler Error RC2126
expected menu string
Each MENUITEM and POPUP statement must contain a text field, which is a string enclosed in double quotation marks that specifies the name of the menu item or pop-up menu. A MENUITEM SEPARATOR statement requires no quoted string.

Resource Compiler Error RC2127
version WORDs separated by commas expected
Version numbers in a version resource should be of type WORD, and separated by commas.

Resource Compiler Error RC2128
DWORD expected
A valid version number was not found. It must be a DWORD type.

Resource Compiler Error RC2129
BEGIN expected in VERSIONINFO resource
The BEGIN keyword must immediately follow the VERSIONINFO keyword.

Return to Main Resource Compiler Messages Page


Resource Compiler Errors RC2130 through RC2236

Resource Compiler Error RC2130
#line expected a string containing the file name, found 'token'
A #line directive was missing a required filename.

Resource Compiler Error RC2131
expecting quoted string for key
The field for this statement must be a character string enclosed in double quotation marks.

Resource Compiler Error RC2132
expected VALUE, BLOCK, or, END keyword
A block in a VERSION resource doesn't end properly, or a new block doesn't begin properly. This results in a VERSION statement that is not a valid block.

Resource Compiler Error RC2133
unexpected value in value data
The raw-data values in the RCDATA statement must be integers or strings, each separated by a comma. Make sure you did not leave out a comma or leave out a quotation mark around a string.

Resource Compiler Error RC2134
BEGIN expected in RCDATA
The BEGIN keyword must immediately follow the RCDATA keyword.

Resource Compiler Error RC2135
file not found: filename
The file specified in the RC command line was not found. Check to see whether the file has been moved to another directory and whether the filename or path is typed correctly. Files are searched for using the INCLUDE environment variable or the visual development environment INCLUDE directory setting (Tools menu, Options item, Directories tab).

Resource Compiler Error RC2136
missing '=' in EXSTYLE=<flags>
An equal sign (=) was missing from an EXSTYLE (Extended Style Flags) statement. When the EXSTYLE is embedded in the DIALOG or MENU statement it must have the following form: EXSTYLE=FLAGS

Resource Compiler Error RC2137
empty character constant
A pair of single quotes was found with no character specified between them.

Resource Compiler Error RC2138
unmatched close comment '/*'
An open comment sequence (/*) was not matched with a close comment sequence (*/) This error can be caused by nesting comments.

Resource Compiler Error RC2139
VERSION not a number
A VERSION resource must be a number.

Resource Compiler Error RC2140
CHARACTERISTICS not a number
A CHARACTERISTICS resource must be a number.

Resource Compiler Error RC2141
invalid type
A different type was expected.

Resource Compiler Error RC2142
ellipsis requires three periods
An incorrect number of periods (.) was used in an ellipsis.

Resource Compiler Error RC2143
font names must be ordinals
The pointsize field in the FONT statement must be an integer, not a string.

Resource Compiler Error RC2144
PRIMARY LANGUAGE ID not a number
The PRIMARY LANGUAGE ID must be a hexadecimal language ID. See Language and Country Strings in the online documentation for a list of valid Language IDs.

Resource Compiler Error RC2145
PRIMARY LANGUAGE ID too large
The PRIMARY LANGUAGE ID must be a valid hexadecimal language ID. See Language and Country Strings in the Ronline documentation for a list of valid Language IDs.

Resource Compiler Error RC2146
missing COMMA in LANGUAGE statement
The comma separating the primary language and secondary language is missing. The LANGUAGE statement must use the following syntax: LANGUAGE primary_language_ID,secondary_language_ID

Resource Compiler Error RC2147
SUBLANGUAGE ID not a number
The SUBLANGUAGE ID value must be a number. The LANGUAGE statement must use the following syntax: LANGUAGE primary_language_ID,secondary_language_ID
Valid SUBLANGUAGE IDs are defined as SUBLANG_ constants in the WINNT.H file.

Resource Compiler Error RC2148
SUBLANGUAGE ID too large
The SUBLANGUAGE ID value was out of range. The LANGUAGE statement must use the following syntax: LANGUAGE primary_language_ID,secondary_language_ID
Valid SUBLANGUAGE IDs are defined as SUBLANG_ constants in the WINNT.H file.

Resource Compiler Error RC2149
expected numeric constant in string table
A numeric constant, defined in a #define statement, must immediately follow the BEGIN keyword in a STRINGTABLE statement.

Resource Compiler Error RC2150
expected string in STRINGTABLE
A string is expected after each stringid value in a STRINGTABLE statement.

Resource Compiler Error RC2151
cannot re-use string constants
You are using the same value twice in a STRINGTABLE statement. Make sure you are not mixing overlapping decimal and hexadecimal values. Each ID in a STRINGTABLE must be unique. For maximum efficiency use contiguous constants that start on a multiple of 16.

Resource Compiler Error RC2152
invalid control character
A control character in the ACCELERATORS statement is invalid. A valid control character consists of one letter (only) following a caret (^).

Resource Compiler Error RC2153
hex constants must have at least 1 hex digit
An empty hexadecimal constant was found.

Resource Compiler Error RC2154
control character out of range [^A - ^Z]
A control character in the ACCELERATORS statement is invalid. The character following the caret (^) must be between A and Z, inclusive.

Resource Compiler Error RC2155
invalid accelerator
An event field in the ACCELERATORS statement was not recognized or was more than two characters in length.

Resource Compiler Error RC2156
expected string or constant accelerator command
RC was not able to determine what kind of key is being set up for the accelerator. The event field in the ACCELERATORS statement might be invalid.

Resource Compiler Error RC2157
expected comma in accelerator table
The Resource Compiler requires a comma between the event and idvalue fields in the ACCELERATORS statement.

Resource Compiler Error RC2159
invalid accelerator type [ASCII or VIRTKEY]
The type field in the ACCELERATORS statement must contain either the ASCII or VIRTKEY value.

Resource Compiler Error RC2160
## cannot occur at the beginning of a macro definition
A macro definition began with a token-pasting operator (##).

Resource Compiler Error RC2161
## cannot occur at the end of a macro definition
A macro definition ended with a token-pasting operator (##).

Resource Compiler Error RC2162
expected macro formal parameter
The token following a stringizing operator (#) was not a formal parameter name.

Resource Compiler Error RC2163
accelerator type required [ASCII or VIRTKEY]
The type field in the ACCELERATORS statement must contain either the ASCII or VIRTKEY value.

Resource Compiler Error RC2164
unexpected value in RCDATA
The raw-data values in the RCDATA statement must be integers or strings, each separated by a comma. Make sure you did not leave out a comma or leave out a quotation mark around a string.

Resource Compiler Error RC2165
string not found in DLGINCLUDE statement
The statement did not specify a valid include file. The DLGINCLUDE statement must use the following syntax:
DLGINCLUDE "filename.h"

Resource Compiler Error RC2166
numeric value expected at line
The resource on the specified line must be a numeric value.

Resource Compiler Error RC2167
unrecognized VERSIONINFO field; BEGIN or comma expected
An unrecognized field was found in the FIXED part of a VERSIONINFO structure declaration. A VERSIONINFO field must be DWORDS separated by a comma.

Resource Compiler Error RC2168
resource too large
The size limitation of a resource was exceeded. This limit does not apply to cursors, icons, bitmaps, or other file-based resources.

Resource Compiler Error RC2169
resource file filename is not in 2.03 format
The specified resource used a format earlier than version 2.03. The resource file must be converted or re-created using the format for version 3.00 or later.

Resource Compiler Error RC2170
bitmap file filename is not in 3.00 format
Bitmaps using the Windows version 2.x format cannot be used in version 3.x resource files. The bitmap must be redrawn or converted to 3.x format.

Resource Compiler Error RC2171
unknown DIB header format
The bitmap header is not a BITMAPCOREHEADER or BITMAPINFOHEADER structure.

Resource Compiler Error RC2174
bitmap file filename is not in 2.03 format
A bitmap used a format earlier than version 2.03. The bitmap must be converted or redrawn using the format for version 3.00 or later.

Resource Compiler Error RC2175
resource file filename is not in 3.00 format
The specified resource used a format earlier than version 3.00. The resource file must be converted or recreated using the format for version 3.00 or later.

Resource Compiler Error RC2176
old DIB in filename.
An old format Device Independent Bitmap was found in the specified file. It should be converted to the current format.

Resource Compiler Error RC2177
constant too big
A constant value was too large to be represented in the type to which it was assigned.

Resource Compiler Error RC2180
unable to open temporary file
The Resource Compiler was unable to open a temporary file. The probable cause is either that you do not have write permissions for the directory, or that the directory does not exist. The Resource Compiler attempts to use these files in the directory specified by the TMP (or GetSystemTempDirectory) environment variable or the current directory if none is specified.

Resource Compiler Error RC2181
duplicate font ID fontID
The specified font ID was already defined.

Resource Compiler Error RC2189
#error : error
This error is used to display other error messages.

Resource Compiler Error RC2235
too many arguments supplied
An expression contained more formal parameters than expected.

Resource Compiler Error RC2236
required parameter missing
An expression contained fewer formal parameters than expected.

Return to Main Resource Compiler Messages Page


Resource Compiler Warnings RC4000 through RC4413

The following topics cover Resource Compiler Warnings RC4000 through RC4413:

Resource Compiler Warning RC4000
UNKNOWN WARNING
Note the circumstances of the warning, try to isolate the problem and create a reproducible test case, then consult the technical-support help file or the technical-support section in one of your manuals.

Resource Compiler Warning RC4002
too many actual parameters for macro 'identifier'
The number of actual parameters specified with the given identifier was greater than the number of formal parameters given in the macro definition of the identifier. The additional actual parameters were collected but ignored during expansion of the macro.

Resource Compiler Warning RC4003
not enough actual parameters for macro 'identifier'
The number of actual parameters specified with the given identifier was less than the number of formal parameters given in the macro definition of the identifier. When a formal parameter is referenced in the definition and the corresponding actual parameter has not been provided, empty text is substituted in the macro expansion.

Resource Compiler Warning RC4004
missing close parenthesis after 'defined'
An opening parenthesis was not matched with a closing parenthesis.

Resource Compiler Warning RC4005
'identifier' : macro redefinition
The given identifier was defined twice. The compiler used the second macro definition. This warning can be caused by defining a macro on the command line and in the code with a #define directive. It also can be caused by macros imported from include files. To eliminate the warning, either remove one of the definitions or use an #undef directive before the second definition.

Resource Compiler Warning RC4006
#undef expected an identifier
The name of the identifier whose definition was to be removed was not given with the #undef directive. The #undef directive was ignored.

Resource Compiler Warning RC4009
string too big, trailing chars truncated
A string was too large to fit in a buffer. Trailing characters were truncated and the remaining string was used.

Resource Compiler Warning RC4011
identifier truncated to 'identifier'
An identifier was too long and was truncated to the name shown in the warning.

Resource Compiler Warning RC4012
float constant in a cross compilation
A float constant may not have the same value on different target platforms.

Resource Compiler Warning RC4067
unexpected characters following 'token' directive - newline expected
A newline character should follow the specified token.

Resource Compiler Warning RC4079
unexpected token 'token'
Check the syntax of the line containing the specified token.

Resource Compiler Warning RC4093
unescaped newline in character constant in inactive code
The constant expression of an #if, #elif, #ifdef, or #ifndef preprocessor directive evaluated to zero, making the code that follows inactive. Within that inactive code, a newline character appeared within a set of single or double quotation marks. All text until the next double quotation mark was considered to be within a character constant.

Resource Compiler Warning RC4111
unexpected token 'string'
Check the syntax of the line containing the specified token.

Resource Compiler Warning RC4117
macro name 'macro' is reserved, macro ignored
The specified macro was given a reserved name.

Resource Compiler Warning RC4203
SHIFT or CONTROL used without VIRTKEY
In an accelerator table resource, SHIFT or CONTROL require VIRTKEY. Because SHIFT and CONTROL are indicated as flag bits in a VIRTKEY type accelerator, they cannot exist independent from a VIRTKEY.

Resource Compiler Warning RC4204
ASCII character not equivalent to virtual key code
A string literal was used for the virtual key code in a VIRTKEY type accelerator. This warning lets you continue, but be aware that the accelerator keys generated may not match the string you indicated. (VIRTKEYs use different key codes than ASCII accelerators.) While string literals are syntactically valid, you can only ensure that you get the accelerator you want by using the VK_* #define values in WINDOWS.H.

Resource Compiler Warning RC4205
string literal longer than 256 - stored anyway
A literal sting exceeded 256 characters. It was stored intact.

Resource Compiler Warning RC4206
name string too long - truncated at 256
A name string exceeded the limit of 256 characters. It was truncated to 256 characters.

Resource Compiler Warning RC4207
type string too long - truncated at 256
A type string exceeded the limit of 256 characters. It was truncated to 256 characters.

Resource Compiler Warning RC4208
title string too long - truncated at 256
A title string exceeded the limit of 256 characters. It was truncated to 256 characters.

Resource Compiler Warning RC4413
cannot determine file type for 'filename' : assuming 8-bit ASCII
The type of specified file is not known to the Resource Compiler. It was compiled as an 8-bit ASCII file.

Return to Main Resource Compiler Messages Page


Resource Compiler Errors RW1004 through RW4004

The following topics cover Resource Compiler Errors RW1004 through RW4004:

Resource Compiler Fatal Error RW1004
Unexpected end of file
This error can be caused by omitting the linefeed and carriage-return characters on the last line of a text file.

Resource Compiler Fatal Error RW1009
Error creating resource-name
Could not create specified .RES file. Make sure it is not being created on a read-only drive. Use the /V option to find out whether the file is being created.

Resource Compiler Fatal Error RW1016
RC terminating after preprocessor errors
The Resource Compiler halted due to other errors. Fix the other errors and recompile.

Resource Compiler Fatal Error RW1021
I/O error reading file
The Resource Compiler was not able to read a file. Check that the drive containing the file is available and that the file is valid.

Resource Compiler Fatal Error RW1022
I/O error writing file
The Resource Compiler could not write to a file. This error may be caused by insufficient disk space. You must have free space equivalent to about twice the size of the executable file you are creating. Other possible reasons for this error are:

  • Writing to a read-only volume
  • Writing to a bad sector
  • A sharing violation

Resource Compiler Fatal Error RW1023
I/O error writing file, drive full
The Resource Compiler could not write a file to a drive because the drive was full. You must have free space equivalent to about twice the size of the executable file you are creating.

Resource Compiler Fatal Error RW1025
Out of far heap memory
There wasn't enough memory. Consider using the Control Panel, System icon, Performance tab to increase your system's virtual memory, reboot, and retry.

Resource Compiler Fatal Error RW1030
Output Error
The output error can be caused by any of following conditions:

  • Errors occurred when linking file
    LINK failed. See Set Linker Options and Linker Reference for more information about linking an executable.
  • .EXE file too large; relink with higher /ALIGN value
    If the .EXE file is larger than 800K, you should use the /ALIGN:32 value on your LINK line.
  • File not created by LINK
    You must create the .EXE file with a version of Microsoft LINK later than 5.0 or with LINKW.
  • Invalid .EXE file
    Make sure that the linker created the .EXE file correctly and that the file exists. You can check the .EXE file with the DUMPBIN utility.
  • Not a Microsoft Windows format .EXE file
    Make sure that the linker created the .EXE file correctly and that the file exists. You can check the .EXE file with the DUMPBIN utility.
  • Unable to create destination
    RC was not able to create the destination file. Make sure that there is enough disk space and that you have write permission on the volume.
  • Unable to open exe-file
    RC could not open this .EXE file. Make sure that the linker created it correctly and that the file exists.

Resource Compiler Error RW2001
Invalid directive in preprocessed RC file
The RC file contains a #pragma directive. Use the #ifndef preprocessor directive with the RC_INVOKED constant that the Resource Compiler defines when it processes an include file. Place the #pragma directive inside a block of code that is not processed when the RC_INVOKED constant is defined. Code in the block is processed only by the C/C++ compiler and not by the Resource Compiler. The following sample code demonstrates this technique:

  #ifndef RC_INVOKED
  #pragma pack(2)  // C/C++ only, ignored by Resource Compiler
  #endif

The #pragma preprocessor directive has no meaning in an .RC file. The #include preprocessor directive is used frequently in an .RC file to include a header file (either a project-based custom header file or a standard header file provided by Microsoft with one of its products). Some of these include files contain the #pragma directive. Because a header file can include one or more other header files, the file that contains the offending #pragma directive may not be immediately obvious. The #ifndef RC_INVOKED technique can control including header files in project-based header files.

Resource Compiler Error RW2002
Parsing error
The parsing error can be caused by any of following conditions:

  • Accelerator type required (ASCII or VIRTKEY)
    The type field in the ACCELERATORS statement must contain either the ASCII or VIRTKEY value.
  • BEGIN expected in accelerator table
    The BEGIN keyword must immediately follow the ACCELERATORS keyword.
  • BEGIN expected in dialog
    The BEGIN keyword must immediately follow the DIALOG keyword.
  • BEGIN expected in menu
    The BEGIN keyword must immediately follow the MENU keyword.
  • BEGIN expected in RCData
    The BEGIN keyword must immediately follow the RCDATA keyword.
  • BEGIN keyword expected in string table
    The BEGIN keyword must immediately follow the STRINGTABLE keyword.
  • Cannot re-use string constants
    You are using the same value twice in a STRINGTABLE statement. Make sure you are not mixing overlapping decimal and hexadecimal values. Each ID in a STRINGTABLE must be unique. For maximum efficiency use contiguous constants that start on a multiple of 16.
  • Control character out of range [^A - ^Z]
    A control character in the ACCELERATORS statement is invalid. The character following the caret (^) must be between A and Z, inclusive.
  • Empty menus not allowed
    An END keyword appears before any menu items are defined in the MENU statement. Empty menus are not permitted by the Resource Compiler. Make sure you do not have any open quotation marks within the MENU statement.
  • END expected in dialog
    The END keyword must occur at the end of a DIALOG statement. Make sure there are no open quotes left from the preceding statement.
  • END expected in menu
    The END keyword must come at the end of a MENU statement. Make sure you do not have any open quotation marks or a mismatched pair of BEGIN and END statements.
  • Expected comma in accelerator Table
    RC requires a comma between the event and idvalue fields in the ACCELERATORS statement.
  • Expected control class name
    The class field of a CONTROL statement in the DIALOG statement must be one of the following types: BUTTON, COMBOBOX, EDIT, LISTBOX, SCROLLBAR, STATIC, or user-defined. Make sure the class is spelled correctly.
  • Expected font face name
    The typeface field of the FONT option in the DIALOG statement must be an ASCII character string enclosed in double quotation marks. This field specifies the name of a font.
  • Expected ID value for menuitem
    The MENU statement must contain a menuID field, which specifies the name or number that identifies the menu resource.
  • Expected menu string
    Each MENUITEM and POPUP statement must contain a text field, which is a string enclosed in double quotation marks that specifies the name of the menu item or pop-up menu. A MENUITEM SEPARATOR statement requires no quoted string.
  • Expected numeric command value
    RC was expecting a numeric idvalue field in the ACCELERATORS statement. Make sure that you have used a #define constant to specify the value and that the constant is spelled correctly.
  • Expected numeric constant in string table
    A numeric constant, defined in a #define statement, must immediately follow the BEGIN keyword in a STRINGTABLE statement.
  • Expected numeric point size
    The pointsize field of the FONT option in the DIALOG statement must be an integer point size value.
  • Expected numerical dialog constant
    A DIALOG statement requires integer values for the x, y, width, and height fields. Make sure that these values are included after the DIALOG keyword and that they are not negative.
  • Expected string in STRINGTABLE
    A string is expected after each stringid value in a STRINGTABLE statement.
  • Expected string or constant accelerator command
    RC was not able to determine what kind of key is being set up for the accelerator. The event field in the ACCELERATORS statement might be invalid.
  • Expecting number for ID
    Expecting a number for the id field of a control statement in the DIALOG statement. Make sure you have a number or #define statement for the control ID.
  • Expecting quoted string in dialog class
    The class field of the CLASS option in the DIALOG statement must be an integer or a string, enclosed in double quotation marks.
  • Expecting quoted string in dialog title
    The captiontext field of the CAPTION option in the DIALOG statement must be an ASCII character string enclosed in double quotation marks.
  • File not found: filename
    The file specified in the RC command line was not found. Check to see whether the file has been moved to another directory and whether the filename or path is typed correctly. Files are searched for using the INCLUDE environment variable or the Visual Workbench setting, if available.
  • Font names must be ordinals
    The pointsize field in the FONT statement must be an integer, not a string.
  • Invalid accelerator
    An event field in the ACCELERATORS statement was not recognized or was more than two characters in length.
  • Invalid accelerator type (ASCII or VIRTKEY)
    The type field in the ACCELERATORS statement must contain either the ASCII or VIRTKEY value.
  • Invalid control character
    A control character in the ACCELERATORS statement is invalid. A valid control character consists of one letter (only) following a caret (^).
  • Invalid control type
    Each control statement in a DIALOG statement must be one of the following: CHECKBOX, COMBOBOX, CONTROL, CTEXT, DEFPUSHBUTTON, EDITTEXT, GROUPBOX, ICON, LISTBOX, LTEXT, PUSHBUTTON, RADIOBUTTON, RTEXT, SCROLLBAR. Make sure these control statements are spelled correctly.
  • Invalid type
    The resource type was not among the types defined in the WINDOWS.H file.
  • Text string or ordinal expected in control
    The text field of a CONTROL statement in the DIALOG statement must be either a text string or an ordinal reference to the type of control is expected. If using an ordinal, make sure that you have a #define statement for the control.
  • Mismatched parentheses
    Make sure you have closed every open parenthesis in the DIALOG statement.
  • Unexpected value in RCData
    The raw-data values in the RCDATA statement must be integers or strings, each separated by a comma. Make sure you did not leave out a comma or leave out a quotation mark around a string.
  • Unknown menu subtype
    The item-definition field of the MENU statement can contain only MENUITEM and POPUP statements.

Resource Compiler Error RW2003
Generation Error
General errors can be caused by any of following conditions:

  • Error: Bitmap file resource-file is not in 3.00 format
    Bitmaps using the Windows version 2.x format cannot be used in version 3.x resource files. The bitmap must be redrawn or converted to 3.x format.
  • Error: Old DIB in resource-name.
    A Device Independent Bitmap (DIB) in the specified resource is not compatible with the 3.0 format. The bitmap must be redrawn or converted to the 3.x format.
  • Error: Resource file resouce-name is not in 3.00 format
    An icon or cursor in the specified resource used a previous format. The icon or cursor must be redrawn or converted to the 3.x format.
  • Unknown DIB header format
    The bitmap header is not a BITMAPCOREHEADER or BITMAPINFOHEADER structure.
  • Bitmap file resource file is not in 2.03 format
    A bitmap used a format earlier than version 2.03. The bitmap must be converted or redrawn using the format for version 3.00 or later.
  • Resource file is not in 3.00 format
    A cursor or icon used a format earlier than version 3.00. The resource must be converted or redrawn using the format for version 3.00 or later.
  • Unable to open temporary file
    The Resource Compiler was unable to open a temporary file. The probable cause is either that you do not have write permissions for the directory or that the directory does not exist. The Resource Compiler attempts to use these files in the directory specified by the TMP environment variable or the current directory if none is specified.

Resource Compiler Warning RW4001
.EXE processing options (/L /M /P /T /K /E /31 or /30)
 .EXE processing options (/L /M /P /T /K /E /31 or /30) were specified when no executable file would be processed. These options can only be used when the result is an .EXE file (not a .RES file).

Resource Compiler Warning RW4003
SHIFT or CONTROL used without VIRTKEY
 In an accelerator table resource, SHIFT or CONTROL require VIRTKEY. Because SHIFT and CONTROL are indicated as flag bits in a VIRTKEY type accelerator, they cannot exist independent from a VIRTKEY.

Resource Compiler Warning RW4004
ASCII character not equivalent to virtual key code
 A string literal was used for the virtual key code in a VIRTKEY type accelerator. This warning lets you continue, but be aware that the accelerator keys generated may not match the string you indicated. (VIRTKEYs use different key codes than ASCII accelerators.)

Return to Main Resource Compiler Messages Page


New Features for Compaq Visual Fortran Version 6.1

New features added to Compaq Visual Fortran (Visual Fortran) Version 6.1 (since Version 6.0.A) include the following:

  • The Compaq Extended Math Library (CXML) is now provided with the Visual Fortran kit (all editions). CXML is a highly efficient set of math library routines that covers Basic Linear Algebra (BLAS), Linear Algebra Routines (LAPACK), sparse linear system solvers, sorting routines, random number generation, and signal processing functions.

    In addition to being provided with Visual Fortran, CXML is also available on other Compaq Fortran platforms. CXML is:

    • Provided with Compaq Fortran Version 5.3 (or later) for Tru64 UNIX Alpha systems and Compaq Fortran Version 1.0 (or later) for Linux Alpha Systems
    • Provided with Compaq Visual Fortran Version 6.1 (or later)
    • Provided with Compaq Fortran Version 7.3 (or later) for OpenVMS Alpha systems
    • Available as a separate download for most platforms (see the CXML home page at http://www.compaq.com/math)

    For more information on CXML, see Using the Compaq Extended Math Library (CXML) in the Programmer's Guide or the online PDF file Cxmlref.pdf. For information on online PDF files, see The IMSL Routines and CXML Routines Online PDF Documentation.

  • IMSL® Version 4 libraries are now provided with the Professional Edition (prior to Visual Fortran 6.1, Visual Fortran provided IMSL Version 3 libraries). The IMSL routines reference documentation is available in PDF format (not HLP format).

    For information on using the IMSL libraries, see Using the IMSL Mathematical and Statistical Libraries in the Programmer's Guide. For information on online PDF files, see The IMSL Routines and CXML Routines Online PDF Documentation. For more information about IMSL and Visual Numerics®, Inc., see http://www.vni.com.

  • New functionality has been added to the Dialog Procedures:
    • You can use ActiveX Controls in your dialog boxes. See Using ActiveX Controls in the Using Dialogs section in the Programmer's Guide.

    • Edit Box control enhancements:

      You can now use multi-line edit controls and the maximum size restriction of 256 characters has been removed. The Edit Box control supports 2 additional integer indexes (see Using Edit Boxes):

      • DLG_TEXTLENGTH - Sets or Gets the current length of the text in the edit box.
      • DLG_POSITION - Sets or Gets the current text cursor position in the edit box.

    • The dialog box supports a new callback index, DLG_SIZECHANGE (see Control Indexes). This callback is invoked when the size of the dialog box changes.

    • New dialog routines are provided:
      • DlgSetTitle - Sets the title of the dialog box.
      • DlgFlush - Updates the display of the dialog box. Useful when changing the dialog box outside of a dialog callback.
      • DlgModalWithParent - Allows you to specify the parent window of a modal dialog box. Useful in an SDI or MDI Windows application that uses modal dialog boxes.
      • DlgIsDlgMessageWithDlg - Allows you to specify which dialog box to check. Useful when the dialog box was created in a DLL.
  • New SPORT_xxx (Serial Port) routines have been added.

    The SPORT_xxx collection of routines helps Fortran programmers do basic input and output to serial communication ports. The programming model is much the same as a normal file except the user does a connect/release instead of an open/close. Two types of read and write operations are provided:

    • Read and write arbitrary data from/to the port
    • Read and write line terminated data

    Calls are provided to set basic port parameters such as baud rate, stop bits, timeouts, and so on. Additionally, a call is provided to return the WIN32 handle to the port so that raw WIN32 APIs may be used to implement additional needs of the programmer.

    The documentation overview can be found in Using the Serial I/O Port Routines in the Programmers Guide.

    For a detailed description of the routines, see the Language Reference, A to Z Reference under S (SPORT_xxx), such as SPORT_CONNECT.

  • The new subroutine TRACEBACKQQ allows you to initiate a stack trace in your program whenever you like. The input arguments allow you to specify your own message text to head the output and other options as well. See the following for more information:

    • Obtaining Traceback Information with TRACEBACKQQ in the Programmer's Guide
    • TRACEBACKQQ in the Language Reference, A to Z Reference.

  • In Developer Studio, you can now print a Fortran source file in color (requires a color printer). After you open the source file in the text editor, in the File menu select Print Colorized Fortran. This has been tested with the Internet Explorer and Netscape browsers. Because Print Colorized Fortran does not know when printing has completed, it creates and leaves the HTML file in your TEMP directory. Delete previously printed HTML files from your TEMP directory to free up disk space. Print Colorized Fortran uses the FSC utility to create an HTML file with the coloring information and then instructs the application on your system that handles HTML files to print the file. If you encounter a problem using the Print Colorized Fortran item, please use the FSC utility directly.

    The FSC.EXE utility takes an .F90 or .FOR source file and produces an HTML version that is colorized per the current Developer Studio Color settings in the registry. It has default colors that are used if the current registry settings are not available. The resultant HTML file may be printed or viewed with your favorite browser. This utility may be invoked from a command prompt (use FSC -? or FSC /h for help) or from within Developer Studio.

  • VFRUN provides a self-extracting executable file that installs redistributable Visual Fortran run-time components on the target system. These run-time components include DLLs and other files, as described in "Redistributing Visual Fortran Files" in Compaq Visual Fortran Installing and Getting Started.

    VFRUN files are provided for different Visual Fortran releases and for x86 and Alpha systems. For example, for Visual Fortran v6.1, VFRUN61i.exe is provided for x86 systems and VFRUN61a.exe is provided for Alpha systems. You can download VFRUN from the Visual Fortran Web site, http://www.compaq.com/fortran (click on Downloads and Updates, then Run-Time Redistributables Kit). Please download the VFRUN kit for the version of Visual Fortran used to create the executable application.

  • Visual Fortran (VF) Reporter is a new tool that helps you report problems by e-mail to the Visual Fortran team. This tool gathers and displays system information and guides you to send relevant information in an e-mail message. This tool can be optionally installed during Visual Fortran installation. For information on technical support and using VF Reporter, see Compaq Visual Fortran Installing and Getting Started.

  • Greater Access to Windows APIs

    Additional interface definitions have been provided to simplify calling Win32 routines from Visual Fortran:

    • DFWINTY.F90 has 980 new derived types and 4070 new Fortran parameter constants added. These new items represent the difference between Microsoft Visual C++ 4 header files and Visual C++ 6 header files.

    • USER32.F90 has 72 new interfaces to routines in USER32.LIB. These new routine interfaces again represent the difference between Microsoft Visual C++ 4 header files and Visual C++ 6 header files.

    • KERNEL32.f90 has 50 new interfaces to routines in KERNEL32.LIB.

    • GDI32.F90 has 25 new interfaces to routines in GDI32.LIB.

    • ADVAPI32.F90 has 50 new interfaces to routines in ADVAPI32.LIB.

    In all these files, the new material is under conditional compilation so that defining "__DO_NOT_INCLUDE_VC6_ITEMS" will remove the new items. Search for the string above to locate the new items which will be found towards the ends of the files.

    The files are shipped without the string being defined, and the mod files will contain the new items.

  • New or changed compiler options include:

    • The /align option now includes the /align:sequence keyword to allow alignment of derived type data with the SEQUENCE statement. This option appears in the Fortran Data category in the Project Settings dialog box (see Categories of Compiler Options).

    • The /ccdefault:keyword option controls carriage control use when writing to a terminal screen. This new option appears in the Run-Time category in the Project Settings dialog box.

    • The /cxml option requests that the Compaq Extended Math Library (CXML) library be linked against (provided for documentation purposes only). This new option appears in the Library category in the Project Settings dialog box.

    • The /fast option now sets the /arch:host /tune:host /align:sequence options.

    • The /imsl option ensures that the IMSL libraries will be passed to the linker (your program needs to specify the appropriate USE statements and set the IMSL environment variables). This new option appears in the Library category in the Project Settings dialog box.

  • Visual Fortran puts literals into read-only memory so storing into a dummy argument that has a constant as its associated actual argument will result in an access violation and program termination:

 call f(0)
 ...
 subroutine f(i)
 i=1                ! this will die
  • Two new Fortran source directives for controlling optimizations are now available:

    • cDEC$ IVDEP
    • cDEC$ UNROLL

    For an overview of these directives, see Compiler Directives Related to Performance in the Programmer's Guide.

    For more detail, see IVDEP Directive and UNROLL Directive in the Language Reference.

  • Version 6.1 for x86 (Intel) systems contains all of the applicable updated files from the Microsoft Visual Studio 6.0 Service Pack 3. Therefore, Version 6.1 x86 users do not need to install Visual Studio 6.0 Service Pack unless you have other Visual Studio products. Version 6.1 for Alpha systems contains all of the applicable updated files from the Microsoft Visual Studio 6.0 Service Pack 2.

  • You can now maintain previously saved Fortran Environment Project Settings (see Saving and Using the Project Setting Environment for Different Projects. Use the Manage Saved Fortran Environment icon in the Fortran toolbar. Also, application wizards that assist in creating a new Fortran Windows project have been enhanced.

  • HTML Help now supports the ability to define (View menu, Define Subset... item) and use subsets of the current collection of HTML Help titles (see Compaq Visual Fortran Installing and Getting Started). This is especially useful when using the full-text search capabilities of HTML Help.

  • HTML help no longer includes embedded Adobe Acrobat PDF files. Instead, the PDF files ship on the Visual Fortran CD-ROM (and are installed if requested). For details, see The IMSL Routines and CXML Routines Online PDF Documentation. This reduces the size of the Visual Fortran HTML help (CHM) file and minimizes the possibility of software problems displaying embedded PDF files reported on certain systems.

  • For additional details, see the online release notes, installed in Program Files\Microsoft Visual Studio\Df98.

Changes to Compaq Array Visualizer are described separately in the Array Visualizer HTML Help documentation.


New Features for Compaq Visual Fortran Version 6.5 and 6.5A

New features added to Compaq Visual Fortran (Visual Fortran) Version 6.5A (since Visual Fortran Version 6.5) include the following:

  • The Fortran COM Server now allows you to select an out-of-process (.EXE) COM server. Users now have a choice of the type of server, either a DLL (in-process) COM server and an EXE (out-of-process) COM server. Other Fortran COM Server enhancements allow array arguments to be assumed shape and you can now add the ISupportErrorInfo interface to your server.
  • The following new compiler options have been added:
    • /assume:[no]protect_constants specifies whether constant actual arguments can be changed.
    • /check:arg_temp_created requests that a run-time informational message appear if actual arguments are copied into temporary storage before routine calls.
    • /warn:ignore_loc requests that the compiler issues warnings when %LOC is stripped from an argument
  • The following new ATTRIBUTES directives have been added: ALLOW_NULL, DECORATE, IGNORE_LOC, and NOMIXED_STR_LEN_ARG
  • The optional KIND argument has been added to INDEX, LEN_TRIM, MAXLOC, MINLOC, SCAN, and VERIFY intrinsic procedures.
  • For additional new features and details, see the online release notes (relnotes.txt or relnotes.htm).
  • New or significantly revised sections in the Programmer's Guide based on customer feedback include Coding Requirements for Fortran Windows Applications, Using Menus and Dialogs in SDI and MDI Fortran Windows Applications, Using the Resource Editor to Design a Dialog, and Compatibility with Compaq Fortran on Other Platforms.
  • The section Pointer Arguments in the Language Reference has been significantly revised based on customer feedback.

New features added to Compaq Visual Fortran Version 6.5 (since Visual Fortran Version 6.1) include the following:

  • The Fortran COM Server project type and the Fortran COM Server Wizard, described in Creating a COM Server. The Fortran COM Server Wizard helps you create a COM server or dual interface server. In addition, new information about using COM and Automation is provided in Getting a Pointer to an Object's Interface.
  • New COM routines are provided:
    • COMStringFromGUID passes a GUID and returns the corresponding string representation.
    • COMIsEqualGUID determines if two GUIDs are the same.
  • Visual Fortran now generates optimized code for the IntelTM PentiumTM III, AMDTM K6, and AMD AthlonTM architectures, by providing new keywords for the /arch and /tune compiler options.
  • New intrinsic procedures added:
    • INT_PTR_KIND returns the INTEGER KIND that will hold an address.
    • KIND= is now an optional argument to the intrinsic procedures LEN, SHAPE, SIZE, LBOUND, and UBOUND.
    • For x86 systems, POPCNT, POPPAR, LEADZ, and TRAILZ perform bit-related operations on integer data.
  • New exception handling routines are provided:

    • CLEARSTATUSFPQQ exception flags in the floating-point processor status word (x86 processors).
    • GETEXCEPTIONPTRSQQ returns a pointer to C run-time exception information pointers appropriate for use in signal handlers established with SIGNALQQ or direct calls to the C rtl signal() routine (x86 processors). For additional information about GETEXCEPTIONPTRSQQ, see Obtaining Traceback Information with TRACEBACKQQ and TRACEBACKQQ.
  • The new QuickWin graphics routine SETTEXTCURSOR has been added to set the height and width of the text cursor (the caret) for the window in focus.
  • The interface to the AUTOAddArg subroutine has changed. The output_arg argument (LOGICAL) is now the intent_arg argument (INTEGER). New code should use the new documented interface. The old interface is supported for compatibility purposes.
  • New information about advanced exception handling and setting up various types of handlers for x86 systems is provided in Advanced Exception and Termination Handling Considerations.
  • For non-native unformatted files, you can now use the FORT_CONVERT.ext or FORT_CONVERT_ext environment variable method to specify that files with certain file extensions (such as .DAT) are in a specified non-native format (see Methods of Specifying the Data Format). (Visual Fortran's native numeric formats are little endian, including IEEE floating-point formats.)
  • Previous versions of Visual Fortran allowed only procedures and COMMON blocks to have the DLLEXPORT or DLLIMPORT ATTRIBUTE. You can now export/import module variables and arrays.
  • A Visual Fortran compiled module now contains all of the information from modules used (USE statement) by the module. This may greatly increase the size of compiled modules, especially if the modules contain a USE DFWIN or USE DFWINTY statement. There are ways to minimize the information contained in compiled modules when calling Win32 routines, as described in Calling Win32 Routines and the Visual Fortran Windows Module.
  • In order to conform with clarified wording in the Fortran 95 standard, the compiler has been changed so that when a READ statement encounters an end-of-file condition, and there is no END specifier but there is an ERR specifier, the ERR= branch is not taken. Similarly, if an end-of-record condition occurs but there is no EOR specifier, an ERR branch is not taken. If you do not specify a routine to handle such errors with the IOSTAT specifier, omitting the END or EOR specifier results in a severe run-time error (such as numbers 24 or 268 respectively).
  • The run-time system has been changed to perform more thorough edit checking on list-directed input. In accordance with the Fortran 95 Standard, the run-time system no longer accepts as numeric input "+", "-", ".", "D", "E", or "Q" without expressing at least 1 digit. For example, the run-time system used to allow a single "+" to convert to a 0, but now it will return a FOR$IOS_LISIO_SYN (number 59) error. In addition, ambiguous expressions such as "+-" and "--" will be rejected
  • Support has been added for reading nondelimited character strings as input for character NAMELIST items.
  • The %VAL and %REF used on actual arguments now override any argument-passing mechanism specified in an explicit interface.
  • New Visual Fortran Samples (described in Roadmap to the Visual Fortran Samples) are provided, including:
    • COM sample: Adder
    • DIALOG sample: Celsicon
    • ExceptionHandling samples: ClearFP, Cslexp2, Cslexp4, GetEptrs, Vbvf1, and Winexcp1
    • Isovar sample (ISO varying strings)
    • Mixed-language samples, new samples for MASM and Delphi
    • QuickWin samples: Conapp, Dirkeys4, PostMini, and Resize
    • Isovar, an ISO varying string sample
  • Compiling modules is now faster.
  • Concurrent-use licensing is now available.
  • For additional new features and details, see the online release notes (relnotes.txt or relnotes.htm), located in the root directory of the Visual Fortran CD-ROM or installed in Program Files\Microsoft Visual Studio\Df98.
  • New or significantly revised sections in the Programmer's Guide based on customer feedback include Specifying Consistent Library Types and Using the Console.

Changes to Compaq Array Visualizer are described separately in the Array Visualizer HTML Help documentation.


Using the Compaq Visual Fortran Web Pages

Compaq Fortran provides an Internet Web site that offers comprehensive information about all Compaq Fortran products. You can view the home page for Compaq Fortran, at:

http://www.compaq.com/fortran.

The following tables summarize important links for:

  • Compaq Visual Fortran (Windows systems)
  • Compaq Fortran for Alpha systems

Important links about Compaq Visual Fortran (Windows systems):

For information on: | Click (or type) this:
Visual Fortran product information, differences between Visual Fortran editions, and system requirements | http://www.compaq.com/fortran/visual
Register your Visual Fortran purchase or update your information | http://www.compaq.com/fortran/register
Suggested prices of Visual Fortran editions and version upgrades | http://www.compaq.com/fortran/visual/pricing.html
Where you can purchase Visual Fortran worldwide | http://www.compaq.com/fortran/visual/wheretobuy.html
Downloadable service updates for supported versions | http://www.compaq.com/fortran/visual/updates.html
Support options for Visual Fortran | http://www.compaq.com/fortran/support/visual.html
Knowledge base of support articles | http://www.compaq.com/fortran/kb/qlist.html
List of Frequently Asked Questions (FAQ) | http://www.compaq.com/fortran/visual/faq.html
Array Visualizer home page (Professional and Enterprise editions) | http://www.compaq.com/fortran/aview
Compaq Extended Math Library pages, including download kits | http://www.compaq.com/fortran/math
Latest online documentation | http://www.compaq.com/fortran/docs
Online bookstore (third-party books) | http://www.compaq.com/fortran/books.html
Links and articles | http://www.compaq.com/fortran/resources.html

Important links about Compaq Fortran for Alpha (and VAX) systems:

For information on: | Click (or type) this:
Support options for Compaq Fortran products | http://www.compaq.com/fortran/support
Compaq Fortran for Tru64 UNIX Alpha home page, including latest release and update kits | http://www.compaq.com/fortran/dfau.html
Compaq Fortran for Linux Alpha home page, including latest release and update kits | http://www.compaq.com/fortran/linux
Compaq Fortran for OpenVMS Alpha home page, including latest release and update kits | http://www.compaq.com/fortran/dfav.html
Compaq Fortran for OpenVMS VAX home page, including latest release and update kits | http://www.compaq.com/fortran/dfvv.html
Compaq Extended Math Library home page, including download kits | http://www.compaq.com/fortran/math
Latest online documentation | http://www.compaq.com/fortran/docs
Links and articles | http://www.compaq.com/fortran/resources.html


The IMSL Routines and CXML Routines Online PDF Documentation

Visual Fortran provides a full set of Intrinsic Procedures, statements, and other elements of the Fortran 95/90 language.

Visual Fortran provides specialized routines, such as routines for graphics. The Visual Fortran intrinsic procedures, statements, and routines are described in the Visual Fortran online Language Reference, especially in the A to Z Reference section.

In addition, Visual Fortran also provides additional routines, including the following:

  • IMSL Libraries (included in the Professional and Enterprise Edition)

  • Compaq Extended Math Library (CXML)

The online reference documentation for the IMSL and CXML routines are provided in Adobe® Acrobat® PDF file format. To view this documentation, you must install the Acrobat Reader, Version 3.01 or later. You can download the most recent version of Adobe Acrobat Reader from http://www.adobe.com or use the version provided on the Visual Fortran CD-ROM (see Compaq Visual Fortran Installing and Getting Started).

The following chapters in the online Visual Fortran Programmer's Guide provide general information about using the IMSL and CXML routines from Visual Fortran applications:

  • Using the IMSL Mathematical and Statistical Libraries

  • Using the Compaq Extended Math Library (CXML)

The following directories contain Adobe Acrobat PDF files that provide detailed information on the routines:

  • For information about the CXML routines (after installation), use Acrobat Reader to open the file cxmlref.pdf in:
    Program Files\Microsoft Visual Studio\Df98\Cxml\Doc

  • For information about the IMSL routines (after installation), use Acrobat Reader to open the file imsl.pdf in:
    Program Files\Microsoft Visual Studio\Df98\IMSL\Help

If you choose not to install these PDF files, you can open (or copy) them from the Visual Fortran CD-ROM.

The online file Cvf_gs.pdf in the root directory of the Visual Fortran CD-ROM contains the Compaq Visual Fortran Installing and Getting Started.

Related Home Pages:

Compaq Visual Fortran Home Page


Topic Not Found

No matching topic was found.

To view this topic, the online Help "Platform SDK" must be installed or the media CD-ROM must be mounted. Also, the "Platform SDK" must be included in the HTML Help subset being used.

For more information, see the Compaq Visual Fortran Installing and Getting Started manual.