After trying to delve a bit into the mechanics behind cases such as this question brings into light, I still don't understand why the third line in the code below generates only a warning while the second line is an error.
int main()
{
const char* const& a = "bla"; // Valid code
const char*& a2 = "bla"; // Invalid code
char* const& a3 = "bla"; // Should be invalid but settles for a warning
return 0;
}
I know that while the reference initialization is converting the string literal to a pointer reference then it shouldn't be dropping any cv-qualifiers the object has, and as the converted type is const char* const (converted from the string literal "bla", i.e. const char[4]) it seems to be of the same case as the second line. The only difference being that the const being dropped belongs to the C string itself and not to the pointer.
Reproduces on both GCC 8.2 and Clang 6.0.0 without specifying any extra conformance flags.
Output from gcc:
<source>:4:23: error: cannot bind non-const lvalue reference of type 'const char*&' to an rvalue of type 'const char*'
const char*& a2 = "Some other string literal";
^~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:5:23: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
char* const& a3 = "Yet another string literal";
Why are current day compilers conforms to the first case but not to the second? Or alternatively, is there a fundamental difference I'm missing here between the two cases?