bottom type as parameter or local variable, does that make sense?

Timon Gehr timon.gehr at gmx.ch
Mon Jan 17 19:01:53 UTC 2022


On 1/17/22 18:53, Elronnd wrote:
> On Monday, 17 January 2022 at 16:11:03 UTC, Timon Gehr wrote:
>> if a type `A*` is a subtype of a type `B*`, then `A.sizeof>=B.sizeof`. 
>> `noreturn*` is a subtype of any `T*`. Hence, `noreturn.sizeof` should 
>> be at least `size_t.max` or even `∞`.
> 
> I don't think this is right; it must be that A.sizeof==B.sizeof.

Well, that clearly can't be the case, unless you want to claim that 
`int.sizeof==noreturn.sizeof==long.sizeof`:

```d
void main(){
      noreturn* null_;
      int* ip = null_;
      long* lp = null_;
      class C{ int* foo(){ return null_; } }
      class D:C{ override noreturn* foo(){ return null_; } }
      int* f(int* b){ return b+1; }
      long* g(long* b){ return b+1; }
      f(null_);
      g(null_);
}
```

In any case, to the question "how big is a value that can never be 
allocated", "∞" is a natural answer, even if you don't buy the 
derivation over subtyping.

> 
> B* f(B* b) { return b+1; }
> 
> What happens if you pass in an A*, and A.sizeof>B.sizeof? 

Just another reason why pointer arithmetic is unsafe. E.g., see what 
happens in C++, where class references are explicitly typed as pointers:

```c++
#include <iostream>
using namespace std;
struct B{ int x; };
struct A:B{ int y=123; };
B* f(B* b){ return b+1; }
int main(){ cout<<f(new A)->x<<'\n';  } // "123"
```


More information about the Digitalmars-d mailing list