www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - cannot call impure function ~this

reply "Namespace" <rswhite4 googlemail.com> writes:
I get this error:
----
/d701/f223.d(11): Error: pure function 'f223.getA' cannot call 
impure function 'f223.A.~this'
----

with this code:
----
import std.stdio;

struct A {
public:
	~this() {
		writeln("DTor");
	}
}

A getA() pure nothrow {
	return A();
}

void main()
{
	A a = getA();
	
	writeln("end of main");
}
----

But without pure and nothrow I get this output:
----
end of main
DTor
----

Why the compiler thinks that the function should/could call 
A::~this?
Oct 15 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Tuesday, 15 October 2013 at 21:37:40 UTC, Namespace wrote:
 I get this error:
 ----
 /d701/f223.d(11): Error: pure function 'f223.getA' cannot call 
 impure function 'f223.A.~this'
 ----

 with this code:
 ----
 import std.stdio;

 struct A {
 public:
 	~this() {
 		writeln("DTor");
 	}
 }

 A getA() pure nothrow {
 	return A();
 }

 void main()
 {
 	A a = getA();
 	
 	writeln("end of main");
 }
 ----

 But without pure and nothrow I get this output:
 ----
 end of main
 DTor
 ----

 Why the compiler thinks that the function should/could call 
 A::~this?
It could have something to do with the fact that RVO is an optimization *opportunity* that the compiler is allowed to go for, even if it changes the program output. Hoewever, being an *opportunity*, the compiler still has to make sure the code is valid without said optimization, which in this case, isn't: getA would destroy it's temporary after blitting it on the stac, leading to an impure call.
Oct 16 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Wednesday, 16 October 2013 at 07:23:45 UTC, monarch_dodra 
wrote:
 On Tuesday, 15 October 2013 at 21:37:40 UTC, Namespace wrote:
 I get this error:
 ----
 /d701/f223.d(11): Error: pure function 'f223.getA' cannot call 
 impure function 'f223.A.~this'
 ----

 with this code:
 ----
 import std.stdio;

 struct A {
 public:
 	~this() {
 		writeln("DTor");
 	}
 }

 A getA() pure nothrow {
 	return A();
 }

 void main()
 {
 	A a = getA();
 	
 	writeln("end of main");
 }
 ----

 But without pure and nothrow I get this output:
 ----
 end of main
 DTor
 ----

 Why the compiler thinks that the function should/could call 
 A::~this?
It could have something to do with the fact that RVO is an optimization *opportunity* that the compiler is allowed to go for, even if it changes the program output. Hoewever, being an *opportunity*, the compiler still has to make sure the code is valid without said optimization, which in this case, isn't: getA would destroy it's temporary after blitting it on the stac, leading to an impure call.
So it _could_ be impure, but mostly it isn't, right?
Oct 16 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 16 October 2013 at 07:27:25 UTC, Namespace wrote:
 On Wednesday, 16 October 2013 at 07:23:45 UTC, monarch_dodra 
 wrote:
 On Tuesday, 15 October 2013 at 21:37:40 UTC, Namespace wrote:
 I get this error:
 ----
 /d701/f223.d(11): Error: pure function 'f223.getA' cannot 
 call impure function 'f223.A.~this'
 ----

 with this code:
 ----
 import std.stdio;

 struct A {
 public:
 	~this() {
 		writeln("DTor");
 	}
 }

 A getA() pure nothrow {
 	return A();
 }

 void main()
 {
 	A a = getA();
 	
 	writeln("end of main");
 }
 ----

 But without pure and nothrow I get this output:
 ----
 end of main
 DTor
 ----

 Why the compiler thinks that the function should/could call 
 A::~this?
It could have something to do with the fact that RVO is an optimization *opportunity* that the compiler is allowed to go for, even if it changes the program output. Hoewever, being an *opportunity*, the compiler still has to make sure the code is valid without said optimization, which in this case, isn't: getA would destroy it's temporary after blitting it on the stac, leading to an impure call.
So it _could_ be impure, but mostly it isn't, right?
I guess that's one way to put it. I'd say it *is* impure, but all its impure bits have been optimized out. That's my explanation anyways. I'm curious: Is this a problem for you? The function calling getA *can't* be pure either, so marking getA as pure is ... I was going to say useless, but I guess "pure" is always an optimization opportunity for the compiler. I'd file an ER, you never know.
Oct 16 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Wednesday, 16 October 2013 at 07:32:27 UTC, monarch_dodra 
wrote:
 On Wednesday, 16 October 2013 at 07:27:25 UTC, Namespace wrote:
 On Wednesday, 16 October 2013 at 07:23:45 UTC, monarch_dodra 
 wrote:
 On Tuesday, 15 October 2013 at 21:37:40 UTC, Namespace wrote:
 I get this error:
 ----
 /d701/f223.d(11): Error: pure function 'f223.getA' cannot 
 call impure function 'f223.A.~this'
 ----

 with this code:
 ----
 import std.stdio;

 struct A {
 public:
 	~this() {
 		writeln("DTor");
 	}
 }

 A getA() pure nothrow {
 	return A();
 }

 void main()
 {
 	A a = getA();
 	
 	writeln("end of main");
 }
 ----

 But without pure and nothrow I get this output:
 ----
 end of main
 DTor
 ----

 Why the compiler thinks that the function should/could call 
 A::~this?
It could have something to do with the fact that RVO is an optimization *opportunity* that the compiler is allowed to go for, even if it changes the program output. Hoewever, being an *opportunity*, the compiler still has to make sure the code is valid without said optimization, which in this case, isn't: getA would destroy it's temporary after blitting it on the stac, leading to an impure call.
So it _could_ be impure, but mostly it isn't, right?
I guess that's one way to put it. I'd say it *is* impure, but all its impure bits have been optimized out. That's my explanation anyways. I'm curious: Is this a problem for you? The function calling getA *can't* be pure either, so marking getA as pure is ... I was going to say useless, but I guess "pure" is always an optimization opportunity for the compiler. I'd file an ER, you never know.
No, I was just curious what's behind it. So specifically why the compiler could call the destructor.
Oct 16 2013
parent reply "Kenji Hara" <k.hara.pg gmail.com> writes:
On Wednesday, 16 October 2013 at 07:58:09 UTC, Namespace wrote:
 On Wednesday, 16 October 2013 at 07:32:27 UTC, monarch_dodra 
 wrote:
 On Wednesday, 16 October 2013 at 07:27:25 UTC, Namespace wrote:
 On Wednesday, 16 October 2013 at 07:23:45 UTC, monarch_dodra 
 wrote:
 On Tuesday, 15 October 2013 at 21:37:40 UTC, Namespace wrote:
 I get this error:
 ----
 /d701/f223.d(11): Error: pure function 'f223.getA' cannot 
 call impure function 'f223.A.~this'
 ----

 with this code:
 ----
 import std.stdio;

 struct A {
 public:
 	~this() {
 		writeln("DTor");
 	}
 }

 A getA() pure nothrow {
 	return A();
 }

 void main()
 {
 	A a = getA();
 	
 	writeln("end of main");
 }
 ----

 But without pure and nothrow I get this output:
 ----
 end of main
 DTor
 ----

 Why the compiler thinks that the function should/could call 
 A::~this?
It could have something to do with the fact that RVO is an optimization *opportunity* that the compiler is allowed to go for, even if it changes the program output. Hoewever, being an *opportunity*, the compiler still has to make sure the code is valid without said optimization, which in this case, isn't: getA would destroy it's temporary after blitting it on the stac, leading to an impure call.
So it _could_ be impure, but mostly it isn't, right?
I guess that's one way to put it. I'd say it *is* impure, but all its impure bits have been optimized out. That's my explanation anyways. I'm curious: Is this a problem for you? The function calling getA *can't* be pure either, so marking getA as pure is ... I was going to say useless, but I guess "pure" is always an optimization opportunity for the compiler. I'd file an ER, you never know.
No, I was just curious what's behind it. So specifically why the compiler could call the destructor.
In this case, the created struct literal A() will be moved out to the function getA(). So dtor is not called and compiler should not cause "cannot call impure function" error. I filed a bug report and posted possible compiler fix. http://d.puremagic.com/issues/show_bug.cgi?id=11286 https://github.com/D-Programming-Language/dmd/pull/2677 Kenji Hara
Oct 17 2013
parent "Namespace" <rswhite4 googlemail.com> writes:
 In this case, the created struct literal A() will be moved out 
 to the function getA(). So dtor is not called and compiler 
 should not cause "cannot call impure function" error.

 I filed a bug report and posted possible compiler fix.

 http://d.puremagic.com/issues/show_bug.cgi?id=11286
 https://github.com/D-Programming-Language/dmd/pull/2677

 Kenji Hara
Nice, thank you!
Oct 17 2013