- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi
We updated Intel Visual Fortran Composer XE 2011 to XE 2013 SP1 and Visual Studio 2008 to 2010 Premium.
It seems that the VALUE attribute is not working anymore and it's not recognized as a special word in Visual Studio.
Here's small sample:
Fuction specification:
integer(4) function csta_sect_num(selected, mode) use, intrinsic :: ISO_C_BINDING use CSE_STA_USER IMPLICIT NONE LOGICAL(C_BOOL), VALUE, intent(in) :: selected integer(C_INT), optional, intent(in) :: mode ...
Interface:
interface csta_sect_num function csta_sect_num (selected, mode) result (num) use, intrinsic :: ISO_C_BINDING implicit none logical(C_BOOL), VALUE, intent(in) :: selected integer(C_INT), optional, intent(in) :: mode integer(C_INT) :: num end function csta_sect_num end interface csta_sect_num
C++ declaration:
extern "C" int csta_sect_num (bool selected, int * mode = 0);
C++ function call:
bool sel = false; int num = csta_sect_num(sel);
The selected argument gets passed by reference and will crash the program.
If I add
BIND(C,NAME='csta_sect_num')
to the function definition and to its interface, it will work, or if I add the
!DIR$ ATTRIBUTES VALUE :: selected
compiler directive to the parameter, it will also work.
Shouldn't the VALUE attribute work also without neither of these additions?
br
Janne
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You need BIND(C) on the declaration of the routine in Fortran. But my guess is that you also have /standard-semantics enabled.
We had incorrectly implemented VALUE - without BIND(C), it does NOT mean pass-by-value. We left the default behavior the old one, but if you asked for Fortran 2003 semantics, you get the standard-required behavior (which is to pass an anonymous copy by reference.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve and thanks for your answer!
The Fortran 2003 semantics is turned on.
If BIND(C) is used, the routine works when called from Fortran and from C++. From C++'s point of view, it's still kind of by value, right? What I mean is that the Fortran compiler magically makes things work when the routine is called by value from C++ which is exactly what we want. :)
- Janne
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There's no magic involved.
If the procedure has the BIND(C) attribute, specifying VALUE means pass and receive by value. If you call a Fortran routine declared this way, the compiler is supposed to make a definable copy of the dummy argument.
If the procedure does NOT have BIND(C) but the argument has VALUE, then the effect is that a definable copy is passed by reference.
We mis-implemented this many years ago so that the standard VALUE attribute was treated exactly like ATTRIBUTES VALUE. For 14.0, we fixed this, but for various reasons made it not the default behavior. To get the standard behavior, you need to specify /assume:std-value or /standard-semantics. In a future release we may make the standard behavior the default.
You probably want BIND(C) on the routine interface so you get pass-by-value from either Fortran or C++.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, thanks for the clarification. This makes sense. The good thing is that BIND(C) works also when called from Fortran and we don't need to make two different versions of the same function for C++ and Fortran callers.
- Janne

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