Argument Corrupted when Passed from Fortran to C++

Dear Support,

We are currently trying to run our code with the PGI compiler instead of the Intel compiler. We are using PGI 11.8. The code compiles and runs fine under the Intel compiler. However with PGI it compiles fine but we’re getting run time errors. This is on RedHat Linux 5.3

The code is mixed language of Fortran, C, and, and C++. This is the first time for us to use the PGI compiler with mixed Fortran and C++ code. The issue we are seeing is that variables being passed from Fortran to C++ get messed up.

I am not able to post the actual code, but below is an example of how it looks like.

The Fortran code looks something like:

character(len=*) :: myVariable
myVariable = 'DEEP'
PRINT *,'myVariable while in Fortran is ', myVariable
        call test(myVariable)
.
.
.

The C++ code looks something like:

extern "C"
{
   void test(char *myVariable)
  {
    cout << "myVariable after getting passed to cpp is ";
    cout << myVariable;
.
.
.

Running the program gives the below result, the variable seems to get extra junk characters at the end which are showing up as question marks after it’s passed to C++ which messes up if-statement checks that follow:


myVariable while in Fortran is DEEP
myVariable after getting passed to cpp is DEEP????

NOTE: When I copied the question marks to be posted in this forum, they got pasted as \ufffd\ufffd\ufffd\ufffd, so I just changed them back to the question marks for the posting.

The Intel compiler flags we use are (these are working fine):

Fortran: -w -pc64  -openmp_stubs -fp-model precise -cpp -assume buffered_io -assume byterecl -prefetch -traceback -132 -O3 -xP -ftz

C/C++: -ftz -O3

Fortran linker: Same as Fotran flags in addition to -cxxlib

The PGI compiler flags we are using:

Fortran: -w -pc 64 -Mnoopenmp -Kieee -Mpreprocess  -Mbyteswapio -Bstatic -Mextend -fast -Mvect=nosizelimit

C/C++: -Bstatic  -fast

Fortran linker: -lC -lstd

I am not sure what’s wrong here, could I be missing compiler or linking flags or is there something wrong with the way the call and passing is done?

Thank you for your help in advance.

sindimo

Hi sindimo,

C and C++ expect character arrays to be NULL terminated while Fortran does not. Hence, when passing character from Fortran to C/C++, you need to add the NULL character to the end of the string. For example:

character(len=*) :: myVariable
myVariable = 'DEEP'//char(0)

Hope this helps,
Mat

Dear Mat,

Thank you for the explanation. Adding the NULL character to the end seems to fix the content of the strings after getting passed to C++.

However, our actual code has lots of calls from FORTRAN to C++ with strings being passed around, is there a more convenient way of doing this instead of having to manually append the NULL character to the arguments? With the Intel compiler that seems to be taken care of on its own as we are not explicitly handling it and it still works, are there any compilation/linking flags with the PGI compiler that can accomplish this or at least ease it a bit?

Thank you again for all of your help.

With the Intel compiler that seems to be taken care of on its own as we are not explicitly handling it and it still works

It would be a violation of the Fortran standard, and any compiler doing such things (adding NULLs to strings gratuitously) would be shunned by users.

Please show an example where Intel Fortran + whichever C/C++ compiler used provide automatic handling of null termination. I do not believe that this feature either exists or would be desirable.

The Fortran 2003 C-interoperability does not cover strings. CHARACTER arguments passed by Fortran have to pass the string length as a hidden argument, and the C/C++ callee should expect and exploit this length argument. The details of how this is done vary by compiler.

The Intel compiler and the PGI compilers provide you some aids to make the string passing easier, but both require that you modify the code slightly. Both allow you use a C suffix to a string constant, e.g.,

character (len=10) :: str = '123456789'C