Integer precision of function return types

Jonathan M Davis newsgroup.d at jmdavisprog.com
Fri Sep 27 21:17:19 UTC 2024


On Friday, September 27, 2024 2:13:45 PM MDT thinkunix via Digitalmars-d-learn 
wrote:
> monkyyy via Digitalmars-d-learn wrote:
> > On Friday, 27 September 2024 at 04:23:32 UTC, thinkunix wrote:
> >> What about using 'auto' as the return type?
> >> I tried it and it seemed to work OK.
> >>
> >> Wondering if there are any good reasons to use auto,
> >> or bad reasons why not to use auto here?
> >
> > You have started a style debate that will last a week, great work
>
> That was not my intent.  It was an honest question.  I'm here to learn
> and not looking to start debates or for attitude.
>
> I've seen a lot of "use auto everywhere" especially in C++ and was
> wondering where the D community stands on it's use.  Is it generally
> favored or not?
>
> Personally, I think auto makes understanding code harder for humans.
> But in this example, it seemed like auto was a good fit.

Well, I don't think that auto is a particularly controversial topic among D
programmers, but there's no question that in at least some cases, it becomes
a question of preference and style.

auto is used heavily in D, and for some kinds of code, it has to be. In
particular, range-based code routinely returns "Voldemort" types (types
which you can't name) from a function. You care that it's a range (so that
needs to be clear from the documentation), but you're not supposed to know
or care what the actual type is. Before we had that, the signatures for a
lot of range-based functions (e.g. most of std.algorithm) were actually
pretty terrible to read and understand, because the explicit types were so
long and messy (since it's very common for ranges to wrap one another, and
they're usually templated). In a lot of those situations, you really only
care about the API of the type and not what the exact type is. So, auto
simplifies the code considerably and makes it easier to understand.

auto is also pretty critical in generic code in general, because it allows
you to not worry about the exact type you're dealing with. You just need to
worry about which kinds of operations work with that particular type. So,
variables get declared as auto all the time in typical D code. A lot of D
programmers will only use the type explicitly with variables if they want to
force a particular type or if they think that it makes that code easier to
understand.

auto can also make code more maintainable in that when refactoring code, the
type will update automatically, so if it changes, you don't have to change
it all over the place. On the flip side though, it does make it harder to
know what types you're dealing with, which can sometimes make it harder to
read and maintain code. So, when auto isn't actually needed, there's always
going to be some debate about whether it's better to use auto or not, and
that's subjective enough that you're really going to have to decide on your
own what works for you.

Also, for better or worse, because the function has to be compiled to
determine the actual return type (so it won't work with function prototypes
like in .di file), function attributes are inferred for auto return
functions just like they are for templated functions, so some D programmers
will make functions auto just to get the attribute inference.

I would guess that as a general rule, most folks prefer explicit types in
function signatures where auto isn't needed simply because it's
self-documenting at that point. So, I would think that most D programmers
would use an explicit type with the function being discussed in this thread,
but auto will certainly work just fine. Without any explicit casts within
the function, because doing math on char or ubyte results in int, the result
is going to be int (as opposed to uint like in the original post). So, if
that works for what the function is intended for, and the documentation is
clear about what's being returned, then it's not a problem.

However, in this particular case, it's arguably better to return ubyte than
int or uint. That's because the result will always fit within a ubyte, and
if you don't return a ubyte, the caller is going to have to cast to ubyte to
do something like assign the value to a ubyte. So, simply returning auto
as-is arguably isn't desirable. That being said, you can still use auto if
you want to. Because the math results in int, casts to ubyte will be
required regardless of whether the return type in the signature is ubyte or
auto, but you could choose to use auto and have the result be ubyte thanks
to the casts.

Ultimately though, I would argue that in this case, auto just makes the code
harder to understand. The documentation can easily say that the return type
is ubyte in spite of it saying auto, but it's just as easy to type ubyte,
and then the return type is immediately obvious instead of requiring
additional documentation just to say what's being returned. So, while auto
is used quite heavily in D code, I wouldn't expect many folks to choose to
use auto for this particular function.

- Jonathan M Davis





More information about the Digitalmars-d-learn mailing list