2

I have a subroutine in a shared library:

SUBROUTINE DLLSUBR(ARR)
   IMPLICIT NONE
   INTEGER, PARAMETER :: N = 2
   REAL ARR(0:N)
   arr(0) = 0
   arr(1) = 1
   arr(2) = 2
END

And let's assume I will call it from executable by:

REAL ARR(0:3)
CALL DLLSUBR(ARR)

Note: The code happily compiles and runs (DLLSUBR is inside a module) without any warning or error in Debug + /check:all option switched on.

Could this lead to memory corruption or some weird behaviour? Where I can find info about passing array with different size in the Fortran specification?

Peter Petrik
  • 9,701
  • 5
  • 41
  • 65

1 Answers1

3

It is actually allowed for explicit shape arrays by the rules of sequence association, if you make the dummy argument element count to be smaller or equal. It is prohibited when the subroutine expects more elements then it gets.

The explicit shape arrays often require the arguments to be passed by a copy. This happens when the compiler cannot prove the array is contiguous (a pointer or an assumed shape array dummy argument). If smaller number of elements was passed, the subroutine could then access some garbage after the copy of the portion of the array.

In your case everything will be OK, because you are passing more to a subroutine expecting less.

Fortran 2008 12.5.2.11.4:

4 An actual argument that represents an element sequence and corresponds to a dummy argument that is an array is sequence associated with the dummy argument if the dummy argument is an explicit-shape or assumed-size array. The rank and shape of the actual argument need not agree with the rank and shape of the dummy argument, but the number of elements in the dummy argument shall not exceed the number of elements in the element sequence of the actual argument. If the dummy argument is assumed-size, the number of elements in the dummy argument is exactly the number of elements in the element sequence.

  • If it is shared library, it needs to be exported to be able to link it (independently of language on the other side) – Peter Petrik Jan 30 '14 at 12:45
  • Also how it breaks the standard, can you point me the link/section? Compilers can check API, but I would like to know more about ABI change (API remains the same in my example) – Peter Petrik Jan 30 '14 at 12:52
  • ad comment 1) Yes, but on normal operating systems you don't care about those directives, because it is done automatically. I had to find out what it does on Windows. Also, I never had to do that when I used gfortran for some `bind(C)` callbacks in DLL on Windows, it just worked. – Vladimir F Героям слава Jan 30 '14 at 13:19
  • ad comment 2) It is not standard conforming to call a subroutine with explicit shape arrays with a an actual argument with nonconforming shape. I do not have time to search for the chapter. If you mean by ABI just the fact that you just pass the pointer, then no, it doesn't break the ABI for common compilers. But it can fail and cause memory corruption anyway. – Vladimir F Героям слава Jan 30 '14 at 13:21
  • But remember your first sentence of the question is a nonsense, there is NO standard ABI for Fortran. – Vladimir F Героям слава Jan 30 '14 at 13:22
  • default behaviour: on linux, all function are exported from a shared library. on windows you have to specify which functions should be exported – Peter Petrik Jan 30 '14 at 13:22
  • My limited experience when making plugins to the X-Plane flight simulator on Windows tells me the opposite, I didn't have to specify anything, I just used `bind(C)`. – Vladimir F Героям слава Jan 30 '14 at 13:25
  • http://stackoverflow.com/questions/20684297/why-arent-my-fortran-functions-exported-when-using-the-bindc-name-name-att – Peter Petrik Jan 30 '14 at 13:30
  • Than it is compiler specific. I used MinGW. – Vladimir F Героям слава Jan 30 '14 at 13:38
  • Thanks, it makes sense now. I have edited my question to be more clear, but that makes a part of your answer out-of-date. Would you mind to correct your answer? – Peter Petrik Feb 20 '14 at 12:52
  • Isn't part >> The host code may just copy the smaller number of elements and pass a pointer to the copy. The subroutine would then access some garbage after the copy of the portion of the array. << related only to situation when subroutine expects more elements then it gets? – Peter Petrik Feb 20 '14 at 13:14