GCC 7.2 and clang 5.0 seem to disagree about the following code when compiled with -std=c++17 -Werror -Wconversion:
#include <iostream>
#include <string>
#include <string_view>
int main(int argc, char* argv[]) {
std::string s = "Hello, World";
std::string_view vs{s};
std::cout << std::string{vs} << '\n';
return EXIT_SUCCESS;
}
Compiled with clang++ -std=c++17 -Wall -Werror -Wconversion, it compiles correctly (see https://godbolt.org/g/JZn8cL)
However, GCC 7.2 issues a somewhat perplexing diagnostic (see https://godbolt.org/g/kmYbJ3):
<source>: In function 'int main(int, char**)':
7 : <source>:7:26: error: choosing 'std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::__sv_type() const [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::__sv_type = std::basic_string_view<char>]' over 'constexpr std::basic_string_view<_CharT, _Traits>::basic_string_view(const std::basic_string_view<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]' [-Werror=conversion]
std::string_view vs{s};
^
7 : <source>:7:26: error: for conversion from 'std::__cxx11::string {aka std::__cxx11::basic_string<char>}' to 'std::basic_string_view<char>' [-Werror=conversion]
7 : <source>:7:26: note: because conversion sequence for the argument is better
cc1plus: all warnings being treated as errors
Compiler exited with result code 1
Both compilers compile the code fine after changing vs{s} to vs(s).
Which compiler is right here? Is brace initialization of a std::string_view from a std::string running afoul of conversion rules somehow, and clang is failing to issue a diagnostic when it could/should? Or is GCC in the wrong and the diagnostic is erroneous?
Which compiler is right here?
Both? Compilers are allowed to give warnings, or not, as they choose. It's just that when you write:
std::string_view vs{s};
You might be under the impression that this is doing something like aggregate initialization or at least invoking a string_view constructor, but it's not - and maybe that impression isn't as likely to happen if you wrote:
std::string_view vs(s);
so gcc gives you a warning (since you asked for one).
The code is fine. Both compilers are fine. Just use ()s to initialize, there's no reason to use {} here (there is no difference in behavior in the two approaches).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With