Solved

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

Posted on 2010-08-18
4
846 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

Suggested Solutions

This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

734 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