Bug 24166 – strange errors returning references to void

Status
NEW
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-09-27T09:35:40Z
Last change time
2024-12-13T19:31:00Z
Assigned to
No Owner
Creator
John Colvin
Moved to GitHub: dmd#20336 →

Comments

Comment #0 by john.loughran.colvin — 2023-09-27T09:35:40Z
Starting with a correct program as a baseline: auto ref foo(T)(T[] a, size_t i) { return a[i]; } void main() { int[] a = [1,2,3]; blah(&foo(a, 1)); } void blah(void* a) { import std.stdio : writeln; writeln(a); // prints some pointer value } now moving on to some odd situations. Changing `a` to be `void[]`: auto ref foo(T)(T[] a, size_t i) { return a[i]; } void main() { void[] a = [1,2,3]; blah(&foo(a, 1)); } void blah(void* a) { import std.stdio : writeln; writeln(a); } onlineapp.d(2): Deprecation: `a[i]` has no effect onlineapp.d(7): Error: `foo(a, 1LU)` is not an lvalue and cannot be modified Strange, `foo` is not inferred as `ref`. Ok, let's force it by removing that `auto` ref foo(T)(T[] a, size_t i) { return a[i]; } void main() { void[] a = [1,2,3]; blah(&foo(a, 1)); } void blah(void* a) { import std.stdio : writeln; writeln(a); } onlineapp.d(2): Deprecation: `a[i]` has no effect C well that's odd! That statement should definitely have an effect. But what's also strange is that `C` is an unlikely pointer value (it prints `3` on another machine I tried). Let's try with ldc: onlineapp.d(2): Deprecation: `a[i]` has no effect Invalid bitcast %16 = bitcast void <badref> to i8*, !dbg !3044 LLVM ERROR: Broken module found, compilation aborted! #0 0x0000564ffa018667 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/dlang/ldc-1.34.0/bin/ldc2+0x6632667) Error: Error executing /dlang/ldc-1.34.0/bin/ldc2: Aborted (core dumped) oh dear...
Comment #1 by razvan.nitu1305 — 2023-10-09T15:13:38Z
I don't think that void arrays where defined so you can return individual elements. This opens a big hole in the type system. Consider the function signature: void foo(void[] b); When you look at this signature you understand that the function does not return anything. From that point of view, I was expecting that: ref void foo(void[] b); would yield a compilation error, but currently it does not (I would argue that this needs to be fixed, the compiler probably just ignores the ref). So, you do not expect that foo actually returns anything. But when void arrays come into play: void foo(void[] b) { return b[0]; } the signature of foo could mean 2 things: either you don't return nothing or you return a void variable. How would you even store that thing, cause you cannot declare a void variable and you cannot assign the value of a void function. So, my 2 cents: void arrays where designed just to be used inside the boundaries of a function: you store some data you receive from the network, you cast it to the appropriate type and then you return it. If you want to escape an element of the void array, you need to cast it. So the compiler is right to report the deprecation on line "return a[i]" but I guess it could be more explicit: "void functions cannot return elements of void arrays. If you want to return the element, please cast it to the appropriate type."
Comment #2 by robert.schadek — 2024-12-13T19:31:00Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20336 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB