This binary operation is invalid for this data type, but why ?

This binary operation is invalid for this data type, but why ?

Bild des Benutzers emreka82

I have written a module ( a prt of it shown here) and subroutine inside it, as follows:

  1. module class_mg
  2. type ptr
  3. type(c), pointer :: pp
  4. end type ptr
  5. !............
  6. type c
  7. !............
  8. integer c_no
  9. type(c), pointer :: prnt=>NULL()
  10. type(ptr), pointer :: ng(:)=>NULL()
  11. type(ptr), pointer :: ch(:)=>NULL()
  12. integer compc
  13. !............
  14. end type c
  15. !............
  16. type(c), pointer :: root
  17. !............
  18. !............
  19. contains
  20. recursive subroutine set_ng(c_no, root)
  21. type(c), pointer :: root
  22. if(c_no==0) then
  23. !............
  24. root%ng(3)%pp=>root%prnt%ch(3)%pp
  25. root%ng(2)%pp=>root%prnt%ch(1)%pp
  26. if(root%prnt%ng(1)%pp /= 0 .and. root%prnt%ng(1)%pp%compc==0) then
  27. root%ng(1)%pp=>root%prnt%ng(1)%pp%ch(3)%pp
  28. root%prnt%ng(1)%pp%ch(3)%pp%ng(3)%pp=>root
  29. end if
  30. !............
  31. end if
  32. end subroutine set_ng
  33. end module class_mg

The code fails to compile,  returning the following error message in line 26: error #6355: This binary operation is invalid for this data type.   [PP]

Am I doing something wrong? Thanks

Emre K.

11 Beiträge / 0 neu
Letzter Beitrag
Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.
Bild des Benutzers mecej4

if(root%prnt%ng(1)%pp /= 0

attempts to compare a value of type integer to a component of type pointer variable of type(c), and

root%prnt%ng(1)%pp%compc==0

compares a component of type integer to an integer.

The former comparison is invalid; nor is it clear what the intended effect may be.

Bild des Benutzers Steve Lionel (Intel)
Best Reply

Use ASSOCIATED to ask if the pointer is associated (not null).

Steve
Bild des Benutzers emreka82

Quote:

mecej4 wrote:

if(root%prnt%ng(1)%pp /= 0

attempts to compare a value of type integer to a component of type pointer variable of type(c), and

root%prnt%ng(1)%pp%compc==0

compares a component of type integer to an integer.

The former comparison is invalid; nor is it clear what the intended effect may be.

Actually, I want to wrote: if(root%prnt%ng(1) /= 0, but because of the array definition in a pointer does not work like this in Fortran, I have to show it with a ragged array and use pp... So I want to say that if the first holder of the array ng is not equal to zero then if condition can be used. Is it clear ?

When I do that thing with the C++ code (such as; root->prnt->ng[1] != 0 ) in a similar fashion, there is no error, which is also interesting for me...

Bild des Benutzers emreka82

Quote:

Steve Lionel (Intel) wrote:

Use ASSOCIATED to ask if the pointer is associated (not null).

Steve,
Shouldn't I have to nullify the pointer before allocate it, and also at the end of the use deallocate ? ASSOCIATED is the checking of it, right ?

Bild des Benutzers Steve Lionel (Intel)

Yes, you should have added a default initialization for pp to NULL() as was done for other pointer components. The DEALLOCATE will set it to null automatically.

Steve
Bild des Benutzers emreka82

Quote:

Steve Lionel (Intel) wrote:

Yes, you should have added a default initialization for pp to NULL() as was done for other pointer components. The DEALLOCATE will set it to null automatically.

Steve,

Then, where do I need ASSOCIATE declaration inside my code, is it necessary ? More importantly, can it solve my "invalid data type" problem ?
Thanks.

Emre

Bild des Benutzers mecej4

Steve's suggestion was to replace the invalid statement

if(root%prnt%ng(1)%pp /= 0)
with
if(associated(root%prnt%ng(1)%pp))...
.

Whether this change will enable your code to function properly, however, is not something that one can answer, given the fragmentary view that has been divulged.

Bild des Benutzers emreka82

Quote:

mecej4 wrote:

Steve's suggestion was to replace the invalid statement

if(root%prnt%ng(1)%pp /= 0)

with

if(associated(root%prnt%ng(1)%pp))...

.

Whether this change will enable your code to function properly, however, is not something that one can answer, given the fragmentary view that has been divulged.

Thanks mecej, I have a minor problem besides these, for example:
In c++:
if(*root->type==out && intersect==2)
{ *root->type=split;
}

and out and split are the enumerated types, such as: enum ctype { out, cut, inside, split};

In Fortran, the following works for the first line, but it does not work inside the if clause :

if(associated(root%type_%out) .and. intersect==2) then
associated(root%type_%split)
end if

The problems are the enumerated filetypes and "*root->type=split" inside the if clause. Thanks again.

Bild des Benutzers mecej4

In Fortran, an expression by itself does not form a valid statement. That is the error in your second line,

associated(root%type_%split)

Because you have only shown code fragments (in particular, the data type mapping from C to Fortran is not shown completely), it is not feasible for me to guess what you wish to accomplish. If you want to associate a pointer variable, you have to follow the appropriate Fortran syntax. ASSOCIATED() is a function of type logical.

Bild des Benutzers emreka82

Quote:

mecej4 wrote:
.......Because you have only shown code fragments (in particular, the data type mapping from C to Fortran is not shown completely), it is not feasible for me to guess what you wish to accomplish. ...

First of all, the codes that I try to write down are very long but there are troublesome "tricky" points inside some of the codes, which are discussed here. My example starts inside the datastructure class, a enumeration type, as I said before:

C++:


//datastr.h:
#ifndef DATASTR

#define DATASTR
enum ctype { out, cut, in, split};

// continues...
class c

{	public:
// continues...
ctype	*type;

int		*sq_i;
// continues...
};
#endif

//mg.h
#ifndef MG

#define MG
using namespace std;
#include "datastr.h"
class mg : public c

{

		public:

// continues...
c	*root;

// continues...
};
#endif


// sq_i.cpp
#include "mg.h"
void mg::sq_i(c *nov)
// continues...
int intersec(0);
if (*nov->type==out && intersec>2)

{

exit(EXIT_FAILURE);

	}

else

	{	*nov->type=split;

		*nov->sq_i=-40;

	}
// continues...
}


// create.cpp
#include "mg.h"
void mg::create()
{

root = new c;

// continues...

sq_i(root);

// continues...

}

I am trying to write in Fortran form.

Fortran:

module class_datastr
    type ctype
        integer, pointer :: out, cut, in, split
    end type ctype
! continues...
type c
! continues...
type(ctype),	pointer :: type_

integer,		pointer :: sq_i
! continues...
end type c
end module class_datastr

module class_mg
use class_datastr
! continues...
type(c), pointer :: root
! continues...
end module class_mg


recursive subroutine mg_sq_i(nov)
use class_mg
type(c), pointer :: nov 
! continues...
integer intersec
! continues...
if(associated(nov%type_%out) .and. intersec>2) then
exit
else
associated(nov%type_%split)

nov%sq_i=-40
end if
! continues...
end subroutine sq_i


subroutine mg_create
use class_mg
allocate(root)
! continues...
call sq_i(root)
! continues...
end subroutine mg_create

Above, I write some parts of the modules(classes) and subroutines, selected from my codes.
The problem is the *nov->type=split; line inside the create.cpp code. I wish you understand the issue here. Thanks for the effort mecej.

Melden Sie sich an, um einen Kommentar zu hinterlassen.