[libcxx-commits] [PATCH] D108080: [libcxx] simplifies nodiscard by permanently enabling the attribute...
Christopher Di Bella via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Aug 15 09:15:46 PDT 2021
cjdb added inline comments.
================
Comment at: libcxx/docs/UsingLibcxx.rst:274-281
+For this reason libc++ provides an extension that does just that! The extended
+applications of ``[[nodiscard]]`` take two forms:
1. Backporting ``[[nodiscard]]`` to entities declared as such by the
standard in newer dialects, but not in the present one.
2. Extended applications of ``[[nodiscard]]``, at the library's discretion,
----------------
Quuxplusone wrote:
> This PR seems acceptable to me. (I think it's likely better than the status quo, because it's simpler.) However, I'd still prefer to see libc++ distinguish the "conforming implementation" parts from the "non-conforming" parts. After all, this is supposed to be a valid C++ program, right?
> ```
> #include <utility>
> int main() { std::move(1); }
> ```
> With this PR, libc++ will refuse to compile that program, so libc++ won't technically be conforming anymore. This //could// piss off customers with big old codebases. Whenever we do an API-breaking change, it's useful to give customers a way to opt out of it.
>
> So, I counterpropose that we still do //most// of this simplification, but:
> - Continue to mark the extensions with `_LIBCPP_NODISCARD_EXT` instead of `_LIBCPP_NODISCARD`
> - Make `__config` look like this:
> ```
> #if __has_cpp_attribute(nodiscard) || defined(_LIBCPP_COMPILER_MSVC)
> # define _LIBCPP_NODISCARD [[nodiscard]]
> #elif defined(_LIBCPP_COMPILER_CLANG_BASED) && !defined(_LIBCPP_CXX03_LANG)
> # define _LIBCPP_NODISCARD [[clang::warn_unused_result]]
> #else
> // We can't use GCC's [[gnu::warn_unused_result]] and
> // __attribute__((warn_unused_result)), because GCC does not silence them via
> // (void) cast.
> # define _LIBCPP_NODISCARD
> #endif
>
> #if defined(_LIBCPP_DISABLE_NODISCARD_EXT) && _LIBCPP_DISABLE_NODISCARD_EXT
> # define _LIBCPP_NODISCARD_EXT
> #else
> # define _LIBCPP_NODISCARD_EXT _LIBCPP_NODISCARD
> #endif
> ```
> After all, this is supposed to be a valid C++ program, right?
> ```
> #include <utility>
> int main() { std::move(1); }
> ```
This is also a conforming C++20 program.
```
#include <vector>
int main()
{
auto v = std::vector{0, 1, 2};
v.empty(); // [[nodiscard]] as of C++20
}
```
> With this PR, libc++ will refuse to compile that program, so libc++ won't technically be conforming anymore.
Since `[[nodiscard]]` has no normative effect, both of our examples are technically conforming, with and without this patch.
> Whenever we do an API-breaking change, it's useful to give customers a way to opt out of it.
If a user doesn't want to/can't fix their broken code, there are still two ways they can opt out:
* Cast-to-void
* Enable `-Wno-unused-result`
> This //could// piss off customers with big old codebases.
I don't think we should hedge on the //possibility// of someone getting upset with libc++ because we now flag their buggy/questionable code (see my commit message). Let's apply it as-is, and if there are a substantial number of complaints, we can consider adding a libc++-specific knob then.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D108080/new/
https://reviews.llvm.org/D108080
More information about the libcxx-commits
mailing list