caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: "David Allsopp" <dra-news@metastack.com>
To: "OCaml List" <caml-list@inria.fr>
Subject: [Caml-list] Libraries exporting external definitions in modules
Date: Fri, 27 Dec 2013 13:27:53 -0000	[thread overview]
Message-ID: <000001cf0307$75fa3520$61ee9f60$@metastack.com> (raw)

I've hit an unexpected gotcha using external declarations in .mli files.

I have a module where the functions exported are all C stubs and so, knowing
that exposing the external definition in the .mli file allows the compiler
to generate more efficient function calls, I'd exported the functions using
external declarations in the .mli files.

The module also contains an important piece of initialisation code which
must be run before any of the other functions will work. So, simplified, it
looks like this:

Foo.ml
------
external bar : 'a -> unit = "my_c_implementation_of_bar"
external baz : unit -> unit = "very_important_initialisation_stub"

let _ =
  baz ()

Foo.mli
-------
external bar : 'a -> unit = "my_c_implementation_of_bar"

This is then wrapped up in a .cmxa file and the .cmxa, .cmx, .a and .cmi
files installed as normal. Now I produce a program using it:

Bar.ml
------
Foo.bar 42

and compile this program using ocamlopt -o fubar foo.cmxa Bar.ml

When I run it, the initialisation code in Foo.ml calling baz never takes
place (which I can tell because it means that the call to Foo.bar, which
does take place, fails).

After much head-scratching, I realised that the reason for this is that the
external declaration in Foo.mli means that the module Foo presumably isn't
linked as its code was deemed unnecessary (as it would be if Bar.ml only
referenced types in the module Foo, rather than values).

So, my question: is that really correct behaviour? I can see why referencing
a type only is not sufficient to cause a module to be linked, but surely
referencing a value (even when it's declared external) should not exempt the
linker from actually linking the module code - at least when the module
contains top-level code (rather than just static values or functions)?

It seems a shame to slow the calls down (however trivially) by removing the
external declarations from the .mli file (i.e. declaring val bar : 'a ->
unit in the .mli) simply to keep the linker happy.


David

PS I don't expect it's relevant, but for this I was running OCaml 4.01.0 on
Linux/armv6l


             reply	other threads:[~2013-12-27 13:26 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-27 13:27 David Allsopp [this message]
2013-12-27 14:14 ` Markus Mottl
2013-12-28 14:40 ` Gerd Stolpmann
2014-01-02 10:22   ` David Allsopp

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='000001cf0307$75fa3520$61ee9f60$@metastack.com' \
    --to=dra-news@metastack.com \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).