microsoft / STL

MSVC's implementation of the C++ Standard Library.
Other
10.25k stars 1.51k forks source link

<array>: array<const T, 0> allows fill() and swap() #1295

Open StephanTLavavej opened 4 years ago

StephanTLavavej commented 4 years ago

Similar-but-distinct from #942; we should track it as a separate issue. The following libcxx tests are skipped:

https://github.com/microsoft/STL/blob/9e76d8c3d3700e086f3fbedd0c5b71f1678e4796/tests/libcxx/expected_results.txt#L543-L545 https://github.com/microsoft/STL/blob/9e76d8c3d3700e086f3fbedd0c5b71f1678e4796/tests/libcxx/skipped_tests.txt#L543-L545

Because they're implemented as no-ops:

https://github.com/microsoft/STL/blob/9e76d8c3d3700e086f3fbedd0c5b71f1678e4796/stl/inc/array#L600-L622

WG21-N4861 [array.members]/3 specifies fill() with "Effects: As if by fill_n(begin(), N, u)." and /4 specifies swap() with "Effects: Equivalent to swap_ranges(begin(), end(), y.begin())."

Notably, these "equivalent to" calls are ill-formed for const T (even if there happen to be zero of them), so libcxx is correct to expect these to fail to compile (this is what meow.fail.cpp means).

We should be able to fix this without breaking ABI; static_assert should be sufficient.

AdamBucior commented 4 years ago

It's weird to me that the member swap does not allow non-swappable types when size is 0 but the non-member swap allows them (even though it just calls the member swap). https://github.com/microsoft/STL/blob/5f3e91211ab25a2f493edf5f7d28520ac6b81d28/stl/inc/array#L771-L774 Is it a bug in the standard?

CaseyCarter commented 4 years ago

Is it a bug in the standard?

It certainly seems so. I was trying to ignore this, but now you've prompted me to poke LWG about it.