Closed mw66 closed 6 months ago
looks like a gec
bug, I can use ISE compiler without any problem with the same code:
$ ec -finalize -config src/system.ecf
This project has more than one target:
[1] all_classes
[2] gedoc
Select the target you want (0 to quit): 2
Eiffel Compilation Manager
Version 23.09.10.7341 - linux-x86-64
Degree 6: Examining System
Degree 5: Parsing Classes
Degree 4: Analyzing Inheritance
Degree 3: Checking Types
Degree 2: Generating Byte Code
Degree 1: Generating Metadata
Melting System Changes
...
It's not a bug in gec
. Let me first explain what a CAT-call is. Let's assume we have this code:
class ANIMAL
feature
f (other: ANIMAL)
do
end
end
and:
class BIRD
inherit
ANIMAL
redefine
f
end
feature
f (other: BIRD)
do
other.fly
end
fly
do
print ("fly")
end
end
and finally:
class AA
create
make
feature
make
local
a: ANIMAL
other: ANIMAL
b: BIRD
do
create b
a := b
create other
a.f (other)
end
end
At runtime a
is a bird, but other
is a regular animal. So we will try to call fly
on a regular animal, but there is no such routine in class ANIMAL
. The Gobo Eiffel compiler tries to warn about this problem at compile time:
PS C:\sandbox> gec system.ecf
Degree 6: 0/0/0 0:0:0.033
Degree 5: 0/0/0 0:0:0.212
Degree 4: 0/0/0 0:0:0.092
Degree 3: 0/0/0 0:0:0.066
[CATCALL] class [detachable] AA (18,4): type '[detachable] ANIMAL' of actual argument #1 does not conform to type '[attached] BIRD' of formal argument in feature `f' in class '[detachable] BIRD'
Degree -2: 0/0/0 0:0:0.019
Degree -3: 0/0/0 0:0:0.037
Degree -4: 0/0/0 0:0:3.586
Total Time: 0/0/0 0:0:4.051
But by default this should just be a warning. An executable should have been generated. And if you execute it:
PS C:\sandbox> .\aa.exe
CAT-call error!
aa: system execution failed.
Following is the set of recorded exceptions:
-------------------------------------------------------------------------------
Class / Object Routine Nature of exception Effect
-------------------------------------------------------------------------------
AA root's creation CAT-call error.:
<0000000000000000> Developer exception. Fail
-------------------------------------------------------------------------------
AA root's creation
<0000000000000000> Routine failure. Exit
-------------------------------------------------------------------------------
gec
has a command-line option --catcall
:
--catcall=no|error|warning
Should CAT-call errors be considered as fatal errors,
as warnings, or just ignored? (default: warning)
So if you don't want to see the warning, just use --catcall=no
. With this option, it will behave like ISE Eiffel where is does not warn at compile time, but raises an exception at runtime. This is what we get with ISE Eiffel:
PS C:\sandbox> .\EIFGENs\aa\W_code\aa.exe
Catcall detected in {BIRD}.f for arg#1: expected BIRD but got ANIMAL
aa: system execution failed.
Following is the set of recorded exceptions:
-------------------------------------------------------------------------------
Class / Object Routine Nature of exception Effect
-------------------------------------------------------------------------------
BIRD f @1 Segmentation violation:
<000001D97CD095C8> Operating system signal. Fail
-------------------------------------------------------------------------------
BIRD f @1
<000001D97CD095C8> Routine failure. Fail
-------------------------------------------------------------------------------
AA make @4
<000001D97CD09588> Routine failure. Fail
-------------------------------------------------------------------------------
AA root's creation
<000001D97CD09588> Routine failure. Exit
-------------------------------------------------------------------------------
The warning reported by gec
is based on dynamic type set analysis. It means that gec
has detected some likelihood that a CAT-call may occur at runtime. But there is no guarantee that this will actually happen. It depends on the actual execution path in the code.
Now back to your actual code. The routine is_equal
is often the source of CAT-call. So I would recommend using same_string
instead. But here, when comparing the name of features, I would rather use:
query := a_class.queries.item(i)
if query.is_attribute and attached query.first_precursor as l_first_precursor then
if not query.name.same_feature_name (l_first_precursor.name) then
Why I cannot make this
is_equal
call compile?I checked the
Void
, andif attached ...
, why it's still complaining?