Passing struct to function
Steven Schveighoffer
schveiguy at yahoo.com
Wed Jun 13 17:37:44 UTC 2018
On 6/13/18 1:08 PM, Michał wrote:
> On Wednesday, 13 June 2018 at 16:40:51 UTC, Steven Schveighoffer wrote:
>> On 6/13/18 10:43 AM, Michał wrote:
>>> When I pass my struct to function something is going wrong. I don't
>>> know how to fix it.
>>>
>>> Code:
>>> import std.stdio;
>>>
>>>
>>> void print(ref Vector v, string s){
>>> writefln("%s==%s %s", &v.x, v.ptr, s);
>>> }
>>>
>>> struct Vector {
>>> int x;
>>> int* ptr;
>>>
>>> this(this) {
>>> ptr = &x;
>>> print(this, "postblit");
>>> }
>>> }
>>>
>>> void someFunc(Vector t) {
>>> print(t, "in someFunc");
>>> }
>>>
>>> void main() {
>>> auto tmpA = Vector();
>>> tmpA.ptr = &tmpA.x;
>>> print(tmpA, "start");
>>>
>>> someFunc(tmpA);
>>> }
>>>
>>>
>>> Result on my machine:
>>> 7FFF7D70BC00==7FFF7D70BC00 start
>>> 7FFF7D70BBF0==7FFF7D70BBF0 postblit
>>> 7FFF7D70BBD0==7FFF7D70BBF0 in someFunc
>>>
>>> In the last line pointers are not matching. I thought that postblit
>>> will do the thing but it is not the case. How to make 'ptr' to be
>>> null or '&this.x' all the time?
>>
>> D allows moving any struct instance without calling postblit, as long
>> as the original is no longer used.
>>
>> The optimizer is likely seeing here that the memory can be copied
>> without calling postblit, because nobody is using tmpA after the call.
>>
>> In general, you should NOT store an internal pointer in a struct,
>> unless you allocate it on the heap.
>>
>> -Steve
>
>
> I need internal pointer because I want to implement vector(like in C++)
> with 'small vector optimization', when i have internal pointer it is
> very easy and functions like 'add' don't have additional checks.
>
> If storing internal pointers is forbidden do you know some way to
> implement 'small vector optimization' without additional checks in 'add'
> function?
Hm... the only way to do it in D is to provide a function that checks
whether the small vector optimization is in play, and return a
pointer/slice to itself.
With D it is possible to alias the getter function that provides the
actual data to allow code to look nicer.
For example (crude example):
struct Vector(T)
{
bool svo; // small vector optimization
union
{
T[4] local;
T[] heap;
}
inout(T)[] get() inout { return svo ? local[], heap; }
alias get this;
... // implement specialized append, concat operators, etc.
}
Now, you can use Vector as if it were an array, and it just works.
-Steve
More information about the Digitalmars-d-learn
mailing list