June 03, 2017
On Saturday, 3 June 2017 at 19:55:30 UTC, ag0aep6g wrote:
> On 06/03/2017 09:37 PM, Moritz Maxeiner wrote:
>> Of course, but AFAIK you'd need to explicitly assign it to an object, so `ptr` won't null by accident, but only by explicit programmer intent (same as overwriting the memory the object lives in via things like `memcpy`); and you can always screw things intentionally (you could also assign some invalid value to the pointer via `memcpy`).
>
> I'd say `.init` can easily happen accidentally. Especially when `@disable this(this);` is involved.
>
> When you can't copy, you may have to move sometimes. But std.algorithm.move overwrites the old location with `.init`, assuming that `.init` can safely be destroyed.

Calling std.algorithm.move is explicit programmer intent, I consider that about as accidental as calling memcpy with a source full of zeroes.
In any case, having that check in the destructor is fairly cheap, so better safe than sorry (and include it).
June 03, 2017
On Saturday, 3 June 2017 at 20:13:30 UTC, Moritz Maxeiner wrote:

> Calling std.algorithm.move is explicit programmer intent, I consider that about as accidental as calling memcpy with a source full of zeroes.
> In any case, having that check in the destructor is fairly cheap, so better safe than sorry (and include it).

Yes, it's explicit. Destructor call is still implicit though, and it better not be performing null dereference or something equally nasty :)
June 03, 2017
On Saturday, 3 June 2017 at 20:25:22 UTC, Stanislav Blinov wrote:
> On Saturday, 3 June 2017 at 20:13:30 UTC, Moritz Maxeiner wrote:
>
>> Calling std.algorithm.move is explicit programmer intent, I consider that about as accidental as calling memcpy with a source full of zeroes.
>> In any case, having that check in the destructor is fairly cheap, so better safe than sorry (and include it).
>
> Yes, it's explicit. Destructor call is still implicit though, and it better not be performing null dereference or something equally nasty :)

Quite, but if you backtrack to my initial statement, it was about ptr not being/becoming null (implicitly) in the first place, which *might* allow you to skip the check (if you don't set it to null via external means, such as memcpy, move, etc).
June 03, 2017
On Saturday, 3 June 2017 at 20:53:05 UTC, Moritz Maxeiner wrote:
> On Saturday, 3 June 2017 at 20:25:22 UTC, Stanislav Blinov wrote:
>> On Saturday, 3 June 2017 at 20:13:30 UTC, Moritz Maxeiner wrote:
>>
>>> Calling std.algorithm.move is explicit programmer intent, I consider that about as accidental as calling memcpy with a source full of zeroes.
>>> In any case, having that check in the destructor is fairly cheap, so better safe than sorry (and include it).
>>
>> Yes, it's explicit. Destructor call is still implicit though, and it better not be performing null dereference or something equally nasty :)
>
> Quite, but if you backtrack to my initial statement, it was about ptr not being/becoming null (implicitly) in the first place, which *might* allow you to skip the check (if you don't set it to null via external means, such as memcpy, move, etc).

It's only true as long as you have full control of the source. Once you're using libraries and generic code, it's possible that it's out of your hands:

import core.stdc.stdio;
import std.exception;

// external library
struct RingBuffer(T,size_t size) {
    T[size] values = T.init; // the culprit
    // interface snipped...
}

// own code
struct FileWrapper {
    FILE* file;

    @disable this();
    @disable this(this);

    this(FILE* file) {
        enforce(file);
        this.file = file;
    }

    ~this() {
        fclose(file);
    }
}

void main() {
    // whoops, segfault
    RingBuffer!(FileWrapper,8) container;
}

June 03, 2017
On Saturday, 3 June 2017 at 21:16:08 UTC, Stanislav Blinov wrote:
> On Saturday, 3 June 2017 at 20:53:05 UTC, Moritz Maxeiner wrote:
>>
>> Quite, but if you backtrack to my initial statement, it was about ptr not being/becoming null (implicitly) in the first place, which *might* allow you to skip the check (if you don't set it to null via external means, such as memcpy, move, etc).
>
> It's only true as long as you have full control of the source.
> Once you're using libraries and generic code, it's possible that it's out of your hands:

It's always true, because I explicitly wrote *might*, not *will*, to indicate that it depends on your use case. Your example is a common use case where you can't skip the check.
June 03, 2017
On Saturday, 3 June 2017 at 21:39:54 UTC, Moritz Maxeiner wrote:
> On Saturday, 3 June 2017 at 21:16:08 UTC, Stanislav Blinov wrote:
>> On Saturday, 3 June 2017 at 20:53:05 UTC, Moritz Maxeiner wrote:
>>>
>>> Quite, but if you backtrack to my initial statement, it was about ptr not being/becoming null (implicitly) in the first place, which *might* allow you to skip the check (if you don't set it to null via external means, such as memcpy, move, etc).
>>
>> It's only true as long as you have full control of the source.
>> Once you're using libraries and generic code, it's possible that it's out of your hands:
>
> It's always true, because I explicitly wrote *might*, not *will*, to indicate that it depends on your use case. Your example is a common use case where you can't skip the check.

Programmers and their tight-binding logic...

- Honey, please buy a loaf of bread. If there are eggs, buy a dozen.
...
- Hello, do you have eggs?
- Yes.
- Dozen loaves of bread, please.

;)
June 03, 2017
On Saturday, 3 June 2017 at 21:46:45 UTC, Stanislav Blinov wrote:
> On Saturday, 3 June 2017 at 21:39:54 UTC, Moritz Maxeiner wrote:
>> It's always true, because I explicitly wrote *might*, not *will*, to indicate that it depends on your use case. Your example is a common use case where you can't skip the check.
>
> Programmers and their tight-binding logic...
>
> - Honey, please buy a loaf of bread. If there are eggs, buy a dozen.
> ...
> - Hello, do you have eggs?
> - Yes.
> - Dozen loaves of bread, please.
>
> ;)

That usually happens when two sides interpret an ambiguous statement ;)
1 2
Next ›   Last »