(Only half joking with the poll options, too.)

  • @corroded
    link
    2
    edit-2
    3 days ago

    When would this actually be necessary? Realistically, I see two possibilities.

    1 - The function’s purpose is to generate a result value, meaning that ignoring the result is a waste of a function call and any resources consumed by the function. In this case, though, nobody would ever be calling the function unless they specifically wanted the result.

    2 - The caller must take ownership of the result. In this case, just don’t return raw pointers.

    The addition of [[nodiscard]] suggests that there are valid reasons, but I have never personally come across one.

    • @[email protected]OP
      link
      fedilink
      English
      13 days ago

      Consider, say, the printf family of functions. The side-effect of their invocation is quite notorious and clear: print something to the screen, or write it to a file, etc. This kind of thing is not expressable (and should not be expressed as) as a return type. But these functions do have a return value: a status code indicating whether the write-to-medium was successful or else why. It’s so easy to discard this information and end up eg.: ignorin a write that didn’t happen because there was not enough room, or writing more bytes than the destination buffer could afford to take (hellooooo, buffer overflow!).

      There are lots of functions (probably entire categories, but I’m not that strong on type theory) where the “result” is vastly different from the “return” or can not be expressed as such. Foremost cases I can come up with are I/O, stuff on complex types where types also represent actions or components with side effects (eg.: GUIs), and pretty much anything about inserting or removing elements from containers. In those cases, if the two things differ but the return is also important, it’d be nice to have a mechanism to make sure that it can’t be accidentally ignored (explicit, intentional ignoring is fine; that’s what we have (void)(expr...) in the language).

      Another reason for having this capability is having a function with a composite return-result type, such as a std::expected<T,E> where you want to help make sure the composition is handled correctly by the caller.