Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problème avec l'héritage et les variables virtuelles #4459

Closed
vicuna opened this Issue Nov 29, 2007 · 2 comments

Comments

Projects
None yet
1 participant
@vicuna
Copy link
Collaborator

vicuna commented Nov 29, 2007

Original bug ID: 4459
Reporter: @chambart
Status: closed (set by @garrigue on 2007-11-30T00:17:19Z)
Resolution: fixed
Priority: normal
Severity: minor
Version: 3.10.0
Fixed in version: 3.10+dev
Category: ~DO NOT USE (was: OCaml general)

Bug description

Le code :

class virtual a =
object
val virtual v : int
end

class b =
object
inherit a
val v = 1
end

renvoie une exception a l'execution:
Fatal error: exception Not_found
Raised at file "map.ml", line 104, characters 16-25
Called from file "camlinternalOO.ml", line 245, characters 30-54
Called from file "list.ml", line 74, characters 24-34
Called from file "camlinternalOO.ml", line 244, characters 5-100
Called from file "camlinternalOO.ml", line 324, characters 2-11
Called from unknown location
Called from file "camlinternalOO.ml", line 334, characters 17-33
Called from unknown location

Additional information

par contre avec

class virtual a =
object
val virtual v : int
method get = v
end

il n'y a pas d'exception.

Le problème viens de la simplification dans les lambda termes:

Comme les variables sont declarees avec le tag StrictOpt,
si elle ne sont pas utilisées, leur declaration est suprimée.

avec l'option -drawlamda
(letrec
(a/61
(let (a_tables/71 (makemutable 0 0a 0a 0a))
(makeblock 0 0a
(function class/75
(let
(v/64 (apply (field 2 (global CamlinternalOO!)) class/75 #"v"))
(function env/77 self/76
(apply (field 23 (global CamlinternalOO!)) self/76 class/75))))
0a 0a)))

avec -dlamda
(letrec
(a/61
(makeblock 0 0a
(function class/75
(function env/77 self/76
(apply (field 23 (global CamlinternalOO!)) self/76 class/75)))
0a 0a))

Le problème ne se pose pas avec les méthodes virtuelles car la
déclaration des méthodes se fait avant l'héritage:

class virtual a =
object
val virtual v : int
method virtual get : int
end

class b =
object
inherit a
val v = 1
method get = 1
end

avec -dlambda:
(let (shared/96 [0: #"get"] shared/97 [0: #"v"])
(letrec
(a/61
(makeblock 0 0a
(function class/109
(function env/111 self/110
(apply (field 23 (global CamlinternalOO!)) self/110 class/109)))
0a 0a))
(letrec
(b/69
(let
(b_init/100
(function class/90
(* get est déclarée avant l'héritage, donc ce n'est pas grave si la classe a ne l'a pas declare, par contre 'a' n'est déclarée qu'apres *)
(let
(get/73
(apply (field 6 (global CamlinternalOO!)) class/90
#"get")
inh/98
(apply (field 17 (global CamlinternalOO!)) class/90
shared/97 shared/96 0a a/61 1a)
obj_init/94 (field 0 inh/98)
v/72 (field 1 inh/98))
(seq
(apply (field 9 (global CamlinternalOO!)) class/90
get/73
(function self-2/75
(funct-body 122-136 (before 135-136 1))))
(function env/92 self/91
(let
(self/93
(apply (field 23 (global CamlinternalOO!))
self/91 class/90))
(seq
(seq (apply obj_init/94 self/93)
(array.unsafe_set self/93 v/72 1))
(apply (field 25 (global CamlinternalOO!))
self/91 self/93 class/90))))))))
(apply (field 18 (global CamlinternalOO!)) shared/96 b_init/100)))

Une méthode pour contourner le problème est d'écrire la classe
b sous la forme

class b =
object
val v = 1
inherit a
method get = 1
end

Sinon il est possible d'empecher la simplification problematique du lambda
terme en déclarant les variables par des "let stricts":
remplacer la ligne

  Llet(StrictOpt, id, transl_val tbl create name, rem))

par

  Llet(Strict, id, transl_val tbl create name, rem))

dans la fonction transl_vals de bytecomp/transclass.ml

mais ce n'est pas très satisfaisant.

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Nov 29, 2007

Comment author: jm

Apparemment le problème a été résolu dans la branche release310 :

% ocaml
Objective Caml version 3.10.1+dev3 (2007-11-26)

class virtual a =

object val virtual v : int end;;
class virtual a : object val virtual v : int end

class b =

object
inherit a
val v = 1
method get = v
end;;
class b : object val v : int method get : int end

print_int (new b)#get;;

1- : unit = ()

Peut-être par ce commit:

Author: Jacques Garrigue
Date: Mon May 21 05:52:07 2007 +0000

allow delayed creation of virtual instance variables
@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Nov 30, 2007

Comment author: @garrigue

Oui, le probleme apparait quand v n'est pas utilise' dans la classe ou on l'introduit. Mais comme vous l'avez remarque', c'est de'ja corrige'.

@vicuna vicuna closed this Nov 30, 2007

@vicuna vicuna added the bug label Mar 19, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.