Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
#0 0x000000000084b20f in draw.TestScene.prepareAbstractModel() (this=0x7ffff45cc300) at src/draw.d:56
#1 0x000000000084b06c in draw.TestScene.this(des.space.camera.Camera) (this=0x7ffff45cc300, cam=0x7ffff45cc158) at src/draw.d:39
#2 0x000000000080aa85 in _D3des4util4arch3emm21ExternalMemoryManager57__T6newEMMTC4draw9TestSceneTC6camera18MouseControlCameraZ6newEMMMFC6camera18MouseControlCameraZC4draw9TestScene (
this=0x7ffff45cc238, _param_0=0x7ffff45cc100) at descore/import/des/util/arch/emm.d:49
#3 0x000000000084fa8c in window.MainWindow.prepare() (this=0x7ffff45cc200) at src/window.d:26
#4 0x000000000069ea60 in des.app.base.DesApp.addWindow(des.app.base.DesWindow() delegate) (this=0x7ffff45cd780, winFunc=...) at des/import/des/app/base.d:318
#5 0x000000000084f808 in D main () at src/main.d:11
Не стоит указывать аттрибуты шаблонным функциям, если они будут вызываться из @nogc кода, при этом внутри них будут вызываться тоже функции, помеченные как @nogc, компилятор инстацирует их соответствующим образом. Это поможет в случае повторного использования кода, когда внутри шаблонной функции будет вызываться не @nogc функция.
import std.stdio;
import std.typetuple;
import std.range;
template isIRWL(R) { enum isIRWL = isInputRange!R && hasLength!R; }
template FloatHandler(R) { enum FloatHandler = is( ElementType!R == float ); }
float avg(R1,R2)( R1 a, R2 b ) // не указываем какая функция
if( allSatisfy!(isIRWL,R1,R2) && allSatisfy!(FloatHandler,R1,R2) )
{
auto c = chain( a, b );
float res = 0.0f;
foreach( val; c ) res += val;
return res / c.length;
}
struct Bar
{
float val;
size_t cnt;
@nogc: // все функции в этой структуре такие
this( float n, size_t c ) { val = n; cnt = c; }
void popFront() { cnt--; }
float front() { return val; }
size_t length() @property { return cnt; }
bool empty() { return cnt == 0; }
}
float call_nogc() @nogc // указываем конкретно
{
// всё в порядке, avg инстанцируется как @nogc,
// так как все вызовы в Bar @nogc
return avg( Bar(1.0f,3), Bar(4.0f,6) );
}
struct Foo
{
float val;
size_t cnt;
// здесь вызовы обычные
this( float n, size_t c ) { val = n; cnt = c; }
void popFront() { cnt--; }
float front() { return val; }
size_t length() @property { return cnt; }
bool empty() { return cnt == 0; }
}
// код с ошибочным вызовом
//float foo_call_nogc() @nogc // функция помечена как @nogc
//{
// return avg( Foo(1,10), Foo(8,2) );
//
// пытается вызвать non-@nogc функции в Bar
// attrib.d(54): Error: @nogc function 'attrib.foo_call_nogc' cannot call non-@nogc function 'attrib.Foo.this'
// attrib.d(54): Error: @nogc function 'attrib.foo_call_nogc' cannot call non-@nogc function 'attrib.Foo.this'
// avg инстанцируется соответствующим образом, как non-@nogc
// attrib.d(54): Error: @nogc function 'attrib.foo_call_nogc' cannot call non-@nogc function 'attrib.avg!(Foo, Foo).avg'
//}
float foo_call()
{
return avg( Foo(1,10), Foo(8,2) ); // тут всё в порядке, мы повторно используем avg
}
void main()
{
writeln( call_nogc() );
writeln( foo_call() );
}
Управление и уборка в D