--- void f() { void[] arr; size_t* _length = &arr.length; // Error: arr.length is not an lvalue void** _ptr = &arr.ptr; // Error: cast(void*)arr is not an lvalue } --- What is the case not to behave like a struct of two elements? Workaround: --- size_t* arrayLengthRef(T)(ref T[] arr) { return (cast(size_t*)&arr); } T** arrayPtrRef(T)(ref T[] arr) { return (cast(T**)&arr) + 1; } ---
arr.length is a read/write property. Writing length is not a simple field set, it calls a runtime function. arr.ptr is a read only property. Setting these must be done in tandem, and is done via the slicing interface or via the length set operation. You can circumvent as you say, but it should not be easy, since it is very dangerous.