Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29278 Discussions

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

emreka82
Beginner
2,801 Views

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.

0 Kudos
1 Solution
Steven_L_Intel1
Employee
2,801 Views
Use ASSOCIATED to ask if the pointer is associated (not null).

View solution in original post

0 Kudos
10 Replies
Steven_L_Intel1
Employee
2,802 Views
Use ASSOCIATED to ask if the pointer is associated (not null).
0 Kudos
mecej4
Honored Contributor III
2,801 Views
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.
0 Kudos
emreka82
Beginner
2,801 Views
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...
0 Kudos
emreka82
Beginner
2,801 Views
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 ?
0 Kudos
Steven_L_Intel1
Employee
2,801 Views
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.
0 Kudos
emreka82
Beginner
2,801 Views
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
0 Kudos
mecej4
Honored Contributor III
2,801 Views
Steve's suggestion was to replace the invalid statement [fortran]if(root%prnt%ng(1)%pp /= 0)[/fortran] with [fortran]if(associated(root%prnt%ng(1)%pp))...[/fortran].
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.
0 Kudos
emreka82
Beginner
2,801 Views
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.
0 Kudos
mecej4
Honored Contributor III
2,801 Views
In Fortran, an expression by itself does not form a valid statement. That is the error in your second line,[fortran]associated(root%type_%split)[/fortran] 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.
0 Kudos
emreka82
Beginner
2,801 Views
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++: [cpp] //datastr.h: #ifndef DATASTR #define DATASTR enum ctype { out, cut, in, split}; // continues... class c { public: // continues... ctype *type; int *sq_i; // continues... }; #endif [/cpp] [cpp] //mg.h #ifndef MG #define MG using namespace std; #include "datastr.h" class mg : public c { public: // continues... c *root; // continues... }; #endif [/cpp] [cpp] // 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... } [/cpp] [cpp] // create.cpp #include "mg.h" void mg::create() { root = new c; // continues... sq_i(root); // continues... } [/cpp] I am trying to write in Fortran form. Fortran: [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 [/fortran] [fortran] module class_mg use class_datastr ! continues... type(c), pointer :: root ! continues... end module class_mg [/fortran] [fortran] 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 [/fortran] [fortran] subroutine mg_create use class_mg allocate(root) ! continues... call sq_i(root) ! continues... end subroutine mg_create [/fortran] 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.
0 Kudos
Reply