- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm using the latest Intel Visual Fortran Compiler (ver 11.1.060 update 5) with Visual Studio 2008 profesional edition on Windows XP. I found there's a potential bug in the lastest Intel Visual Fortran Compiler, which didn't exist in previous versions. The bug causes problem passing the string length from Fortran to C functions. You know, when calling C functions with string arguments in Fortran program, the compiler appends the length of the string(s) to the end of the argument list (see http://docs.hp.com/en/B3909-90002/ch08s05.html). Somehow, the value of the string length isn't correctly passed to C or C++ function with the latest Fortran Compiler.
I tried the following code with both the compiler versions "11.1.060 update 5" and "11.0.061". The code worked properly when compiled with version "11.0.061". It failed during run-time when compiled with version "11.1.060 update 5". The source code and solution file are also attached.
---- C++ code -------------
#include
using namespace std;
extern "C"
{
void fix_string_for_f90(char s[], long int len)
{
int i;
for (i = strlen(s); i < len; i++)
s = ' ';
}
void print_string(char s[], long int len)
{
cout << "String printed in C: " << endl;
cout << s << endl;
fix_string_for_f90(s,len);
}
}
--------- Fortran code ------------------
program string_test
INTERFACE
SUBROUTINE print_string(string) BIND (C,NAME = "print_string")
CHARACTER(LEN=*) :: string
END SUBROUTINE print_string
END INTERFACE
character(100) :: string
string = "Hello World."//char(0)
CALL print_string(string)
WRITE(*,*) " String printed in Fortran: "
WRITE(*,*) TRIM(string)
end program string_test
I tried the following code with both the compiler versions "11.1.060 update 5" and "11.0.061". The code worked properly when compiled with version "11.0.061". It failed during run-time when compiled with version "11.1.060 update 5". The source code and solution file are also attached.
---- C++ code -------------
#include
using namespace std;
extern "C"
{
void fix_string_for_f90(char s[], long int len)
{
int i;
for (i = strlen(s); i < len; i++)
s = ' ';
}
void print_string(char s[], long int len)
{
cout << "String printed in C: " << endl;
cout << s << endl;
fix_string_for_f90(s,len);
}
}
--------- Fortran code ------------------
program string_test
INTERFACE
SUBROUTINE print_string(string) BIND (C,NAME = "print_string")
CHARACTER(LEN=*) :: string
END SUBROUTINE print_string
END INTERFACE
character(100) :: string
string = "Hello World."//char(0)
CALL print_string(string)
WRITE(*,*) " String printed in Fortran: "
WRITE(*,*) TRIM(string)
end program string_test
Link Copied
1 Reply
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The code worked "properly" in the older compilers because the compiler had a bug which matched the bug in your code. The compiler's bug was fixed - now it's your turn.
Here's how it was described in the release notes. The reference to Update 2 is not quite correct - some of these changes did not appear until later. (Why you are referencing an HP manual is puzzling - and note that the HP manual does not make any reference to BIND(C).)
---
Earlier versions of the Intel Fortran Compiler incorrectly passed or used hidden arguments for
procedures with the BIND(C) attribute. For example, if a Fortran routine had a CHARACTER
argument and had BIND(C) specified, the compiler would assume that two hidden arguments
were passed for the function return address and length, plus another hidden argument for each
character argument. While such hidden arguments are necessary and correct for noninteroperable
(without the BIND(C) attribute) Fortran procedures, the Fortran standard prohibits
them for interoperable procedures. The Fortran and C argument list must have a 1:1
correspondence.
In many cases where this problem occurs, the procedure does not meet the standards rules for
interoperable procedures. For example, if an argument is of type CHARACTER, the length
must be 1 an array of such characters may be an argument. Arrays of any nature are not
permitted as function return values for interoperable procedures. However, it is possible to
create a standard-conforming interoperable procedure for which the compiler was passing or
expecting hidden arguments.
In 11.1 Update 2, the compiler has been corrected to no longer pass or expect hidden
arguments. If you wrote C code which assumed that such hidden arguments needed to be
passed you will have to rewrite it and recompile. You may find that in some cases, functions will
need to be converted to subroutines with the result variable passed as an actual argument. We
apologize for the inconvenience, but it is important for correctness and portability to have this
error repaired.
---
Note also the comment that CHARACTER arguments with length other than 1 are "not interoperable" in the eyes of the standard. You can declare the argument as an array of CHARACTER(1) values and still pass a character string to it.
Here's how it was described in the release notes. The reference to Update 2 is not quite correct - some of these changes did not appear until later. (Why you are referencing an HP manual is puzzling - and note that the HP manual does not make any reference to BIND(C).)
---
Earlier versions of the Intel Fortran Compiler incorrectly passed or used hidden arguments for
procedures with the BIND(C) attribute. For example, if a Fortran routine had a CHARACTER
argument and had BIND(C) specified, the compiler would assume that two hidden arguments
were passed for the function return address and length, plus another hidden argument for each
character argument. While such hidden arguments are necessary and correct for noninteroperable
(without the BIND(C) attribute) Fortran procedures, the Fortran standard prohibits
them for interoperable procedures. The Fortran and C argument list must have a 1:1
correspondence.
In many cases where this problem occurs, the procedure does not meet the standards rules for
interoperable procedures. For example, if an argument is of type CHARACTER, the length
must be 1 an array of such characters may be an argument. Arrays of any nature are not
permitted as function return values for interoperable procedures. However, it is possible to
create a standard-conforming interoperable procedure for which the compiler was passing or
expecting hidden arguments.
In 11.1 Update 2, the compiler has been corrected to no longer pass or expect hidden
arguments. If you wrote C code which assumed that such hidden arguments needed to be
passed you will have to rewrite it and recompile. You may find that in some cases, functions will
need to be converted to subroutines with the result variable passed as an actual argument. We
apologize for the inconvenience, but it is important for correctness and portability to have this
error repaired.
---
Note also the comment that CHARACTER arguments with length other than 1 are "not interoperable" in the eyes of the standard. You can declare the argument as an array of CHARACTER(1) values and still pass a character string to it.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page