TypeFunction example creatiing a conversion matrix

Stefan Koch uplink.coder at gmail.com
Fri Oct 2 04:53:12 UTC 2020


On Friday, 2 October 2020 at 03:26:57 UTC, Adam D. Ruppe wrote:
> On Friday, 2 October 2020 at 03:11:34 UTC, Stefan Koch wrote:
>>  - doesn't work for -betterC
>
> This is trivially easy to fix. Wrap the function in a template 
> and use an eponymous enum to collapse it to a literal:
>
>
> ----
> template makeConvMatrix(T...) { // wrapper added
>         string helper()
>         {
>             string result;
>             static foreach(t; T)
>             {
>                 result ~= "\t" ~ t.stringof;
>             }
>             result ~= "\n";
>             static foreach(t1; T)
>             {
>                 result ~= t1.stringof;
>                 static foreach(t2; T)
>                 {
>                     result ~=  "\t" ~ (is(t1:t2) ? "yes" : 
> "no");
>                 }
>                 result ~= "\n";
>             }
>             return result;
>         }
>
>         enum makeConvMatrix = helper(); // eponymous call
> }
>
> extern(C) // for betterC
> void main()
> {
>     import core.stdc.stdio;
>     static immutable convMatrix = makeConvMatrix!(byte, ubyte, 
> short, ushort, int, uint, long, ulong); // no more () there
>
>     printf("%s\n", convMatrix.ptr);
> }
> ------
>
> Generates a reasonably small executable too (this pattern btw 
> is what my change to dmd a couple months ago is able to 
> recognize):
>
> $ ls -lh bc
> -rwxr-xr-x 1 me users 19K Oct  1 23:19 bc
> $ ls -lh bc.o
> -rw-r--r-- 1 me users 2.4K Oct  1 23:19 bc.o
> $ nm bc.o
> 0000000000000000 t
> 0000000000000000 D _D2bc4mainUZ10convMatrixyAa
>                  U _GLOBAL_OFFSET_TABLE_
> 0000000000000000 r _TMP0
> 0000000000000000 W main
>                  U printf
>
>
> Which is identical to if I delete the template from the source 
> entirely and just replace it with a string literal. Nothing of 
> it is emitted to the object file, so the linker doesn't even 
> have to strip it.
>
> Worth noting that not all cases work out this well. But this 
> one actually does.

You still create unnecessary symbols.
Just use the template twice with different arguments.

--
     static immutable convMatrix = makeConvMatrix!(byte, ubyte, 
short, ushort, int, uint, long, ulong); // no more () there
     static immutable convMatrix2 = makeConvMatrix!(ubyte, short, 
ushort, int, uint, long, ulong); // no more () there

     printf("%s\n", convMatrix.ptr);
     printf("%s\n", convMatrix2.ptr);
--

0000000000000000 t
0000000000000008 R _D2t412__ModuleInfoZ
0000000000000000 D _D2t44mainUZ10convMatrixyAa
0000000000000010 D _D2t44mainUZ11convMatrix2yAa
                  U _d_dso_registry
                  U _GLOBAL_OFFSET_TABLE_
0000000000000000 W main
                  U printf
                  U __start_minfo
                  U __stop_minfo
0000000000000000 r _TMP0
0000000000000142 r _TMP1

uplink at uplink-black:~$ ls -lh t4.o
-rw-r--r-- 1 uplink uplink 4,5K Okt  2 06:51 t4.o



More information about the Digitalmars-d mailing list