- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello!
Please answer some questions about fortran construction
1. I have a function:
function GetArgumentName() result(Res) character(250) Res ... end function
How can i use substring of first character without declaring additional variables like this:
GetArgumentName()(1:1)
Compiler don't let me so
2. I have a function:
function GetArray() result(Res) integer(1:100) Res end function
Why compiler do not let me use the following expression:
n = 5 + GetArray()(1)
where i want to add to 5 the first element of the array?
3. I have a type and a function:
type T_Point real X, Y end type function GetPoint() result(Res) type(T_Point) Res end function
Why compiler do not let me use the following expression:
r = 5.0 + GetPoint() % X
Is it really necessary to declare auxiliary variables every time to execute these expressions?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It's the Fortran language that does not allow you to do those things, not the compiler. A function reference isn't a data object that can be itself qualified with subobjects.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you very much Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Averkov, Igor wrote:..
Please answer some questions about fortran construction ..
How can i use substring of first character without declaring additional variables like this:
GetArgumentName()(1:1)
.
.. use the following expression:
n = 5 + GetArray()(1)
r = 5.0 + GetPoint() % X.
Is it really necessary to declare auxiliary variables every time to execute these expressions?
As stated upthread, the Fortran standard does not allow your to use function references the way you want.
However look into ASSOCIATE construct: https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-associate
ASSOCIATE can prove very valuable in situations where you need to associate objects and their subobjects or function results, see below. While you're at it. you may want to look at BLOCK construct in Fortran also: https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-block
type :: T_Point real :: x = 0.0 real :: y = 0.0 end type blk2: block integer :: n asc2: associate ( Array => GetArray() ) n = 5 + Array(1) print *, "Associate 2: n = ", n, "; expected is 47" end associate asc2 end block blk2 blk3: block real :: n asc3: associate ( Pt => GetPoint() ) n = 5.0 + Pt%X print *, "Associate 3: n = ", n, "; expected is 6.0" end associate asc3 end block blk3 asc1: associate ( ArgName => GetArgumentName() ) print *, "Associate 1: ArgName(1:1) = ", ArgName(1:1) end associate asc1 contains function GetArgumentName() result(ret) ! Function result character(len=250) :: ret ret = "Hello World!" end function function GetArray() result(Res) ! Function result integer :: Res(1:100) Res = 42 end function function GetPoint() result(Res) ! Function result type(T_Point) :: Res Res%X = 1.0 ; Res%Y = 2.0 end function end
Upon execution, the first two work ok. Intel Fortran compiler gives a compile time warning and then crashes at run-time with the CHARACTER object result from a function, both a bug me thinks:
C:\Temp>ifort /standard-semantics /warn:all /check:all /stand:f18 /warn:stderrors /traceback p.f90 Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.1.0.056 Pre-Release Beta Build 20190321 Copyright (C) 1985-2019 Intel Corporation. All rights reserved. ifort: NOTE: The Beta evaluation period for this product ends on 9-oct-2019 UTC. p.f90(23): warning #5481: Variable ARGNAME has substring ending point 1 which is greater than the variable length of 0 print *, "Associate 1: ArgName(1:1) = ", ArgName(1:1) -----------------------------------------------^ Microsoft (R) Incremental Linker Version 14.16.27027.1 Copyright (C) Microsoft Corporation. All rights reserved. -out:p.exe -subsystem:console -incremental:no p.obj C:\Temp>p.exe Associate 2: n = 47 ; expected is 47 Associate 3: n = 6.000000 ; expected is 6.0 forrtl: severe (408): fort: (12): Variable ARGNAME has substring ending point 1 which is greater than the variable length of 0 Image PC Routine Line Source p.exe 00007FF606D0C611 Unknown Unknown Unknown p.exe 00007FF606D014C3 MAIN__ 23 p.f90 p.exe 00007FF606D50DE2 Unknown Unknown Unknown p.exe 00007FF606D517B4 Unknown Unknown Unknown KERNEL32.DLL 00007FFD429B37E4 Unknown Unknown Unknown ntdll.dll 00007FFD42DECB81 Unknown Unknown Unknown C:\Temp>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@FortranFan Thanks for your comment. That feature is very elegant. However, here is another question: when one associates a function with a name, and the name is used in the association block, is the function going to be called every time, or is it called only once upon entry to the associate construct?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A. King wrote:@FortranFan Thanks for your comment. That feature is very elegant. However, here is another question: when one associates a function with a name, and the name is used in the association block, is the function going to be called every time, or is it called only once upon entry to the associate construct?
In principle, the evaluation of the expression based on the function reference should only take place once during the association of the entity (e.g., Pt above) with the selector. Note where the selector (e.g., GetPoint() above) is not a variable, as in say a function reference, or is otherwise not allowed to be in a variable definition context, the associating entity and any of its subobjects, if applicable, cannot be present in a variable definition context either, like on the left-hand side of an assignment. Such requirements on the coder allow a compiler not to invoke a function any further during the execution of the block i.e., the instructions between "associate(..)" and "end associate".
Hope this helps,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>In principle, the evaluation of the expression based on the function reference should only take place once during the association of the entity (e.g., Pt above) with the selector.
You also have available the now depreciated statement function.
Or you can write a Get function:
type T_Point real X, Y end type function GetPoint() result(Res) type(T_Point) Res end function function GetX(p) result(Res) type(T_Point) :: p real :: Res Res = p%x end function GetX ... something = GetX(GetPoint())
Jim Dempsey

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page