- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, everyone. There is a problem a I'm not quite understand about optional dummy argument. Here is the code:
MODULE Test
IMPLICIT NONE
TYPE :: MyType
INTEGER :: a
CONTAINS
GENERIC, PUBLIC :: Set => SetBy2Arguments,&
SetBy3Arguments
PROCEDURE, PASS :: SetBy2Arguments
PROCEDURE, PASS :: SetBy3Arguments
END TYPE MyType
CONTAINS
FUNCTION SetBy2Arguments(this, arg1, arg2)
IMPLICIT NONE
INTEGER :: SetBy2Arguments
CLASS(MyType), INTENT(IN) :: this
INTEGER, INTENT(IN) :: arg1
INTEGER, INTENT(IN) :: arg2
SetBy2Arguments = this%a + arg1 + arg2
RETURN
END FUNCTION SetBy2Arguments
FUNCTION SetBy3Arguments(this, arg1, arg2, arg3)
IMPLICIT NONE
INTEGER :: SetBy3Arguments
CLASS(MyType), INTENT(IN) :: this
INTEGER, INTENT(IN) :: arg1
INTEGER, INTENT(IN) :: arg2
INTEGER, OPTIONAL, INTENT(IN) :: arg3
SetBy3Arguments = this%a + arg1 + arg2 + arg3
RETURN
END FUNCTION SetBy3Arguments
END MODULE Test
When compiling, The compiler generates a warning message saying that:
warning #8449: The type/rank/keyword signature for this specific procedure matches another specific procedure that shares the same generic binding name. [SETBY3ARGUMENTS]
So why are these 2 binding procedures matches each other ? And How is the compiler treat a dummy argument that has an OPTIONAL attribute ? Appriciate any replies, thanks.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Consider a call to SET(arg1, arg2, arg3) from some other part of your code. How does the compiler know whether to direct the call to SetBy2Arguments or to SetBy3Arguments? By looking at the number and types of the actual arguments used. If the optional argument is left out, the remaining three arguments of the latter match exactly with the three arguments of the former. Therefore, the compiler would not be able to decide which to choose -- there would be an ambiguity that it could not resolve.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Given the following code:
TYPE(MyType) :: x PRINT *, x%Set(1, 2)
which specific binding and procedure do you expect to be invoked? Is it going to be `SetBy2Arguments`with all of its arguments, or is if going to be `SetBy3Arguments` with the last optional argument missing?
The two specific bindings are not distinguishable, hence this is not permitted.
Optional arguments are arguments that don't have to be present when the procedure is invoked. Inside a procedure with an optional argument, you can test whether the argument was present or not using the PRESENT intrinsic. If the actual argument was present, then the dummy argument is pretty much just like a normal argument. If the actual argument was not present, then you cannot define or reference the dummy argument, bar using it as the argument to PRESENT, or passing it on as an actual argument to another procedure with a corresponding optional argument.
If the actual argument corresponding to `arg3` was not present in a call to `SetBy3Arguments`, then your code has a problem, as you are including it in the sum regardless of whether the actual argument is present or not. Correct handling of an optional argument would be something like:
FUNCTION SetBy3Arguments(this, arg1, arg2, arg3)
INTEGER :: SetBy3Arguments
CLASS(MyType), INTENT(IN) :: this
INTEGER, INTENT(IN) :: arg1
INTEGER, INTENT(IN) :: arg2
INTEGER, OPTIONAL, INTENT(IN) :: arg3
IF (PRESENT(arg3)) THEN
! arg3 is present, we can reference it.
SetBy3Arguments = this%a + arg1 + arg2 + arg3
ELSE
! arg3 is not present, don't touch it!
SetBy3Arguments = this%a + arg1 + arg2
END IF
END FUNCTION SetBy3Arguments
Edit: mecej4 beat me to it, but I enjoy hearing the sound of my own keyboard.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you all, lanH and mecej4. now I quite understand the compiler's behavior.
PS: I was intended to use the PRESENT intrinsic but only to find it was missing when I've posted. Thanks for your remind, lanH.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page