User talk:Zmi007: Difference between revisions

m
 
(6 intermediate revisions by 3 users not shown)
Line 35:
===Writing an integer===
I don't have access to a F2003 compiler, and don't want to spend ''my'' money to gain access, especially when the prices I've seen are around US$3,000. The system I use dual starts to Linux or wunduhs, so there is a possibility there, but also a lot of time and patience needed to find a compatible compiler. I do have a wunduhs F95 compiler (alas, its microflaccid "visual" interface won't work on 64 bit or later than wunduhs XP) ... And here is a collection of IFMT(n) functions...
: Seriously? ) GNU gfortran is very close to be named a F2003 compiler and costs zero $. Your current task can be solved in a very elegant and simple way with parametrized derived types but there is one big problem there: they are still missing in almost any Fortran compiler including gfortran ) So, yes, you have right here, I wrote [http://pastebin.com/Mw08KFAb similar routines] for integers with interface int2char but using kind parameter extends its usability to compilers with different integer kinds. Your problem is that you attempt to preserve portability of the code for very large set of compilers, but your price for it is too high, imho (subset of the Fortran language standard of the worst supported compiler in your set). With one simple step towards F2003 standard many problems become realizable with significantly less efforts and code. [[User:Zmi007|Zmi007]] ([[User talk:Zmi007|talk]]) 23:48, 16 December 2015 (UTC)
::I don't use Linux/unix much so the rigmarole of choosing and installing a compiler is an obstacle. I definitely do not want the old-style of first choosing and installing a C-compiler so as to compile the software I first desired. Still, I have made a trial attempt in the past, and was baulked by a trivial incompatibility, namely that A%B is the official style for compound data names, and I can't stand it, and have used A.B (as I had with B6700 Algol (which uses % to dignify a line comment, as does matlab, end ...), and pl/i, etc) so I was faced with either finding a compiler variant that allowed this deviationism, or, editing the source files to conform to a disliked form. That trial compiler also was not declared F2003 and may not have dealt with some of the constructions that try the diligence of those transferring from one compiler/system to another compiler/system - those would only be found via testing and compiler complaint, but the % for . complaints swamped the initial output. A serious difficulty was expected over the STRUCTURE/UNION/MAP facility (essentially, EQUIVALENCE ideas expanded to data structures) whereby disc file records could contain different types of data. This I expected trouble over but did not reach because of the .% issue. There is the TRANSFER facility that is approved furrytran these days, but I want to be sure that no actual transfer to/from work areas takes place! Data shovelling takes a lot of time, and adding intermediate stops would exacerbate the delay. To check on this would require time spent with tests and inspection of the compiler-generated code in the various cases - more time and patience. Naturally, the compiler documentation is not at all clear on such details. I was startled for instance to replace some parallel arrays by a data structure equivalent and find that the resulting programme ran about three times slower rather than at the same speed. It transpired that suddenly, a binary search routine was being invoked with its array parameter being copied in (and back), thus vitiating the speed advantage of a binary search over a linear search. Fortunately, there were only two usages, so in-line code was not too much effort and restored the pace yet retained the organisational clarity of a data aggregate in place of an aggregation of individual arrays.
:::Happy new year![[User:Dinosaur|Dinosaur]] ([[User talk:Dinosaur|talk]]) 01:01, 31 December 2015 (UTC)
<lang Fortran>
CHARACTER*2 FUNCTION I2FMT4(N) !These are all the same.
Line 76 ⟶ 80:
END INTERFACE FFMT
</lang>
On the face of it, the task is easy, but there are traps. Many Fortran compilers do not handle the case of a WRITE statement invoking a WRITE statement as via a function (e.g. <code>WRITE (OUT,"(3A)") "Yes, we have ",IFMT(N)," Bananas!"</code>), or, possibly allow this so long as one or the other, or perhaps both refrain from using a FORMAT in them, or the statements involved do not trigger some detail. Determining exactly what is possible on one compiler is not a good idea, because another compiler may well have different rules, and thereby, portability fades. Thus the I2FMT routines play with simple arithmetic rather than unlimber the FORMAT apparatus (which is also time-consuming: a fortnight back I modified a prog. that systematically used multiple WRITE statements of assorted texts (generating .kml text for Google Earth's system) into one that used compound WRITE statements of those texts and was startled by a fivefold increase in speed of execution), and there is the question of whether it is better to place the two characters one-at-a-time in two statements rather than use // - which is likely to mean that the expression's value is developed in a work area, then that is copied to the recipient. I couldn't face all this with I8FMT, though I did for function SLASHDATE, allowing four digits for the year number - this function gets heavy use in my major project. A second question is whether or not the function name can be used as a variable within the function, not merely as the destination for an assignment of the final result. In other words, function I8FMT's code could write to a variable I8FMT rather than to HIC then assign HIC's content to I8FMT. Similar usages are possible for arithmetic functions, but, some compilers I have encountered fail to do this properly and thereby, portability fades. If recursion is contemplated, then, a recursive function FACT(X) could refer to FACT within itself as a variable, but FACT(X - 1) would be a function invocation, and this protocol would work even for functions with no parameter as in F vs. F().
<lang Fortran>
CHARACTER*10 FUNCTION SLASHDATE(DAYNUM) !This is relatively innocent.
Line 121 ⟶ 125:
 
Which is pointless in F95, where CHARACTER functions always return a fixed number of characters - so I have routines such as SSPACE to single-space a line of text... Only with the latter day STRING style could this be done properly.
 
I'm still uncomfortable about the unlimbering of memory re-allocation on every change to a string. There are ploys, such as the obvious "do nothing" if the new size is the same as the old size. Presuming that this memory churning would be mixed in with the other memory churning of arrays of floating-point numbers, etc. this means that the precise state of the memory depends now not just on the churn of number storage, but also of text twiddling. Still, given that modern computers have plenty of memory and that there are no mistakes in the memory manipulation, this shouldn't matter... I have from time-to-time mused on a half-way house, wherein a string has a length ''and'' a maximum size: any manipulations up to the size limit incur no re-allocation and so can be done in-place. This would offload some of the demand for cunning in the memory re-allocation routines but of course means that the string manipulation procedures become even more complex. [[User:Dinosaur|Dinosaur]] ([[User talk:Dinosaur|talk]]) 08:28, 12 December 2015 (UTC)
 
== Call a foreign-language function ==
 
I don't quite agree with your comment, on two points.
 
First, the definition. Quoting '''[[Foreign function interface]]''':
 
''Foreign function interface, or FFI, is a common name for a facility in a programming language (especially a high-level one that does not usually work in terms of pointers, raw structure layout, etc.) to invoke functions and access data structures defined using another one (especially C).''
 
Calling C from Fortran qualifies obviously as FFI. The only difference with, say, a Common Lisp FFI to C, is that it's specified by the standard. C is nevertheless ''foreign'' to Fortran. It's rather rare for standardized languages, but not unique: Ada has interfaces to C, COBOL and Fortran, for instance.
 
Second point, you write that you should write a C wrapper. But C has no standard way to call another language. If you can do it with standard C, then you will be able to do it with Fortran and ISO_C_BINDING and if you need nonstandard C features, then the Fortran vendor may provide the same nonstandard features. And often it's what happens. A classic example is calling a ''STDCALL'' function on Windows, while, usually, C programs (and Fortran programs, at least with BIND(C)), use the ''CDECL'' convention. But, this is not really a language concern, it's on the ABI level. And, as C compiler provide the nonstandard __stdcall keyword, Fortran compilers provide either a STDCALL keyword (Absoft Pro Fortran), or another nonstandard way to declare the function: Intel Fortran has "DEC! ATTRIBUTES STDCALL :: fun", while GNU Fortran has the same (replace DEC with GNU). All in all, in all cases I know off, if you can do it in C, you can do it in Fortran without a wrapper. It may be simpler with a wrapper though.
 
There are other cases for which one must use nonstandard features. Another example is calling a function that needs arguments with a special memory alignment. Intel has "DEC$ ATTRIBUTES ALIGN" for this. Even in Fortran alone, this allows the compiler to optimize better with SIMD instructions.
 
Notice that even before ISO_C_BINDING, Fortran compiler vendors used to provide some way to interface with C. There are DEC extensions, for instance. Incidentally, Intel still uses these extensions instead of the new standard bindings, for interface modules to the Windows API. I guess it's so that older programs don't break. It's also often easier to use integer variables holding pointers, than the c_f_pointer and c_f_procpointer subroutines.
 
On the other hand, there are languages for which a wrapper is mandatory. An example is VBA, in 32 bit applications. Since VBA can only call STDCALL functions, a CDECL function can't be called without a wrapper (which may be written in C, Pascal or Fortran for instance). In 64 bits applications, this not a problem anymore, since there is only one calling convention.
 
[[User:Arbautjc|Arbautjc]] ([[User talk:Arbautjc|talk]]) 18:27, 24 November 2016 (UTC)
Anonymous user