Antipattern in core.memory.GC.addRange?

Steven Schveighoffer schveiguy at yahoo.com
Sat Sep 23 15:53:45 UTC 2017


On 9/23/17 1:30 AM, safety0ff wrote:
> On Friday, 22 September 2017 at 21:29:10 UTC, Steven Schveighoffer wrote:
>> GC.addRange has this signature:
>>
>> static nothrow @nogc void addRange(in void* p, size_t sz, const 
>> TypeInfo ti = null);
>>
>> I see a large problem with this. Let's say you malloc an array of 
>> struct pointers:
>>
>> struct Foo { ... }
>>
>> import core.stdc.stdlib;
>> auto ptrs = (cast(Foo *)malloc(Foo.sizeof * 10))[0 .. 10];
>>
>> Now, you want to store GC pointers in that block, you need to add the 
>> range to the GC:
>>
>> GC.addRange(ptrs.ptr, ptrs.length);
>>
>> See the problem?
> 
> Yes, you forgot to multiply by Foo.sizeof.
> 
> Using the pattern from the example in the documentation,
> the code would be:
> 
> size_t bytes = Foo.sizeof * 10;
> auto ptrs = (cast(Foo *)malloc(bytes))[0 .. 10];
> GC.addRange(ptrs.ptr, bytes);
> 

Right, the problem is that the API accepts this without error, because 
of the implicit cast to void *.

The simple rule should be that if we can prevent something obviously 
wrong from compiling, we should do so.

-Steve


More information about the Digitalmars-d mailing list