- 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