Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

using integer in place of logical

DataScientist
Valued Contributor I
935 Views

Is this code, standard-complying:

integer :: i = 1
if (i) Print *, "Hello World!"
end

If not, why does Intel ifort happily compile and execute the code with no error? This seems too obvious to be a compiler bug. So, it is there likely for a reason. But this code does not compile with Gfortran.

0 Kudos
1 Solution
IanH
Honored Contributor II
928 Views

A. King wrote:

Is there any plans to change this default behavior (for example, by allowing the compiler to keep the significant digits even when no kind is specified for the constant)?

There have been proposals to allow the default kind in a program unit (or other scoping unit) to be specified for the relevant intrinsic types.

But that aside, the implied proposal above is impractical.  Depending on exactly what is being proposed there are multiple problems, but tos start consider the real literal `0.1` as an example in this alternative world - what kind is it?

I expect that a "physical chemist with background in [many things]" understood the limits of precision of floating point representation, so I suspect the underlying issue was simply that they thought that the default kind in Fortran was akin to double precision kind.  There's no need to make literal resolution inscrutably opaque, confusing or incompatible in order to remedy that.

In terms of the issue with the large array constructor, Fortran has excellent support for "compile time" constant expression evaluation, which includes the ability to build up large arrays from smaller arrays, amongst many other things.  I'd not expect issues with things like code bloat - compilers are pretty good at not including things in the executable that aren't required and/or loaders only load the pages from executables that are required.

View solution in original post

0 Kudos
22 Replies
DataScientist
Valued Contributor I
846 Views

Thanks. Therein, Steve says, this behavior is not standard-compliant, yet, the ifort flag "-standard-semantics" provides this functionality. How could this be possible? This looks more like a compiler bug then.

0 Kudos
mecej4
Honored Contributor III
846 Views

Use the /stand option if you want the compiler to warn about non-standard extensions in your code. By default, this option is not active, allowing customers to continue to run their non-standard code as it did for decades. You can make this option the default for your PC by putting "/stand", without the quotes, in the file ifort.cfg (in the same BIN directory as the compiler itself).

For details, see https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-alphabetical-list-of-compiler-options and click on the "stand" entry.

Finer control over default options can be exercised by setting one or two environment variables, see https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-supported-environment-variables .

0 Kudos
Steve_Lionel
Honored Contributor III
846 Views

Conversion between numeric and logical is an extension, and will be flagged as such when you ask for standards checking, as mecej4 says. -standard-semantics does something different - it changes default behaviors (not syntax) in cases where the standard evolved to specify something different than what had been the previous default.

This extension is more than 40 years old, reaching back to at least the first DEC VAX FORTRAN, if not to the DEC PDP-11 compilers. It was useful on VAX/VMS for dealing with "condition codes", but in hindsight was probably not a good idea as it has tripped up many users. For many years, this extension also applied to list-directed and namelist I/O, but that is no longer enabled by default. 

Additional reading that may be of interest is this old blog post of mine: Doctor Fortran in "To .EQV. or to .NEQV., that is the question", or "It's only LOGICAL"

0 Kudos
DataScientist
Valued Contributor I
846 Views

Steve and others, Thank you. Everytime I start to believe that I know ifort well, it surprises me.  So, is there a flag to automatically disable all extensions, so that the compilation fails instead of getting only compiler warnings?

0 Kudos
DataScientist
Valued Contributor I
846 Views

So, when I add /stand:f18, I get a compilation error on one of the .F90 files that has several parameter arrays, each of which spans more than a thousand continuation lines, each line of which is very close to 132 characters long. Is there a Fortran-standard way of declaring parameter data arrays that are very large (other than converting them to non-parameters and reading them from an external file at runtime, which is undesirable)?

As a side note, I wish the standard committee would consider extending the maximum line length and continuation lines. The giant monitors available these days can fit lines as long as several hundred characters.

0 Kudos
FortranFan
Honored Contributor II
846 Views

A. King wrote:

..  So, is there a flag to automatically disable all extensions, so that the compilation fails instead of getting only compiler warnings?

Try /warn:stderrors

https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-warn

0 Kudos
FortranFan
Honored Contributor II
846 Views

A. King wrote:

.. Is there a Fortran-standard way of declaring parameter data arrays that are very large (other than converting them to non-parameters and reading them from an external file at runtime, which is undesirable)? ..

Standard specified array construction syntax is it and it is 'constructed' in the standard with scant regard for diverse background of coders in scientific and technical computing even.

Not too long ago, I had a physical chemist with extensive experimental research experience with a decent background in numerics and C++, MATLAB, Python, Java, C#, etc. (basically everything other than Fortran) 'dabble' in Fortran for a model intended for use in a FORTRAN-based chemical process simulator.  This scientist was working with arrays of many, many physical constants (reaction equilibrium, kinetics, and other parameters), sought a certain precision in the calculations involving all those arrays, struggled for over a day to get the desired precision, and decided to compute using any one of other options besides Fortran once the need to mark the literal constants with the right 'kind' was pointed out - since then, the chemical process simulator has moved to modern C++ also.  The scientist had first written the code along the following lines (trivialized for illustration):

   integer, parameter :: WP = selected_real_kind( p=15 )
   real(WP), parameter :: factors(*) = [ 0.333333333333333, 0.666666666666666 ]
   ! ** instead of the following; having to suffix the literal constants like so is untenable
   !real(WP), parameter :: factors(*) = [ 0.333333333333333_wp, 0.666666666666666_wp ]
   print *, "factors = ", factors
end

Upon execution, the output is

 factors =  0.333333343267441 0.666666686534882

A. King wrote:

.. As a side note, I wish the standard committee would consider extending the maximum line length and continuation lines. The giant monitors available these days can fit lines as long as several hundred characters.

Unless there is some slip between now and the final publication, it looks like the next Fortran standard revision (202X) will do away with the limit on continuation lines (Fortran 2018 standard has it as 255) and greatly ease the limit on overall characters in a code statement.

0 Kudos
DataScientist
Valued Contributor I
846 Views

Thanks, FortranFan, I ended up converting all parameter arrays to variables to assign the values in chunks of 255 line-continuations (to conform with the standard). But, that is still undesired. The array is supposed to be constant, not variable. I personally believe the Fortran committee should (have) consider(ed) these minimal improvements, such as (virtually) unlimited line-length/continuation. But, perhaps there are good reasons for not doing so that I am not aware of. (This whole task of constant-to-variable-conversion to make it standard-compliant took a few hours of programming, which could have been used to do something more useful).

0 Kudos
DataScientist
Valued Contributor I
846 Views

Here is an interesting solution that was just offered on Stackoverflow, which honestly, had not come to my mind:

https://stackoverflow.com/questions/57740655/is-there-a-standard-compliant-way-to-assign-segments-of-a-fortran-parameter-arra/57740910#57740910

0 Kudos
DataScientist
Valued Contributor I
846 Views

@FortranFan, btw, why does Fortran treat the precision of literal constants this way? This was actually, the first bug that I had in my first Fortran program, and for quite some time I had no clue why my code gave a different result from MATLAB's output.

0 Kudos
Steve_Lionel
Honored Contributor III
846 Views

A. King wrote:

I personally believe the Fortran committee should (have) consider(ed) these minimal improvements, such as (virtually) unlimited line-length/continuation.

See https://j3-fortran.org/doc/year/19/19-138r1.txt for a proposal accepted as a work item for the next revision.

0 Kudos
DataScientist
Valued Contributor I
846 Views

That's great Steve, than  ks!

0 Kudos
DataScientist
Valued Contributor I
846 Views

Hi again Steve, I see that the Fortran standard states something similar to: "The number of digits specified in the significand of a real literal constant has no effect on its kind. In particular, it is permitted to write more digits than the processor can in fact use." This is relevant to the point raised by FortranFan above. Why is this the default behavior chosen in Fortran? In fact, it seems a bit dangerous and perhaps misleading to allow the behavior as shown in FortranFan's example in the above:

	   integer, parameter :: WP = selected_real_kind( p=15 )
	   real(WP), parameter :: factors(*) = [ 0.333333333333333, 0.666666666666666 ]
	   ! ** instead of the following; having to suffix the literal constants like so is untenable
	   !real(WP), parameter :: factors(*) = [ 0.333333333333333_wp, 0.666666666666666_wp ]
	   print *, "factors = ", factors
	end

Is there any plans to change this default behavior (for example, by allowing the compiler to keep the significant digits even when no kind is specified for the constant)?

0 Kudos
GVautier
New Contributor II
846 Views

A. King wrote:

 (other than converting them to non-parameters and reading them from an external file at runtime, which is undesirable)?

Have you consider to group all these datas in an binary file to be readden once or converted to an obj file linked to the executable?

0 Kudos
Steve_Lionel
Honored Contributor III
846 Views

A. King wrote:
Is there any plans to change this default behavior (for example, by allowing the compiler to keep the significant digits even when no kind is specified for the constant)?

No, there are not. Literals have a specific type and kind based on their form. It would be even more dangerous to have that change depending on how many digits there were and the particulars of the kinds supported by the current platform.

0 Kudos
IanH
Honored Contributor II
929 Views

A. King wrote:

Is there any plans to change this default behavior (for example, by allowing the compiler to keep the significant digits even when no kind is specified for the constant)?

There have been proposals to allow the default kind in a program unit (or other scoping unit) to be specified for the relevant intrinsic types.

But that aside, the implied proposal above is impractical.  Depending on exactly what is being proposed there are multiple problems, but tos start consider the real literal `0.1` as an example in this alternative world - what kind is it?

I expect that a "physical chemist with background in [many things]" understood the limits of precision of floating point representation, so I suspect the underlying issue was simply that they thought that the default kind in Fortran was akin to double precision kind.  There's no need to make literal resolution inscrutably opaque, confusing or incompatible in order to remedy that.

In terms of the issue with the large array constructor, Fortran has excellent support for "compile time" constant expression evaluation, which includes the ability to build up large arrays from smaller arrays, amongst many other things.  I'd not expect issues with things like code bloat - compilers are pretty good at not including things in the executable that aren't required and/or loaders only load the pages from executables that are required.

0 Kudos
DataScientist
Valued Contributor I
846 Views

@Vautier, Thanks for the suggestion. That sounds like a very good option. Although, that would still require to remove the parameter attributes of the arrays. I think an idea like Ada's "constant variable" would be great to see in Fortran (not sure if this is what it is called), where one defines the variable only once and thereafter the variable becomes immutable (something between a variable and a parameter).

and thanks @Ian @Steve, based on my interactions with the general programming community (mostly non-HPC), it seems like there is a lot of misunderstanding about Fortran (like the Chemist example above, and much worse examples of total misinformation that I have seen). Fortran >2003-2018 deserves a far better recognition. Has been great choice for our work, to say the least.

0 Kudos
GVautier
New Contributor II
846 Views

In a obj file, I think it's possible to set the memory block readonly.

You can also integrate a binary file in ressources. It may be readonly in this case.

0 Kudos
FortranFan
Honored Contributor II
782 Views

IanH (Blackbelt) wrote:

.. I expect that a "physical chemist with background in [many things]" understood the limits of precision of floating point representation, so I suspect the underlying issue was simply that they thought that the default kind in Fortran was akin to double precision kind.  .. 

In terms of the issue with the large array constructor, Fortran has excellent support for "compile time" constant expression evaluation ..

A. King wrote:

.. it seems like there is a lot of misunderstanding about Fortran (like the Chemist example above, ..

The issues really are the calendar and the programming paradigm of coders!  Sure if the year is 1985 and/or the coders are coming from the most basic sequential programming approach of FORTRAN II thru' 77 (it's Turning-complete after all and one can write highly valuable software with it as clearly demonstrated) or BASIC, then ok.  But not otherwise.

OP's question "Is there a Fortran-standard way of declaring parameter data arrays that are very large (other than converting them to non-parameters and reading them from an external file at runtime, which is undesirable)?" is a fairly common need and this is exactly where Fortran with its restrictions of constant expression is precisely well behind the times, for Fortran does not allow a constant expression type of a user-defined function, one that returns a result of a 'literal' type when applied with constant expression arguments and whose instructions then are constant expressions that can all be evaluated at compile-time .

Such a user-defined 'constexpr' function is really what a coder often needs to employ to construct arrays of named constants e.g., a huge array of coefficients to initialize a calculation but which Fortran does not allow.  To the contrary, the simplest of circumstances in Fortran, say to put together arrays of named constants using a lookup table, is either not possible or requires "tricks" with MERGE (and other intrinsic functions only) that are "inscrutably opaque, confusing or incompatible".

"Constexpr everything, or as much as the compiler can" is the approach that's nearly a decade in prevalence in many modern codes toward scientific and technical computing now but which sees limitations with Fortran.

Same goes with other aspects of interest whether generics or metaprogramming, etc.  Then when individual coders run into issues like with real literal constants or other 'gotchas', they "move on".  And the same goes with large code bases (e.g., process simulators) who "move on" to other computing options.  This is particularly the case in the broader commercial space of industrial software and computing.

0 Kudos
Reply