DIMENSION definition within a subroutine [duplicate] - fortran

This question already has answers here:
Array declaration in Fortran
(2 answers)
Closed 7 years ago.
I'm trying to figure out what (if at all) is the difference between the following definitions of variables (i.e. in subroutine/function interface)
CALL example(RealVar)
where the definition of the dummy variable within the subroutine in the one case would be:
SUBROUTINE example(var)
REAL(wp), INTENT(<IN/OUT/INOUT>) :: var(0:n)
...
And in another case:
SUBROUTINE example(var)
REAL(wp), INTENT(<IN/OUT/INOUT>), DIMENSION(0:n) :: var
...
Is there any difference between the definitions?
Will the compiler treat it any differently?
Is this just a backwards-compatibility thing?

1) Is there any difference? No
2) Will the compiler treat it any differently? Almost certainly not
3) Backwards compatibility? Sort of but not really!
Personally I prefer the second form, but it's purely stylistic,
Ian

Related

Handing optional parameters to subroutines [duplicate]

This question already has an answer here:
Is it necessary to check an optional argument before passing it to another optional argument?
(1 answer)
Closed 4 years ago.
I have two subroutine. One calls the other and the both have the same optional parameter:
program main
call a()
call a(7)
contains
subroutine a(var)
implicit none
integer, intent(in), optional :: var
call b(var)
end subroutine
subroutine b(var)
implicit none
integer, intent(in), optional :: var
if(present(var)) then
write (*,*) "var = ", var
else
write (*,*) "not given"
endif
end subroutine
end program main
In the first call of a gives var to b even though it is not given. I tried this in gfortran and ifort and it seems to work. I am wondering though:
Is this valid standard-fortran or am I just abusing some loophole here?
We use that many times, but your question lead to me to also verify it.
According to Metcalf, Reid, and Cohen in Modern Fortran Explained (ch. 5.13), it is valid code. Optional arguments can be propagated through any number of subsequent calls as long as the dummy arguments are also optional.
Also the Fortran standard has some comments on this (ch. 15.5.2.12):
An optional dummy argument that is not present is subject to the following restrictions.
..
shall not be supplied as an actual argument corresponding to a nonoptional dummy argument
other than as the argument of the intrinsic function PRESENT or as an argument of a function
reference that is a constant expression.
..
Except as noted in the list above, it may be supplied as an actual argument corresponding to an optional dummy
argument, which is then also considered not to be present.

Compiler difference between gfortran and ifort (allocatable arrays and global variables)

The Code
The following MWE describes what I want to use (note that I did not design this, I am merely trying to use someones code, I would not usually use global variables).
PROGRAM MAIN
IMPLICIT NONE
integer :: N
real(8), allocatable :: a(:,:)
N=3
allocate(a(N,3))
a=initialize_array()
CONTAINS
function initialize_array() result(a)
IMPLICIT NONE
real(8) :: a(N,3)
a=1
end function initialize_array
END PROGRAM MAIN
The Problem
gfortran gives an error which reads Error: Variable 'n' cannot appear in the expression at (1), pointing to to the real(8) :: a(N,3) inside the function.
In a subroutine it would work, so what might be the problem here?
The question
Why does ifort (v. 15.0.3) compile this, while gfortran (v. 4.8.4) does not?
As has been commented by others, it is hard to say whether something is clearly allowed: the language is mostly based on rules and constraints giving restrictions.
So, I won't prove that the code is not erroneous (and that gfortran is not allowed to reject it), but let's look at what's going on.
First, I'll object to one thing given by High Performance Mark as this is slightly relevant:
The declaration of an array with a dimension dependent on the value of a variable, such as a(N,3), requires that the value of the variable be known (or at least knowable) at compile time.
The bounds of an explicit shape array need not always be given by constant expressions (what we loosely define as "known/knowable at compile time"): in some circumstances an explicit shape array can have bounds given by variables. These are known as automatic objects (and the bounds given by specification expressions).
A function result is one such place where an automatic object is allowed. In the question's example for the declaration of the function result, N is host associated and forms a specification expression.
Rather than exhausting all other constraints to see that the declaration of a truly is allowed, let's look at how gfortran responds to small modifications of the program.
First, a trimmed down version of the question's code to which gfortran objects.
integer n
contains
function f() result(g)
real g(n)
end function f
end program
The function result for f has the name g. It doesn't matter what we call the function result, so what happens when we call it f?
integer n
contains
function f()
real f(n)
end function f
end program
This compiles happily for me.
What if we frame this first lump in a module instead of a main program?
module mod
integer n
contains
function f() result(g)
real g(n)
end function f
end module
That also compiles.
The natural conclusion: even if gfortran is correct (we've missed some well-hidden constraint) to reject the first code it's either horribly inconsistent in not rejecting the others, or the constraint is really quite strange.
I think this might be an explanation, though like #VladimirF I can't actually either recall or find the relevant section (if there is one) of the standard.
This line
real(8) :: a(N,3)
declares that the result of the function is an array called a. This masks the possibility of the same name referring to the array a by host association. The a inside the function scope is not the a in the program scope.
The declaration of an array with a dimension dependent on the value of a variable, such as a(N,3), requires that the value of the variable be known (or at least knowable) at compile time. In this case giving n in the host scope the attribute parameter fixes the problem. Though it doesn't fix the poor design -- but OP's hands seem tied on that point.
It doesn't surprise me that the Intel compiler compiles this, it compiles all sorts of oddities that its ancestors have compiled over the years for the sake of backwards compatibility.
I only offer this half-baked explanation because experience has taught me that as soon as I do one of the real Fortran experts (IanH, francescalus, (usually) VladimirF) will get so outraged as to post a correction and we'll all learn something.

How to force compiler to interpret omitted intent as intent(inout)

This question is connected to the problem: how to detect violation of intent(in) inside subprograms. But I haven't found the answer in the related question Enforce intent(in) declared variables in Fortran as constant also in called subroutines/functions.
A variable which is declared as intent(in) can be modified by another subprogram/function with omitted intent declaration.
For example:
module test
implicit none
contains
subroutine fun1(x)
real(8), intent(in)::x
call fun2(x)
end subroutine
subroutine fun2(x)
real(8) :: x
x = 10
end subroutine
end module
This code can be compiled without any errors/warnings by gfortran and ifort. So my questions are:
Is it possible to forbid omitting intent declaration?
Is it possible to force a Fortran compiler to interpret omitted intent as intent(inout)?
Both answers are NO. Unspecified intent is fundamentally different from all other intents. It is different from intent(inout), because you can pass a nondefinable expression to a subroutine with unspecified intent.
Also in many contexts it is not allowed to specify intent at all (procedure arguments, pointers in Fortran 95,...)
If you want to require specifying of intent, you may define your subroutine as pure but it does much more than that. But it may be the right thing for you. It forbids any side-effects.
I think you should get a compile error due to the automatically defined interface. I would expect the same with a wrong dimension for example (I switched the fun2 dummy argument x to z that I think demonstrates more clearly my point).
module test
implicit none
contains
subroutine fun1(x)
real(8), intent(in)::x
call fun2(x)
end subroutine
subroutine fun2(z)
real(3) :: z
z = 10
end subroutine
end module

What is a block in C++? [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
What is (double (^)(int))foofoo
I've tried searching for a definition on Google and SO and I found examples in which they are used but not clearly defined. By "block" I mean the caret symbol (^). I found it on a site where cdecl they described:
(double (^)(int, long long )) foo
as
cast foo into block(int, long long) returning double
I've never once seen this symbol used before today. Can anyone clearly describe what a block is and include with it a minimal working example? Thanks.
Blocks are a non-standard extension to the C (and not only to the Objective-C) language by Apple. They realize closures (lambda functions, etc., however you call them) - basically they're unnamed function-like entities, enclosing code that can be called. They facilitate writing for example event-driven code, where callbacks are used exhaustively.

What does the [REFERENCE] tag do in an argument declaration?

I am writing an custom callback function in Fortran for a piece of software (example here) that includes the following argument declaration
SUBROUTINE CONTACT_FORCE(TIME,UPAR,NPAR,PEN,RVEL,JFLAG,IFLAG,RESULT)
!DEC$ ATTRIBUTES DLLEXPORT,C::CONTACT_FORCE
...
DOUBLE PRECISION RESULT[REFERENCE](6) !Compiles ok
Which compiles fine with Compaq Visual Fortran 6. So my question is what does the [REFERENCE] tag do? I thought that Fortran passes everything by reference (and not by value). Of course there nothing in the compiler help about this, and searching online is difficult because the word reference is used so much with respect to Fortran that I don't know how to narrow it down.
Edit the above must be identical to
SUBROUTINE CONTACT_FORCE(TIME,UPAR,NPAR,PEN,RVEL,JFLAG,IFLAG,RESULT)
!DEC$ ATTRIBUTES DLLEXPORT,C::CONTACT_FORCE
!DEC$ ATTRIBUTES REFERENCE::RESULT
...
DOUBLE PRECISION RESULT(6) !Compiles ok
I'm assuming MS products here. Fortran can be made to pass by value or by reference if the C or STDCALL attribute is used. See here:
http://msdn.microsoft.com/en-us/library/aa294334(v=vs.60).aspx