Can writing INTENT(...) declarations be a waste of time?

It’s a promise made by the programmer, so the MAYBE part hits home.
In hindsight designating arguments mutable and the default being immutable like in Rust would have been nice. It is actually enforced by the compiler and the syntax (& and &mut) is relatively compact and easy to discern visually.

I like that. INTENT(). Works for me. I might even change my comments to !INTENT() to mark where I intentionally do not want an INTENT specified.

I presume this is on entry to the routine.
This is what worries me about using INTENT.
There is uncertainty of what happens if the variable was not updated, but again with intent(out), it should have been updated.

Thanks, now I learned that intent is a compile time check, and becomes a run time one only when this isn’t possible.

@ricriv Not quite. A conformant compiler is required to perfom some compile-time checks for some intent (e.g. checking that an intent(in) dummy is not redefined at any point), but not all of them (checking that an intent(out) dummy is fully defined in all cases would be a too complex task, and even impossible in many cases at compile time).

Then, compilers are allowed to perform all possible run-time checks, but none of them is required. For performance reasons, runtime checks are usually disabled by default and/or enabled only in debug mode.

1 Like

I was inspired by this thread to write a small program to check the way compilers handle these intent() clauses. The attached program shows that at least flang, gfortran and ifx can detect the violations if you help them to via explicit intent(). If there is no intent in the routine setvia, then they all three accept the program source and produce an executable. If there is, the program is rejected.
chk_intentin_set_via.f90 (1.0 KB)

No, it does not. Unspecified INTENT is a YOLO thing, you promise the compiler that you will never make a mistake, and a decent compiler will take you at your word. On the other hand, you also are not giving it any hints that it can use to optimize execution. Marking a dummy as INTENT(IN) can help optimize across statements in the same way that we discussed in Quiz : So, you think you know Fortran expressions about a single statement.

If syntax is required for “unspecified INTENT”, I think INTENT(UNSPECIFIED) seems the obvious choice. It could be coupled with an IMPLICIT NONE(INTENT) which will reject code that doesn’t explicitly specify INTENT for all dummies.

2 Likes

As mentioned upthread, there are several cases where intent is more than a compile-time check, and certainly can change how a compiler compiles code. The derived type with initializers/intent(out) is one case. Details of allocatable arguments are another.

Yes, an intent(out) argument that is a derived type with default initialization is reset to those values upon entry. There is also the situation with a derived type with a finalizer, where the final subprogram is invoked automatically upon entry. A feature of both of these cases is that the compiler must always perform this operation upon entry, so if the programmer does it explicitly before the subprogram call, it is just wasted effort. In the allocatable case, the compiler can at least check the allocation status and do conditional deallocation, but in these other cases it is not so straightforward for a compiler to test for modification status. Thus in a limited sense, these conventions lead to more obscure code rather than clearer code, which I think is the basis for the original post in this thread.

These triggers can also be combined. One example I’ve used before is an allocatable linked list dummy argument with a recursive allocatable component. With intent(out) the whole linked list is recursively deallocated upon entry. The problem is that this first-to-last recursive deallocation is not necessarily the best way to deallocate the list, so although is is handy and convenient, it is not necessarily the most efficient (which is from last to first).

I remember another odd situation with an optional, allocatable, intent(out) dummy argument. I think this was with the intel fortran compiler about 10 years ago. For some reason, it did not do the required deallocation on entry, so when the subsequent allocatable statements were executed it generated run time errors. I had to hack the code for a few years to do a manual deallocation on entry. The hack had to outlive the compiler bug fix because I wanted the code to work with both current and past versions of that compiler.

I guess the issue is that these features are used by programmers, and they cannot really be avoided unless intent(out) is avoided, and that by itself would lead to compromises on code clarity and efficiency.

Are there any other ways that intent(out) is used by programmers to simplify codes, and are there any associated gotchas?

1 Like