On Monday, 4 September 2017 at 09:47:12 UTC, Moritz Maxeiner
wrote:
On Monday, 4 September 2017 at 09:15:30 UTC, ag0aep6g wrote:
On 09/04/2017 06:10 AM, Moritz Maxeiner wrote:
Indeed, but it also means that - other than null
dereferencing - pointer issues can by made into reference
issues my dereferencing a pointer and passing that into a
function that takes that parameter by reference.
Why "other than null dereferencing"? You can dereference a
null pointer and pass it in a ref parameter. That doesn't
crash at the call site, but only when the callee accesses the
parameter:
[...]
Because I was ignorant and apparently wrong, thanks for the
correction.
Still, though, this is surprising to me, because this means
taking the address of a parameter passed by reference (which is
in your case is typed as an existing int) can be null. Is this
documented somewhere (couldn't find it in the spec and it seems
like a bug to me)?
LDC treats passing `null` to a reference parameter as UB.
It doesn't matter when the program crashes after passing null to
ref, exactly because it is UB.
Because the caller has to do the dereferencing (semantically) you
only have to do the null-check in the caller, and not in callee.
This removes a ton of manual null-ptr checks from the code, and
enables more optimizations too.
For class parameters, they are pointers not references, as in: it
is _not_ UB to pass-in `null`. Very unfortunate, because it
necessitates null-ptr checks everywhere in the code, and hurts
performance due to missed optimization opportunities.
(The spec requires crashing on null dereferencing, but this spec
bit is ignored by DMD and LDC, I assume in GDC too. Crashing on
`null` dereferencing requires a null-check on every dereferencing
through an unchecked pointer, because 0 might be a valid memory
access, and also because ptr->someDataField is not going to
lookup address 0, but 0+offsetof(someDataField) instead, e.g.
potentially addressing a valid low address at 1000000, say.)
- Johan