From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 306FF7EE99 for ; Fri, 27 Dec 2013 14:26:10 +0100 (CET) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of dra-news@metastack.com) identity=pra; client-ip=62.13.148.106; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="dra-news@metastack.com"; x-sender="dra-news@metastack.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of dra-news@metastack.com designates 62.13.148.106 as permitted sender) identity=mailfrom; client-ip=62.13.148.106; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="dra-news@metastack.com"; x-sender="dra-news@metastack.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@outmail148106.authsmtp.co.uk) identity=helo; client-ip=62.13.148.106; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="dra-news@metastack.com"; x-sender="postmaster@outmail148106.authsmtp.co.uk"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtEBAOx+vVI+DZRqnGdsb2JhbABYg0O7RRYOAQEBAQEIFAk8giwIAh0BEkwFFlIjHAEEHgWHeKA1qCiTWgSPHp46 X-IPAS-Result: AtEBAOx+vVI+DZRqnGdsb2JhbABYg0O7RRYOAQEBAQEIFAk8giwIAh0BEkwFFlIjHAEEHgWHeKA1qCiTWgSPHp46 X-IronPort-AV: E=Sophos;i="4.95,560,1384297200"; d="scan'208";a="42455290" Received: from outmail148106.authsmtp.co.uk ([62.13.148.106]) by mail3-smtp-sop.national.inria.fr with ESMTP; 27 Dec 2013 14:26:09 +0100 Received: from mail-c235.authsmtp.com (mail-c235.authsmtp.com [62.13.128.235]) by punt18.authsmtp.com (8.14.2/8.14.2/) with ESMTP id rBRDQ8lh071102 for ; Fri, 27 Dec 2013 13:26:08 GMT Received: from romulus.metastack.com (cpc1-cmbg5-0-0-cust241.5-4.cable.virginm.net [81.98.252.242]) (authenticated bits=0) by mail.authsmtp.com (8.14.2/8.14.2/) with ESMTP id rBRDQ77n074232 for ; Fri, 27 Dec 2013 13:26:07 GMT Received: from Altus (host86-138-229-79.range86-138.btcentralplus.com [86.138.229.79]) (authenticated bits=0) by romulus.metastack.com (8.14.2/8.14.2) with ESMTP id rBRDQ0gE009643 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO) for ; Fri, 27 Dec 2013 13:26:05 GMT From: "David Allsopp" To: "OCaml List" Date: Fri, 27 Dec 2013 13:27:53 -0000 Organization: MetaStack Solutions Ltd. Message-ID: <000001cf0307$75fa3520$61ee9f60$@metastack.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Outlook 14.0 Thread-Index: Ac8DBOOEhiNNiVCzT2ux7GEWcUW+5g== Content-Language: en-gb X-Scanned-By: MIMEDefang 2.65 on 172.16.0.20 X-Server-Quench: 716b3497-6efa-11e3-b802-002590a15da7 X-AuthReport-Spam: If SPAM / abuse - report it at: http://www.authsmtp.com/abuse X-AuthRoute: OCd1ZAARAlZZVg1f DC4bFwdFRBksPQFF ChxFJgxfNlEAUAAU NkdBMnJSNkcdTBdX QSgJXEsgBQ5uW2N0 aBpQbg9fZEBOWEti UVZASkxQEQd2AxgD GRwbTRk8NXckDB93 YhhiWXRZX0Y0d09/ QwBTFGtUZmNpb30Z BRYJagJVJQBXLBdF aE1/VHEIaGVWZ380 FlAlGzE7JzxFKSlO CgwdNVUIXUcNEXYx VwwPBzMmGQUJSisy KR06K1kaBw4QNA03 Nlc8XV8DWwBe X-Authentic-SMTP: 61633634383431.1023:706 X-AuthFastPath: 0 (Was 255) X-AuthSMTP-Origin: 81.98.252.242/25 X-AuthVirus-Status: No virus detected - but ensure you scan with your own anti-virus system. Subject: [Caml-list] Libraries exporting external definitions in modules 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