Solved

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

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

Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

Question has a verified solution.

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

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…
This article will show, step by step, how to integrate R code into a R Sweave document
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
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.

623 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