Value type conversion to reference not working e.g. BOOLEAN_REF/BOOLEAN

22 views
Skip to first unread message

Thomas Beale

unread,
Dec 13, 2017, 8:41:58 AM12/13/17
to Eiffel Users

I've asked this question various times over the years, but what the compiler and runtime do changes, so I'll ask it again...

The following code executes in the debugger:


create prim_obj
.make(eif_fld_val)

-- definition of the relevant call
class PRIMITIVE_OBJECT
  make
(a_val: like value)
   
do
        value
:= a_val
   
end

  value
: ANY
end



At runtime, the 'a_val' is a BOOLEAN in one case, and it shows like this in the object tool.



Which is odd for a BOOLEAN, but not for a BOOLEAN_REF (presumably that's how a BOOLEAN_REF displays).

Anyway, this value / object is passed to the make routine above. It doesn't complain, but it doesn't set the value field - not to a BOOLEAN, nor a BOOLEAN_REF.

The execution dies on the following call:

check attached prim_obj.value end

Which is expected, given the assignment failed. However, it normally works, which makes me think its either non-deterministic, or it depends on the version of the compiler or some library detail.

There seems to be a problem in the compiling and runtime handling here, since there was no complaint in the call to make(), but the value did not get attached. I think all expanded value objects (BOOLEAN, INTEGER etc) should silently convert back and forth to their XX_REF form, as appears to be the case according to the debugger above. But it seems not to have worked properly - the debugger is probably showing 'BOOLEAN' in the 'eif_fld_val' row due to the dynamic type being set to the value for BOOLEAN, not BOOLEAN_REF< but in fact the object appears to be a BOOLEAN_REF.

The following two statements both generate a type id of 2250 for this BOOLEAN object and the field in its parent object (but I think from memory, these values are build-dependent, not universal).

fld_att_dyn_tid := attached_type (dynamic_type (eif_fld_val))
fld_static_tid
:= field_static_type_of_type (i, dynamic_type (an_obj))


Any thoughts on what is going on here?

- thomas

Alexander Kogtenkov

unread,
Dec 13, 2017, 9:18:56 AM12/13/17
to eiffel...@googlegroups.com
Hi Thomas,

In order to make sure we are on the same page, the code below is a complete version that can be compiled and run. For me it prints
   202
   202
   True
   True
   True
   True

I guess, you are doing something else. So, it would be nice to get the version that fails.

Alexander Kogtenkov


class PRIMITIVE_OBJECT
create
 make
feature
 make(a_val: like value)
  do
   value := a_val
  end
 value: ANY
end

class TEST
inherit
 INTERNAL
 REFLECTOR
create
 make
feature
 eif_fld_val: BOOLEAN
 make
  local
   an_obj: TEST
   prim_obj: PRIMITIVE_OBJECT
   r: REFLECTED_OBJECT
  do
    -- Setup.
   eif_fld_val := True
   an_obj := Current
   create prim_obj.make (eif_fld_val)
    -- Check low-level type information.
   io.put_integer (attached_type (dynamic_type (eif_fld_val)))
   io.put_new_line
   io.put_integer (field_static_type_of_type (1, dynamic_type (an_obj)))
   io.put_new_line
    -- Retrieve data using object tests.
   check
    is_attached: attached prim_obj.value as b
   then
    print (b)
    io.put_new_line
   end
   check
    is_boolean: attached {BOOLEAN} prim_obj.value as b
   then
    io.put_boolean (b)
    io.put_new_line
   end
    -- Retrieve data using reflection.
   create {REFLECTED_REFERENCE_OBJECT} r.make (prim_obj)
   check
    is_reference_field: r.field_type (1) = Reference_type
    is_attached: attached r.reference_field (1) as b
   then
    print (b)
    io.put_new_line
   end
   check
    is_boolean: attached {BOOLEAN} r.reference_field (1) as b
   then
    io.put_boolean (b)
    io.put_new_line
   end
  end
end


 Thomas Beale <wolan...@gmail.com>:

Eric Bezault

unread,
Dec 13, 2017, 9:52:11 AM12/13/17
to eiffel...@googlegroups.com
It's probably not related to this problem, but in eif_macro.h I found:


#define RTCCL(x) ((x && eif_is_expanded(HEADER(x)->ov_flags))? RTRCL(x):
(x))


I think that it would be safer to write:


#define RTCCL(x) (((x) && eif_is_expanded(HEADER(x)->ov_flags))?
RTRCL(x): (x))


(all occurrences of 'x' in parentheses).

--
Eric Bezault
mailto:er...@gobosoft.com
http://www.gobosoft.com
> end
>
>   value:ANY
> end
>
>
>
> At runtime, the 'a_val' is a BOOLEAN in one case, and it shows like
> this in the object tool.
>
> <https://lh3.googleusercontent.com/-K8SAwCBOKTs/WjEp7Sq_o_I/AAAAAAAAA4E/Ii4dHbcv6vgKz0QljY8H-hkmswHmS5ybgCLcBGAs/s1600/ES-bool-objects.png>
>
>
>
> Which is odd for a BOOLEAN, but not for a BOOLEAN_REF (presumably
> that's how a BOOLEAN_REF displays).
>
> Anyway, this value / object is passed to the make routine above. It
> doesn't complain, but it doesn't set the value field - not to a
> BOOLEAN, nor a BOOLEAN_REF.
>
> The execution dies on the following call:
>
> check attached prim_obj.value end
>
> Which is expected, given the assignment failed. However, it normally
> works, which makes me think its either non-deterministic, or it
> depends on the version of the compiler or some library detail.
>
> There seems to be a problem in the compiling and runtime handling
> here, since there was no complaint in the call to make(), but the
> value did not get attached. I think all expanded value objects
> (BOOLEAN, INTEGER etc) should silently convert back and forth to
> their XX_REF form, as appears to be the case according to the
> debugger above. But it seems not to have worked properly - the
> debugger is probably showing 'BOOLEAN' in the 'eif_fld_val' row due
> to the dynamic type being set to the value for BOOLEAN, not
> BOOLEAN_REF< but in fact the object appears to be a BOOLEAN_REF.
>
> The following two statements both generate a type id of 2250 for
> this BOOLEAN object and the field in its parent object (but I think
> from memory, these values are build-dependent, not universal).
>
> fld_att_dyn_tid :=attached_type (dynamic_type (eif_fld_val))
> fld_static_tid :=field_static_type_of_type (i,dynamic_type (an_obj))
>
>
> Any thoughts on what is going on here?
>
> - thomas
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Eiffel Users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to eiffel-users...@googlegroups.com
> <mailto:eiffel-users...@googlegroups.com>.
> Visit this group at https://groups.google.com/group/eiffel-users.
> For more options, visit https://groups.google.com/d/optout.


Thomas Beale

unread,
Dec 13, 2017, 10:04:34 AM12/13/17
to Eiffel Users
Alex,

I'll try to construct a minimal system that replicates the problem; however, it doesn't always occur, and in a finalised version of the system, it seems that things mostly work...

thanks

- thomas

Eric Bezault

unread,
Dec 13, 2017, 10:25:17 AM12/13/17
to eiffel...@googlegroups.com, Thomas Beale
Hi Thomas,

Is your system multithreaded? If not, perhaps the object, when
a clone of a expanded object, is not correctly protected against
garbage collection. That's what comes to my mind to explain the
randomness of this problem.

I remember giving it a try on my computer last year (using your
application directly), but never managed to reproduce it.

If I remember correctly you were using mingw as back-end C compiler
whereas I was using microsoft C compiler.
>  Thomas Beale <wolan...@gmail.com <javascript:>>:
>
>
> I've asked this question various times over the years, but what
> the compiler and runtime do changes, so I'll ask it again...
>
> The following code executes in the debugger:
>
>
> create prim_obj.make(eif_fld_val)
>
> --definition of the relevant call
> classPRIMITIVE_OBJECT
>   make(a_val:like value)
> do
>         value :=a_val
> end
>
>   value:ANY
> end
>
>
>
> At runtime, the 'a_val' is a BOOLEAN in one case, and it shows
> like this in the object tool.
>
> <https://lh3.googleusercontent.com/-K8SAwCBOKTs/WjEp7Sq_o_I/AAAAAAAAA4E/Ii4dHbcv6vgKz0QljY8H-hkmswHmS5ybgCLcBGAs/s1600/ES-bool-objects.png>
>
>
>
> Which is odd for a BOOLEAN, but not for a BOOLEAN_REF
> (presumably that's how a BOOLEAN_REF displays).
>
> Anyway, this value / object is passed to the make routine above.
> It doesn't complain, but it doesn't set the value field - not to
> a BOOLEAN, nor a BOOLEAN_REF.
>
> The execution dies on the following call:
>
> check attached prim_obj.value end
>
> Which is expected, given the assignment failed. However, it
> normally works, which makes me think its either
> non-deterministic, or it depends on the version of the compiler
> or some library detail.
>
> There seems to be a problem in the compiling and runtime
> handling here, since there was no complaint in the call to
> make(), but the value did not get attached. I think all expanded
> value objects (BOOLEAN, INTEGER etc) should silently convert
> back and forth to their XX_REF form, as appears to be the case
> according to the debugger above. But it seems not to have worked
> properly - the debugger is probably showing 'BOOLEAN' in the
> 'eif_fld_val' row due to the dynamic type being set to the value
> for BOOLEAN, not BOOLEAN_REF< but in fact the object appears to
> be a BOOLEAN_REF.
>
> The following two statements both generate a type id of 2250 for
> this BOOLEAN object and the field in its parent object (but I
> think from memory, these values are build-dependent, not universal).
>
> fld_att_dyn_tid :=attached_type (dynamic_type (eif_fld_val))
> fld_static_tid :=field_static_type_of_type (i,dynamic_type (an_obj))
>
>
> Any thoughts on what is going on here?
>
> - thomas
>
>

Woland's Cat

unread,
Dec 13, 2017, 10:31:01 AM12/13/17
to eiffel...@googlegroups.com
On 13/12/2017 15:25, Eric Bezault wrote:
Hi Thomas,

Is your system multithreaded? If not, perhaps the object, when
a clone of a expanded object, is not correctly protected against
garbage collection. That's what comes to my mind to explain the
randomness of this problem.

ah - that is a good thought. It is set to 'Thread' and I use the Process library to manage editor, browser launches and so on.

So it seems it may make sense to turn of the GC around those calls and see if things still break.

However, I would really like more bullet-proof semantics around expanded types and ANY-conformance. What is happening in the debugger does not look kosher to me...



I remember giving it a try on my computer last year (using your
application directly), but never managed to reproduce it.

If I remember correctly you were using mingw as back-end C compiler
whereas I was using microsoft C compiler.

yes - now I remember the discussion. Yes, I am using mingw in the distribution.

- thomas


--
Thomas Beale
Principal, Ars Semantica
Consultant, ABD Team, Intermountain Healthcare
Management Board, Specifications Program Lead, openEHR Foundation
Chartered IT Professional Fellow, BCS, British Computer Society
Health IT blog | Culture blog
Reply all
Reply to author
Forward
0 new messages