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

adding read-only specifications to fortran

nooj
Beginner
1,306 Views
I'd like to parallelize a large section of code, and would like the compiler to help me make sure I'm not editing external variables. What would be the ramifications of extending the fortran standard to include read-only assertions for module variables, as with the intent(in) for passed vars?

module big_hairy_module
integer foo
end module

function legacy_procedure_number_49563()
use big_hairy_module, readonly: foo
legacy_procedure_number_49563 = foo + 1
return
end function

Is there a better way of confirming that a particular module is never written to, short of going through every line of code?


While we're on the subject of compile-time assertions, I have two other extensions I thought of. Chances are there's a very good reason why they don't exist--such as "No one happened to bother to putting it in a Fortran standard, and no one really wants to break the standard."--but I looked and haven't come across them.

One is having an "intent(none)" to assert that the passed var is never used in the body of the code. This is much easier than modifying the arg list for large verified/validated codes, and better if the var may be used again in future development phases.

The other is less useful: a simple "Parameter foo, defined elsewhere in code I can't control, must be equal to bar or this procedure won't run."

Does all this go on the FAQ?

- Nooj
0 Kudos
4 Replies
Steven_L_Intel1
Employee
1,306 Views
I assume you mean the module variable. If you make the module variable PRIVATE, then it cannot be referenced by other program units that USE the module. If you want limited access to it, provide "get" and "set" procedures in the module.

You can also add the PROTECTED attribute, which is close to what you want, if you still want the variable to be readable. This will protect against assignments, though if the variable is a pointer the attribute applies to the pointer itself and not the data it points to.

I'm a bit puzzled at the request for INTENT(NONE). Why not just name the dummy argument DONOTUSEME or something like that?
0 Kudos
mecej4
Honored Contributor III
1,306 Views
Although I can understand your wish to have language features to help protect yourself from programming errors, the specific features asked for are infeasible because they go against certain basic principles.

As Steve Lionel has stated, you can certainly PROTECT module variables in, say, Module-A, and the protection is enforced in all other modules and procedures that USE Module-A. There is, on the other hand, no provision for being selective about providing that protection.

To illustrate why: suppose your requested feature were implemented, and Subroutine-B uses unprotected variables from Module-A, and specifies protection for those variables within itself. However, if Subroutine-B calls, directly or indirectly, another Subroutine-C which also uses those variables from Module-A, but Subroutine-C does not specify similar protection , the protection in Subroutine-B is only an illusion, since C can change those module variables.

In general, to make separate compilation possible, a procedure cannot be allowed to specify restrictions on the construction of other procedures. The only way to make this possible would be to allow INTENT specification for not only procedure arguments but also USE-associated variables, if one does not wish to think about prohibiting some procedure calls and allowing others, and having to provide rules for selecting which ones fall into which category.

For similar reasons, your proposed INTENT(NONE) would not work. Subroutine-B may specify INTENT(NONE), but if it passes those arguments to Subroutine-C, which is separately compiled and has no knowledge of restrictions in Subroutine-B, Subroutine-C could act against the INTENT specifications in Subroutine-B.

The last item that you wished for ("Parameter foo, defined elsewhere in code I can't control"): You must at least know the name of the parameter and where it is declared and defined, otherwise you cannot use it in the code that you are writing. It follows that you can USE the module where the parameter is defined, and place "assertions" in your code to check if the imported value is admissible.
0 Kudos
nooj
Beginner
1,306 Views
@steve:
> get and set procedures.
oh, good idea! i haven't done that since my objective-c days.

> name the dummy variable DONTUSEME.
another good idea. not sure why i haven't thought of that. actually, someone suggested the same thing when i wanted to keep a phone number in my phone so i would be sure never to answer, and wanted to avoid calling it, too.

@mecej4:
> restrictions on the construction of other procedures.
i knew there were complications i wasn't thinking of. with the intent(NONE), i was intending that it couldn't reference the argument anywhere, even in passing to another subroutine.

> place "assertions" in your code to check if the imported value is admissible.
right, exactly. the thing is, i don't know how to write such an assertion that will be evaluated at compile time.
(a good assertion, that is; everything i've found on the net creates as many problems as it solves.)

thanks, both of you.
- nooj
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,306 Views
Nooj,

Have you experimented with making your function PURE?

This will require you to extract data from the function via the return or via INTENT(OUT).

Jim Dempsey
0 Kudos
Reply