Many INTENT(OUT) warnings (warning #6843) from generated code created by the Fortran Module wizard

Many INTENT(OUT) warnings (warning #6843) from generated code created by the Fortran Module wizard

When I compile Fortran interface code that is generated by the Fortran Module wizard when it parses our COM type library I am getting many of the following warning messages:

warning #6843: A dummy argument with an explicit INTENT(OUT) declaration is not given an explicit value.

And example of one of the functions that is generating this warning message (for nUomGroupID) is:

INTEGER(2) FUNCTION IComponentFile_GetDataUnits($OBJECT, nUomGroupID, $STATUS)
     IMPLICIT NONE    
     INTEGER(INT_PTR_KIND()), INTENT(IN)    :: $OBJECT     ! Object Pointer
     !DEC$ ATTRIBUTES VALUE    :: $OBJECT
     INTEGER(2), INTENT(OUT), VOLATILE    :: nUomGroupID    
     !DEC$ ATTRIBUTES REFERENCE    :: nUomGroupID
     INTEGER(4), INTENT(OUT), OPTIONAL    :: $STATUS     ! Method status
     !DEC$ ATTRIBUTES REFERENCE            :: $STATUS
     INTEGER(2), VOLATILE :: $RETURN
     INTEGER(4) $$STATUS
     INTEGER(INT_PTR_KIND()) invokeargs
     invokeargs = AUTOALLOCATEINVOKEARGS()
     CALL AUTOADDARG(invokeargs, '$RETURN', $RETURN)
     CALL AUTOADDARG(invokeargs, '$ARG1', nUomGroupID, AUTO_ARG_OUT)
     $$STATUS = AUTOINVOKE($OBJECT, 16, invokeargs)
     IF (PRESENT($STATUS)) $STATUS = $$STATUS
     IComponentFile_GetDataUnits = $RETURN
     CALL AUTODEALLOCATEINVOKEARGS (invokeargs)
END FUNCTION IComponentFile_GetDataUnits

What must I do to eliminate these warnings? I do not want to suppress the warning completely because I want to know when the compiler thinks we have not properly set a return value with INTENT(OUT). Is there something I should change in the COM object to prevent this warning, or must I modify the generated module code after it is generated?

 

publicaciones de 14 / 0 nuevos
Último envío
Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.

I'm sorry about the code example; I didn't know how to do syntax highlighting. Here's another go at showing the example of a function that compiles with the INTENT(OUT) warning message:


INTEGER(2) FUNCTION IComponentFile_GetDataUnits($OBJECT, nUomGroupID, $STATUS)

	IMPLICIT NONE
	INTEGER(INT_PTR_KIND()), INTENT(IN)	:: $OBJECT	 ! Object Pointer

	!DEC$ ATTRIBUTES VALUE	:: $OBJECT

	INTEGER(2), INTENT(OUT), VOLATILE	:: nUomGroupID

	!DEC$ ATTRIBUTES REFERENCE	:: nUomGroupID

	INTEGER(4), INTENT(OUT), OPTIONAL	:: $STATUS	 ! Method status

	!DEC$ ATTRIBUTES REFERENCE			:: $STATUS

	INTEGER(2), VOLATILE :: $RETURN

	INTEGER(4) $$STATUS

	INTEGER(INT_PTR_KIND()) invokeargs

	invokeargs = AUTOALLOCATEINVOKEARGS()

	CALL AUTOADDARG(invokeargs, '$RETURN', $RETURN)

	CALL AUTOADDARG(invokeargs, '$ARG1', nUomGroupID, AUTO_ARG_OUT)

	$$STATUS = AUTOINVOKE($OBJECT, 16, invokeargs)

	IF (PRESENT($STATUS)) $STATUS = $$STATUS

	IComponentFile_GetDataUnits = $RETURN

	CALL AUTODEALLOCATEINVOKEARGS (invokeargs)

END FUNCTION IComponentFile_GetDataUnits

 

I've seen this myself. It's not always clear to me if the issue is that the COM object incorrectly describes the argument or if the module wizard is incorrectly adding intent(out). It's something I have not found the time to investigate so far. I suggest hand-editing the generated source to use INOUT instead of OUT where appropriate.

Steve - Intel Developer Support

To my thinking (at the risk of being shot down in flames surely the reference attribute and intent(out) are mutually exclusive so the compiler should generate an error not a warning?

I don't think intent(out) and the reference attribute are mutually exclusive. In this case the purpose of the IComponentFile_GetDataUnits() function is to set the nUomGroupID and pass this back to the calling subroutine via the function's argument list. The return value of  IComponentFile_GetDataUnits() is an integer that indicates if the COM functions were able to successfully retrieve the value.

Therefore nUomGroupID must be a reference, and the intention is that the function will explicity set the value of nUomGroupID. So nUomGroupID is indeed a reference and INTENT(OUT).

It seems to me the compiler is not recognizing that 

CALL AUTOADDARG(invokeargs, '$ARG1', nUomGroupID, AUTO_ARG_OUT)

will set the value of nUomGroupID.

Or, as Steve indicates, the COM objects may not be describing the argument in a way that can be interpreted well by the Fortran Module Wizard. Or the Module Wizard may not be correctly interpreting the argument.

In any case I have decided to isolate all of our generated Fortran module code into its own static library and using the /Qdiag-disable:6843 additional command line option to suppress this particular warning. This way all of the human generated code still must behave with the INTENT(OUT) specification and I do not need to develop and maintain a module wizard post-processor.

d'oh!  Brain fade! I saw reference and read Value! :-)

The Interface for AUTOADDARG is available to IComponentFile_GetDataUnits via "USE IFAUTO". AUTOADDARG has Intent(in) for nUomGroupID therefore as nUomGroupID is intent(out) it is potentially initialised on entry to IComponentFile_GetDataUnits and remains so! You should get runtime errors with 'check initialised on' The compiler is a bit late in the day the wizard should have thrown up an error or perhaps by option added some 'error' comments to the source output perhaps if is is a consequence of a poorly written COM object.

As Steve suggests changing to INTENT(INOUT) would be safer

The calls to AUTOAddArg() build the argument list to the COM function into invokeargs and also define the intent for each of the arguments. In this case the intent for nUomGroupID,  AUTO_ARG_OUT, means that when AUTOInvoke() is called to execute the COM function, nUomGroupID will be overwritten by the function.

nUomGroupID is properly set by this function and is not set to an unintialized/compiler initialized value when IComponentFile_GetDataUnits() is called.  

Defining INTENT(INOUT) for nUomGroupID isn't really correct for the intention -- the function will not do anything with an input value of nUomGroupID because it is only returning a value from a data collection.

I understand the AUTO_ARG_OUT parameter is also defining an intent for the data flow control within the application , in which case it suggests that the error is the INTENT(IN)  associated with the 'value' parameter in the interface for  AUTOADDARG  in IFCOM. If it where INOUT or not specified you would not get a warning I would expect.

 

 

I think that INTENT(IN) for the 'value' parameter in interface AUTOADDARG is correct. AUTOADDARG should not mutate 'value' -- it is only adding 'value's reference to 'invoke_args.'

It seems to me the compiler ought to recognize that the combination of

[fortran]
INTEGER(2), INTENT(OUT), VOLATILE :: nUomGroupID
!DEC$ ATTRIBUTES REFERENCE :: nUomGroupID
CALL AUTOADDARG(invokeargs, '$ARG1', nUomGroupID, AUTO_ARG_OUT)
$$STATUS = AUTOINVOKE($OBJECT, 76, invokeargs)
[\fortran]

means that the COM object is responsible for setting nUomGroupID and so will not be set explicitly with the  = assignment operator.

However, I'm pretty ignorant (and often amazed) of how the Intel compiler's magic works, so perhaps recognizing this situation isn't possible or not worth the overhead (our generated module code already takes a relatively long time to compile).

If all INTENT(OUT) means is that an explicit = assignment operator is expected by the compiler, then perhaps the module wizard should omit the INTENT(OUT) in these scenarios. 

For now, in practice, I really do think the best option is to isolate generated code into a static library and suppress this particular message if you desire having no compile warnings for a good build. Hand-editing or post-processing the generated code is less desirable, especially if you must do this frequently -- it requires you to maintain a written procedure or post-processor code which get stale quickly. 

 I am not all all convinced. In general AUTOADDARG could  supply a value to the COM interface (IN) call, get a value (OUT) or both (INOUT) however the interface it says INTENT(IN) in all cases! What the compiler actually does might not be a problem in terms of the end result being OK but I am of the opinion that the code as is should generate an error. I think the lack of an explicit assignment that the compiler can see (it all happens in some external routines) may suppress the error being generated in this case hence the intent is ignored and just a warning given.

 I think I would like some further input from Dr Fortran to clarify,

 

I doubt the combination of my Intel Karate level and technical diction will be enough to convince you but I'll try! And it's always reassuring to get an official prognosis from the Doctor.

AUTOADDARG is not calling the COM interface. AUTOADDARG is building\appending\adding the arguments that will eventually be passed to the COM object when the object is eventually invoked. This is what invokeargs is -- the argument list built by a series of AUTOADDARG calls that the COM object needs to execute.

Once all of the arguments (their name, their value, and their intended behavior) are added to invokeargs, the AUTOINVOKE() function is what actually invokes\calls the COM object.

In the case of 

CALL AUTOADDARG(invokeargs, '$ARG1', nUomGroupID, AUTO_ARG_OUT)

AUTOADDARG adds a reference to nUomGroupID to invokeargs, but does not change the value of nUomGroupID.

When

$$STATUS = AUTOINVOKE($OBJECT, 76, invokeargs)

is executed, the COM object is invoked. Because invokeargs contains a reference to nUomGroupID, the COM object can modify the value of nUomGroup. The value of nUomGroupID is changed by the AUTOINVOKE function, not the AUTOADDARG subroutine.

So I think all of the INTENTs are correct and that there should not be a compile error.

 

OK. The innermost  workings of AUTO are beyond my current knowledge. Your explanation has detail, is articulate and sounds credible so I will accept that at face value, ninja status or not.. That being the case it would appear to me that the AUTOADDARG interface statement is not being used in the normal way and is being processes as a special case 'template' for doing stuff. The norms have just gone out of the window, and the INTENT in that interface is being used (or indeed not used) in a non-standard way.

I just had a look at the COM interfaces I use for excel (provided by Intel) and everything has intent specified other than the cases like your example where the intent is notably absent!  So either the module wizard has changed, it is a function of the program being processed, or the excel case has been edited......

The Excel.f90 in the sample has been edited.

I am away from the office this week and will try to look into this next week.

Steve - Intel Developer Support

Deje un comentario

Por favor inicie sesión para agregar un comentario. ¿No es socio? Únase ya