Variable length argument list in Fortran? - fortran

Has Fortran ever gotten around to handling subroutine argument lists with arbitrary length, like C can do? (BTW, "present" isn't going to work for what I am trying to do.) Thanks.

There are no such subroutines in Fortran.
The syntax rule for a subroutine statement in Fortran 2008 is (12.6.2.3, R1235):
[ prefix ] SUBROUTINE subroutine-name [ ( [ dummy-arg-list ] ) [ proc-language-binding-spec ] ]
where dummy-arg-list is a list (in assumed syntax rule terms) of dummy-args. A dummy-arg is (R1235) either a name or a literal *.
[Before we get too excited about the possibility of variadic support, the * refers, of course, to an alternate return indicator.]
A list (R101) still refers to a well-defined (at source time) number of items.
There is a stated restriction regarding interoperability with C, that (15.3.7) the C prototype
... does not have variable arguments as denoted by the ellipsis (...)
Similar arguments apply to (Fortran) functions.

Related

Is it possible to suppress the top level in a reference to a derived type?

This is hard to describe in words but an example should make it clear. Let's say I have a variable of a derived type, with the following components.
x%length
x%width
Is there any automatic way to refer to these without the top level? In other words to refer to them as simply
length
width
Of course, I could first do
length => x%length
width => x%width
for ALL individual components of the derived type. But my use case involves thousands of variables, so I'd prefer not to do it that way.
As an example from another language, python will essentially allow this suppression with:
from x import *
There is no such a functionality in fortran as far as I know, at least in the implementations that I have at hand. Beside that, the objectives of my post is to make some other thinks clear.
The python from x import * is the equivalent of use x in fortran. I am not very pythonic, but I do not think that you can import member of a class directly. So, that works as long as x is a pyton module, not a python class to my limited knowledge. use x will also works as long as x is a fortran module.
One of the programming language that I know of and that implements the feature that you are after is pascal. There is this handy construct with that allows you to do that.
with x do
begin
lenght ....
width ....
end
Indeed, it is very helpful in that it allows you to strip a part of the object name and get directly to fields. I loved it when I was using pascal, but it's been a long time.
Delphi certainly allows that too.
How about the Fortran 2003 associate construct? This will, in a sense, manage for you the pointer assignments that you listed:
Program test
Type :: t
Integer :: length
Integer :: width
End Type
Type (t) :: x = t(42, 43)
Associate (length=>x%length, width=>x%width)
Print *, length, width
End Associate
End Program
Quoting from Fortran 2003 (e.g., at http://www.j3-fortran.org/doc/year/04/04-007.pdf): "The ASSOCIATE construct associates named entities with expressions or variables during the execution of its block."
The December 2015 ACM Fortran Forum "Compiler Support" article lists the associate construct as being fully supported by Cray, IBM, Intel and NAG and partially supported by gfortran.
I don't think there is any way to simplify this though if you have many type components to alias in this way.

C++ Array Definition with Lower and Upper Bound?

My daughter's 12th standard C++ textbook says that
the notation of an array can (also) be given as follows: Array name
[lower bound L, upper bound U]
This was a surprise for me. I know Pascal has this notation, but C++? Had never seen this earlier. I wrote a quick program in her prescribed compiler (the ancient Turbo C++ 4.5), and that does not support it. Did not find this syntax in Stanley Lippman's book either. Internet search did not throw up this. Or maybe I didn't search correctly?
So, is it a valid declaration?
This is not valid, from the draft C++ standard section 8.3.4 Arrays the declaration must be of this form:
D1 [ constant-expressionopt] attribute-specifier-seqopt
and we can from section 5.19 Constant expressions the grammar for constant expression is:
constant-expression:
conditional-expression
This grammar does not allow us to get to the comma operator either to do something like this:
int a[ 1, 2 ] ;
^
as others have implied since there is no path to comma operator from conditional-expression. Although if you add parenthesis we can get to the comma operator since conditional-expression allows us to get to primary-expression which gets us () so the following would be valid:
int a[ (1, 2) ] ;
^ ^
Note, in C++03 you were explicitly forbidden from using the comma operator in a constant expression.
No it's not true, unless someone has overloaded the comma operator and possibly [] as well which is very unlikely. (Boost Spirit does both but for very different reasons).
Without any overloading at all, Array[x, y] is syntatically invalid since the size must be a constant-expression and these cannot contain the comma operator; as to do so would make it an assignment-expression.
Burn the book and put Stroustrup in her Christmas stocking!

How is sequence syntactic sugar ([1..6]) translated into actual list syntax ( 1:2:3...6 )?

How does Haskell translate [ and ] into the list definitions? Are they value constructors or something? Are they newtypes? Is there a way to define an outfix syntax, as opposed to an infix one?
This syntax is defined in the Report, and in particular in section 3.10. [1..6] is defined to mean enumFromTo 1 6. You can't define syntax like that yourself.

Passing lists from Mathematica to c++ (Mathlink)

I simply want to pass a list of integers to a function written in C++. I've set up the template (.tm) file and all, and I can successfully call a test function whith scalar arguments. Calling the function with the list argument behaves as though the function was not defined at all. I suspect that the argument types don't match.
In the documentation for templates (http://reference.wolfram.com/mathematica/ref/file/file.tm.html) the datatype for lists is something like "Int32List". When I use that, my C++ function must contain an extra long parameter for the list length. The only example code which uses a list is "sumalist.tm". This example uses IntegerList (a type which doesn't appear in the doku).
When I use Int32List, the mprep result requires a function with an extra integer argument (not long as written in the doku). When I use the undocumented IntegerList type, the extra argument is of type long.
During my experiments with scalar types, I had a similar problem - a c++ function was called properly when using "Integer" in the tm-file, and not recognized with "Integer32".
The "sumalist.tm" example also uses a strange Pattern (list:{___Integer}) about which I didn't find any documentation. I'd also like to understand what the Evaluate line means (I suspect that it's used make the function callable without the curly braces around the list).
So who know which datatypes are really appropriate to call a c++ function with a list - maybe also with reals... ?
The mapping of MathLink data types (e.g., Integer32, Integer32List, ...) to C/C++ types is described on the MathLink template file documentation page.
The page no longer documents the old interface types Integer, Real, IntegerList and RealList. These should no longer be used, because the mapping of these types depends on C types whose bit length is platform and compiler dependent (e.g., long). Use the corresponding new type with explicit bit length instead (i.e., Integer32 or Integer64 instead of Integer). The old interface types are still documented in the somewhat dated MathLink reference guide.
The following talk slides contain a simple MathLink example that shows how to implement a MathLink function that adds a scalar value to a vector of reals. This may serve as a starting point.
I don't know much about MathLink, but I can explain the pattern, list:{___Integer}.
The colon is just the general form for a named pattern, that is symbol:pattern just says that the object referred to by symbol has to match pattern. Indeed, pattern like a_Integer or b__List are really just short forms for a:_Integer and b:__List.
So what we are left with interpreting is {___Integer}. This is a pattern matching a list of arbitrary many (including zero) integers. It works as follows:
{Pattern} is the Pattern for a list whose contents matches Pattern
___Integer is the Pattern for a sequence of zero or more Integers.

Mix C-string and fortran-string in one file

I have one question with mixing C-string and fortran-string in one file.
Supposed I am playing with the name string with fixed length 9, I define a length Macro like
#define NAME_LEN 9
in a .c file.
There is an existing fortran-function, let's name it fortran_function(char* name)
Now I have to call this fortran function in a c function, let's name is
c_function(char name[]) {
fortran_function(name)
}
Now the problem is, how should I declare the c_function signature?
c_function(char name[])
c_function(char name[NAME_LEN +1])
or
c_function(char name[NAME_LEN])
Under what situations, I should use 9 as name length or 10?
My understanding is that, as long as you passed a null-terminated string with 9 characters to the c_function, all the declaration are correct. Is that right?
Any other concern should be put here? Any potential bugs?
There's one more gotcha here, if I remember correctly. Fortran does not use null-terminated strings; instead, it pads the right end of the buffer with 0x20 (space). So, if you have access to the Fortran source, I would modify the function signature to take the length of the passed-in string as an argument. Otherwise, you will probably crash the Fortran side of the code.
Dave is correct, the standard Fortran concept for strings is fixed-length, padded with blanks on the right. (Fortran now also have variable length strings, but these are not yet common and would be very tricky to inter-operate with C.) If you want the lengths fixed, then have the same parameter NAME_LEN in your Fortran code, with the same value. Dave's suggestion of an additional length argument is probably better.
An additional refinement is to use the ISO C Binding facility on the Fortran side (corrected per the comment!)
subroutine Fort_String_code (my_string), bind (C, name="Fort_String_code")
use iso_c_binding
integer, parameter :: NAME_LEN = 9
character (kind=c_char, len=1), dimension (NAME_LEN), intent (inout) :: my_string
etc. The "bind" name is the name by which C can call the Fortran routine -- it can be different from the Fortran name. Also provided as part of the iso_c_binding is the symbol C_NULL_CHAR which you can use in the Fortran code to provide the terminating null character that C expects, etc.
There's no difference to those calls. The c compiler will treat them all as char*. You just have to make sure you null terminate it before you use it in c. If you're only using the string in the fortran side and the c functions are just holding on to it, then you don't need to do anything.