Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
27545 Discussions

Program Passes Character String Length Incorrectly to Pointer Function

Craig_T_Dedo
Beginner
1,307 Views

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?

Labels (1)
0 Kudos
15 Replies
Steve_Lionel
Black Belt Retired Employee
1,302 Views

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.

mecej4
Black Belt
1,254 Views

Craig, I do not understand what you mean by the term "pointer function". Please clarify.

Craig_T_Dedo
Beginner
1,242 Views

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.

Arjen_Markus
Honored Contributor I
1,048 Views

 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 ;).

 

Craig_T_Dedo
Beginner
1,249 Views

I forgot to mention that the OS is Red Hat Enterprise Linux Version 7.9.

Ron_Green
Moderator
1,248 Views

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.

Ron_Green
Moderator
1,212 Views

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)

Craig_T_Dedo
Beginner
1,174 Views

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.

Arjen_Markus
Honored Contributor I
1,048 Views

 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)
mecej4
Black Belt
1,033 Views

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?

IanH
Black Belt
897 Views

@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.)

mecej4
Black Belt
840 Views

Thanks, Ian; I find the feature described in section 6.5, "Pointer functions" of the paper The New Features of Fortran 2008 .

Craig_T_Dedo
Beginner
1,105 Views

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.

Arjen_Markus
Honored Contributor I
1,048 Views

 (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)

 

 

Ron_Green
Moderator
1,104 Views

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

 

 

Reply