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
Undocumented ocamlc and ocamlopt link behaviour difference #7271
Comments
Comment author: furuse You can reproduce the problem with the following code: (* a.ml *) let f = ref (fun () -> assert false : unit -> unit) (* b.ml *) let () = A.f := (fun () -> prerr_endline ":-)") (* c.ml *) let () = if false then ignore (B.g 1 2) $ ocamlopt -c a.ml I found this when I was playing with compiler-libs.common of 4.03.0. Env.scrape_alias failed since Env.strengthen was not initialized by Mtype. I tried to link Mtype by inserting a dummy expression like if false then Mtype.scrape Env.empty (Mty_signature []) , but it did not make ocamlopt link Mtype. Currently I use the following instead to avoid the issue: let () = ignore (Mtype.strengthen == Mtype.strengthen) |
Comment author: @damiendoligez I think the recommended way to force inclusion (under 4.03.0 or later) would be: ignore (Sys.opaque_identity Mtype.scrape) But I agree we need to (at least) document the difference between byte-code and native. |
Comment author: @gasche The particular case of compiler-libs.common is related to #6509 , see in particular the discussion in I still think that relying on module linking to initialize back-patched functions in this case is fragile and that we should have a more explicit API for compiler-libs users to explicitly request their initialization -- and thus force their linking. |
Comment author: @mshinwell I'm not sure the Sys.opaque_identity line that @doligez writes above will work except when using Flambda---we should check. |
Comment author: @xavierleroy My recommendation is to apply -linkall to the libraries or compilation units that have initialization code with important effects. Note that in 4.05 and up -linkall can be applied to a single compilation unit. I'm not sure what needs to be done / can be done for release 4.05 and even for future releases. |
Comment author: @xavierleroy Mentioned this issue in section 11.5 of the manual (differences ocamlc/ocamlopt). |
Original bug ID: 7271
Reporter: furuse
Status: resolved (set by @xavierleroy on 2017-10-19T14:16:37Z)
Resolution: fixed
Priority: low
Severity: minor
Version: 4.03.0
Target version: 4.06.0 +dev/beta1/beta2/rc1
Fixed in version: 4.06.0 +dev/beta1/beta2/rc1
Category: misc
Related to: #6509
Monitored by: @gasche
Bug description
I wrote a code like the following to enforce a compilation unit M linked. In bytecode, it works fine:
if false then M.f () (* dummy code to make sure M is linked. *)
However, ocamlopt seems to erase the entire expression. As a result the reference to M is lost and M is never linked together. The intention of linking of M is to execute an initialization side effect in M.
This is very confusing behaviour difference between ocamlc and ocamlopt. If it is not a bug, it should be noted in OCaml reference manual 11.5: "Compatibility with the bytecode compiler".
The text was updated successfully, but these errors were encountered: