fortranfortran2003

Hexadecimal Constants


I want to declare an integer parameter based on its hexadecimal representation. What are the differences between:

INTEGER(kind=int32), PARAMETER :: a = Z'FFFFFFFF'
INTEGER(kind=int32), PARAMETER :: b = int(Z'FFFFFFFF', kind=int32)
INTEGER(kind=int32), PARAMETER :: c = transfer(Z'FFFFFFFF', 1_int32)

(And yes, I know that this is just -1.)

gfortran seems to give me an integer overflow error during compile (helpfully telling me that I can ignore that with -fno-range-check) for the above a and b, but not for c.

I need to make it Fortran 2003 compliant, as this code might be compiled with different compilers elsewhere.


Solution

  • The first and third statements are not valid Fortran. A boz literal constant can only appear in a number of limited contexts - the int intrinsic being one of those contexts.

    The middle statement sets the value of the named constant to a processor dependent value based on the sequence of bits specified by the boz-literal-constant. The value is processor dependent because the most significant bit in the resulting value is one.

    Elaborating, using the Fortran 2008 rules (Fortran 2003 was different, as Vladimir notes):

    Under Fortran 2003 the sequence of bits is interpreted as a positive number using the largest integer representation available on the processor. The resulting value will be out of the range of an INTEGER(INT32) object, making the code non-conforming.