- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi to all. Is there any approach to define a derived type parameter whose components are decorated with PRIVATE attribute ? Like:
module test implicit none type :: my private integer :: a contains ...........some type-bound procedures....... end type my type(my), parameter :: const_my = my(a=100) !!! This is wrong here !!! end module test
If not, any suggestions that I could accomplish things like this, Thanks for reply.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If there is nothing in the contains section (or there is no contains section at all), the compiler does not complain. Can you show us the error messages?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So you want a parameter with procedures... that could potentially modify the parameter?
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Arjen Markus wrote:
If there is nothing in the contains section (or there is no contains section at all), the compiler does not complain. Can you show us the error messages?
It seems that I have made a little mistake here. when the error occurs, the defination of the parameter is within the program scope but not the module scope, and it generates the error of "error #6053: Structure constructor may not have fields with the PRIVATE attribute".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
So you want a parameter with procedures... that could potentially modify the parameter?
Jim Dempsey
It's not like that, Jim. What I mean to do is to accomplish things just like a C# class constant.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can't have a structure constructor that has values associated with components that aren't accessible. The whole point of private components is that, outside of the definition scope, those components are not visible.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Blane J. wrote:
.. What I mean to do is to accomplish things just like a C# class constant.
I presume the interest is in a feature like so:
class Greeter { .. const string Greeting = "Hello World!" .. }
If that's the case, then it is not supported as such by Fortran.
What is your use case? If you can explain it here, perhaps someone might be able to offer workarounds you have not thought of and which you might like. You may also have your friends at Intel contemplate such a capability in a future Fortran standard revision.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve Lionel (Intel) wrote:
You can't have a structure constructor that has values associated with components that aren't accessible. The whole point of private components is that, outside of the definition scope, those components are not visible.
Thanks, Steve. So here at the moment the whole module is the defination scope.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FortranFan wrote:
What is your use case? If you can explain it here, perhaps someone might be able to offer workarounds you have not thought of and which you might like. You may also have your friends at Intel contemplate such a capability in a future Fortran standard revision.
What I exactly want is to define a derived type parameter and the derived type have all private components. Such as:
type :: Time private integer(8) :: ticks contains ! Some procedures to process the calculation. end type Time type(Time), parameter :: MaxValue = Time(HUGE(0_8))
Accroding to what we discuessed above, the parameter defination should be within the module scope, and any scope else will return an comiple time, Thanks FortranFan.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This works fine as long as the reference to the private component is in the module. If the type is made available by use association, you can't reference the private component.
The following compiles without errors:
module timemod type :: Time private integer(8) :: ticks !contains ! Some procedures to process the calculation. end type Time type(Time), parameter :: MaxValue = Time(HUGE(0_8)) end module timemod program foo use timemod type(time) :: t t = MaxValue end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve Lionel (Intel) wrote:
This works fine as long as the reference to the private component is in the module. If the type is made available by use association, you can't reference the private component.
The following compiles without errors:
module timemod type :: Time private integer(8) :: ticks !contains ! Some procedures to process the calculation. end type Time type(Time), parameter :: MaxValue = Time(HUGE(0_8)) end module timemod program foo use timemod type(time) :: t t = MaxValue end
And till now I had the clear view on it. Thanks Steve.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
In your example, where MaxValue is declared as parameter, are type contained procedures still callable? And if so, what about a contained procedure that modifies ticks?
IOW while
MaxValue = newValue
will be prohibited by the compiler, how about:
result = MaxValue%AddToTicksFunction(deltaTicks)
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Perfectly fine to call a type-bound procedure that is accessible, no matter what it does. Private accessibility means that you can't touch that component directly. You can always call into a module procedure to do whatever it wants. Basically, any context where you could name the component, even where the name is optional, is not permitted.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That is not what I asked. Let me rephrase the question. The example given had:
type(Time), parameter :: MaxValue = Time(HUGE(0_8))
Where parameter implies to the compiler that the value is a compile time constant (literal). In the code section
MaxValue = newValue
will be prohibited by the compiler, how about:
result = MaxValue%AddToTicksFunction(deltaTicks)
Then to complete the question, because MaxValue was declared to the compiler as parameter, then what is the value of
result = MaxValue%getTicks()
when issued after the result = MaxValue%AddToTicksFunction(deltaTicks)?
Is it the compile time parameter value, or the runtime resultant value?
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
result = MaxValue%AddToTicksFunction(deltaTicks) is fine. The ticks component is not referenced.
result = MaxValue%getTicks() is also legal - and in fact a reasonable way of doing information hiding with get/set procedures.
Don't get hung up on MaxValue being a PARAMETER - in these contexts it is simply a way to reference the derived type, though it will become the "passed object" dummy argument.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
That is not what I asked. Let me rephrase the question. The example given had:
type(Time), parameter :: MaxValue = Time(HUGE(0_8))Where parameter implies to the compiler that the value is a compile time constant (literal). In the code section
MaxValue = newValue
will be prohibited by the compiler, how about:
result = MaxValue%AddToTicksFunction(deltaTicks)
Then to complete the question, because MaxValue was declared to the compiler as parameter, then what is the value of
result = MaxValue%getTicks()
when issued after the result = MaxValue%AddToTicksFunction(deltaTicks)?
Is it the compile time parameter value, or the runtime resultant value?
Jim Dempsey
It hasn't been specified whether the function referenced by the AddToTicksFunction binding modifies the passed argument. If it doesn't modify the argument (say the dummy argument corresponding to the passed argument is INTENT(IN)) then the call with a named constant as an actual argument corresponding to the passed argument is fine. If it does modify the passed argument then a call with a named constant as the actual argument corresponding to the passed argument is not - if the relevant dummy argument corresponding to the passed argument is INTENT(xxOUT) then the compiler should complain.
It is the same situation as passing the literal constant `1` as an actual argument to a function. If the function doesn't modify the associated dummy argument, all good. If it does modify it, the universe ends, and the compiler might also complain about it.
(Adding something to a "maximum value" will probably have other issues.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ian, Steve,
I though my choice of name of function was self explanatory.
MaxValue%AddToTicksFunction(deltaTicks)
Adds the (to be) dummy argument deltaTicks to the type embodied (and hidden) variable ticks, same as would a setTicks setter function. In this case the (hidden/protected) ticks is modified at runtime. PARAMETERS are (IMHO), well, parameters: immutable compile time "constants". Therefor, the compiler could conceivably use the compile time value of the parameter in lieu of the runtime value of a "variable".
IVF Documentation>>An entity with the PARAMETER attribute must not be a variable, a coarray, or a procedure.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I was commenting only on the legality of the reference, not what such a procedure might do. Ian took that up. Yes, a PARAMETER is not writable, so if the procedure tried updating the passed-object dummy it would fail. That has nothing to do with private components.
As for the restriction you mention, the PARAMETER is not a variable or a procedure. It is a named constant of a derived type that has type-bound procedures associated with it. Nothing wrong with that.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
I though my choice of name of function was self explanatory.
MaxValue%AddToTicksFunction(deltaTicks)
Adds the (to be) dummy argument deltaTicks to the type embodied (and hidden) variable ticks, same as would a setTicks setter function. In this case the (hidden/protected) ticks is modified at runtime.
This is perhaps more a question of style, but I don't write functions with dummy arguments that do not have the INTENT(IN) or VALUE attribute [unless I am interfacing with something that otherwise requires it (WinMain, C api's)]. The equivalent of `setTicks` is always a subroutine, if the add operation was going to mutate its argument, it would also be a subroutine. I know of many others that follow a similar style. The motivation for this style is the specific semantics of function references and the restrictions on statements more generally that are set out in the standard.
Consequently, when I saw AddToTicksFunction, as a function reference, my initial assumption was that you were not modifying the actual argument.
~~~
Overloaded structure constructors (a generic function that has the same name as the type) can be useful in situations where you have private components.
MODULE m IMPLICIT NONE ! Just so things don't get accidentally exposed. PRIVATE TYPE, PUBLIC :: t INTEGER, PRIVATE :: component CONTAINS PROCEDURE :: set PROCEDURE :: get PROCEDURE :: add END TYPE t ! Programmers can overload or hide the compiler provided structure ! constructor. This can be useful when you have private components. INTERFACE t MODULE PROCEDURE t_constructor END INTERFACE t TYPE(t), PARAMETER, PUBLIC :: apple = t(1) CONTAINS SUBROUTINE set(object, value) CLASS(t), INTENT(INOUT) :: object INTEGER, INTENT(IN) :: value object%component = value END SUBROUTINE set FUNCTION get(object) CLASS(t), INTENT(IN) :: object INTEGER :: get get = object%component END FUNCTION get FUNCTION add(left_hand_side, right_hand_side) CLASS(t), INTENT(IN) :: left_hand_side INTEGER, INTENT(IN) :: right_hand_side TYPE(t) :: add add = t(left_hand_side%component + right_hand_side) END FUNCTION add ! Two arguments, just to make it distinguishable from the structure ! constructor. ! ! If this had the exact same signature as the structure constructor, ! then it would effectively hide the structure constructor. For the ! sake of the example I don't want to do this. FUNCTION t_constructor(a, b) INTEGER, INTENT(IN) :: a INTEGER, INTENT(IN) :: b TYPE(t) :: t_constructor t_constructor%component = a + b END FUNCTION t_constructor END MODULE m PROGRAM p USE m IMPLICIT NONE ! Cannot do this - the t in the initializer resolves to the ! structure constructor, and the relevant component is private. ! ! (ifort's error is a bit misleading.) ! TYPE(t), PARAMETER :: a = t(2) ! Cannot do this - the t in the initializer resolves to the ! overload of the structure constructor, and that isn't ! valid in a constant expression. ! TYPE(t), PARAMETER :: b = t(3, 4) ! Can do this - the value of the named constant in this scope ! is the value of the named constant from the module. TYPE(t), PARAMETER :: named_constant = apple TYPE(t) :: variable ! Can do this - the t in the expression resolves to the ! overloaded structure constructor. variable = t(5, 6) ! Can not do this - trying to change a named constant. ! CALL named_constant%set(7) ! Can do this. CALL variable%set(8) ! Can do this - the add function does not change its argument, ! and the left hand side of the assignment is a variable. variable = named_constant%add(9) ! Likewise, both of these are fine. PRINT *, named_constant%get(), variable%get() END PROGRAM p
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>variable = named_constant%add(9)
Not quite what I'd postulated. Consider (untested)
module timemod type :: Time private integer(8) :: ticks contains ! add value to ticks and return the result procedure :: AddToTicksFunction end type Time type(Time), parameter :: MaxValue = Time(HUGE(0_8)) contains ! add value to ticks and return the result function AddToTicksFunction(this, deltaTicks) class(Time), intent(in) :: this integer(8), intent(in):: deltaTicks integer(8) :: AddToTicksFunction this%ticks = this%ticks + deltaTicks AddToTicksFunction = this%ticks end function AddToTicksFunction end module timemod program foo use timemod type(time) :: t t = MaxValue print *,MaxValue%AddToTicksFunction(-1) print *,MaxValue%AddToTicksFunction(-1) end
Note, the code is not modifying the dummy argument. Rather, the object (part of the object called ticks) of which the object (MaxValue) is a parameter, is instructed to be modified. IIF ticks is modifiable, then MaxValue cannot be by definition a PARAMETER. Where was the grammar police when the committee would permit a variable parameter???
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Oh...
I think I see the error in my interpretation. Presumably the intent(in) would prohibit this%ticks =...
Change class(Time),
intent
(
in
) :: this to
class(Time),
intent
(
inout
) :: this
Presumably, the compiler could (would) catch the inout applied to a parameter(ized) type.
Jim Dempsey
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page