Integer precision of function return types

Quirin Schroll qs.il.paperinik at gmail.com
Thu Sep 26 21:17:44 UTC 2024


On Thursday, 26 September 2024 at 06:53:12 UTC, Per Nordlöw wrote:
> Should a function like
>
> ```d
> uint parseHex(in char ch) pure nothrow @safe @nogc {
> 	switch (ch) {
> 	case '0': .. case '9':
> 		return ch - '0';
> 	case 'a': .. case 'f':
> 		return 10 + ch - 'a';
> 	case 'A': .. case 'F':
> 		return 10 + ch - 'A';
> 	default:
> 		assert(0, "Non-hexadecimal character");
> 	}
> }
> ```
>
> instead return an ubyte?

```d
ubyte parseHex(immutable char ch) pure nothrow @safe @nogc {
	switch (ch) {
	case '0': .. case '9':
		return (ch - '0') & 0x0F;
	case 'a': .. case 'f':
		return (10 + ch - 'a') & 0x0F;
	case 'A': .. case 'F':
		return (10 + ch - 'A') & 0x0F;
	default:
		assert(0, "Non-hexadecimal character");
	}
}
```

I’d say yes, use `ubyte`. I also did two things:
- `(…) & 0x0F` to enable value-range propagation. Essentially, 
the compiler understands that the result of `&` will only ever be 
the minimum of the operands and one operand is `0x0F` which fits 
in a `ubyte`, therefore the expression implicitly converts. 
Always use implicit conversions when they avoid using `cast`. 
With `cast`, in general, you can do bad things. The compiler only 
allows safe casts implicitly, even in `@system` code. Your code 
is marked `@safe`, but this is general advice.
- I removed `in` from the parameter and used `immutable`. The 
`in` storage class means `const` as of now, but with the 
`-preview=in` and `-preview=dip1000` switches combined, it also 
means `scope` and `scope` means something to DIP1000, which can 
become dangerous on `@system` code. Do not use `in` unless you 
know why exactly you’re using it.

Also, for what it’s worth, you could use an `in` and `out` 
contract.


More information about the Digitalmars-d-learn mailing list