www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Constant function/delegate literal

reply Vladimir Matveev <dpx.infinity gmail.com> writes:
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.
Jan 14 2012
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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.
Jan 14 2012
parent reply Vladimir Matveev <dpx.infinity gmail.com> writes:
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.
Jan 15 2012
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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.
Jan 15 2012
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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
Jan 15 2012
parent reply Don Clugston <dac nospam.com> writes:
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
Jan 17 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
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.
Jan 17 2012