Problem with coupling shared object symbol visibility with protection

Walter Bright via Digitalmars-d digitalmars-d at puremagic.com
Wed Jan 28 03:00:12 PST 2015


On 1/27/2015 2:05 PM, Rainer Schuetze wrote:
>
>
> On 26.01.2015 23:24, Walter Bright wrote:
>>> The problem here is that you don't want to make someHelperFunc()
>>> export because that would mean users could call it directly, but
>>> you want it to be available for cross shared library calls. The
>>> cross shared library call happens if a template is instanced from a
>>> different shared library / executable than the module it was
>>> originally located in.
>>
>> exporting a template and then having the user instantiate outside of
>> the library doesn't make a whole lot of sense, because the
>> instantiation won't be there in the library. The library will have to
>> instantiate every use case. If the compiler knows the library
>> instantiated it, it won't re-instantiate it locally.
>
> The problem is not about into which binary the template is generated to (this
> must be the binary where it is used),

The example had marked the template itself as 'export'. This raises the specter 
of which binary the template instantiation exists in.

> but how to access private non-templated methods called by the template.
>
>  From the core.time.FracSec example:
>
> export struct FracSec
> {
>      ///...
>      static FracSec from(string units)(long value)
>          if(units == "msecs" ||
>             units == "usecs" ||
>             units == "hnsecs" ||
>             units == "nsecs")
>      {
>          immutable hnsecs = cast(int)convert!(units, "hnsecs")(value);
>          _enforceValid(hnsecs);
>          return FracSec(hnsecs);
>      }
>
>      private static void _enforceValid(int hnsecs)
>      {
>          if(!_valid(hnsecs))
>              throw new TimeException("FracSec must ...");
>      }
>      ///...
> }
>
> _enforceValid() could also be a free function. It is likely to be compiled into
> druntime.dll, but needs to be exported from the DLL to be callable by the
> instantiation of the template function in another DLL. The "private" forbids
> exporting, though.

I tend to view a DLL's exports as being inherently not private, hence D's export 
design being a "super" public. At the risk of sounding flip, I suggest simply 
removing the 'private' from free functions one wishes to export. If the user is 
calling undocumented functions that start with '_', we can presume they know 
what they're doing.

If you still want to hide the free function, it can be done like this:

   struct Bar(T) {
     void callit() { Impl.freefunc(); }
   }

   private struct Impl {
         export static void freefunc() { }
   }



More information about the Digitalmars-d mailing list