https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120131

--- Comment #9 from kargls at comcast dot net ---
(In reply to Vladimir Terzi from comment #8)
> I initially changed the status, because I assumed that my questions in
> comment #2 will be ignored.
> 
> (In reply to kargls from comment #6)
> > I suppose it is somewhat naive of gfortran contributors to expect that users
> > read the documentation supplied with the compiler.
> 
> Not in the case of what is assumed to be common knowledge.  Most of Stack
> Overflow users claimed that the correct integer*4 range in Fortran is
> [-2147483648:2147483647].  This statement can even be found in Fortran
> language references of Oracle and IBM.
> 
> (In reply to kargls from comment #6)
> > ‘-fno-range-check’
> >      Disable range checking on results of simplification of constant
> >      expressions during compilation.  For example, GNU Fortran gives an
> >      error at compile time when simplifying ‘a = 1. / 0’.  With this
> >      option, no error is given and ‘a’ is assigned the value
> >      ‘+Infinity’.  If an expression evaluates to a value outside of the
> >      relevant range of [‘-HUGE()’:‘HUGE()’], then the expression is
> >      replaced by ‘-Inf’ or ‘+Inf’ as appropriate.  Similarly, ‘DATA
> >      i/Z'FFFFFFFF'/’ results in an integer overflow on most systems, but
> >      with ‘-fno-range-check’ the value "wraps around" and ‘i’ is
> >      initialized to -1 instead.
> > 
> > Those last two sentences are important.
> 
> I fail to see, how this two sentences explain that z'80000000' is an invalid
> integer of kind 4 due to the Fortran standard.
> 
> (In reply to kargls from comment #6)
> > % gfortran14 -o z -fno-range-check -pedantic a.f90 && ./z
> > a.f90:1:21:
> > 
> >     1 | print *,  -2147483648
> >       |                     1
> > Warning: Integer outside symmetric range implied by Standard Fortran at (1)
> >  -2147483648
> > 
> > So, yes, more than one gfortran contributor has thought about the corner
> > case of -huge(1) - 1.
> 
> This is the message I would have wished to see as the error message in this
> case.

GCC bugzilla is not the place to learn Fortran.

   F2023, 6.2.3  Constants

   R605 literal-constant  is int-literal-constant
                          or real-literal-constant
                          or complex-literal-constant
                          or logical-literal-constant
                          or char-literal-constant
                          or boz-literal-constant

   F2023, 7.4.3.1 Integer type

   Any integer value can be represented as a signed-int-literal-constant.

   R707 signed-int-literal-constant is [ sign ] int-literal-constant
   R708 int-literal-constant        is digit-string [ _kind-param ]
   R709 kind-param                  is digit-string
                                    or scalar-int-constant-name
   R710 signed-digit-string         is [ sign ] digit-string
   R711 digit-string                is digit [ digit ] ...
   R712 sign                        is +
                                    or ­

'K = -2147483648' is an expression via R605 and R708.

   F2023, 10.1.2.2  Primary

   R1001 primary

   10.1.2.2 Primary  is literal-constant
                     or ...

We have already established 'K = -2147483648' is an expression.

   F2023, 10.1.2.4 Level-1 expressions

   R1003 level-1-expr      is [ defined-unary-op ] primary
   R1004 defined-unary-op  is .letter [ letter ] ... .


   F2023, 10.1.2.5  Level-2 expressions

   R1005 mult-operand  is level-1-expr [ power-op mult-operand ]
   R1006 add-operand   is [ add-operand mult-op ] mult-operand
   R1007 level-2-expr  is [ [ level-2-expr ] add-op ] add-operand
   ...
   R1010 add-op        is +
                       or ­
   ...
   Note

   Simple examples of a level-2 expression are:

   Example  Syntactic class  Remarks
   ...      ...              ...
   +1       level-2-expr     + is an add-op and 1 is an add-operand. (R1007)


You can replace the '+' add-op with the '-' add-op in the above note.
(And, yes, I know a Note in the Fortran standard is non-normative text.)
This should be sufficient in understanding why gfortran issues
an error without the -fno-range-check option.  Other compiler that
silently accept 'K = -2147483648' are simply appeasing their users.


Now, you're going to complain that gfortran accepts 'K = - HUGE(1) - 1'.

   F2023, 10.1.5.2.4  Evaluation of numeric intrinsic operations

   The execution of any numeric operation whose result is not defined
   by the arithmetic used by the processor is prohibited.

You are hitting processor-dependent behavior.  The arithmetic for
INTEGER on your system has the range [-HUGE(1)-1, HUGE(1)].

But, wait a minute, what about the model number representation of
an INTEGER from F2023, 16.4?  This seems to imply that an INTEGER
is symmetric (and hence the -pedantic warning which I have considered
for removal).  The model numbers apply to the intrinsic subprograms,
and the Fortran standard is careful to distinguish between the model
numbers and machine representable numbers.

   F2023, 16.9.1 General
   ...
   A program shall not invoke an intrinsic procedure under circumstances
   where a value to be assigned to a subroutine argument or returned as
   a function result is not representable by objects of the specified
   type and type parameters.

This statement says 'is not representable' not 'in not a model number'.

The warning under the -pedantic option was added before I found the
above (or equivalent statement) in the F95 or F2003 standard.  This
was an attempt to deal with something like 'K = IABS(J)', which is
a standard conforming expression except when 'J = -2147483648'.

Turning to a BOZ, Z'80000000' is not an INTEGER according the 
Fortran 2023 standard.

   F2023, Binary, octal, and hexadecimal literal constants

   A binary, octal, or hexadecimal constant (boz-literal-constant)
   is a sequence of digits that represents an ordered sequence of bits.
   Such a constant has no type.

Now, F2023 allows a declaration statement of the form 

   INTEGER :: K = Z'80000000'

(see R605 above) where the type conversion is performed based on the
type of the left-hand variable.  gfortran does not currently support
this feature.  You need to use a F2018 standard conforming feature,

   INTEGER :: K = INT(Z'80000000', KIND(1))

While there a few knowledgeable individuals on stackoverflow, they
sometimes miss the subtle nature of the Fortran.

Reply via email to