---- module bug; static { __gshared int sa; extern(C) __gshared int sb; } private { __gshared int pa; extern(C) __gshared int pb; } ---- dmd -c bug.d nm -c bug.o output: 0000000000000008 B _D3bug2pai 0000000000000000 B _D3bug2sai 000000000000000c B pb 0000000000000004 B sb expected output: 0000000000000008 b _D3bug2pai 0000000000000000 b _D3bug2sai 000000000000000c b pb 0000000000000004 b sb ---------------- Either static or private should provide the C's static semantic of defining a local symbol, i.e. one that can only be accessed from within the same object file. Probably only useful for extern(C) as D declarations are scoped by the mangling but for D it would still shrink the symbol table.
This is done deliberately as the code/data for one module can be distributed among several object files (unlike C) and the only way they can communicate is via a global name.
It would be good to reconsider this for PIC code where every access to global symbols is indirect through the GOT table. > as the code/data for one module can be distributed among several object files Do you mean the multilib support?
(In reply to comment #2) > It would be good to reconsider this for PIC code where every access to global > symbols is indirect through the GOT table. > This could be achieved by changing the default visibility to hidden. Similar to Windows only symbols with the export attribute would be visible in a shared library thus allowing link-time optimizations for non-exported symbols. http://gcc.gnu.org/wiki/Visibility
(In reply to Martin Nowak from comment #2) > > as the code/data for one module can be distributed among several object files > > Do you mean the multilib support? ``` private __gshared int something; int getSomething(T)() { …; return something; } ``` If the (public) template is instantiated and emitted into another object file / binary, it still needs to be able to access the private symbol.