Solved

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

Posted on 2010-08-18
4
838 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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
wordappend challenge 8 200
base64 decode encode 12 145
What language/protocol is the Angular Chat? 2 85
Problem to Alipay 10 43
Navigation is an important part of web design from a usability perspective. But it is often a pain when it comes to a developer’s perspective. By navigation, it often means menuing. This is less theory and more practical of how to get a specific gro…
There is an easy way, in .NET, to centralize the treatment of all unexpected errors. First of all, instead of launching the application directly in a Form, you need first to write a Sub called Main, in a module. Then, set the Startup Object to th…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

860 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