Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Fortran have undefined behavior?

Tags:

fortran

In C and C++, there many operations that cause undefined behavior, i.e. situations that allow the compiler to do anything it wants. Examples include using a variable after deallocating it, deallocating a variable twice and dereferencing null pointers.

Does Fortran also have undefined behavior? I had a look at a specification draft, but failed to find anything in there. For instance, is using a variable after its deallocation guaranteed to crash the program, or may it silently do the wrong thing?

like image 706
Christian Brüggemann Avatar asked Aug 19 '19 14:08

Christian Brüggemann


People also ask

What is undefined behavior in programming?

So, in C/C++ programming, undefined behavior means when the program fails to compile, or it may execute incorrectly, either crashes or generates incorrect results, or when it may fortuitously do exactly what the programmer intended.

Is there undefined behavior in Python?

Python has undefined behavior because it's implementations are written in languages that do.

Why does undefined behavior exist?

Undefined behavior exists mainly to give the compiler freedom to optimize. One thing it allows the compiler to do, for example, is to operate under the assumption that certain things can't happen (without having to first prove that they can't happen, which would often be very difficult or impossible).

What happens undefined behavior?

Undefined behavior can lead to security vulnerabilities in software. For example, buffer overflows and other security vulnerabilities in the major web browsers are due to undefined behavior. The Year 2038 problem is another example due to signed integer overflow.


2 Answers

The Fortran standard does admit similar concepts to the idea of "undefined behaviour" of C and C++. It's often phrased by people supporting broken Fortran code as "the compiler may now start World War III", or similar.

The Fortran language specification has two ideas of conformance (see Fortran 2018, 4.2). The main one is what a program must look like to be able to considered a Fortran program. The second is what a processor must do in response to a submitted program unit to be considered a Fortran processor.

If a conforming Fortran processor is asked to process something that is not a Fortran program, the standard rarely says what must happen. There are some diagnoses that must be offered, but often there is not.

In the case of "using a variable after its deallocation", an attempt to do this is a violation of that part of the language standard that defines the Fortran program. A compiler may then "start World War III" without violating the Fortran standard, because the Fortran standard doesn't say that it must not (or must do something else).

Now, how do we look at the Fortran standard document and decide whether the not-quite-Fortran program has a particular required effect? The text from 4.2 mentions a number of situations where a compiler must have "the capability to detect and report the use within a submitted program unit". If your proposed program doesn't hit any of those you're in "undefined" territory.

The main time a program error must be reportable is in the case

the use within a submitted program unit of a form or relationship that is not permitted by the numbered syntax rules or constraints

Let's consider arbitrarily Fortran 2018, 15.5.1C1523 (R1520) Syntax of a procedure reference. We see things like "R1520":

R1520 function-reference is procedure-designator ( [ actual-arg-spec-list ] )

and "C1523":

C1523 (R1520) The procedure-designator shall designate a function.

before we have a list of things like:

The data-ref in a procedure-designator shall not be an unallocated allocatable variable or a pointer that is not associated.

In this case, the rule R1520, numbered constraint C1523 (which applies to this rule) and following text give constraints on the Fortran program. If your submitted program doesn't meet those, it's not a conforming Fortran program.

A compiler asked to process such a non-conforming program, where that program violates R1520 or C1523, must be able to detect that (based on the above). A compiler doesn't have to complain about or detect violations of the un-numbered text. It's allowed to assume that any program it's presented with doesn't break such an un-numbered restriction.

This one here I quote is (coincidentally) one example of a prohibition on a program incorrectly using a previously deallocated variable.

If a processor operates in a "compile-then-run" way, the numbered rules/constraints are typically ones that can be assessed "at compile time".

Another specific and significant example of undefined behaviour is using a variable without first giving it a value ("defining" it). The Fortran standard simply says (Fortran 2018 9.2 p2):

A reference is permitted only if the variable is defined. A reference to a data pointer is permitted only if the pointer is associated with a target object that is defined. A variable becomes defined with a value when events described in 19.6.5 occur.

This isn't a numbered syntax rule or constraint and is a (significant) burden on the program that the compiler is allowed to assume has been met.

like image 97
francescalus Avatar answered Oct 17 '22 07:10

francescalus


Yes, it has. It is just called differently. There are many things that you could do and will make your code not standard conforming, for which there is no requirement to for the processor (compiler) to diagnose such non-conformance (of course, many deviations must be diagnosed). Often the situations will be similar to C undefined-behaviour one (like accesing an array out-of-bounds, signed integer overflow,...). We just say that the code is not standard conforming, that means the standard does not prescribe the outcome of such a code. Such code is not covered but the standard and so anything can result if some compiler (processor) does compile it and you do run it.

That is different from processor dependent behaviour, that one is standard and just implementation dependent.

Just searching here at StackOverflow should give you plenty of examples. Like Is passing the same entity to arguments with different intent undefined behavior? How do Fortran and MPI_Reduce deal with integer overflow?

This answer just answers the question asked but does not attempt to list all possible kinds of UB that can happen in Fortran.

like image 13
Vladimir F Героям слава Avatar answered Oct 17 '22 05:10

Vladimir F Героям слава