Implicit static->dynamic arr and modifying

H. S. Teoh via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue May 6 08:35:04 PDT 2014


On Tue, May 06, 2014 at 01:06:14AM -0700, Jonathan M Davis via Digitalmars-d-learn wrote:
> On Mon, 05 May 2014 22:16:58 -0400
> Nick Sabalausky via Digitalmars-d-learn
> <digitalmars-d-learn at puremagic.com> wrote:
> 
> > On 5/5/2014 10:11 PM, Nick Sabalausky wrote:
> > > Is this kinds stuff a sane thing to do, or does it just work by
> > > accident?:
> > >
> > > void modify(ubyte[] dynamicArr)
> > > {
> > >      dynamicArr[$-1] = 5;
> > > }
> > >
> > > void main()
> > > {
> > >      ubyte[4] staticArr = [1,1,1,1];
> > >      modify(staticArr);
> > >      assert(staticArr == [1,1,1,5]);
> > > }
> >
> > Duh, it's just using a normal slice of the static array...
> >
> > // Roughly:
> > dynamicArr.ptr = &staticArr;
> > dynamicArr.length = typeof(staticArr).sizeof;
> >
> > So all is well, and deliberately so. Pardon the noise.
> 
> It's definitely deliberate, though I think that it's a flaw in the
> language's design. IMHO, static arrays should never be automatically
> sliced, but unfortunately, changing that would break too much code at
> this point. The biggest problem is the fact that it's inherently
> unsafe, though unfortunately, the compiler currently considers it
> @safe:
> 
> https://issues.dlang.org/show_bug.cgi?id=8838
[...]

A particularly pernicious instance of this hole is the following:

	class C {
		int[] data;
		this(int[] args...) @safe {
			data = args;
		}
	}

	C f() @safe {
		return new C(1,2,3);
	}

	void main() {
		import std.stdio;
		writeln(f().data); // on my system, writes garbage
	}

Exercise for the reader: spot the bug.


T

-- 
English has the lovely word "defenestrate", meaning "to execute by
throwing someone out a window", or more recently "to remove Windows from
a computer and replace it with something useful". :-) -- John Cowan


More information about the Digitalmars-d-learn mailing list