Solved

Passing character from gnu C (gcc) to gfortran includes NUL terminator

Posted on 2010-08-18
4
840 Views
Last Modified: 2013-11-08
When passing a character array from gcc to gfortran the string contains the NUL character which terminates the string in C, but not in FORTRAN.

On the HP UNIX system the NUL did not get sent when passing it across, but in the GNU C/Fortran world on Linux it is passed which is causing problems for programs I am trying to convert to Linux.

I can, and have written a subroutine which will strip this NUL so I have a solution, however I believed that by using ISO_C_BINDING and then passing the string that it would not send the NUL across, which would have been a nicer solution.

Do you know if using ISO_C_BINDING from gfortran and then having C/gcc pass the characters that it ought not send the NUL or have I misinterpreted something?

If this is true do you have some working code to show this? I tried it and it still sent the NUL, so I can't see the point in using ISO_C_BINDING and C_CHAR?

(p.s. I am using gcc 4.4.? and in RedHat Linux if that is of any importance.)

Kind Regards,
Max
0
Comment
Question by:madmax61
  • 2
  • 2
4 Comments
 
LVL 5

Accepted Solution

by:
dcesari earned 500 total points
ID: 33473046
The ISO_C_BINDING interface is, intentionally, just a way for purely interfacing data types between C and Fortran, but it does not affect the data contents, so it allows you to pass a CHARACTER to a char* and vice-versa but it does not check/modify its contents, and in particular the zero termination.

So, I agree with you, ISO_C_BINDING it is quite deceiving when working with CHARACTERs, but on the other side CHARACTER and char* are quite different concepts which would be anyway difficult to harmoinize, Fortran CHARACTER has a fixed length, (which is unknown to C if you simply pass to a ISO_C_BINDING-interfaced function just the character vaule itself), while, when interpretating a char* as a string in C it is a string of variable length zero-terminated, with possible buffer overflows, etc.

I suppose that in HP fortran CHARACTER strings contain internally an additional null character at len()+1 position, so the program does not complain about it, but this is a non standard behavior over which you cannot rely if you want your program to be portable.

So a quick solution is to detect the null and tell fortran that the string finishes just before it.
A better solution, feasible with F2003, but which I did not studied deeply enough, would be to define in Fortran a special variable length-zero-terminated character type (something similar is in the ISO_VARYING_STRING but not zero terminated AFAIK) which can be exchanged freely with C but supports at the same time most of the methods of traditional Fortran CHARACTER variables.


0
 
LVL 5

Assisted Solution

by:dcesari
dcesari earned 500 total points
ID: 33473088
An example of how a character can be passed cleanly with its right length but without nul terminator from C to Fortran is the attached one, making use of an intermediate wrapper routine which detects the NULL terminator and passes to the second subroutine only the portion of string before it. (it is untested, may have errors).
MODULE mymod
USE,INTRINSIC :: ISO_C_BINDING
IMPLICIT NONE

CONTAINS

! wrapper subroutine
SUBROUTINE calledfromc(numeric, cchar) BIND(C,name="CalledFromC")
INTEGER(kind=C_INT) :: numeric
CHARACTER(kind=C_CHAR) :: cchar(*)

INTEGER,PARAMETER :: charmax=1024
INTEGER :: i

DO i=1,charmax
  IF (cchar(i) == C_NULL_CHAR) EXIT
ENDDO

CALL calledfromfortran(num, cchar(:i-1))

END SUBROUTINE calledfromc

! real fortran subroutine
SUBROUTINE calledfromfortran(numeric, cchar) 
INTEGER(kind=C_INT) :: numeric
CHARACTER(kind=C_CHAR,len=*) :: cchar

! here cchar can be used as usual in Fortran

END SUBROUTINE calledfromfortran

END MODULE mymod

Open in new window

0
 

Author Closing Comment

by:madmax61
ID: 33473920
Really helpful excellent answers over 2 posts.

Very much appreciated.

Split the points as both answers were just as helpful, even though the same person.

Many thanks.

Cheers,
Max
0
 

Author Comment

by:madmax61
ID: 33481023
As it turns out the NUL character WAS being passed on HP-UX from C to  FORTRAN. The difference I was experiencing between Linux and HP-UX was that the NUL character was displaying in the output from the program in vi on our Linux system and not on the HP. In any case I wasn't happy that when a passed string from C when being printed in the GFORTRAN program I was porting across to Linux was printing out this NUL, so I still wanted to resolve this issue.
Again thankyou for the answers, they were exactly the info I required.
Having the BIND and ISO_C_BINDING business is more likely to confuse than assist in this case is my feeling.
Cheers,
Max
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
why to use string 10 62
Setup specific permissions in Microsoft Access 9 60
seriesUp challenge 7 191
Excel file not created as expected 7 90
The purpose of this article is to demonstrate how we can use conditional statements using Python.
Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
The viewer will learn how to implement Singleton Design Pattern in Java.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

740 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question