I am trying to understand how CRCs for interfaces are generated by OCaml (bytecode, version 4.13.2) when there is no corresponding
let t () = print_endline "hello world"
let t2 () = 1
ocamlc -c a.ml && ocamlobjinfo a.cmo this gives a CRC of
ec612c3e86eaca57a236b43aa1d6cdb5. If I change
let t () = print_endline "hello world!"
let t2 () = 1
The CRC is instead
798a526927928bf5d325066505f0fada. Is this CRC not supposed to be based on the interface of the module
A and not the implementation?
The following seems to indicate so: If I make
val t : unit -> unit
val t2 : unit -> int
Then both versions of
a.ml give the same CRC (
The reason I am curious about this is that it’s preventing us from reloading modules as cmos in the toplevel if they have no
mli file: Almost any change to the
ml file causes CRC mismatches.
The cmi files contain locations by default, so anything that can change the locations associated to the exported items will change the CRC of the cmi.
You can use the
-no-keep-locs flag to make the CRCs independent of the locations.
Can you explain why locations seems to not be used if there is an
mli file? You say ‘locations by default’ - is this because there are several schemes for what to use in a
“By default” means you can turn them off with
-no-keep-locs (in practice, when the flag is used all locations are replaced with a dummy location).
If there is an
mli file, the locations of the interface are the ones of the
mli file. You can check that adding whitespace in the
mli file changes the CRC, unless you use
If you’re curious, you can check that in the case without a
mli file, only the locations for exported items are relevant by adding whitespace, comments, or code which doesn’t bind anything (such as
let _ = ...) at the end of the file, and these additions will likely not change the CRC.
Thank you again. I now understand what location means in this context - I thought it was location in the compiled code and not in the source file. This makes things clear.