Distinguishing between head node and other nodes in a derived type procedure
Am working on a module that looks a little like this:
module linked_elems
type link
integer :: i
double precision :: a
type(link), pointer :: parent=>null()
type(link), pointer :: child=>null()
contains
procedure forward_op
! and all the usual linked list stuff
end type
type(link), target :: head
contains
subroutine forward_op(ln)
class(link), target :: ln
! do stuff to ln%i and ln%a
! if ln == head do extra stuff to ln%i and ln%a
!Operands of comparison operator '==' at (1) are CLASS(link)/TYPE(link)V
!if (ln == head) then
! print *,'ln is head'
!endif
!Error: ‘pointer’ argument of ‘associated’ intrinsic at (1) must be a POINTER
!if (associated(ln, head)) then
! print *, 'ln is head'
!endif
end subroutine
end module
The real module is much more involved, but this illustrates the problem I am having. In subroutine forward_op()
, the head node of the linked list needs to be treated a little differently than any of the other nodes. I am having trouble figuring out how the subroutine can tell whether it is dealing with the head node. In the code I have put in the two approaches I have tried, along with the compilation errors they give.
I can distinguish the head node by the fact that if the code is executed properly, it will be the only node whose parent element is unassociated. But maybe someone is going to come along later and try to put the code to use in, for instance, a way that needs a circular linked list, and then the parent criterion won't work. In any event, it seems to me preferable to find some way to detect the head node based simply on its own existence in memory, apart from the values of any of its elements. Is there a way to do this?
linked-list fortran
add a comment |
Am working on a module that looks a little like this:
module linked_elems
type link
integer :: i
double precision :: a
type(link), pointer :: parent=>null()
type(link), pointer :: child=>null()
contains
procedure forward_op
! and all the usual linked list stuff
end type
type(link), target :: head
contains
subroutine forward_op(ln)
class(link), target :: ln
! do stuff to ln%i and ln%a
! if ln == head do extra stuff to ln%i and ln%a
!Operands of comparison operator '==' at (1) are CLASS(link)/TYPE(link)V
!if (ln == head) then
! print *,'ln is head'
!endif
!Error: ‘pointer’ argument of ‘associated’ intrinsic at (1) must be a POINTER
!if (associated(ln, head)) then
! print *, 'ln is head'
!endif
end subroutine
end module
The real module is much more involved, but this illustrates the problem I am having. In subroutine forward_op()
, the head node of the linked list needs to be treated a little differently than any of the other nodes. I am having trouble figuring out how the subroutine can tell whether it is dealing with the head node. In the code I have put in the two approaches I have tried, along with the compilation errors they give.
I can distinguish the head node by the fact that if the code is executed properly, it will be the only node whose parent element is unassociated. But maybe someone is going to come along later and try to put the code to use in, for instance, a way that needs a circular linked list, and then the parent criterion won't work. In any event, it seems to me preferable to find some way to detect the head node based simply on its own existence in memory, apart from the values of any of its elements. Is there a way to do this?
linked-list fortran
Why do you needclass(link)
to be target and not pointer? If it wastype()
, you should still be able to make a pointer tolink
:link_p => link
and do the associated checkassociated(link_p, head)
. But the whole design with one single fixed head looks strange. You can probably always takecptr
s, convert them to integers and compare those...
– Vladimir F
Jan 2 at 19:01
@VladimirF Making class(link) a pointer is a complete no-go. Regardless of whether I do any comparisons at all, the compiler tells me that the argument to that routine cannot be a pointer.
– bob.sacamento
Jan 2 at 19:05
1
Either the subroutine needs to be told it's dealing with the head node or to figure it out for itself. You could achieve the former by adding a logical field (perhaps calledis_head
) to the node. If that doesn't float your boat and you want to go with the subroutine figuring things out for itself, perhaps have the head node point to itself as its ownparent
.
– High Performance Mark
Jan 2 at 19:06
The head bode can be identified by having null parent (or maybe by being parent of itself). The null parent approach is the more reasonable, for me. It also makes obvious if a branch is removed from a tree, is becomes the root of a new tree and vice versa
– Rodrigo Rodrigues
Jan 2 at 19:22
add a comment |
Am working on a module that looks a little like this:
module linked_elems
type link
integer :: i
double precision :: a
type(link), pointer :: parent=>null()
type(link), pointer :: child=>null()
contains
procedure forward_op
! and all the usual linked list stuff
end type
type(link), target :: head
contains
subroutine forward_op(ln)
class(link), target :: ln
! do stuff to ln%i and ln%a
! if ln == head do extra stuff to ln%i and ln%a
!Operands of comparison operator '==' at (1) are CLASS(link)/TYPE(link)V
!if (ln == head) then
! print *,'ln is head'
!endif
!Error: ‘pointer’ argument of ‘associated’ intrinsic at (1) must be a POINTER
!if (associated(ln, head)) then
! print *, 'ln is head'
!endif
end subroutine
end module
The real module is much more involved, but this illustrates the problem I am having. In subroutine forward_op()
, the head node of the linked list needs to be treated a little differently than any of the other nodes. I am having trouble figuring out how the subroutine can tell whether it is dealing with the head node. In the code I have put in the two approaches I have tried, along with the compilation errors they give.
I can distinguish the head node by the fact that if the code is executed properly, it will be the only node whose parent element is unassociated. But maybe someone is going to come along later and try to put the code to use in, for instance, a way that needs a circular linked list, and then the parent criterion won't work. In any event, it seems to me preferable to find some way to detect the head node based simply on its own existence in memory, apart from the values of any of its elements. Is there a way to do this?
linked-list fortran
Am working on a module that looks a little like this:
module linked_elems
type link
integer :: i
double precision :: a
type(link), pointer :: parent=>null()
type(link), pointer :: child=>null()
contains
procedure forward_op
! and all the usual linked list stuff
end type
type(link), target :: head
contains
subroutine forward_op(ln)
class(link), target :: ln
! do stuff to ln%i and ln%a
! if ln == head do extra stuff to ln%i and ln%a
!Operands of comparison operator '==' at (1) are CLASS(link)/TYPE(link)V
!if (ln == head) then
! print *,'ln is head'
!endif
!Error: ‘pointer’ argument of ‘associated’ intrinsic at (1) must be a POINTER
!if (associated(ln, head)) then
! print *, 'ln is head'
!endif
end subroutine
end module
The real module is much more involved, but this illustrates the problem I am having. In subroutine forward_op()
, the head node of the linked list needs to be treated a little differently than any of the other nodes. I am having trouble figuring out how the subroutine can tell whether it is dealing with the head node. In the code I have put in the two approaches I have tried, along with the compilation errors they give.
I can distinguish the head node by the fact that if the code is executed properly, it will be the only node whose parent element is unassociated. But maybe someone is going to come along later and try to put the code to use in, for instance, a way that needs a circular linked list, and then the parent criterion won't work. In any event, it seems to me preferable to find some way to detect the head node based simply on its own existence in memory, apart from the values of any of its elements. Is there a way to do this?
linked-list fortran
linked-list fortran
asked Jan 2 at 18:43
bob.sacamentobob.sacamento
2,66332863
2,66332863
Why do you needclass(link)
to be target and not pointer? If it wastype()
, you should still be able to make a pointer tolink
:link_p => link
and do the associated checkassociated(link_p, head)
. But the whole design with one single fixed head looks strange. You can probably always takecptr
s, convert them to integers and compare those...
– Vladimir F
Jan 2 at 19:01
@VladimirF Making class(link) a pointer is a complete no-go. Regardless of whether I do any comparisons at all, the compiler tells me that the argument to that routine cannot be a pointer.
– bob.sacamento
Jan 2 at 19:05
1
Either the subroutine needs to be told it's dealing with the head node or to figure it out for itself. You could achieve the former by adding a logical field (perhaps calledis_head
) to the node. If that doesn't float your boat and you want to go with the subroutine figuring things out for itself, perhaps have the head node point to itself as its ownparent
.
– High Performance Mark
Jan 2 at 19:06
The head bode can be identified by having null parent (or maybe by being parent of itself). The null parent approach is the more reasonable, for me. It also makes obvious if a branch is removed from a tree, is becomes the root of a new tree and vice versa
– Rodrigo Rodrigues
Jan 2 at 19:22
add a comment |
Why do you needclass(link)
to be target and not pointer? If it wastype()
, you should still be able to make a pointer tolink
:link_p => link
and do the associated checkassociated(link_p, head)
. But the whole design with one single fixed head looks strange. You can probably always takecptr
s, convert them to integers and compare those...
– Vladimir F
Jan 2 at 19:01
@VladimirF Making class(link) a pointer is a complete no-go. Regardless of whether I do any comparisons at all, the compiler tells me that the argument to that routine cannot be a pointer.
– bob.sacamento
Jan 2 at 19:05
1
Either the subroutine needs to be told it's dealing with the head node or to figure it out for itself. You could achieve the former by adding a logical field (perhaps calledis_head
) to the node. If that doesn't float your boat and you want to go with the subroutine figuring things out for itself, perhaps have the head node point to itself as its ownparent
.
– High Performance Mark
Jan 2 at 19:06
The head bode can be identified by having null parent (or maybe by being parent of itself). The null parent approach is the more reasonable, for me. It also makes obvious if a branch is removed from a tree, is becomes the root of a new tree and vice versa
– Rodrigo Rodrigues
Jan 2 at 19:22
Why do you need
class(link)
to be target and not pointer? If it was type()
, you should still be able to make a pointer to link
: link_p => link
and do the associated check associated(link_p, head)
. But the whole design with one single fixed head looks strange. You can probably always take cptr
s, convert them to integers and compare those...– Vladimir F
Jan 2 at 19:01
Why do you need
class(link)
to be target and not pointer? If it was type()
, you should still be able to make a pointer to link
: link_p => link
and do the associated check associated(link_p, head)
. But the whole design with one single fixed head looks strange. You can probably always take cptr
s, convert them to integers and compare those...– Vladimir F
Jan 2 at 19:01
@VladimirF Making class(link) a pointer is a complete no-go. Regardless of whether I do any comparisons at all, the compiler tells me that the argument to that routine cannot be a pointer.
– bob.sacamento
Jan 2 at 19:05
@VladimirF Making class(link) a pointer is a complete no-go. Regardless of whether I do any comparisons at all, the compiler tells me that the argument to that routine cannot be a pointer.
– bob.sacamento
Jan 2 at 19:05
1
1
Either the subroutine needs to be told it's dealing with the head node or to figure it out for itself. You could achieve the former by adding a logical field (perhaps called
is_head
) to the node. If that doesn't float your boat and you want to go with the subroutine figuring things out for itself, perhaps have the head node point to itself as its own parent
.– High Performance Mark
Jan 2 at 19:06
Either the subroutine needs to be told it's dealing with the head node or to figure it out for itself. You could achieve the former by adding a logical field (perhaps called
is_head
) to the node. If that doesn't float your boat and you want to go with the subroutine figuring things out for itself, perhaps have the head node point to itself as its own parent
.– High Performance Mark
Jan 2 at 19:06
The head bode can be identified by having null parent (or maybe by being parent of itself). The null parent approach is the more reasonable, for me. It also makes obvious if a branch is removed from a tree, is becomes the root of a new tree and vice versa
– Rodrigo Rodrigues
Jan 2 at 19:22
The head bode can be identified by having null parent (or maybe by being parent of itself). The null parent approach is the more reasonable, for me. It also makes obvious if a branch is removed from a tree, is becomes the root of a new tree and vice versa
– Rodrigo Rodrigues
Jan 2 at 19:22
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54011556%2fdistinguishing-between-head-node-and-other-nodes-in-a-derived-type-procedure%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54011556%2fdistinguishing-between-head-node-and-other-nodes-in-a-derived-type-procedure%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Why do you need
class(link)
to be target and not pointer? If it wastype()
, you should still be able to make a pointer tolink
:link_p => link
and do the associated checkassociated(link_p, head)
. But the whole design with one single fixed head looks strange. You can probably always takecptr
s, convert them to integers and compare those...– Vladimir F
Jan 2 at 19:01
@VladimirF Making class(link) a pointer is a complete no-go. Regardless of whether I do any comparisons at all, the compiler tells me that the argument to that routine cannot be a pointer.
– bob.sacamento
Jan 2 at 19:05
1
Either the subroutine needs to be told it's dealing with the head node or to figure it out for itself. You could achieve the former by adding a logical field (perhaps called
is_head
) to the node. If that doesn't float your boat and you want to go with the subroutine figuring things out for itself, perhaps have the head node point to itself as its ownparent
.– High Performance Mark
Jan 2 at 19:06
The head bode can be identified by having null parent (or maybe by being parent of itself). The null parent approach is the more reasonable, for me. It also makes obvious if a branch is removed from a tree, is becomes the root of a new tree and vice versa
– Rodrigo Rodrigues
Jan 2 at 19:22