Does VALUE (Fortran 2003 introduction) attribute for a type make compiler directive (!DEC$) superfluous?

Does VALUE (Fortran 2003 introduction) attribute for a type make compiler directive (!DEC$) superfluous?

Is the VALUE attribute introduced as part of Fortran 2003 standard exactly the same as the compiler directive !DEC$ ATTRIBUTES VALUE?  Or are there some differences that the users should keep in mind?

   SUBROUTINE Foo(SomeData, ItsSize)
      !DEC$ ATTRIBUTES VALUE :: ItsSize
   
      USE MyTypeMod, ONLY: MYTYPE, MYTYPE_DEFAULT
 
      IMPLICIT NONE
     
      !.. Argument list
      INTEGER, INTENT(IN), VALUE  :: ItsSize
      TYPE(MYTYPE), INTENT(INOUT) :: SomeData(ItsSize)
 
      !.. Locals
      INTEGER :: I
 
      
      InitData: DO I = 1, ItsSize
      
          SomeData(I) = MYTYPE_DEFAULT
          
      END DO InitData
      
      !..
      RETURN
      
   END SUBROUTINE Foo
 

The specific error message is:

 

------ Build started: Project: TestFoo, Configuration: Release|Win32 ------
 
Compiling with Intel(R) Visual Fortran Compiler XE 14.0.0.103 [IA-32]...
Foo.f90
I:TestFoosorFoo.f90(32): error #7280: This symbol has multiply declared VALUE attributes.   [ITSSIZE]
compilation aborted for I:TestFoosorFoo.f90 (code 1)
 
Build log written to  "file://I:TestFooReleaseWin32TestFoo_BuildLog.htm"
Foo - 2 error(s), 0 warning(s)

 

Thanks,

9 帖子 / 0 全新
最新文章
如需更全面地了解编译器优化,请参阅优化注意事项

Long story...

Late in the development cycle of 14.0 we realized that we had misimplemented the F2003 VALUE attribute, making it a simple alias for ATTRIBUTES VALUE. That is not correct (unless the routine has BIND(C). But when we went to fix it, we found that some of the library modules (IFCORE, IFPORT, etc.) were relying on the old behavior and it was too late to fix those as well. So what we did was keep the default implementation the same and added an option /assume:std_value which gets you the standard's semantics. (You also get this with /standard-semantics.)

So what are the standard's semantics? For a non-BIND(C) routine, it's that an anonymous, redefinable copy of the actual argument is made and passed to the called procedure. (NOT "by value".) The called procedure can modify the argument but any changes are discarded on return. In essence, it's a lot like passing the argument in parentheses.

I suggest you compile with /standard-semantics (in Visual Studio, this is Fortran > Language > Enable F2003 Semantics) and you'll get the behavior I think you want, though I don't see any assignment to ItsSize that would make the F03 VALUE attribute useful.

An alternative if you really want pass-by-value is to make the subroutine BIND(C). Note that an explicit interface is required to be visible to the caller if you give an argument the VALUE attribute (in either method.)

Steve - Intel Developer Support

For scalars, in the absence of additional attributes (OPTIONAL, for example), what is it that means pass by value doesn't end up giving you what VALUE requires in a standard sense?

IanH, from Steve's "long story"...

!DEC$ ATTRIBUTES VALUE :: foo

passes a reference to a newly created anonymous redefinable copy of the actual argument, add OPTIONAL to the attribute list, then this means a NULL reference would indicate lack of value. Whereas

scalar, INTENT(in), VALUE :: foo

Places the the "newly created anonymous redefinable copy of the actual argument" into the fastcall argument register, or location on stack where reference pointer would normally be held, thus making it impossible to disambiguate between not present and 0.

Jim Dempsey

www.quickthreadprogramming.com

引文:

Steve Lionel (Intel) 写道:

Long story...

Late in the development cycle of 14.0 we realized that we had misimplemented the F2003 VALUE attribute, making it a simple alias for ATTRIBUTES VALUE. That is not correct (unless the routine has BIND(C). But when we went to fix it, we found that some of the library modules (IFCORE, IFPORT, etc.) were relying on the old behavior and it was too late to fix those as well. So what we did was keep the default implementation the same and added an option /assume:std_value which gets you the standard's semantics. (You also get this with /standard-semantics.)

So what are the standard's semantics? For a non-BIND(C) routine, it's that an anonymous, redefinable copy of the actual argument is made and passed to the called procedure. (NOT "by value".) The called procedure can modify the argument but any changes are discarded on return. In essence, it's a lot like passing the argument in parentheses.

I suggest you compile with /standard-semantics (in Visual Studio, this is Fortran > Language > Enable F2003 Semantics) and you'll get the behavior I think you want, though I don't see any assignment to ItsSize that would make the F03 VALUE attribute useful.

An alternative if you really want pass-by-value is to make the subroutine BIND(C). Note that an explicit interface is required to be visible to the caller if you give an argument the VALUE attribute (in either method.)

Thanks Steve.

My interest is in interoperability with C and I did mean to include the BIND(C) statement in the included example - thanks for catching my omission.  I now realize other aspects like STDCALL, REFERENCE, ALIAS, etc. can also collide with BIND(C).

So if I understand correctly, with BIND(C), I won't need the compiler directive as well as the /standard-semantics compiler setting i.e., if all I want is interoperaility with a C value-type argument - is that right?

Separately, a couple of questions about enabling F2003 standard-semantics:

1) Is there an explanation somewhere in documentation about all the things that can occur if this setting is applied, especially since all the Fortran 2003 have not yet been implemented?  I've been somewhat scared of using it since I don't know of the consequences of doing so.

2) Is there an equivalent option for Fortran 2008 semantics, or is the 2008 update more of a minor one that it is not applicable?

Thanks,

(I think its the other way around.)

I can understand why the convention might change for VALUE, OPTIONAL (noting that the caller will always know that those attributes apply to the dummy, so it can construct the call appropriately - and an alternative convention might be to have a separate flag that indicates argument presence), but for small types (that fit in registers) which don't have OPTIONAL I would have thought !DEC$ VALUE and VALUE could be equivalent.

Just guessing - was it a complication that arises from pointer association?  Did you just want to keep procedure internals consistent in the face of OPTIONAL or types that don't fit in registers?

I thought (not based on anything authoritative - I might have just imagined this after a glass too many) the rules for VALUE were written such that pass-by-value was a possible implementation option, in some cases at least.  If not, it seems a bit of a pointless feature for non-bind(c) procedures.

With BIND(C), the standard VALUE attribute means pass/receive by value. In F2003/2008, one is allowed to combine VALUE with OPTIONAL as long as BIND(C) isn't used, but the TS29113 "Enhanced C Interoperability" spec relaxes that.

The documentation for /standard-semantics lists all the things it does, and this is also spelled out at the bottom of http://software.intel.com/en-us/articles/intel-fortran-compiler-support-... The purpose of this option is to change the compiler's default semantics when those are old and incompatible with F2003 and newer (including F2008).

I admit that it's not too common that one would want to use VALUE without BIND(C), but it does have a meaning and could be useful in some circumstances.

Steve - Intel Developer Support

Thanks Steve.  Regarding your comment:

引文:

In F2003/2008, one is allowed to combine VALUE with OPTIONAL as long as BIND(C) isn't used, but the TS29113 "Enhanced C Interoperability" spec relaxes that.

How does Intel view TS29113?  To be handled separately as part of some future implementation (Fortran 201x standard, etc.)?  Or to be included on the queue for the ongoing 2003/2008 feature implementations?

Regards,

 

TS29113 is something we know is important but isn't currently being actively implemented. Our development plate is already full for the next year, but I hope we'll get to it after that. I have a side project to create a library including the routines you'd call from C that one could use to get at least some of the functionality.

Steve - Intel Developer Support

发表评论

登录添加评论。还不是成员?立即加入