View mode: basic / threaded / horizontal-split · Log in · Help
January 14, 2012
Constant function/delegate literal
Hi,

Is there a reason why I cannot compile the following code:

module test;

struct Test {
   int delegate(int) f;
}

Test s = Test((int x) { return x + 1; });

void main(string[] args) {
   return;
}

dmd 2.057 says:

test.d(7): Error: non-constant expression cast(int delegate(int))delegate pure
nothrow @safe int(int x)
{
return x + 1;
}

?

This is simple example; what I want to do is to create a global variable
containing a structure with some ad-hoc defined functions. The compiler
complains that it "cannot evaluate .... at compile time". I think this could
be solved by defining a function returning needed structure, but I think this
is cumbersome and inconvenient.

Best regards,
Vladimir Matveev.
January 14, 2012
Re: Constant function/delegate literal
I guess these are CTFE (compile-time function evaluation) issues,
someone else might know more. A workaround is to use a module
constructor which will run before main():

struct Test {
  int delegate(int) f;
}

Test s;

static this() {
   s = Test((int x) { return x + 1; });
}

Note that 's' is thread-local, to make it shared across threads but
without implicit synchronization you can use:

__gshared Test s;

shared static this() {
   s = Test((int x) { return x + 1; });
}

Note the use of *shared* in the module ctor. Without 'shared' it would
run every time a new thread was spawned.
January 15, 2012
Re: Constant function/delegate literal
Thanks, that was very helpful. Module initializer works like a charm. Shame I
didn't find it in the documentation. Thanks again.

Best regards,
Vladimir.
January 15, 2012
Re: Constant function/delegate literal
On Sun, Jan 15, 2012 at 02:21:04PM +0000, Vladimir Matveev wrote:
> Thanks, that was very helpful. Module initializer works like a charm.
> Shame I didn't find it in the documentation. Thanks again.
[...]

It's discussed briefly in Andrei's book (section 11.3, p.356).


T

-- 
If it's green, it's biology, If it stinks, it's chemistry, If it has numbers it's math, If it doesn't work, it's technology.
January 15, 2012
Re: Constant function/delegate literal
On 01/14/2012 07:13 PM, Vladimir Matveev wrote:
> Hi,
>
> Is there a reason why I cannot compile the following code:
>
> module test;
>
> struct Test {
>      int delegate(int) f;
> }
>
> Test s = Test((int x) { return x + 1; });
>
> void main(string[] args) {
>      return;
> }
>
> dmd 2.057 says:
>
> test.d(7): Error: non-constant expression cast(int delegate(int))delegate pure
> nothrow @safe int(int x)
> {
> return x + 1;
> }
>
> ?
>
> This is simple example; what I want to do is to create a global variable
> containing a structure with some ad-hoc defined functions. The compiler
> complains that it "cannot evaluate .... at compile time". I think this could
> be solved by defining a function returning needed structure, but I think this
> is cumbersome and inconvenient.
>
> Best regards,
> Vladimir Matveev.

I think it should work. I have filed a bug report:
http://d.puremagic.com/issues/show_bug.cgi?id=7298
January 17, 2012
Re: Constant function/delegate literal
On 15/01/12 20:35, Timon Gehr wrote:
> On 01/14/2012 07:13 PM, Vladimir Matveev wrote:
>> Hi,
>>
>> Is there a reason why I cannot compile the following code:
>>
>> module test;
>>
>> struct Test {
>> int delegate(int) f;
>> }
>>
>> Test s = Test((int x) { return x + 1; });
>>
>> void main(string[] args) {
>> return;
>> }
>>
>> dmd 2.057 says:
>>
>> test.d(7): Error: non-constant expression cast(int
>> delegate(int))delegate pure
>> nothrow @safe int(int x)
>> {
>> return x + 1;
>> }
>>
>> ?

The 'this' pointer in the delegate:
Test((int x) { return x + 1; });

is a pointer to the struct literal, which isn't constant. You actually 
want it to point to variable s.

OTOH if it were a function, it should work, but it currently doesn't.

>>
>> This is simple example; what I want to do is to create a global variable
>> containing a structure with some ad-hoc defined functions. The compiler
>> complains that it "cannot evaluate .... at compile time". I think this
>> could
>> be solved by defining a function returning needed structure, but I
>> think this
>> is cumbersome and inconvenient.
>>
>> Best regards,
>> Vladimir Matveev.
>
> I think it should work. I have filed a bug report:
> http://d.puremagic.com/issues/show_bug.cgi?id=7298
>
>
January 17, 2012
Re: Constant function/delegate literal
On 01/17/2012 05:02 PM, Don Clugston wrote:
> On 15/01/12 20:35, Timon Gehr wrote:
>> On 01/14/2012 07:13 PM, Vladimir Matveev wrote:
>>> Hi,
>>>
>>> Is there a reason why I cannot compile the following code:
>>>
>>> module test;
>>>
>>> struct Test {
>>> int delegate(int) f;
>>> }
>>>
>>> Test s = Test((int x) { return x + 1; });
>>>
>>> void main(string[] args) {
>>> return;
>>> }
>>>
>>> dmd 2.057 says:
>>>
>>> test.d(7): Error: non-constant expression cast(int
>>> delegate(int))delegate pure
>>> nothrow @safe int(int x)
>>> {
>>> return x + 1;
>>> }
>>>
>>> ?
>
> The 'this' pointer in the delegate:
> Test((int x) { return x + 1; });
>
> is a pointer to the struct literal, which isn't constant.
> You actually want it to point to variable s.


The struct literal residing in static storage has a variable address?
Why would the context pointer point to the struct literal anyway? It is 
not required.

>
> OTOH if it were a function, it should work, but it currently doesn't.
>

It should even work for delegates. The context pointer would just be null.
Top | Discussion index | About this forum | D home