View mode: basic / threaded / horizontal-split · Log in · Help
December 10, 2012
Re: Problem with const correctness
On Monday, 10 December 2012 at 11:39:24 UTC, Thiez wrote:
> On Saturday, 8 December 2012 at 21:47:32 UTC, Dan wrote:
>> My approach is to have a general dup function. I call it gdup, 
>> for global dup so the name does not conflict with the existing 
>> dup. It dup's fields recursively. Feel free to have a look and 
>> any suggestions appreciated. Would greatly appreciate if 
>> seasoned D developers like (Ali,  bearophile, ...) would 
>> review - as I use these mixins to simplify development with 
>> structs.
>
> What would happen to the recursive dup if the structure 
> contains a cycle (e.g. A has a reference to B, which has a 
> reference to C, which has a reference to the original A)?

By reference I assume you mean pointer.

That would be an infinite loop. If you have a compile time cycle 
you would likely need your own custom dups anyway, as you are 
doing low level and heap allocating already. But for the simpler 
cases without cycles, if dup encounters a pointer it creates a 
new instance on the heap (if compilation is possible) and dup's 
into it.
December 10, 2012
Re: Problem with const correctness
On Monday, 10 December 2012 at 12:45:16 UTC, Dan wrote:
> That would be an infinite loop. If you have a compile time 
> cycle you would likely need your own custom dups anyway, as you 
> are doing low level and heap allocating already. But for the 
> simpler cases without cycles, if dup encounters a pointer it 
> creates a new instance on the heap (if compilation is possible) 
> and dup's into it.

Wouldn't it be better to do a cycle detection here? I imagine 
such a thing could be done quite easily by adding every pointer 
in the original struct to an associative array along with its 
(new) copy. Then, whenever you encounter a new pointer, you can 
check if it is already in the AA, and if so use the copy you made 
before. Of course this has some overhead compared to your 
suggestion, but it seems to me it would be safe in all cases, 
which makes more sense with a 'general dup'.
December 10, 2012
Re: Problem with const correctness
On Monday, 10 December 2012 at 13:37:46 UTC, Thiez wrote:
> On Monday, 10 December 2012 at 12:45:16 UTC, Dan wrote:
>> That would be an infinite loop. If you have a compile time 
>> cycle you would likely need your own custom dups anyway, as 
>> you are doing low level and heap allocating already. But for 
>> the simpler cases without cycles, if dup encounters a pointer 
>> it creates a new instance on the heap (if compilation is 
>> possible) and dup's into it.
>
> Wouldn't it be better to do a cycle detection here? I imagine 
> such a thing could be done quite easily by adding every pointer 
> in the original struct to an associative array along with its 
> (new) copy. Then, whenever you encounter a new pointer, you can 
> check if it is already in the AA, and if so use the copy you 
> made before. Of course this has some overhead compared to your 
> suggestion, but it seems to me it would be safe in all cases, 
> which makes more sense with a 'general dup'.

I see a few possibilities:

(0) Do nothing and caveat coder

(1) Compile time check for possibility of cycle and if exists do 
not compile. This way the scenario you mention, which may or may 
not really have instance cycles, would not even compile. This may 
be overly aggressive.

(2) Compile time check for possibility of cycle and runtime 
checks ensuring there are none.

(3) Disallow dup on structs with embedded pointers (excepting 
array and associative array). Similar to (0) but now basic 
structs with pointers to other basic structs and no chance of 
cycles would not be dupable.

I'm fine with any of these because I figure if you are allocating 
your own objects you probably want to write your own postblit and 
dup. But, you are correct, cycle detection at runtime would be 
better - assuming there was no runtime performance hit for the 
case when cycles are not possible which is known at compile time.

I'm not so sure it is as easy as a simple AA, though.
-------
struct S {
 struct Guts {
 }
 Guts guts;
}
S s;
-------

In this case both &s and &s.guts have the same address. So you 
might want to have an AA per type? But where would those exist? 
On the stack? If so how would you pass it through to all the 
recursive calls?

I'm not saying it is not doable - I just think it may be a pretty 
big effort.

Thanks,
Dan
Next ›   Last »
1 2
Top | Discussion index | About this forum | D home