NAG Fortran flags a runtime error with -C=all -C=undefined. I assume this is because 15.5.2.13 par 3, clause (1) says “If it [An optional dummy argument that is not present] is a data object, it shall not be referenced or be defined. If it is of a type that has default initialization, the initialization has no effect.”
So, it looks like VALUE and OPTIONAL together is not useful. There was a long discussion of this on J3, [J3] Default values for optional arguments . I am sorry for mentioning it now.
I think the best solution is to name optional dummies with an _OPT suffix, and always-defined locals without.
states explicitly that OPTIONAL and VALUE attributes are compatible and I saw nothing in the standard looking earlier that said they were not (although nothing explicitly showing how they worked together) so if they are not compatible it seems something like the compatible attributes table used in the IBM manuals should appear in the standard to clarify that. Personally, my example using an associate-name the same as a name currently in scope and the VALUE example both gave me pause but seeing the statement in the IBM manual along with it working in two compilers had removed concern about VALUE,OPTIONAL till you provided this link! If not compatible a lot of compilers appear to not be flagging it with a warning when it would appear easy to flag anything with both attributes.
I did not claim that the attributes VALUE and OPTIONAL were incompatible (although they are incompatible for BIND(C) subprograms). I claimed that it is not useful when the argument is not present, in the sense that it is not conforming to do much with it.
On a second read I see you are indeed not saying you cannot do it, but that you end up with a
undefined variable that you can not define, which indeed does not seem very useful. Would it
be possible to interpret 15.5.2.13 par 3, clause (1) as not applying because due to the VALUE attribute assigned to the name the name is now not pointing to the argument but to a copy with
the same type and kind? With such a reading assigning a value to the variable would not be disallowed and the successful behavior by several of the compilers would not be seen as an extension.
Having seen related discussions multiple times it is a shame that the J3 discussion seems to think an syntax allowing an easy way to declare a default for optional parameters is not a feature worth developing. initialization of saved values is often an issue with many coming from a non-Fortran background as well. Anyone that has written a procedure with multiple optional arguments or one that is polymorphic immediately comes to the conclusion there should be a simpler way.
To keep it possible to declare everything about an argument on a single line and remain compatible with the current state just adding an optional argment to the OPTIONAL property would have been nice, perhaps:
real,intent(in),optional(default=3.0) :: a
it usually comes down to allowing a value in the procedure declaration, which breaks the desire some have to keep it possible to put all aspects of a declaration on a single line
subroutine foo(a=123.0)
or allowing a different meaning for an otherwise forbidden expression
real,intent(in),optional :: a=123.0
but some feel that conflates an already often misunderstood meaning but given the clarity of hindsight I think it would have been nice if
real, :: a=10
would be executed on each entry of the procedure unless the SAVE or OPTIONAL properites appears, where SAVE would indicate it was only executed once and saved, and OPTIONAL would imply it is executed when a value is not passed but the OPTIONAL could even be left off because it could be inferred if the variable is an argument if someone really wanted to minimalize verbosity, possibly. I have seen enough proposals/suggestions that I probably have forgotten some good ones. This issue about a more compact form for specifying default values for optional parameters comes up a lot, which would seem to indicate it warants a solution, but then never gets any traction and shortly resurfaces again. It makes me wonder what if anything will be done to break the cycle.
(I have come to think that any feature not performance-related, or whose purpose is to simply improve quality of life, will be dismissed by the standards committee as “trivial” or “not worth the effort”.)
In regards to the feature, it seems to me that it should be completely separate from OPTIONAL. Calling it DEFAULT, say:
module mod1
implicit none
real, parameter, target :: DEFAULT_TOLERANCE = 0.001
contains
subroutine sub(a, B, C, D, E, F, SET_C)
integer, intent(in) :: a
integer, default :: B = 4 ! here SAVE doesn't apply, assignment is fine
real, default :: C(*) = [1., 2., 3., 4.] ! the compiler can count
real, pointer, default :: D => DEFAULT_TOLERANCE
procedure(someproc), default :: E => someproc
complex, pointer, default :: F => null()
logical, default :: SET_C = .false.
if (SET_C) then ! the `present(...)` check does not apply
...
endif
...
end subroutine
subroutine someproc()
print*,'doing nothing'
end subroutine
end module mod1
Of course, the default attribute would imply intent(in) (maybe the feature could even be intent(default)), and be incompatible with allocatable.
And also, the assigned value must follow the same default initialization rules used for derived type components.
I don’t know about this one. To me, intent(in) means that it cannot (or will not) be modified within the scope, so assigning an internal value to such a variable does not seem consistent.
On the other hand, the other possibility
integer, value, optional :: a = 1
or some similar syntax, would make sense. The value attribute implies that local definitions of that argument can occur to the local copy, but they are not transferred back to the actual argument. So the idea of assigning a default value to the copy when the actual argument is not present seems like a straightforward and consistent extension.
There are many obvious counterexamples to this, where the committee allowed something into the language, sometimes over well reasoned opposition, that turned out to be a bad idea. Implicit save with initialization is one of those things which, ironically, has been criticized a few times in this very thread.
A problem with computer languages is that once some feature is added, it is very difficult for it to be removed. When that happens, it is sometimes easier to just discard the language than it is to fix it. So the standards committee should, rightly, be conservative with new features.
The process of making suggestions to the standard committee is not simple or trivial. There are many things that I would like to see included in the language, but I do not have the time to go through the entire standards document and locate all of the affected text and make the appropriate suggested changes. I admire those who have taken the time and made that kind of effort.
Okay, it could require explicit intent(in) or intent(inout) instead. Although, if the argument is not present (because it was given the default value), why would you need it to be intent(inout)? In any case, the OPTIONAL attribute would still be available, should the DEFAULT attribute not fit your needs.
As I suggested, I think in order for the feature to be even remotely considered by the standard committee, it has to be something different from OPTIONAL —because OPTIONAL has already too may potentially conflicting rules attached to it (like being a reference with allocation-related ties, and also maybe being a VALUE).