Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Casting in eiffel

390 views
Skip to first unread message

Gwenael Blum

unread,
Jan 16, 2001, 6:25:26 AM1/16/01
to
Is there a means to cast variable in Eiffel ?
That's to say to use a variable of class A as if it was one of class B.

Thanks.

Friedrich Dominicus

unread,
Jan 16, 2001, 7:48:13 AM1/16/01
to
Gwenae...@esial.uhp-nancy.fr (Gwenael Blum) writes:

partly. there are the usual transformations like out (String
representation of an object), to_integer, to_double etc in String. But
casts in this sense

int i;
double d;

d := (double) i; are not supported. Of course this is a bad
example because you can assing an INTEGER to a DOUBLE.

Objects have to be conformant. To check if the conformance holds you
can use the assignment Attemp.

Assume you have

class A

end

class B
inherit A
end


then you can do a

a: A
b: B;

a := b

and if you are not sure what it is you can check
b ?= a

if b is unequal void or conformant this will suceed.

The assignment attempt is quite useful e.g. in the NUMERIC hierachy

i_ref is INTEGER_REF;
r_ref is REAL_REF;
d_ref is DOUBLE_REF;
...


try_assignments (other: NUMERIC) is
-- what type is `other', find out with assignment attempt.
do
i_ref ?= other;
r_ref ?= other;
d_ref ?= other;
i_bignum ?= other;
i_rational ?= other;
end;

Now after thos tries you can check

i : INTEGER;
if i_ref /= Void then
-- is is an Integer do you can be sure that this will work
i := i_ref;


I hope I showed how it works.

The conversions and assignments attempt do not work for arbitrary
objects so if you have

class A

end

class B
end

and no relationsship between them you have to write your own
conversion routines.

Hope this helps a bit

Friedrich

sa...@my-deja.com

unread,
Jan 16, 2001, 11:58:14 AM1/16/01
to
In article <97964432...@hermes.scinfo.uhp-nancy.fr>,

Yes, this class will work with ISE eiffel.
Note that this is rarely needed, in most cases a ?= will do.

Sam
oco...@eiffel.com

indexing
description:
"Cast an object to a TARGET_TYPE ignoring conformance.%N%
%eg:%N%
%a: ANY%N%
%l: LINKED_LIST [STRING]%N%
%l := (create {CAST [LINKED_LIST [STRING]}).cast (a)"
keywords: "cast, force"
date: "$Date: 2000/09/26 16:23:42 $"
revision: "$Revision: 1.3 $"

class
CAST [TARGET_TYPE]

inherit
INTERNAL

feature -- Basic operation

cast (a: ANY): TARGET_TYPE is
-- `a' cast to TARGET_TYPE without type check.
do
Result := null_macro ($a)
end

checked_cast (a: ANY): TARGET_TYPE is
-- `a' cast to TARGET_TYPE.
require
type_conforms_to (dynamic_type (a), target_type)
do
Result := null_macro ($a)
end

target_type: INTEGER is
-- Type code of TARGET_TYPE.
do
Result := eif_gen_param_id (-1, $Current, 1)
end

feature {NONE}

null_macro (p: POINTER): TARGET_TYPE is
-- Facilitates assignment without typecheck.
-- foo := null_macro (bar) is Eiffel becomes:
-- foo = (bar); in C.
external
"C [macro <eif_eiffel.h>]"
alias
" "
end

eif_gen_param_id (stype: INTEGER; obj: POINTER; pos: INTEGER):
INTEGER is
-- Type of generic parameter in `obj' at position `pos'.
external
"C (int16, EIF_REFERENCE, int): EIF_INTEGER |
%"eif_gen_conf.h%""
end

end


Sent via Deja.com
http://www.deja.com/

Gwenael Blum

unread,
Jan 17, 2001, 4:40:37 AM1/17/01
to

> Yes, this class will work with ISE eiffel.
> Note that this is rarely needed, in most cases a ?= will do.

Thanks a lot !!

However i have a little problem when compiling :

compile -o test test make
****** Fatal Error : The $ operator must be followed by the final
name of a feature which is not a constant attribute (VUAR.4).
Line 37 column 46 in CAST (./cast.e) :


Result := eif_gen_param_id (-1, $Current, 1)

^

line 34-38 of cast.e :


<<
target_type: INTEGER is
-- Type code of TARGET_TYPE.
do
Result := eif_gen_param_id (-1, $Current, 1)
end
>>

with the test class :

<<
creation
make

feature

make is
local
a : A
laeticia : CAST[B]
do
!!a;

!!b ;
laeticia.cast(a).test ;

end;
end -- class TEST
>>

Gwenael Blum

unread,
Jan 17, 2001, 5:05:57 AM1/17/01
to
>> Yes, this class will work with ISE eiffel.
>> Note that this is rarely needed, in most cases a ?= will do.
>
> Thanks a lot !!
> However i have a little problem when compiling :

Please excuse, first I forgot to say that I compile with SmallEiffel
and second I made a little error in my last post.

my test class is :

> creation
> make
> feature
>
> make is
> local
> a : A
> laeticia : CAST[B]
> do
> !!a;

> !!laeticia ; -- error corrected


> laeticia.cast(a).test ;
> end;
> end -- class TEST

Else, for the previous problem, I replaced '$something'
with 'something.to_pointer.

This time, when compiling, there is a problem with : inherit INTERNAL
****** Fatal Error : Unable to load class.
Line 16 column 4 in CAST (./cast.e) :
INTERNAL
^
I searched for this file but I have not.

Then, when I mask the line inherit INTERNAL :
-- inherit
-- INTERNAL

When compiling :


<<
compile -o test test make

In file included from test1.c:8:
test.h:481: parse error before `a1'
gcc: test1.o: No such file or directory
gcc: No input files
/usr/ccs/bin/sparcv9/strip: test: cannot open file.
No such file or directory
>>

sa...@my-deja.com

unread,
Jan 17, 2001, 11:53:49 AM1/17/01
to
As I said in my original post, the CAST class I posted
will work with ** ISE ** Eiffel. It will not work with SmallEiffel
as it makes external calls to the ISE runtime.
Also, like I said before, in most cases an assignment attempt,
?=, is the "right way"TM to do this sort of thing in Eiffel.
The main reason I use the CAST class is to get around bugs
in ISE's conformance checker. Sometimes I know that something
conforms but the runtime does not agree (mostly relating to
generics involving TUPLEs.)

Sam

In article <97972595...@hermes.scinfo.uhp-nancy.fr>,

Eirik Mangseth

unread,
Jan 18, 2001, 3:14:58 AM1/18/01
to

<sa...@my-deja.com> wrote in message news:944imo$4ne$1...@nnrp1.deja.com...

> As I said in my original post, the CAST class I posted
> will work with ** ISE ** Eiffel. It will not work with SmallEiffel
> as it makes external calls to the ISE runtime.
> Also, like I said before, in most cases an assignment attempt,
> ?=, is the "right way"TM to do this sort of thing in Eiffel.
> The main reason I use the CAST class is to get around bugs
> in ISE's conformance checker.

Wouldn't fixing the conformance checker be better?
(Assuming the poster is Sam O'Connor of ISE fame :)

Eirik Mangseth
Stockpoint Nordic AS
Lysaker, Norway

"If I can't Eiffel in heaven, I won't go"

Friedrich Dominicus

unread,
Jan 18, 2001, 3:34:27 AM1/18/01
to
"Eirik Mangseth" <no_spa...@stockpoint.no> writes:

>
> Wouldn't fixing the conformance checker be better?
> (Assuming the poster is Sam O'Connor of ISE fame :)

Depends on the Way of programming one prefers
- Unix way (don't fix it, patch it)
- do it the right way (fix it, Fix it, FIx it, FIX it) ;-)

Could not resist sorry ;-)
Friedrich

sa...@my-deja.com

unread,
Jan 18, 2001, 12:03:17 PM1/18/01
to
In article <6Cx96.309$P2.178...@news.telia.no>,

"Eirik Mangseth" <no_spa...@stockpoint.no> wrote:
>
> <sa...@my-deja.com> wrote in message
news:944imo$4ne$1...@nnrp1.deja.com...
> > As I said in my original post, the CAST class I posted
> > will work with ** ISE ** Eiffel. It will not work with SmallEiffel
> > as it makes external calls to the ISE runtime.
> > Also, like I said before, in most cases an assignment attempt,
> > ?=, is the "right way"TM to do this sort of thing in Eiffel.
> > The main reason I use the CAST class is to get around bugs
> > in ISE's conformance checker.
>
> Wouldn't fixing the conformance checker be better?

Yes, fixing the conformance checker would undoubtedly be better.

However, there are cases where casting is, IMHO, needed:

- For stylistic reasons: if you know that something is a certain
type because you can infer it from some other known things then
it is cleaner to do a cast than to have a local variable
simply for the purpose of doing an assignment attempt.
A cast compiles away to nothing, an assignment attempt involves
a runtime conformance test.

- Because there is no other way: if you have an agent that returns
INTEGER (or any base type) and you have a reference to it of
type FUNCTION [ANY, TUPLE[], ANY] (return type ANY) and you do
a: ANY; a := agent.item ([]) this is bad.
The integer is written directly into the reference variable `a'.
So if the integer was 7 then `a' now points to memory address 7.
If you know at runtime that the agent will return an INTEGER,
eg from reflection data, you can cast the agent to the correct
type before you call it.
The root of this problem is fundamental flaw in the way base classes
are made to appear like they conform to ANY when they don't really.

Sam

Jim Cochrane

unread,
Jan 18, 2001, 5:50:15 PM1/18/01
to
In article <878zo9t...@frown.here>,

Friedrich Dominicus <fr...@q-software-solutions.com> wrote:
>"Eirik Mangseth" <no_spa...@stockpoint.no> writes:
>
>>
>> Wouldn't fixing the conformance checker be better?
>> (Assuming the poster is Sam O'Connor of ISE fame :)
>
>Depends on the Way of programming one prefers
>- Unix way (don't fix it, patch it)
>- do it the right way (fix it, Fix it, FIx it, FIX it) ;-)
>


Hmm, and what is the Microsoft way? :-)

>Could not resist sorry ;-)
>Friedrich


--
Jim Cochrane
j...@dimensional.com

Friedrich Dominicus

unread,
Jan 19, 2001, 12:56:48 AM1/19/01
to
j...@dimensional.com (Jim Cochrane) writes:

>
>
> Hmm, and what is the Microsoft way? :-)

I'm not sure is it maybe

DENY IT, DENY It, DENY it, DENy it, DEny it, Deny it, deny it,
it has been fixed long ago ;-)

Regards
Friedrich

0 new messages