I'm curious about how people feel this should/could behave with -fno-exceptions. IIRC, Libc++ calls the copy constructor (following the standard), but -fno-exceptions isn't really standard, and from a user perspective that doesn't make sense. `noexcept` is essentially meaningless with -fno-exceptions.
I personally feel like it would be surprising if -fno-exceptions caused the move constructor to be called instead of the copy constructor. My mental model is that -fno-exceptions only disables exceptions as a language feature, but doesn't really instruct libraries to provide a different API (even though the difference in this case is very small). Instead, I feel like it would make more sense if "everything" was implicitly marked noexcept when -fno-exceptions is used (because that's really the case). The library would behave optimally with -fno-exceptions without having to do anything special.
IIUC what you’re saying: the library should just use the noexcept operator to do its business, and it seem like -fno-exceptions should make noexcept always return true? That would be pretty consistent (more than teaching the library about -fno-exceptions for move / copy).
Yes, that's what I mean. I agree with Eric that moving instead of copying provides value, but I think the right way to do it is not to special case libc++, but instead to have all code bases become better under -fno-exceptions by making noexcept do the right thing.
Yeah, that makes sense to me too.
+Richard, I could have sworn you and I chatted quickly about this back in 2016 by my mail-search-fu is failing me. What are your thoughts on having -fno-exceptions affect the value of `noexcept`?
Here are some questions I'd want to have answers to:
* How does this impact GCC compatibility?
* How does this impact the size and performance of generated code?
* Would an exception result in a guaranteed call to terminate like in
a real noexcept function, or undefined behavior as in today's
-fno-exceptions?
* What's the impact on C++17 code, now that 'noexcept' is part of the
type system? Given
void f();
... is that a function with a non-noexcept function type, with
noexcept(f()) being true, or is the type of f also adjusted to 'void()
noexcept'? Both answers seem troublesome.
* What migration strategy do we provide or encourage, in order to
help people move away from the -fno-exceptions language dialect and
back to standard C++? How does this change enable / hinder that?
Longer-term, "Clang should drive the standard, not diverge from it"
(Clang - Get Involved). We should be thinking about
the long term direction of exceptions in C++, and in particular Herb's
P0709. In that vein (particularly considering P0709R2's footnote 10
and nearby text) I'm wondering if we should have an experimental
option to specify that functions are noexcept by default (overridable
by an explicit exception specification) as a bridge for
-fno-exceptions users to take back towards standard C++.
Regardless of whatever else we do, I think we should work to make use
of noexcept a viable alternative to today's -fno-exceptions. In
particular, that means fixing the longstanding issue that LLVM can't
model C++'s "you may choose to not unwind if unwinding would reach a
noexcept function" rule, which currently results in bad codegen for
noexcept functions compared to -fno-exceptions. Eg, compare clang and
GCC codegen with and without -fno-exceptions for:
struct X { ~X(); };
void g();
void f() noexcept {
X x;
g();
}