Distinguishing between head node and other nodes in a derived type procedure












2















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?










share|improve this question























  • 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 cptrs, 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 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


















2















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?










share|improve this question























  • 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 cptrs, 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 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
















2












2








2








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?










share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 2 at 18:43









bob.sacamentobob.sacamento

2,66332863




2,66332863













  • 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 cptrs, 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 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





















  • 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 cptrs, 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 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



















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 cptrs, 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 cptrs, 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














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
});


}
});














draft saved

draft discarded


















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
















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

Npm cannot find a required file even through it is in the searched directory