DIP22 : Private symbol visibility
Dicebot
m.strashun at gmail.com
Wed Jan 30 01:29:16 PST 2013
Case 1 (binary level, C + D):
----- sample.d -----
module sample;
private int func() { return 42; }
----------
----- oops.c -----
#include <stdio.h>
extern int _D6sample4funcFZi();
void* _Dmodule_ref = 0;
void* _D15TypeInfo_Struct6__vtblZ = 0;
void _Dmain() { }
int main()
{
long value = _D6sample4funcFZi();
printf("%ld\n", value);
return 0;
}
----------
----- shell -----
$ dmd - c sample.d
$ gcc -c oops.c
$ gcc oops.o sample.o
./a.out
42
----------
This is valid code now and will break. Internal linkage is a
binary-level encapsulation tool, contrary to language-level
private. Not that when compiling sample.d dmd can't know if
oops.c will actually link to func and make decision about
internal linkage. Saying this is invalid code may severely limit
language interconnection possibilities and something like
injecting druntime.
Case 2 (pure D, language level):
----- sample.d -----
module sample;
private struct Hest
{
int a, b;
}
public alias Hidden UseMe;
----------
----- oops.d -----
import sample;
import std.stdio;
void main()
{
UseMe tmp;
tmp.a = 42;
}
----------
Now suddenly changing Test definition may break code in oops.d
and we need first to make sure Test is not referenced in public
aliases or as function parameter or as public type member field
etc. Again, this code itself is not only valid but quite
idiomatic. Internal linkage provides strong guarantees that any
change to symbol will affect only its module, with no special
cases.
Case 3 (consistency):
I do insist on keeping class and module protection attribute
consistent. Saying class privates are always accessible from
other modules via tupleof & friends and module privates may be
not is causing confusion for no real gain. Also it may break code
if we have any means to enumerate module symbols via traits (do
we? I don't know).
More information about the Digitalmars-d-announce
mailing list