GC.malloc is pure - wat

ag0aep6g via Digitalmars-d digitalmars-d at puremagic.com
Thu Mar 31 15:18:03 PDT 2016


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.


More information about the Digitalmars-d mailing list