Implied-do array constructor, type specs, and differences between GFortran, Intel, and LFortran

By now I’m familiar enough with the way the standard is written to say that that behavior would not be allowed. The standard also doesn’t explicitly say that it’s not allowed to start World War III for such an assignment…

The text from the standard is quoted above, so there is no need to argue about what it implicitly says about this missing case. It simply is not covered in the way the text is written.

That would be one way to change the text so that it covers this missing case. However, I would prefer some wording that is more explicit and stands out in an obvious way to the reader, such as “…otherwise the variable retains its original allocation, shape, and bounds.”

Before f2003, there was no reallocation upon assignment, so this was not an issue. The only assignments that were allowed where those in which the lhs was allocated and shapes of the rhs and lhs array matched, and in those cases the bounds of the lhs were never changed. I think the best argument that the bounds must be unchanged when the shapes match in the later versions of the standard is that this is compatible with the behavior before f2003 (namely f90 and f95). But the problem with that short argument is that a modern programmer must be familiar with f90 and f95, both of which had very limited functionality for allocatable arrays and bounds. F2003 generalized all of these things (e.g. it allowed lower bounds in pointer assignments, allocation on assignment, allocatable dummy arguments, allocatable components, and so on). I think this issue should have been stated clearly and explicitly in the subsequent standards, without the need to know the prior history of the language.

And there goes the theory that the plot of WarGames (1983) was based on a standard-conforming side effect. :smile:

LLVM flang-new also handles the example.

1 Like

Haha, that is correct, but that isn’t exactly the situation here.

The text says several things occur when a certain condition is met (i.e. a shape mismatch between lhs and rhs). It does not say explicitly what occurs when that condition is not met (e.g. when the shapes match, but the bounds differ). So one might assume that some or all of those same things might occur in the other situation too. If starting WW III had been one of the things mentioned in the list of actions when the condition is met, then one might also wonder if that action might occur if the condition is not met.

In this particular situation, a programmer might want the bounds to change, and he might be surprised why they don’t in what might look like a special case. Or the programmer might want the move_alloc() type of action to occur on assignment, because that would be much more efficient, and he might wonder what kind of compiler optimization he could invoke in order to get that to occur. And he might also want the efficient move_alloc() action to occur, but with nondefault bounds for the lhs variable. In the situation we are discussing, the rhs is an array expression (with reshape()), so it cannot be an argument of the move_alloc() intrinsic, the only option the programmer has is the assignment statement or the allocate() statement with source=, and the only way to get nondefault bounds on the lhs is with an allocate() statement, so this is a complicated needle to thread for the programmer to get everything to work correctly. The solutions to this are not obvious to most programmers, particularly those unfamiliar with these features of fortran.

Ha ha ha … readers must realize “Brian Meek’s well-known document on the politics of Fortran Standards development.” never loses relevance, it’s often the “users” and the “vendors” seeing things differently.

As things stand, things are done as though the “document” is

  • of the “vendors”, by the “vendors”, for the “vendors”!!
  • “all implementors are equal but some are more equal than others”

And the poor persevering Fortranners can go pound sand, the wordings are in essence “cast in stone”; “no soup for you” when “thou dost protest too much”!!

I admit to being surprised by the [start:end:stride] syntax for array constructors - I see this is listed as an extension by the Intel documentation; it’s a neat feature I was unaware of. NAG Fortran does not support it. I see it described in my old CVF manual, so I guess it goes back to the DEC days.

2 Likes

On the other hand, the text of the standard is almost never the primary source of information to most programers. They use various books around that explain all of this, with the context, the history, etc…

Nonetheless I’m still struggling to find in the standard what does guarantee that once associated to a target, a pointer won’t become undefined until the target is deallocated (either explicitely or implicitely with the cases listed in the standard (such as reallocation on assignment, target going out of scope…)). I’m sure this is guaranteed, but it’s definitely not easy to get it from the standard…

I think it is not just in one place, it is scattered text associated with dummy arguments and local variables. For example, there is text describing move_alloc() (section 16.9.147) that directly addresses pointers associated with the from= and to= arguments. In this case, if the to= argument has the target attribute, then any previously associated pointers of the from= argument remain associated with the to= argument.

You want section 19.6.6 (F23), “Events that cause variables to become undefined”.