cannot call impure function ~this

Kenji Hara k.hara.pg at gmail.com
Thu Oct 17 01:48:38 PDT 2013


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


More information about the Digitalmars-d-learn mailing list