- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
On rare occasions my program passes a character string length incorrectly to a pointer function. Instead of passing the correct length of the string, the length of the string is an address of some kind of data. E.g., the actual argument is a character string of length 5. However, inside of the pointer function, the length is 842666016, which appears to be some kind of machine address. If I run the program several different times, this error appear at the same place in the program but the length inside of the function is different each time the program is run.
I am getting this error while doing consulting work for Bank of New York Mellon (BNYM). BNYM is using Intel Fortran 19.1.3 under Linux.
Has this error been corrected in a subsequent version of Intel Fortran and, if so, which version?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We'll need to see a test program that shows the problem, Craig. I have not heard of such a compiler bug. More likely it's a coding error in your application that is picking up an uninitialized stack value.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Craig, I do not understand what you mean by the term "pointer function". Please clarify.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It's a function that returns a pointer to a node in a binary tree. For reasons of following mandatory rules of security and confidentiality I can't post the exact source code. Here is an example that illustrates the situation without revealing the exact source code.
Type (Binary_Tree_Node_T) :: Item
. . .
Item => Binary_Tree_Function ( Binary_Tree_Head, Fixed_Length_Char_String )
Fixed_Length_Char_String has the correct length on the caller side. It has a different length that resembles an address inside the function, i.e., a value in the hundreds of millions or billions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I wrote a small program to illustrate such pointer functions:
! chk_string_pointer.f90
! Check pointer functions that return strings
!
module string_pointers
implicit none
character(len=20), dimension(10), target :: array_strings
contains
function pointer_to_string( i )
integer, intent(in) :: i
character(len=:), pointer :: pointer_to_string
pointer_to_string => array_strings(i)
write(*,*) 'Check: ', len(pointer_to_string)
end function pointer_to_string
end module string_pointers
program chk_string_pointer
use string_pointers
implicit none
write(*,*) 'Checking lengths ...'
pointer_to_string(1) = '1234567890'
pointer_to_string(2) = '12345678901234567890'
write(*,*) len(pointer_to_string(3)), ' - 10 expected'
array_strings(1) = array_strings(1)(1:4) // 'ABC'
write(*,*) pointer_to_string(1)
end program chk_string_pointer
The results are, well, odd:
- gfortran version 10.2.0 (equation.com) produces a program, but that gets stuck at line 28 or 30.
- gfortran version 11.2.0 (Cygwin) gets stuck itself (or at least my patience ran out).
- Intel Fortran version 2021.4.0 produces error messages that I cannot link to the source code:
ifort chk_string_pointer.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.4.0 Build 20210910_000000
Copyright (C) 1985-2021 Intel Corporation. All rights reserved.
chk_string_pointer.f90(27): error #6423: This name has already been used as an external function name. [POINTER_TO_STRING]
pointer_to_string(1) = '1234567890'
----^
chk_string_pointer.f90(27): error #6515: This function, which is specified as the left side of an assignment statement, is invalid. [POINTER_TO_STRING]
pointer_to_string(1) = '1234567890'
----^
chk_string_pointer.f90(28): error #6423: This name has already been used as an external function name. [POINTER_TO_STRING]
pointer_to_string(2) = '12345678901234567890'
----^
chk_string_pointer.f90(28): error #6515: This function, which is specified as the left side of an assignment statement, is invalid. [POINTER_TO_STRING]
pointer_to_string(2) = '12345678901234567890'
----^
compilation aborted for chk_string_pointer.f90 (code 1)
Well, so far my demonstration ;).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I forgot to mention that the OS is Red Hat Enterprise Linux Version 7.9.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Craig, the latest compilers don't need a license. I would advise you set up another system or even the same system with the latest 2022.x compilers. Information is HERE
But I agree with Steve that it's probably not a compiler bug. Our ABI for passing strings has not changed for years and years. Pretty straightforward and for sure if there was a bug we'd have heard about it long before now. More than likely you are seeing stack corruption, especially if it's a mixed language application. You may consider the fp-stack-check option which MAY catch something. But it cannot catch all stack corruption issues.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is Binary_Tree_Function a Fortran function?
Is the interface defined with an INTERFACE or is it defined as a module procedure?
Is this a recursive function, implementing a recursive tree search algorithm?
have you unlimited stack before running with
'ulimit -s unlimited' ; a.out (0r whatever command line you use to run the code)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here are the answers to your questions.
Yes, Binary_Tree_Function is a Fortran function.
The function is a module procedure so the interface is explicit.
Yes, it is a recursive function implementing a recursive tree search algorithm.
No, I have not implemented unlimited stack using a command similar to what you recommended.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I wrote a small program to illustrate such pointer functions:
! chk_string_pointer.f90
! Check pointer functions that return strings
!
module string_pointers
implicit none
character(len=20), dimension(10), target :: array_strings
contains
function pointer_to_string( i )
integer, intent(in) :: i
character(len=:), pointer :: pointer_to_string
pointer_to_string => array_strings(i)
write(*,*) 'Check: ', len(pointer_to_string)
end function pointer_to_string
end module string_pointers
program chk_string_pointer
use string_pointers
implicit none
write(*,*) 'Checking lengths ...'
pointer_to_string(1) = '1234567890'
pointer_to_string(2) = '12345678901234567890'
write(*,*) len(pointer_to_string(3)), ' - 10 expected'
array_strings(1) = array_strings(1)(1:4) // 'ABC'
write(*,*) pointer_to_string(1)
end program chk_string_pointer
The results are, well, odd:
- gfortran version 10.2.0 (equation.com) produces a program, but that gets stuck at line 28 or 30.
- gfortran version 11.2.0 (Cygwin) gets stuck itself (or at least my patience ran out).
- Intel Fortran version 2021.4.0 produces error messages that I cannot link to the source code:
ifort chk_string_pointer.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.4.0 Build 20210910_000000
Copyright (C) 1985-2021 Intel Corporation. All rights reserved.
chk_string_pointer.f90(27): error #6423: This name has already been used as an external function name. [POINTER_TO_STRING]
pointer_to_string(1) = '1234567890'
----^
chk_string_pointer.f90(27): error #6515: This function, which is specified as the left side of an assignment statement, is invalid. [POINTER_TO_STRING]
pointer_to_string(1) = '1234567890'
----^
chk_string_pointer.f90(28): error #6423: This name has already been used as an external function name. [POINTER_TO_STRING]
pointer_to_string(2) = '12345678901234567890'
----^
chk_string_pointer.f90(28): error #6515: This function, which is specified as the left side of an assignment statement, is invalid. [POINTER_TO_STRING]
pointer_to_string(2) = '12345678901234567890'
----^
compilation aborted for chk_string_pointer.f90 (code 1)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Arjen, I cannot make sense of your program. On lines 27 and 28, you are treating the identifier pointer_to_string as an array and trying to assign values to the first two elements of the array. However, the definition of pointer_to_string as a function is already in scope. Or, ... , what did I miss?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@mecej4 wrote:
...On lines 27 and 28, you are treating the identifier pointer_to_string as an array and trying to assign values to the first two elements of the array. However, the definition of pointer_to_string as a function is already in scope. Or, ... , what did I miss?
F2008 introduced the ability to have a function with pointer result on the left hand side of an assignment statement. Not that I think it is relevant to the OP's guessing game problem.
(Once the compiler bug that stops this compiling is fixed, Arjen should expect a length of 20, not 10, or there is a typo somewhere.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, Ian; I find the feature described in section 6.5, "Pointer functions" of the paper The New Features of Fortran 2008 .
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I left out an important detail. The functions that search the binary tree use iteration to perform the searches, not recursion. All of the searches are implemented using Do While loops. Within each loop there are tests to exit the loop if found or if at an end node in the binary tree.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
(I have tried posting this answer several times and it did not show up, so hopefully it does now)
I wrote a small program to illustrate such pointer functions:
! chk_string_pointer.f90
! Check pointer functions that return strings
!
module string_pointers
implicit none
character(len=20), dimension(10), target :: array_strings
contains
function pointer_to_string( i )
integer, intent(in) :: i
character(len=:), pointer :: pointer_to_string
pointer_to_string => array_strings(i)
write(*,*) 'Check: ', len(pointer_to_string)
end function pointer_to_string
end module string_pointers
program chk_string_pointer
use string_pointers
implicit none
write(*,*) 'Checking lengths ...'
pointer_to_string(1) = '1234567890'
pointer_to_string(2) = '12345678901234567890'
write(*,*) len(pointer_to_string(3)), ' - 10 expected'
array_strings(1) = array_strings(1)(1:4) // 'ABC'
write(*,*) pointer_to_string(1)
end program chk_string_pointer
The results are, well, odd:
- gfortran version 10.2.0 (equation.com) produces a program, but that gets stuck at line 28 or 30.
- gfortran version 11.2.0 (Cygwin) gets stuck itself (or at least my patience ran out).
- Intel Fortran version 2021.4.0 produces error messages that I cannot link to the source code:
ifort chk_string_pointer.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.4.0 Build 20210910_000000
Copyright (C) 1985-2021 Intel Corporation. All rights reserved.
chk_string_pointer.f90(27): error #6423: This name has already been used as an external function name. [POINTER_TO_STRING]
pointer_to_string(1) = '1234567890'
----^
chk_string_pointer.f90(27): error #6515: This function, which is specified as the left side of an assignment statement, is invalid. [POINTER_TO_STRING]
pointer_to_string(1) = '1234567890'
----^
chk_string_pointer.f90(28): error #6423: This name has already been used as an external function name. [POINTER_TO_STRING]
pointer_to_string(2) = '12345678901234567890'
----^
chk_string_pointer.f90(28): error #6515: This function, which is specified as the left side of an assignment statement, is invalid. [POINTER_TO_STRING]
pointer_to_string(2) = '12345678901234567890'
----^
compilation aborted for chk_string_pointer.f90 (code 1)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
is the character length corrupted on the head node, or does it go bad deep in the search?
Looks like a good debugging issue but for sure try the latest compiler first just in case there is some compiler bug in the older 19.1 compiler.
If the Binary_Tree_Node_T type has a unique ID component, say "node%id", you could put a check at the top of Binary_Tree_Function for the length of the passed string. Psuedo code similar to
integer, parameter :: MAX_CHAR_LEN = 200
...
if ( (len_trim( Fixed_Length_Char_String ) > MAX_CHAR_LEN) .OR. (len_trim(Fixed_Length_Char_string) < 0) ) then
write(*,*) "bad char len ", len_trim( Fixed_Length_Char_String)
write(*,*) "Node ID", node%id
!... better if parent is known, do you have a parent link in the node type? )
write(*,*) "Parent node ID", node%parent%id
stop
end if
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page