Trying to avoid the GC

Shachar Shemesh via Digitalmars-d digitalmars-d at puremagic.com
Wed Dec 31 05:38:04 PST 2014


I have a standard processing that needs to be done over and over again, 
with an inner function that is different between invocations. Here is a 
small sample that illustrates the need:

import std.stdio;

alias dtype = void delegate(int i);
void func(T)( T d )
{
     foreach(i; 0 .. 10) {
         d(i);
     }
}

int main()
{
     int sum;

     func( (int i) {
             sum+=i;
             });

     writeln(sum);

     return 0;
}

If you're wondering, "func" is templated in an attempt (unsuccessful) to 
prevent the problem I'm about to describe.

The problem is that despite both functions being in the same compilation 
unit and the fact it is obvious that the delegate passed to func is 
never used outside of the function, "main" cannot be declared @nogc 
(and, in particular, it allocates the frame for main on the heap). This 
is true also of gdc with -O3.

I've tried the exact same program with g++:

#include <iostream>

template <class T> void func( T d )
{
     for( int i=0; i<10; ++i ) {
         d(i);
     }
}

int main()
{
     int sum;

     func([&](int a) { sum+=a; });

     std::cout<<sum<<"\n";

     return 0;
}

This is almost a direct translation of the D program to C++11. Despite 
that, g++ (with -O3) figure out that func should be inlined, and then 
unrolls the loop, performs it at compile time, and replaces the entire 
program with:

std::cout<<45<<"\n";

For my purposes I do not need compile time evaluation (and D has the 
mechanisms to ensure those). What I do need is for it not to use GC to 
hold the function's frame when it's clear that that frame is never used 
outside of the function.

Failing that, I need an alternative way to wrap a changing action with 
constant loop without using GC controlled memory.

Thanks,
Shachar


More information about the Digitalmars-d mailing list