On 31.03.2016 23:25, Nordlöw wrote:
A solution is to fake purity through
extern(C) pure nothrow @system @nogc
{
void* malloc(size_t size);
void* realloc(void* ptr, size_t size);
void free(void* ptr);
}
Pay attention to the use of malloc() though.
Note that this makes malloc() strongly pure (its single parameters is
passed by value).
As has been explained to me in this very thread, the fact that malloc
returns a pointer to mutable data makes it not strongly pure.
See
http://klickverbot.at/blog/2012/05/purity-in-d/#indirections-in-the-return-type
Therefore successive calls to malloc() with the same
argument will be optimized away and all those calls will return the same
values as the first call. When used in allocators this shouldn't be a
problem, though.
Uh, as far as I see, that would be catastrophic.
I feel like I must be missing something here again, but it looks like
dmd actually gets this wrong:
----
extern(C) void* malloc(size_t size) pure nothrow;
void main()
{
auto a = cast(ubyte*) malloc(1);
auto b = cast(ubyte*) malloc(1);
import std.stdio;
writeln(a is b); /* should be false */
*a = 1;
*b = 2;
writeln(*a); /* should be 1 */
}
----
Compiled with dmd and no optimization switches, this prints "false" and
"1" as expected.
Compiled with `dmd -O -release`, this prints "true" and "2". The heck?
With `ldc2 -O5 -release`: "false" and "1". No problem there.
This looks like a serious bug in dmd to me.