Enforce intent(in) declared variables in Fortran as constant also in called subroutines/functions

前端 未结 2 1762
渐次进展
渐次进展 2021-01-18 21:00

In a subroutine or function an input variable can be defined with intent(in) and the compiler assures that within the subroutine the variable can not be altered. As soon as

2条回答
  •  青春惊慌失措
    2021-01-18 21:13

    As soon as the variable is passed (by reference)

    A warning note: Fortran standard does not specify how variables are passed (by reference, by value or in any other way). This is implementation dependent. Fortran is quite different from C/C++. Better stop to think in C-way. It will be misleading.

    1) Yes and no. It is implementation dependent. First of all INTENT attribute specifies your intentions. As you can see in Fortran standard, Section 5.3.10, NOTE 5.17 (you can get the Final Draft of so-called Fortran 2008 by link at the beginning of this page http://fortranwiki.org/fortran/show/Fortran+2008):

    Argument intent specifications serve several purposes in addition to documenting the intended use of dummy arguments. A processor can check whether an INTENT (IN) dummy argument is used in a way that could redefine it. [...]

    compiler ("processor") can (not should) check such things.

    Secondly (as I already mentioned) you can not be sure that for argument with INTENT(IN) compiler will choose to pass it by value and not by reference. In this case the choice was by reference. At least it seems that i in test subroutine was passed by reference. The next subroutine. The default INTENT is INOUT. That is why it is possible to change the value of argument i (with unspecified that's why default INTENT) in doSomethingNasty. Once again i was passed by reference. Or maybe it even was "copy-in/copy-out". Such freedom exists to allow compiler perform optimizations.

    2) No. If I understand you correctly you need something similar to constant references (to achieve what is called "const correctness"). But we do not even have references in Fortran, so obviously there are no constant references.

    3) There is a way to protect local variables. As M. S. B. pointed out in his answer place your subroutines in MODULEs (or in CONTAINS section of main program) and always specify INTENT attributes for variables. I've tried to compile the code below with different Fortran compilers available to me

    PROGRAM main
    
      INTEGER :: i
    
      i = 21
      CALL test(i)
      WRITE (*,*) "21 expected, but is 42: ", i
    
      CONTAINS
    
        SUBROUTINE test(i)
          INTEGER, INTENT(IN) :: i
          CALL do_something_nasty(i)
        END SUBROUTINE test
    
        SUBROUTINE do_something_nasty(i)
          INTEGER, INTENT(INOUT) :: i
          i = 42
        END SUBROUTINE do_something_nasty
    
    END PROGRAM main
    

    and all compilers (GNU, Intel, Open64, Portland and g95) issued an error message. I think that other compilers (Pathscale, IBM) will behave the same way.

提交回复
热议问题