Should modifying private members be @system?
ag0aep6g
anonymous at example.com
Fri Oct 4 12:13:29 UTC 2019
On Friday, 4 October 2019 at 11:55:11 UTC, Dennis wrote:
> ```
> struct SmallSlice(T) {
> private T* ptr = null;
> private ushort _length = 0;
> ubyte[6] extraSpace;
>
> this(T[] slice) @safe {
> ptr = &slice[0];
> assert(slice.length <= ushort.max);
> _length = cast(ushort) slice.length;
> }
>
> T opIndex(size_t i) @trusted {
> return ptr[0.._length][i];
> }
> }
> ```
>
> The use of @trusted seems appropriate here, right?
No.
> I'm doing pointer slicing, but I know that the _length member
> is correct for ptr since it came from a slice.
You don't know that in opIndex. In opIndex you just know that
there's a `T* ptr` and a `size_t _length`. opIndex doesn't know
where they came from or if they're compatible.
> The struct couldn't have been void-initialized or overlapped in
> a union since that's not allowed in @safe code when there are
> pointer members. Using { initializers } is not allowed since I
> have a constructor, and the members are private so they can't
> be modified outside of my (thoroughly audited) module.
You're not marking the module as @trusted. You're marking
opIndex. When you justify @trusted with something outside the
marked function, you're misusing it.
Unfortunately, breaking the rules like this is rather common. But
it's still breaking the rules. It's still undermining @safe.
[...]
> I'm tossing the idea that __traits(getMembers) should be
> @system when it's bypassing visibility constraints of the
> member. What do you think?
My best idea so far (might not be originally mine) is to let the
@system attribute apply to variables. You'd mark `_length` as
@system and the effect would be that @safe functions would not be
allowed to access it.
More information about the Digitalmars-d
mailing list