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

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

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 posts / novo 0
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.

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.

Best Reply

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

Steve

引文:

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.

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...

引文:

Steve Lionel (Intel) 写道:

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 ?

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

引文:

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,

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

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.

引文:

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.

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.

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.

引文:

mecej4 写道:

.......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.

Faça login para deixar um comentário.