⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gfortran.texi

📁 理解和实践操作系统的一本好书
💻 TEXI
📖 第 1 页 / 共 5 页
字号:
@node BOZ literal constants@subsection BOZ literal constants@cindex BOZ literal constantsBesides decimal constants, Fortran also supports binary (@code{b}),octal (@code{o}) and hexadecimal (@code{z}) integer constants. Thesyntax is: @samp{prefix quote digits quote}, were the prefix iseither @code{b}, @code{o} or @code{z}, quote is either @code{'} or@code{"} and the digits are for binary @code{0} or @code{1}, foroctal between @code{0} and @code{7}, and for hexadecimal between@code{0} and @code{F}. (Example: @code{b'01011101'}.)Up to Fortran 95, BOZ literals were only allowed to initializeinteger variables in DATA statements. Since Fortran 2003 BOZ literalsare also allowed as argument of @code{REAL}, @code{DBLE}, @code{INT}and @code{CMPLX}; the result is the same as if the integer BOZliteral had been converted by @code{TRANSFER} to, respectively,@code{real}, @code{double precision}, @code{integer} or @code{complex}.As GNU Fortran extension the intrinsic procedures @code{FLOAT},@code{DFLOAT}, @code{COMPLEX} and @code{DCMPLX} are treated alike.As an extension, GNU Fortran allows hexadecimal BOZ literal constants tobe specified using the @code{X} prefix, in addition to the standard@code{Z} prefix. The BOZ literal can also be specified by adding asuffix to the string, for example, @code{Z'ABC'} and @code{'ABC'Z} areequivalent.Furthermore, GNU Fortran allows using BOZ literal constants outsideDATA statements and the four intrinsic functions allowed by Fortran 2003.In DATA statements, in direct assignments, where the right-hand sideonly contains a BOZ literal constant, and for old-style initializers ofthe form @code{integer i /o'0173'/}, the constant is transferredas if @code{TRANSFER} had been used; for @code{COMPLEX} numbers, onlythe real part is initialized unless @code{CMPLX} is used. In all othercases, the BOZ literal constant is converted to an @code{INTEGER} value withthe largest decimal representation.  This value is then convertednumerically to the type and kind of the variable in question.(For instance @code{real :: r = b'0000001' + 1} initializes @code{r}with @code{2.0}.) As different compilers implement the extensiondifferently, one should be careful when doing bitwise initializationof non-integer variables.Note that initializing an @code{INTEGER} variable with a statement suchas @code{DATA i/Z'FFFFFFFF'/} will give an integer overflow error ratherthan the desired result of @math{-1} when @code{i} is a 32-bit integeron a system that supports 64-bit integers.  The @samp{-fno-range-check}option can be used as a workaround for legacy code that initializesintegers in this manner.@node Real array indices@subsection Real array indices@cindex array, indices of type realAs an extension, GNU Fortran allows the use of @code{REAL} expressionsor variables as array indices.@node Unary operators@subsection Unary operators@cindex operators, unaryAs an extension, GNU Fortran allows unary plus and unary minus operatorsto appear as the second operand of binary arithmetic operators withoutthe need for parenthesis.@smallexample       X = Y * -Z@end smallexample@node Implicitly convert LOGICAL and INTEGER values@subsection Implicitly convert @code{LOGICAL} and @code{INTEGER} values@cindex conversion, to integer@cindex conversion, to logicalAs an extension for backwards compatibility with other compilers, GNUFortran allows the implicit conversion of @code{LOGICAL} values to@code{INTEGER} values and vice versa.  When converting from a@code{LOGICAL} to an @code{INTEGER}, @code{.FALSE.} is interpreted aszero, and @code{.TRUE.} is interpreted as one.  When converting from@code{INTEGER} to @code{LOGICAL}, the value zero is interpreted as@code{.FALSE.} and any nonzero value is interpreted as @code{.TRUE.}.@smallexample        LOGICAL :: l        l = 1@end smallexample@smallexample        INTEGER :: i        i = .TRUE.@end smallexampleHowever, there is no implicit conversion of @code{INTEGER} values in@code{if}-statements, nor of @code{LOGICAL} or @code{INTEGER} valuesin I/O operations.@node Hollerith constants support@subsection Hollerith constants support@cindex Hollerith constantsGNU Fortran supports Hollerith constants in assignments, functionarguments, and @code{DATA} and @code{ASSIGN} statements.  A Hollerithconstant is written as a string of characters preceded by an integerconstant indicating the character count, and the letter @code{H} or@code{h}, and stored in bytewise fashion in a numeric (@code{INTEGER},@code{REAL}, or @code{complex}) or @code{LOGICAL} variable.  Theconstant will be padded or truncated to fit the size of the variable inwhich it is stored.Examples of valid uses of Hollerith constants:@smallexample      complex*16 x(2)      data x /16Habcdefghijklmnop, 16Hqrstuvwxyz012345/      x(1) = 16HABCDEFGHIJKLMNOP      call foo (4h abc)@end smallexampleInvalid Hollerith constants examples:@smallexample      integer*4 a      a = 8H12345678 ! Valid, but the Hollerith constant will be truncated.      a = 0H         ! At least one character is needed.@end smallexampleIn general, Hollerith constants were used to provide a rudimentaryfacility for handling character strings in early Fortran compilers,prior to the introduction of @code{CHARACTER} variables in Fortran 77;in those cases, the standard-compliant equivalent is to convert theprogram to use proper character strings.  On occasion, there may be acase where the intent is specifically to initialize a numeric variablewith a given byte sequence.  In these cases, the same result can beobtained by using the @code{TRANSFER} statement, as in this example.@smallexample      INTEGER(KIND=4) :: a      a = TRANSFER ("abcd", a)     ! equivalent to: a = 4Habcd@end smallexample@node Cray pointers@subsection Cray pointers@cindex pointer, CrayCray pointers are part of a non-standard extension that provides aC-like pointer in Fortran.  This is accomplished through a pair ofvariables: an integer "pointer" that holds a memory address, and a"pointee" that is used to dereference the pointer.Pointer/pointee pairs are declared in statements of the form:@smallexample        pointer ( <pointer> , <pointee> )@end smallexampleor,@smallexample        pointer ( <pointer1> , <pointee1> ), ( <pointer2> , <pointee2> ), ...@end smallexampleThe pointer is an integer that is intended to hold a memory address.The pointee may be an array or scalar.  A pointee can be an assumedsize array---that is, the last dimension may be left unspecified byusing a @code{*} in place of a value---but a pointee cannot be anassumed shape array.  No space is allocated for the pointee.The pointee may have its type declared before or after the pointerstatement, and its array specification (if any) may be declaredbefore, during, or after the pointer statement.  The pointer may bedeclared as an integer prior to the pointer statement.  However, somemachines have default integer sizes that are different than the sizeof a pointer, and so the following code is not portable:@smallexample        integer ipt        pointer (ipt, iarr)@end smallexampleIf a pointer is declared with a kind that is too small, the compilerwill issue a warning; the resulting binary will probably not workcorrectly, because the memory addresses stored in the pointers may betruncated.  It is safer to omit the first line of the above example;if explicit declaration of ipt's type is omitted, then the compilerwill ensure that ipt is an integer variable large enough to hold apointer.Pointer arithmetic is valid with Cray pointers, but it is not the sameas C pointer arithmetic.  Cray pointers are just ordinary integers, sothe user is responsible for determining how many bytes to add to apointer in order to increment it.  Consider the following example:@smallexample        real target(10)        real pointee(10)        pointer (ipt, pointee)        ipt = loc (target)        ipt = ipt + 1       @end smallexampleThe last statement does not set @code{ipt} to the address of@code{target(1)}, as it would in C pointer arithmetic.  Adding @code{1}to @code{ipt} just adds one byte to the address stored in @code{ipt}.Any expression involving the pointee will be translated to use thevalue stored in the pointer as the base address.To get the address of elements, this extension provides an intrinsicfunction @code{LOC()}.  The @code{LOC()} function is equivalent to the@code{&} operator in C, except the address is cast to an integer type:@smallexample        real ar(10)        pointer(ipt, arpte(10))        real arpte        ipt = loc(ar)  ! Makes arpte is an alias for ar        arpte(1) = 1.0 ! Sets ar(1) to 1.0@end smallexampleThe pointer can also be set by a call to the @code{MALLOC} intrinsic(see @ref{MALLOC}).Cray pointees often are used to alias an existing variable.  Forexample:@smallexample        integer target(10)        integer iarr(10)        pointer (ipt, iarr)        ipt = loc(target)@end smallexampleAs long as @code{ipt} remains unchanged, @code{iarr} is now an alias for@code{target}. The optimizer, however, will not detect this aliasing, soit is unsafe to use @code{iarr} and @code{target} simultaneously.  Usinga pointee in any way that violates the Fortran aliasing rules orassumptions is illegal. It is the user's responsibility to avoid doingthis; the compiler works under the assumption that no such aliasingoccurs.Cray pointers will work correctly when there is no aliasing (i.e., whenthey are used to access a dynamically allocated block of memory), andalso in any routine where a pointee is used, but any variable with whichit shares storage is not used.  Code that violates these rules may notrun as the user intends.  This is not a bug in the optimizer; any codethat violates the aliasing rules is illegal.  (Note that this is notunique to GNU Fortran; any Fortran compiler that supports Cray pointerswill ``incorrectly'' optimize code with illegal aliasing.)There are a number of restrictions on the attributes that can be appliedto Cray pointers and pointees.  Pointees may not have the@code{ALLOCATABLE}, @code{INTENT}, @code{OPTIONAL}, @code{DUMMY},@code{TARGET}, @code{INTRINSIC}, or @code{POINTER} attributes. Pointersmay not have the @code{DIMENSION}, @code{POINTER}, @code{TARGET},@code{ALLOCATABLE}, @code{EXTERNAL}, or @code{INTRINSIC} attributes.Pointees may not occur in more than one pointer statement.  A pointeecannot be a pointer.  Pointees cannot occur in equivalence, common, ordata statements.A Cray pointer may also point to a function or a subroutine.  Forexample, the following excerpt is valid:@smallexample  implicit none  external sub  pointer (subptr,subpte)  external subpte  subptr = loc(sub)  call subpte()  [...]  subroutine sub  [...]  end subroutine sub@end smallexampleA pointer may be modified during the course of a program, and thiswill change the location to which the pointee refers.  However, whenpointees are passed as arguments, they are treated as ordinaryvariables in the invoked function.  Subsequent changes to the pointerwill not change the base address of the array that was passed.@node CONVERT specifier@subsection @code{CONVERT} specifier@cindex @code{CONVERT} specifierGNU Fortran allows the conversion of unformatted data between little-and big-endian representation to facilitate moving of databetween different systems.  The conversion can be indicated withthe @code{CONVERT} specifier on the @code{OPEN} statement.@xref{GFORTRAN_CONVERT_UNIT}, for an alternative way of specifyingthe data format via an environment variable.Valid values for @code{CONVERT} are:@itemize @w{}@item @code{CONVERT='NATIVE'} Use the native format.  This is the default.@item @code{CONVERT='SWAP'} Swap between little- and big-endian.@item @code{CONVERT='LITTLE_ENDIAN'} Use the little-endian representation        for unformatted files.@item @code{CONVERT='BIG_ENDIAN'} Use the big-endian representation for        unformatted files.@end itemizeUsing the option could look like this:@smallexample  open(file='big.dat',form='unformatted',access='sequential', &       convert='big_endian')@end smallexampleThe value of the conversion can be queried by using@code{INQUIRE(CONVERT=ch)}.  The values returned are@code{'BIG_ENDIAN'} and @code{'LITTLE_ENDIAN'}.@code{CONVERT} works between big- and little-endian for@code{INTEGER} values of all supported kinds and for @code{REAL}on IEEE systems of kinds 4 and 8.  Conversion between different``extended double'' types on different architectures such asm68k and x86_64, which GNU Fortransupports as @code{REAL(KIND=10)} and @code{REAL(KIND=16)}, willprobably not work.@emph{Note that the values specified via the GFORTRAN_CONVERT_UNITenvironment variable will override the CONVERT specifier in theopen statement}.  This is to give control over data formats tousers who do not have the source code of their program available.Using anything but the native representation for unformatted datacarries a significant speed overhead.  If speed in this area mattersto you, it is best if you use this only for data that needs to beportable.@node OpenMP@subsection OpenMP@cindex OpenMPOpenMP (Open Multi-Processing) is an application programminginterface (API) that supports multi-platform shared memory multiprocessing programming in C/C++ and Fortran on many architectures, including Unix and Microsoft Windows platforms.It consists of a set of compiler directives, library routines,and environment variables that influence run-time behavior.GNU Fortran strives to be compatible to the @uref{http://www.openmp.org/drupal/mp-documents/spec25.pdf,OpenMP Application Program Interface v2.5}.To enable the processing of the OpenMP directive @code{!$omp} infree-form source code; the @code{c$omp}, @code{*$omp} and @code{!$omp}directives in fixed form; the @code{!$} conditional compilation sentinelsin free form; and the @code{c$}, @code{*$} and @code{!$} sentinelsin fixed form, @command{gfortran} needs to be invoked with the@option{-fopenmp}. This also arranges for automatic linking of theGNU OpenMP runtime library @ref{Top,,libgomp,libgomp,GNU OpenMPruntime library}.The OpenMP Fortran runtime library routines are provided both in aform of a Fortran 90 module named @code{omp_lib} and in a form ofa Fortran @code{include} file named @file{omp_lib.h}.An example of a parallelized loop taken from Appendix A.1 ofthe OpenMP Application Program Interface v2.5:@smallexampleSUBROUTINE A1(N, A, B)  INTEGER I, N  REAL B(N), A(N)!$OMP PARALLEL DO !I is private by default  DO I=2,N    B(I) = (A(I) + A(I-1)) / 2.0  ENDDO!$OMP END PARALLEL DOEND SUBROUTINE A1@end smallexamplePlease note:@itemize@item@option{-fopenmp} implies @option{-frecursive}, i.e. all local arrayswill be allocated on the stack. When porting existing code to OpenMP,this may lead to surprising results, especially to segmentation faultsif the stacksize is limited.@itemOn glibc-based systems, OpenMP enabled applications can not be staticallylinked due to limitations of the underlying pthreads-implementation. Itmight be possible to get a working solution if 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -